// Text of project Roll Project written on 5/9/97 at 2:51 PM // Beginning of text file Definitions.f /* ** Newton Developer Technical Support Sample Code ** ** WhoOwesWhom, a Stationery Example ** ** by Bob Ebert & Greg Christie, Newton Developer Technical Support ** ** Copyright © 1995 by Apple Computer, Inc. All rights reserved. ** ** You may incorporate this sample code into your applications without ** restriction. This sample code has been provided "AS IS" and the ** responsibility for its operation is 100% yours. You are not ** permitted to modify and redistribute the source as "DTS Sample Code." ** If you are going to re-distribute the source, we require that you ** make it clear in the source that the code was descended from ** Apple-provided sample code, but that you've made changes. */ // App stuff constant kSuperSymbol := '|IOU:PIEDTS|; // A good idea, generally constant kDataSymbol := '|IOU:PIEDTS|; // For single dataDef apps // constant kData2Symbol := '|UOMe:PIEDTS|; // example of a 2nd data def symbol constant kTestMinAppSize := nil; constant kTestMaxAppSize := nil; constant kMinWidth := 220; constant kMaxWidth := 240; constant kMinHeight := 220; constant kMaxHeight := 336; // End of text file Definitions.f // Beginning of text file RollDefinitions.f // Copyright ©1995 Apple Computer, Inc. All rights reserved. // App Specific Specific Stuff constant kAppTitle := "Roll Starter"; // End of text file RollDefinitions.f // Beginning of file protoCheckAllButton // Before Script for protoCheckAllButton // Copyright ©1995-7 Apple Computer, Inc. All rights reserved. // This file shows how to create a simple button which does a "check all" // for an overview. It matches the 2.1 OS feature, checking all items // in the current folder. Most of the work is actually in the CheckAll // method of the newtOverLayout protoCheckAllButton := {viewBounds: {left: 7, top: 0, right: 33, bottom: 13}, buttonClickScript: func() if newtAppBase.currentLayout = 'overView then begin if layout.checkAllPrimed then layout:UnCheckAll() else layout:CheckAll(); layout.checkAllPrimed := NOT layout.checkAllPrimed; end;, icon: MakePixFamily( GetResourceFromFile({filename: "DigDug:DTS:Newton Sample Code:Ready to Bless:WhoOwesWhom-5:Common Files:resources.rsrc" , resource: 132}), nil, [ {rsrcSpec: GetResourceFromFile({filename: "DigDug:DTS:Newton Sample Code:Ready to Bless:WhoOwesWhom-5:Common Files:resources.rsrc" , resource: 132}), bitDepth: 1}, {rsrcSpec: GetResourceFromFile({filename: ":", resource: }), bitDepth: 2}, {rsrcSpec: GetResourceFromFile({filename: ":", resource: }), bitDepth: 4}, {rsrcSpec: GetResourceFromFile({filename: ":", resource: }), bitDepth: 8}]);, debug: "protoCheckAllButton", _proto: @198 /* protoPictureButton */ }; constant |layout_protoCheckAllButton| := protoCheckAllButton; // End of file protoCheckAllButton // Beginning of file myNewtLabelInputLine // Before Script for myNewtLabelInputLine /* ** Newton Developer Technical Support Sample Code ** ** WhoOwesWhom, a Stationery Example ** ** by Bob Ebert & Greg Christie, Newton Developer Technical Support ** ** Copyright © 1995 by Apple Computer, Inc. All rights reserved. ** ** You may incorporate this sample code into your applications without ** restriction. This sample code has been provided "AS IS" and the ** responsibility for its operation is 100% yours. You are not ** permitted to modify and redistribute the source as "DTS Sample Code." ** If you are going to re-distribute the source, we require that you ** make it clear in the source that the code was descended from ** Apple-provided sample code, but that you've made changes. ** ** newtFooView -- Do It Yourself simple labeled slotView sample. Gregory N. Christie ** This is intended to illustrate how to create a proto which works with the ** newtApp set of protos, but which is built entirely from standard (that is, ** non-newtApp) parts. */ myNewtLabelInputLine := {viewBounds: {left: 0, top: 8, right: 0, bottom: 32}, viewJustify: 9728, path: nil // pathExpr defining where this view should get it's data // from and where it should update to. , TargetData: // Does the actual work of updating this view. func() begin if target AND path then Clone(target.(path)) else defaultValue; end, Retarget: // when called, updates this view from the entry. func() begin inReTarget := true; SetValue(self.entryLine, 'text, :TargetData()); inReTarget := nil; end, viewLineSpacing: 25, jamSlot: nil // Should this view be Jammed? nil for no, otherwise this slot contains // a pathExpr defining where the jammed info should be gotten from. // akin to path but for the foreign entry. , JamFromEntry: // Used when this entry is "Jammed" by a foreign entry. // Execution controlled by JamSlot func( otherEntry ) begin if jamSlot then begin target.(path) := nil; if otherEntry then target.(path) := otherEntry.(jamSlot); end; end;, defaultValue: "" // if target.(path) = nil, then use this value See :TargetData(). , textChanged: func() begin if NOT inReTarget then begin target.(path) := Clone(self.text); :StartFlush(); end; end, inReTarget: nil // used to block a viewChangedScript/SetValue loop , viewSetupDoneScript: func() begin SetValue(self.entryLine,'text, :TargetData()); end, debug: "myNewtLabelInputLine", _proto: @189 /* protoLabelInputLine */ }; constant |layout_myNewtLabelInputLine| := myNewtLabelInputLine; // End of file myNewtLabelInputLine // Beginning of file iouDataDef // Before Script for iouDataDef // Copyright © 1995 by Apple Computer, Inc. All Rights Reserved. iouDataDef := {symbol: kDataSymbol, name: "IOU" // Shows up in "New" button. , description: "An IOU Entry" // shows up in "info" slip when you tap in the newtEntryHeader bar , icon: GetPictAsBits("overviewIcon", true), superSymbol: kSuperSymbol, StringExtract: // Called by overview to get a text description of the data. func(item, numLines) begin if numLines = 1 then return item.title else return item.title && item.(kDataSymbol).who; end, TextScript: // used by text transports (for example, email) to get a text version of the entire entry // differs from StringExtract in that this returns the whole thing as text. func(item, target) begin item.text := "IOU\n" & target.(kDataSymbol).who && "owes me" && NumberStr(target.(kDataSymbol).howMuch); end, version: 1, height: 176, FillNewEntry: // takes a new entry "shell" and fills it with class-specific data // We recommend that the data-def specific data be kept in a sub-frame in the // entry. (This provides a nice abstraction layer which may come in handy when // using the dataDef with other applications, or updating generic data.) func(theNewEntry) begin constant kOneWeekInSeconds := 7*1440; // number of seconds in one week constant kDataTemplate := '{ who: nil, phone: nil, howMuch: 0, dueDate: nil, risk: "Dunno", notes: nil, }; theNewEntry.(kDataSymbol) := Clone(kDataTemplate); theNewEntry.(kDataSymbol).dueDate := time()+(kOneWeekInSeconds); // Give 'em a week to pay theNewEntry.class := theNewEntry.viewStationery := kDataSymbol; theNewEntry.title := ShortDate(time()); theNewEntry; end, MakeNewEntry: // If the newtApp opening this has no CreateBlankEntry method for the newtSoup, // then this method will be called. So create a "minimal" soup entry for the // otherwise-generic application. (Just use FillNewEntry on an empty frame...) func() begin :FillNewEntry({}); // † end; // †to the first time reader: // * MakeNewEntry is sent as a message to the datadef, so :FillNewEntry calls // the right function. // * We pass the empty frame because FillNewEntry needs a frame to fill, and the // dataDef can provide no other information. // * FillNewEntry evaluates to the newly filled entry, which will be the return value // from this method. , debug: "iouDataDef", _proto: @451 /* newtStationery */ }; constant |layout_iouDataDef| := iouDataDef; // End of file iouDataDef // Beginning of file iouDefaultViewDef // Before Script for iouDefaultViewDef // Copyright © 1995 by Apple Computer, Inc. All Rights Reserved. iouDefaultViewDef := {viewBounds: {left: 0, top: 0, right: 0, bottom: 0}, viewFlags: 1, viewFormat: 1, viewJustify: 240, name: "IOU Info" // Appears in the "Show" button , symbol: 'default // one viewDef *must* be the 'default , type: 'editor // 'viewer, 'editor, 'printFormat are standards, but you can extend the types , viewDefHeight: 176 // each slotView is 8+34 high, add 8 border at bottom // this slot is not used for card flavor of newtApplications , protection: 'private // show this only in this app. For instance, DONT show it in IOBox , debug: "iouDefaultViewDef", viewClass: 74 /* clView */ }; who := {viewBounds: {left: 8, top: 0, right: -8, bottom: 32}, path: [pathExpr: kDataSymbol, 'who] // where to look in a soup entry for this data , label: "Who:", usePopup: "nil", viewJustify: 8240, debug: "who", _proto: @427 /* newtSmartNameView */ }; AddStepForm(iouDefaultViewDef, who); iouDefaultViewDef_v425_0 := {path: [pathExpr: kDataSymbol, 'phone], label: "Phone:", viewJustify: 8240, viewBounds: {left: 8, top: 0, right: -8, bottom: 32}, _proto: @425 /* newtLabelPhoneInputLine */ }; AddStepForm(iouDefaultViewDef, iouDefaultViewDef_v425_0); how much := {viewBounds: {left: 8, top: 0, right: -8, bottom: 32}, path: [pathExpr: kDataSymbol, 'howMuch], label: "How Much:", viewJustify: 8240, JamFromEntry: // Used when this entry is "Jammed" by a foreign entry. // This "do-nothing" script will prevent a foreign entry from overwriting this slot. func(otherEntry) begin nil; end, debug: "how much", _proto: @423 /* newtLabelNumInputLine */ }; AddStepForm(iouDefaultViewDef, how much); date due := {viewBounds: {left: 8, top: 0, right: -8, bottom: 32}, path: [pathExpr: kDataSymbol, 'dueDate], label: "Date Due:", viewJustify: 8240, JamFromEntry: // Used when this entry is "Jammed" by a foreign entry. // This "do-nothing" script will prevent a foreign entry from overwriting this slot. func(otherEntry) begin nil; end, debug: "date due", _proto: @424 /* newtLabelDateInputLine */ }; AddStepForm(iouDefaultViewDef, date due); iouDefaultViewDef_v0_4 := {viewBounds: {left: 8, top: 0, right: -8, bottom: 32}, viewJustify: 8240, path: [pathExpr: kDataSymbol, 'risk] // pathExpr defining where this view should get it's data // from and where it should update to. , labelCommands: ["Dunno", "Trustworthy","DeadBeat"], label: "Risk:", _proto: myNewtLabelInputLine }; AddStepForm(iouDefaultViewDef, iouDefaultViewDef_v0_4); constant |layout_iouDefaultViewDef| := iouDefaultViewDef; // End of file iouDefaultViewDef // Beginning of file iouNotesViewDef // Before Script for iouNotesViewDef // Copyright © 1995 by Apple Computer, Inc. All Rights Reserved. iouNotesViewDef := {viewBounds: {left: 0, top: 0, right: 0, bottom: 0}, viewFlags: 1, viewFormat: 1, viewJustify: 240, name: "IOU Notes" // Visible in "Show" menu , symbol: 'notes // can be anything unique within the "dataDef" namespace, we used 'default already , type: 'editor, minimalBounds: // compute the minimal size for the viewDef at run-time. // not used for card flavors of NewtApplication func(entry) begin local result := {left: 0, top: 0, right: 0, bottom: viewDefHeight}; // show a little // for editView, make the bounds big enough to contain all the kids if entry.(kDataSymbol).notes then foreach item in entry.(kDataSymbol).notes do result := UnionRect( result, item.viewBounds ); result; end, viewDefHeight: 60 // shows smartName and a little of the editView , protection: 'private // show this only in this app. For instance, DONT show it in IOBox , debug: "iouNotesViewDef", viewClass: 74 /* clView */ }; iouNotesViewDef_v427_0 := {viewBounds: {left: 8, top: 0, right: -8, bottom: 32}, path: [pathExpr: kDataSymbol, 'who], label: "Who:", usePopup: "nil", viewJustify: 8240, _proto: @427 /* newtSmartNameView */ }; AddStepForm(iouNotesViewDef, iouNotesViewDef_v427_0); iouNotesViewDef_v425_0 := {path: [pathExpr: kDataSymbol, 'phone], label: "Phone:", viewJustify: 8240, viewBounds: {left: 8, top: 0, right: -8, bottom: 32}, _proto: @425 /* newtLabelPhoneInputLine */ }; AddStepForm(iouNotesViewDef, iouNotesViewDef_v425_0); iouNotesViewDef_v413_0 := {viewBounds: {left: 0, top: 64, right: 0, bottom: 0}, path: [pathExpr: kDataSymbol, 'notes], viewJustify: 240, _proto: @413 /* newtEditView */ }; AddStepForm(iouNotesViewDef, iouNotesViewDef_v413_0); constant |layout_iouNotesViewDef| := iouNotesViewDef; // End of file iouNotesViewDef // Beginning of file iouPrintFormat // Before Script for _v200_0 // Copyright ©1995 Apple Computer, Inc. All rights reserved. _v200_0 := { printNextPageScript: func() begin nil; // Retrun nil to indicate 'only print one page' end, title: "IOU", symbol: 'iouPrintFormat, _proto: @200 /* protoPrintFormat */ }; _v200_0_v81_0 := {viewBounds: {top: 30, left: 30, right: -30, bottom: -30}, viewFlags: 1, viewFont: tsFancy + tsSize(18) + tsBold, text: "\"\"", fluff: "^0 owes me ^1, payable at exactly ^2.", viewJustify: 8434, viewSetupFormScript: func() begin local theName := "Nobody"; if target.(kDataSymbol).who then theName := target.(kDataSymbol).who; local theAmount := "nothing"; if target.(kDataSymbol).howMuch then theAmount := "$"&& FormattedNumberStr(target.(kDataSymbol).howMuch,"%.2f"); local theDue := "never"; if target.(kDataSymbol).dueDate then theDue := DateNTime(target.(kDataSymbol).dueDate); text := ParamStr(fluff,[theName,theAmount,theDue]); end, viewClass: 81 /* clParagraphView */ }; AddStepForm(_v200_0, _v200_0_v81_0); constant |layout_iouPrintFormat| := _v200_0; // End of file iouPrintFormat // Beginning of file defaultEntryView // Before Script for _v409_0 // Copyright © 1995 by Apple Computer, Inc. All Rights Reserved. _v409_0 := {viewFormat: 1, _proto: @409 /* newtRollEntryView */}; _v409_0_v410_0 := {_proto: @410 /* newtEntryRollHeader */}; AddStepForm(_v409_0, _v409_0_v410_0); // Before Script for _v409_0_v411_0 // this view acts as a "container" for a view instantiated from a viewDef template // based on the class of the target and the type of viewer selected. // That is, this one view has all the "smarts" to pick the right stationery. _v409_0_v411_0 := {viewBounds: {left: 0, top: 16, right: 0, bottom: 0}, viewJustify: 240, _proto: @411 /* newtStationeryView */ }; AddStepForm(_v409_0, _v409_0_v411_0); constant |layout_defaultEntryView| := _v409_0; // End of file defaultEntryView // Beginning of file Default Layout // Before Script for defaultLayout // Copyright © 1995 by Apple Computer, Inc. All Rights Reserved. defaultLayout := {viewBounds: {top: 20, left: 0, right: 0, bottom: -20}, name: "IOU Info" // If this were a multiple-layout style newtApp, this would be used in the newtShowMenu , forceNewEntry: true // create a new entry if the folder is empty. , menuLeftButtons: // these *replace* any menuLeftButtons in the menuLeftButtons of the actual // newtStatusBar in the main layout, but only if statusBarSlot has a value. [ newtInfoButton, newtNewStationeryButton, newtRollShowStationeryButton, ], menuRightButtons: // these *replace* any menuRightButtons in the menuRightButtons of the actual // newtStatusBar in the main layout, but only if statusBarSlot has a value. [], viewJustify: 240, masterSoupSlot: 'IOUSoup // VERY IMPORTANT -- the slot in the allSoups frame in the newtApplication layer , protoChild: GetLayout("DefaultEntryView"), debug: "defaultLayout", _proto: @403 /* newtRollLayout */ }; constant |layout_Default Layout| := defaultLayout; // End of file Default Layout // Beginning of file Overview Layout // Before Script for over // Copyright © 1995 by Apple Computer, Inc. All Rights Reserved. over := {viewBounds: {left: 0, top: 20, right: 0, bottom: -20}, masterSoupSlot: 'IOUSoup // use this slot in the allSoups frame in the main layout , name: "Overview" // never used, but required. , viewJustify: 240, forceNewEntry: true // no empty folders -- create an entry if one doesn't exist , menuLeftButtons: // replaces the menuLeftButtons in the newtStatusBar in the main layout if statusBarSlot is set. [ newtInfoButton, newtNewStationeryButton, ], menuRightButtons: // replaces the menuLeftButtons in the newtStatusBar in the main layout if statusBarSlot is set. [ newtActionButton, newtFilingButton, GetLayout("protoCheckAllButton"), ], centerTarget: true // when you switch to overview, the current entry should be centered in the list , debug: "over", _proto: @374 /* newtRollOverLayout */ }; constant |layout_Overview Layout| := over; // End of file Overview Layout // Beginning of file baseView // Before Script for baseView /* ** Newton Developer Technical Support Sample Code ** ** WhoOwesWhom, a Stationery Example ** ** by Bob Ebert & Greg Christie, Newton Developer Technical Support ** ** Copyright © 1995 by Apple Computer, Inc. All rights reserved. ** ** You may incorporate this sample code into your applications without ** restriction. This sample code has been provided "AS IS" and the ** responsibility for its operation is 100% yours. You are not ** permitted to modify and redistribute the source as "DTS Sample Code." ** If you are going to re-distribute the source, we require that you ** make it clear in the source that the code was descended from ** Apple-provided sample code, but that you've made changes. */ baseView := { allDataDefs: // this needs to be a frame where each slot is the 'symbol value for // the referenced data def. e.g. result := {}; result.(kDataSymbol) := GetLayout("IOUDataDef"); // result.(kData2Symbol) := ... to add a 2nd DataDef result;, allLayouts: // this needs to be a frame where each slot is the 'symbol value for // the layout. Must have a 'default, must have an 'overview. { default: GetLayout("Default Layout"), overview: GetLayout("Overview Layout"), }, allSoups: // this needs to be a frame where each slot is the 'masterSoupSlot value for a layout. // NewtApp looks here to get the appropriate soup information for each layout. // Layouts can use the same 'masterSoupSlot, which is what we do in this sample. // generic entry definition { IOUSoup: { _proto: newtSoup, soupName: "IOU:PIEDTS", soupIndices: [ {structure: 'slot, path: 'title, type: 'string}, {structure: 'slot, path: 'timeStamp, type: 'int}, {structure: 'slot, path: 'labels, type: 'tags }], soupQuery: {type: 'index, indexPath: 'title}, soupDescr: "The IOU soup.", defaultDataType: kDataSymbol, CreateBlankEntry: func() begin // this frame will be passed to FillNewEntry in the appropriate dataDef. local newEntry := Clone({ class: nil, viewStationery: nil, // for compatibility with paper roll title: nil, timeStamp: nil, height: 176, // for page and roll flavors // should be the same as height slot in dataDef // and viewDefHeight in viewDef (if present) }); newEntry.title := ShortDate(time()); newEntry.timeStamp := time(); newEntry; end, } }, appAll: "All Items", appObject: ["Item", "Items"], appSymbol: kAppSymbol, title: kAppTitle, viewJustify: 80, superSymbol: kSuperSymbol // VERY IMPORTANT. Use only DataDefs that have this symbol in their 'superSymbol slot. , statusBarSlot: 'status // contains declared name of the status bar so layouts can use status bar. Optional. , allViewDefs: // this frame must parallel allDataDefs (have the same slots), // each slot contains slots named for the 'symbol slot in the viewDef itself result := {}; result.(kDataSymbol) := { default: GetLayout("IOUDefaultViewDef"), notes: GetLayout("IOUNotesViewDef"), iouPrintFormat: GetLayout("IOUPrintFormat"), // for routing (fax, print, and other 'view transports) protoFrameFormat: // for routing (beaming, mailing, and other frame transports) { _proto: protoFrameFormat, symbol: 'IOUFrameFormat, title: "IOU Frame Format"}, }; // result.(kData2Symbol) := {...} // to add a 2nd DataDef result;, ReorientToScreen: ROM_DefRotateFunc, dateFindSlot: 'timeStamp // which slot in the soup entry to use for date finds. , viewSetupFormScript: func() begin // start by being as big as possible, we will shrink later self.viewJustify := vjParentCenterH + vjParentCenterV; // Setup the bounds based on the screen size or based on // a couple of compile time flags. if kTestMinAppSize then self.viewBounds := SetBounds( 0,0, kMinWidth, kMinHeight ); else if kTestMaxAppSize then self.viewBounds := SetBounds( 0,0, kMaxWidth, kMaxHeight ); else self.viewBounds := SetBounds( 0,0, GetAppParams().appAreaWidth, GetAppParams().appAreaHeight ); // shrink if needed for max width/height local bordersize := BAND(self.viewformat, vfPenMask)>>vfPenShift +BAND(self.viewformat, vfInsetMask)>>vfInsetShift; local fullScreenWidth := self.viewBounds.right-2*borderSize; local fullScreenHeight := self.viewBounds.bottom-2*borderSize; // Now setup the appropriate view bounds. if fullScreenWidth > kMaxWidth OR fullScreenHeight > kMaxHeight then begin // not full screen, so inset remainder and room for border self.viewBounds.right := Min(fullScreenWidth, kMaxWidth); self.viewBounds.bottom := Min(fullScreenHeight, kMaxHeight); end; else begin // really are full screen, so no border, no clickable (assumes dragger) self.viewFormat := vfNone; self.viewFlags := BAND(self.viewFlags, BNOT(vClickable)); end; // If the screen is too small then create a message to display to the user local message; if self.viewBounds.right < kMinWidth then message := "The display is to narrow for " & kAppName & " to open" else if self.viewBounds.bottom < kMinHeight then message := "The display is to short for " & kAppName & " to open"; // If there is a message, then close the application and display the message if message then begin self.viewBounds := RelBounds(-999, -999, 0, 0); GetRoot():Notify( kNotifyAlert, kAppName, message ); AddDelayedCall(func(v) begin RemoveSlot(v, 'viewbounds); v:Close(); end, [self], 1); end; inherited:?viewSetupFormScript(); // this method is defined internally end, NewtInstallScript: func( applicationRef ) begin // This code is to fix a bug in Newton 2.0 OS regarding stationery // registration. See the Q&A titled "How to Avoid NewtApp "Please // insert the card" errors" for more information about the bug. if applicationRef.allViewDefs then foreach dataDefSym, viewDefsFrame in applicationRef.allViewDefs do foreach viewDef in viewDefsFrame do RegisterViewDef( viewDef, EnsureInternal(dataDefSym) ); inherited:?NewtInstallScript( applicationRef ); end, viewQuitScript: // must return the value of inherited:?ViewQuitScript() func() begin // Remove the RAM version of viewFormat so // that we don't have anything left over from // what was setup in the viewSetupFormScript RemoveSlot( self, 'viewFormat ); inherited:?ViewQuitScript(); end, debug: "baseView", _proto: @398 /* newtApplication */ }; newtClockShowBar := {debug: "newtClockShowBar", _proto: @670 /* protoClockFolderTab */}; AddStepForm(baseView, newtClockShowBar); // After Script for newtClockShowBar thisView := newtClockShowBar; thisView._proto := newtClockFolderTab; // •• only because newtClockFolderTab isn't in platform file status := {debug: "status", _proto: @401 /* newtStatusBar */}; AddStepForm(baseView, status); StepDeclare(baseView, status, 'status); // After Script for baseView thisView := baseView; /* ** Newton Developer Technical Support Sample Code ** ** WhoOwesWhom, NewtApp/Stationery Sample ** ** by Greg Christie & Bob Ebert for Newton Developer Technical Support ** ** Copyright © 1995-97 by Apple Computer, Inc. All rights reserved. ** ** You may incorporate this sample code into your applications without ** restriction. This sample code has been provided "AS IS" and the ** responsibility for its operation is 100% yours. You are not ** permitted to modify and redistribute the source as "DTS Sample Code." ** If you are going to re-distribute the source, we require that you ** make it clear in the source that the code was descended from ** Apple-provided sample code, but that you've made changes. */ constant |layout_baseView| := baseView; // End of file baseView // Beginning of text file Install&Remove.f // Copyright ©1995 Apple Computer, Inc. All rights reserved. InstallScript := func(partFrame) begin local theApp := partFrame.theForm; partFrame.removeFrame := theApp:NewtInstallScript(partFrame.theForm); end; RemoveScript := func(partFrame) begin (partFrame.removeFrame):NewtRemoveScript(removeFrame); end; // End of text file Install&Remove.f