Notes {labels: 'NewtDev_d} ERASE! // No empty lines between erase! and first item aComments func() begin end /* - Last compilation 960421 - Compiles under NewtDev 3.3fN + Pack 3.3cN on upgraded OMP w/ OS1.3(414313) - Based on code by Konrad Hinsen, hinsen@ere.umontreal.ca; no|SoftwareGmbH, Ritzstr. 13, D-54595 Pruem, Germany. - See helpbook for more info. - ListExtras is utility for determining app/owner symbols of installed apps. - View on screen's right edge after build is an artifact that goes away when screen refreshed. - Scratchpad useful even under NOS 2.0 -- character entry in long paragraphs still slow (at least in my trial); each NewtDev source page is one "paragraph." - The default placement covers the name of the month in the Dates calendar (Konrad's original placement was on the other side). If you'd prefer a different location simply move the view after a reboot; recompile the code to permanently change the location. - For paraV to save its text in the NewtDev environment requires access to an installed app's savedText slot. */ ----- aTest func() begin end /* */ ----- init func() // :init() // re-eval after changes begin :defConst('kAppSymbol, '|noButts:bc|); :defConst('kGraffitiSym, '|Graffiti:Palm|); :defConst('k2brdr, 12); //2x width of view border :defConst('kDragLip, 5); //drag margin end ----- noButts //:doObj('buildCO,'noButts) //:doObj('add,'noButts) //:saveApp('noButts) //:BuildFolderLib('noButts) //noButts:open() {_proto: protoFloater, // put button bar in the top right corner (for left corner, change L RelB to +, vjParH to left, and invert bounds calc) viewBounds: RelBounds (-2, 2, 0, 12), viewJustify: vjParentRightH+vjParentTopV, viewFormat: vfFillWhite+vfFrameBlack+vfPen*1+vfInset*1+vfRound*0, savedText: "", //for ScratchPad viewQuitScript: func() savedText:= helpView:= nil, viewSetupFormScript: func() begin // calculate correct width depending on number and size of buttons, less 1 for each non-button child local nonButns := 1; local bounds := Clone(viewBounds); if self.stepChildren exists then begin // bounds.right := bounds.left + //for left side bounds.left := bounds.right - (Length(stepChildren)-nonButns) * protoBarButton.viewBounds.right; self.viewBounds := bounds; end; end, // Platform function viewIsOpen: kViewIsOpenFunc, _package: { // Make sure it doesn't close automatically autoClose: 'noAutoClose, shortTitle: "noButts", devSignature: "bc", version: 099, copyright: "(c) 1995, no|Software GmbH; 1996, Bill Cooper", installScript: func(removeFrame) begin // Close card slip if open AddDeferredAction(func() if GetRoot().backupSlip.viewCObject <> nil then GetRoot().backupSlip:close(), []); // Open automatically AddDeferredAction(func() GetRoot().(kAppSymbol):open(), []); end, }, //end of package } ----- noButts.protoBarButton {_proto: protoStaticText, viewBounds: {left:0, right:12, top:0, bottom:0}, viewJustify: vjParentFullV + vjParentLeftH + vjSiblingRightH + vjCenterH + vjCenterV, viewFormat: vfFillWhite + vfFrameMatte + vfPen*1 + vfInset*1, viewFlags: vVisible + vReadonly + vClickable, text: " ", viewFont: ROM_fontSystem9, viewClickScript: func(unit) begin InkOff(unit); count := 0; viewUnit := unit; if :TrackHilite(unit) then begin :Hilite(nil); if count < dragCount then :?buttonClickScript(); end; true //stop others from handling click end, count: 0, dragCount: 20, viewUnit: nil, buttonPressedScript: func() begin //dragging count := count + 1; if count = dragCount then begin :Parent():Drag(viewUnit,nil); :Parent():Dirty(); end; end, //these methods support buttons that popup and postkeys buttonPressedScriptPopUp: func(me,menu) begin count := count + 1; if count = dragCount then DoPopup(menu,0,0,me); end, postTheText: func(txt) PostKeyString('viewFrontKey,txt), pickActionScript2: func(me,a,b) begin setvalue(me,'text,a); //set button text me.bThing:= b; //set post string or app symbol me:Hilite(nil); end, } ----- noButts.help~ {helpBook: :helpBookTemplate(), helpView: nil, //slot holds builtContext buildHelpBook: func() begin self.helpView:= BuildContext({ _proto: GetRoot().TinyTim._proto, bookRef: helpBook}); GetRoot().TinyTim:close(); //in case open helpView:openManual(helpBook); end, } ----- noButts+aCharButton~ {_proto: protoBarButton, text: "d", bThing: "\u0008", menu1: ["d","s","t", ], //button text menu2: ["\u0008"," ","\t",], //post menu3: ["delete","space","tab",], //menu buttonClickScript: func() :postTheText(bThing), buttonPressedScript: func() :buttonPressedScriptPopUp(self,menu3), pickActionScript: func(index) begin :pickActionScript2(self,menu1[index], menu2[index]); :postTheText(bThing); end, } ----- noButts+aReturnButton~ {_proto: protoBarButton, text: "r", buttonClickScript: func() begin PostKeyString('viewFrontKey, "\n") end, } ----- noButts+azBulletButton~ {_proto: protoBarButton, text: "\u2022", //bullet char bThing: "\n\u2022\u ", //current post string menu1: ["\u2022","-",], //button text menu2: ["\n\u2022\u ","\n- ",], //post strings; note space after char menu3: ["\u2022","-",], //menu strings buttonClickScript: func() :postTheText(bThing), buttonPressedScript: func() :buttonPressedScriptPopUp(self,menu3), pickActionScript: func(index) begin :pickActionScript2(self,menu1[index], menu2[index]); :postTheText(bThing); end, } ----- noButts.helpBook+page01 .# this is a comment .subject 1 Credits et al .story noButts. by Bill Cooper. v0.99, 1996.04 Based on "noButtons" by Konrad Hinton, 1995. Free software "copylefted" under the General Public License of the Free Software Foundation. Modify, use and pass on this software as you wish, but always provide the source code if asked. As a courtesy, credit previous authors in your code. Developed on the Newton with NewtDev, Steve Weyer's development system (weyer@netaxs.com). Contact the author at bwcooper@ ucdavis.edu, or P.O. Box 72781, 95617. ----- noButts.helpBook+page02 .subject 1 The Button Bar .story The button bar is positioned in the upper right corner when first opened. Press the " L " button for a second or so, then drag the bar elsewhere if desired. Some buttons have both a tap and a press behavior. Tapping the button performs an action. Pressing the button pops up a menu of options. Selecting a menu item performs the chosen action and makes that the button's new function. ----- noButts.helpBook+page03 .subject 1 The Buttons .story Tapping the first button from the left (initially labeled " d " for delete) inserts a character at the insertion point (also useful for erasing selected text). Pressing this button pops up an options menu. Tapping the button labeled " r " inserts a newline (return) character. This button has no menu. Tapping the third button from the left (a bullet) inserts a newline and a bullet character. Press this button for a menu. The fourth button opens or closes the alphanumeric keyboard. Graffiti appears in the menu if installed. ----- noButts.helpBook+page04 .subject 1 Launch Menu .story The " L " or Launch button menu has four sections. The first lists "quick pick" applications. If Replacer or Ruler is installed they will appear here. The second section shows - and lets you switch between - currently running applications. The third section lists several utilities. One of them, Scatchpad, is described in the next topic. The fourth section is what you are reading. ----- noButts.helpBook+page05 .subject 1 Scatchpad .story Scatchpad is a draggable, writeable view. On it you can write small, quickly editable pieces of text you can paste into other views - useful when editing and adding text in long notes Clear the view with the Clr button; select all text with All. Drag the selected text into the Notepad or use the clipboard. Shapes are not supported. Text is retained by the view when closed. ----- noButts+KeyboardButton~ {_proto: protoBarButton, text: "K", bThing: 'alphaKeyboard, menu1: ["K","G",], menu2: ['alphaKeyboard, kGraffitiSym,], menu3a: ["alphaKbd","Graffiti",], menu3b: ["alphaKbd",], //not a generic solution buttonPressedScript: func() :buttonPressedScriptPopUp(self, if GetRoot().(kGraffitiSym) exists then menu3a else menu3b), toggleApp: func(sym) begin local k := GetRoot().(sym); if :ViewIsOpen(k) then k:Close() else k:Open(); end, buttonClickScript: func() :toggleApp(bThing), pickActionScript: func(index) begin :pickActionScript2(self,menu1[index], menu2[index]); :toggleApp(bThing); end, } ----- noButts+LaunchButton {_proto: protoBarButton, text: "L", quickApps: ['|NewtDevEnv:TKnollSys|, 'calculator, 'backupSlip, 'stylePalette, '|Ruler:bc|, '|Replacer:bc|,], //'dockerChooser, //why does listExtras show card instead of backupSlip? appList: [], firstOpen: 0, lastOpen: 0, extrasEntry: nil, // This function finds the element in // GetGlobals().Extras that corresponds to // a given application symbol. findExtrasEntry: func(sym) begin local app; if extrasEntry = nil then begin foreach app in GetGlobals().Extras do if app.app = sym then break extrasEntry := app; end; extrasEntry; end, // Construct the menu entry for an app. findAppName: func(sym) begin if sym = 'backupSlip then "Card" else //handle exception for backupSlip/card if GetRoot().(sym).title exists then GetRoot().(sym).title; else if :findExtrasEntry(sym) then extrasEntry.text; else SPrintObject(sym); end, // Find the app symbol for a given view. findAppSymbol: func(view) if Band(view.viewFlags,4)=0 then nil else view.appSymbol, viewQuitScript: func() appList:= firstOpen:= lastOpen:= extrasEntry:= nil, } ----- noButts.LaunchButton.buttonClickScript func() begin local app, view, isArchived; local menu := []; appList := []; // make list of quick-access apps foreach app in quickApps do begin extrasEntry := nil; if :findExtrasEntry(app).archived exists then isArchived:= true else isArchived:= nil; // workaround problem w/ keyboard and like returning nil path if (HasSlot(GetRoot(),app) and not :viewIsOpen(GetRoot().(app))) or isArchived then begin AddArraySlot(appList,app); AddArraySlot(menu, :findAppName(app)); end; end; if Length(appList) > 0 then begin AddArraySlot(appList,nil); AddArraySlot(menu,'pickSeparator); end; // make list of open apps firstOpen := Length(appList); foreach view in GetRoot():childViewFrames() do begin app := :findAppSymbol(view); if not app = nil then begin AddArraySlot(appList,app); AddArraySlot(menu, :findAppName(app)); end; end; lastOpen := Length(appList) - 1; if Length(appList) > 0 then begin AddArraySlot(appList,nil); AddArraySlot(menu,'pickSeparator); end; // add user funcs AddArraySlot(appList,'reboot); AddArraySlot(menu,"Reboot"); AddArraySlot(appList,'showMemFree); AddArraySlot(menu,"showMemFree"); AddArraySlot(appList,'doTextFnG); AddArraySlot(menu,"Scatchpad"); //Add info pick AddArraySlot(appList,nil); AddArraySlot(menu,'pickSeparator); AddArraySlot(appList,'doInfoFloatNGo); AddArraySlot(menu,"Info"); // open the popup menu if Length(menu) > 0 then DoPopup(menu,0,0,self); end ----- noButts.LaunchButton.pickActionScript func(index) begin local i,widget; extrasEntry := nil; // reboot: ask for confirmation first if appList[index] = 'reboot then GetRoot():confirm("noButts", "Do you really want to reboot?", self, 'reboot) else // other usr funcs if appList[index] = 'showMemFree then begin playsound(@102); DoPopup([:showMemFree()],12,12,nil); end else if appList[index] = 'doInfoFloatNGo then :buildHelpBook() //:doInfoFloatNGo(); else if appList[index] = 'doTextFnG then begin appArea := getAppParams(); : doTextFnG(); end // open application: hide those above else if index >= firstOpen then begin SetKeyView(nil,nil); for i := firstOpen to index do GetRoot().(appList[i]):show(); for i := index+1 to lastOpen do GetRoot().(appList[i]):hide(); end else // open the selected application if GetRoot().(appList[index]) exists then GetRoot().(appList[index]):open(); else begin widget := Clone( :findExtrasEntry(appList[index])); widget._parent := GetRoot().extrasDrawer; widget._proto := GetRoot().extrasDrawer.baseExtra; AddDeferredAction(func(x) x:buttonClickScript(), [widget]); end; end ----- noButts.LaunchButton.userFuncs~ { showMemFree:func() begin gc(); "after gc():"&NumberStr(stats()); end, reboot: func(flag) if flag then Reboot(), doTextFnG:func() begin if zTextFloatNGo exists then begin zTextFloatNGo:= BuildContext( zTextFloatNGo._proto); zTextFloatNGo:Open(); end; end, } ----- noButts+zTextFloatNGo {_proto: protoFloatNGo, viewFlags:vClickable+vFloating, // keep this dragable view invis until open or bizarre compile! viewSetupDoneScript: func() begin if paraV exists then setValue(paraV,'text,GetRoot().(kAppSymbol).savedText); end, dragBounds: nil, viewSetupFormScript:func() begin local b:= GetAppParams(); local xa:= b.appAreaWidth; local ya:= b.appAreaHeight; local xb:= min(240,xa)-k2brdr; //less 6 pixel border x2 local yb:= min(162,ya)-k2brdr; dragBounds:= SetBounds(0-xb+kDragLip, 0-yb+kDragLip, xa+xb-kDragLip, ya+yb-kDragLip); self.viewbounds := RelBounds(0,20,xb,yb) end, clickAbove:nil, //flg set by paraV if clicked viewQuitscript:func() clickAbove:=nil, viewClickScript:func(unit) if clickAbove then begin clickAbove := nil; // clr always nil // msg not handled, reverts to clParaV receiver end else begin :Drag(unit,dragBounds); clickAbove := nil; true; end, } ----- noButts.zTextFloatNGo+allbut {_proto: protoTextButton, text: "All", viewbounds:Relbounds(45,138,25,9), /* problem centering button text when using view justify flags viewBounds:{left:35,top:-12,right:55,bottom:-3}, viewJustify: vjParentLeftH+vjParentBottomV, */ buttonClickScript: func() begin paraV:SetHilite(0,StrLen(paraV.text),nil); end, } ----- noButts.zTextFloatNGo+clrbut {_proto: protoTextButton, text: "Clr", viewbounds:Relbounds(5,138,25,9), //viewBounds:{left:5,top:-12,right:25,bottom:-3}, //viewJustify: vjParentLeftH+vjParentBottomV, buttonClickScript: func() begin setvalue(paraV,'text,""); end, } ----- noButts.zTextFloatNGo+paraV {viewClass: clParagraphView, viewBounds: {left:3, top:5, right:-3, bottom:-17}, viewJustify: vjParentFullH+vjParentFullV, text:nil, viewFont: fancyFont10, viewFlags: vVisible + vClickable + vGesturesAllowed + vCharsAllowed + vNumbersAllowed, viewFormat: vfFillWhite + vfFrameBlack + vfPen*1 + vfLinesGray, viewLineSpacing: 18, tabs: [36,72,108,144,180,216], viewClickScript:func(unit) begin clickAbove:=true; // flag to parent nil; // msg moves up parent chain end, viewQuitScript: func() begin GetRoot().(kAppSymbol).savedText:=text; //setValue(kNobutSymbol,'savedText,text); end, } ----- x_listExtras //:listExtras() func() begin local app; foreach app in GetGlobals().extras do print(app.text & ":" && app.app); end ----- x_noButts+GraffitiButton~ {_proto: protoBarButton, text: "G", buttonClickScript: func() begin local g := GetRoot().|Graffiti:Palm|; local w; if :ViewIsOpen(g) then g:Close(); else begin //w:= g.viewBounds.right - g.viewBounds.left; g:Open(); //if w > 80 then //g.stepChildren[17] //:buttonClickScript(); end; end, } ----- x_noButts+TopAppButton~ {_proto: protoBarButton, text: "T", actionTable: { |NewtDevEnv:TKnollSys|: func(view) begin view.exprKbd:toggle(); end, paperRoll: func(view) begin GetRoot().stylePalette:open(); end, Names: func(view) begin GetRoot().alphaKbd:open(); end }, buttonClickScript: func() begin local topView := GetView('viewFrontMostApp); local sym := topView.appSymbol; if HasSlot(self.actionTable,sym) then Perform(self.actionTable,sym, [topView]); end, } ----- BYE!