// Text of project MultiRoute written on 9/30/96 at 11:22 AM // Beginning of text file Constants /* ** Newton Developer Technical Support Sample Code ** ** MultiRoute, a Newton 2.0 routing example ** ** by J. Christopher Bell, Newton Developer Technical Support ** ** Copyright © 1996 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 kAboutString := "MultiRoute is Newton DTS Sample Code. This sample shows"& "how to display, route, and print multiple items."; constant kHelpString := "The popup picker in the status bar selects what"&& "multi-item routing method to use. See the sample's GetTargetInfo for more info." && "To test each, select multiple items and try printing using each method."; constant kMyDataClass := '|myDataClass:MultiRoute:DTS|; constant kMultiRouteClassName := "MultiRoute Class"; constant kNewtOverviewString := "NewtOverview Class"; constant kMyPrintFormatSym := '|myPrintFormat:MultiRoute:DTS|; constant kMyFrameFormatSym := '|myFrameFormat:MultiRoute:DTS|; constant kMyPrintFormatName := kAppName && "Print Format"; constant kMyFrameFormatName := kAppName && "Data & Text"; constant kRowHeight := 14; // height of each row on screen constant kRowPrintHeight := 20; // height of each row in printing OpenResFile(home&"Resources"); DefConst('kMyOverviewIcon, GetPictAsBits("OverviewIcon", nil)); DefConst('kMyCheckManyIcon, GetPictAsBits("CheckManyIcon", nil)); CloseResFile(); // Used in the print format DefConst('kCanonicalKid, { _proto: protoStaticText, viewBounds: SetBounds(0,0,0,kRowPrintHeight), viewJustify: vjParentFullH + vjSiblingBottomV }); constant kManyNames := 50; // we offer an Action script to auto-select many overview items // for print format debugging only // End of text file Constants // Beginning of file MyPrintFormat.t MyPrintFormat := { printNextPageScript: func() begin // We still have more pages to print if there is still more data. // See the viewSetupFormScript to see us set up the cursor. // See the MultipleItemTargetView.viewSetupChildrenScript to see how the cursor is used. if cursor:Entry() then begin :RedoChildren(); // recreate new children... true; end; else nil; end, title: kMyPrintFormatName, symbol: kMyPrintFormatSym, viewSetupFormScript: func() begin // Note: do not change viewJustify or viewBounds slots. inherited:?viewSetupFormScript(); // call the inherited method before doing anything else. // Your code goes here. Use :LocalBox() to get the page size and the variable "target" to // access the current item to print/fax. // Since our usesCursor slot is set to true, we'll use the target variable to create a // target cursor. We can send Next, Prev, and Entry messages to it to navigate entries, // similar to a soup cursor. Note that soup entry aliases will be resolved into real // soup entries when they are returned from a target cursor. Also note that if you pass // an item which is NOT a "multiple item target" to GetTargetCursor, it still returns // a target cursor; that cursor will contain only one item. cursor := GetTargetCursor(target, nil); // See the MultipleItemTargetView.viewSetupChildrenScript to see how the cursor data is used. // See the printNextPageScript to see how the cursor is used to determine how many pages to print. end, cursor: nil, usesCursors: true // When usesCursor is true, the Print/Fax transports know that the print format can print multiple items per page. // // Since we set it true, *we* iterate over the items using GetTargetCursor(target, nil). If it were set to nil, // the print format would be created, imaged, and then closed/destroyed between every item; the print format would // just print the contents of "target", which would change as the *system* iterates through each item. , debug: "MyPrintFormat", _proto: @200 }; _view000 := { text: kMyPrintFormatName // same as the format's title slot , viewBounds: {left: 0, top: 5, right: 200, bottom: 30}, viewJustify: 8388626, _proto: @218 }; AddStepForm(MyPrintFormat, _view000); MultipleItemTargetView := {viewBounds: {left: 3, top: 35, right: -3, bottom: -5}, viewFlags: 1, viewFormat: 0, viewJustify: 240, viewSetupChildrenScript: func() begin local text, entry; local howManyKids := RIntToL(:LocalBox().bottom / kRowPrintHeight); self.stepChildren := Array(howManyKids, nil); entry := cursor:Entry(); for i := 0 to howManyKids - 1 do begin if not entry then // there is NOT enough data to fill this page, so we need to kill some kids begin // reduce the size of our stepChildren array; we do NOT need all those kids SetLength(stepChildren, i); // we don't need to be in this loop anymore since all the kids are created break; end; // find the data definition for this object. It may be a 'person, a 'group, a 'company, etc. local dataDef := GetDataDefs(classof(entry)); // get the text for the item if dataDef then text := dataDef:StringExtract(entry, 1); else text := ""; // A hack for users with bad data -- without the correct 'class slot set. stepChildren[i] := { _proto: kCanonicalKid, // a static text with sibling justification (see the Constants file) text: text }; entry := cursor:Next(); end; end, debug: "MultipleItemTargetView", viewClass: 74 }; AddStepForm(MyPrintFormat, MultipleItemTargetView); constant |layout_MyPrintFormat.t| := MyPrintFormat; // End of file MyPrintFormat.t // Beginning of file MultiRoute.t // Before Script for "MultiRoute" /* ** Newton Developer Technical Support Sample Code ** ** MultiRoute, a Newton 2.0 routing example ** ** by J. Christopher Bell, Newton Developer Technical Support ** ** Copyright © 1996 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. */ MultiRoute := {viewBounds: {left: 8, top: 7, right: 216, bottom: 327}, viewFlags: 5, viewFormat: 0, declareSelf: 'base, viewSetupFormScript: func() begin viewBounds := GetAppParams().appAreaBounds; end, GetTargetInfo: func(reason) // reason could be 'routing, 'filing, or other symbols... begin local target; // If any items are checked, we take the array of soup aliases and make them into a "multiple item target". // In your application, the "items" passed to CreateTargetCursor could be aliases, soup entries or simple frames. // "newtOverview Routing" with CreateTargetCursor // The first argument is used as the class of the target for routing ANY entries. The 'newtOverview // class is a "magic" data class which enables routing of types ['text, 'view, 'frame] and handles printing // multiple items automatically (which each item on a new page). This is called the "newtOverview"or "Default" // method of routing multiple items. This can only be used if ALL individual items have individual routing // formats registered on their OWN CLASS to support dataTypes ['text, 'view, 'frame]. If not, or if you // need to support ADDITIONAL dataTypes with a special kind of transport, you can NOT use the 'newtOverview class. // Also, if you want to print/fax multiple items on a page or control which format is used to print individual // items, you can NOT use the 'newtOverview class. // "Custom Overview Routing" with CreateTargetCursor // The other way of routing multiple items is to provide your own class for the multiple item target. This is // used to route ALL the items as a whole. You MUST register routing formats on this data class in order for // transports to appear in the Action list! If you want to print multiple items on a Print/Fax page, you MUST // register a protoPrintFormat-based routing format and set its usesCursors slot to true. See the enclosed // print format for details on how to print multiple items on one page. // For user interface reasons, we strongly recommend that shipping applications ONLY use one of these methods. // This sample can use either method, but it does so only for illustrative purposes! local theClass := if CustomOverviewMode then kMyDataClass else 'newtOverview; if overview.selected and length(overview.selected) > 0 then target := CreateTargetCursor(theClass, overview.selected); {target: target, targetView: base, // we don't return "self" because sometimes self is the Action button, etc. } end, routeScripts: [{ title: "Check 50 Names", icon: kMyCheckManyIcon, // See the overview view's CheckMany slot... routeScript: func(t, tview) GetRoot().(kAppSymbol).overview:CheckMany(); } ], CustomOverviewMode: true // Boolean. This variable determines whether to use "newtOverview" routing, or "custom overview" routing. // See the GetTargetInfo method for more information. , myFormats: // These are used by the part's InstallScript to register the routing formats. // We do NOT just reference these directly in the installScript using DefConst // or GetLayout. This is because the entire routing formats would // be unnecessarily "EnsureInternaled" (copied into NewtonScript memory). Only for // "application/form" parts, the InstallScripts are EnsureInternaled when the package // is installed. By referencing them like partFrame.theForm.myFormats, the formats // are not referenced by the installScript itself and will not be unnecessarily copied. { myPrintFormat: GetLayout("MyPrintFormat.t"), myFrameFormat: { _proto: protoFrameFormat, // default dataTypes = ['frame, 'text] symbol: kMyFrameFormatSym, title: kMyFrameFormatName, } }, ReorientToScreen: ROM_defRotateFunc, debug: "MultiRoute", viewClass: 74 }; overview := {viewBounds: {left: 5, top: 15, right: -5, bottom: -20}, selected: nil, viewJustify: 240, viewSetupFormScript: func() begin local unionSoup := GetUnionSoupAlways(ROM_CardfileSoupName); self.cursor := unionSoup:Query({indexPath: 'sortOn}); inherited:?viewSetupFormScript(); end, Abstract: func(entry, bounds) // return a drawing shape reprsenting the current overview item begin local text; // find the data definition for this object. It may be a 'person, a 'group, a 'company, etc. local dataDef := GetDataDefs(classof(entry)); // get the text for the item if dataDef then text := dataDef:StringExtract(entry, 1); else text := ""; // A hack for users with data without the correct 'class slot set. (not uncommon) // Extract the shape for it MakeText(text, bounds.left, bounds.top, bounds.right, bounds.bottom - 3); end, lineHeight: kRowHeight, CheckMany: // This method is called when a user selects the item "Check 50 Names" from the Action list. func() begin local count := 0; local entry; cursor:Reset(); // we start from the beginning of the alphabet selected := []; // clear the current selected item array entry := cursor:entry(); while (entry and count < kManyNames) do begin AddArraySlot(selected, MakeEntryAlias(entry)); entry := cursor:next(); count := count + 1; end; cursor:Reset(); :RedoChildren(); // rebuild the view (so the checkboxes are updated) end, autoDeselect: true // if the user taps an item, when the pen leaves the item, it will be deselected , debug: "overview", _proto: @460 }; AddStepForm(MultiRoute, overview); StepDeclare(MultiRoute, overview, 'overview); _view001 := {title: kAppName, _proto: @229}; AddStepForm(MultiRoute, _view001); _view002 := { menuLeftButtons: [{ _proto: protoInfoButton, DoInfoAbout: func() :Notify(kNotifyQAlert, kAppName, kAboutString), DoInfoHelp: func() :Notify(kNotifyQAlert, kAppName, kHelpString) }, { _proto: protoPopInPlace, text: kMultiRouteClassName, popup: [kMultiRouteClassName, kNewtOverviewString], pickActionScript: func(index) begin // Set the CustomOverviewMode flag to indicate which overview method we should use. // See the GetTargetInfo method for more information. CustomOverviewMode := (index = 0); inherited:?pickActionScript(index); end, }], menuRightButtons: [{_proto: protoActionButton}], _proto: @401 }; AddStepForm(MultiRoute, _view002); constant |layout_MultiRoute.t| := MultiRoute; // End of file MultiRoute.t // Beginning of text file Install & Remove Scripts /* ** Newton Developer Technical Support Sample Code ** ** MultiRoute, a Newton 2.0 routing example ** ** by J. Christopher Bell, Newton Developer Technical Support ** ** Copyright © 1996 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. */ // Note that we do NOT just reference the routing formats directly in the installScript // using DefConst or GetLayout. This is because the entire routing formats would // be unnecessarily "EnsureInternaled" (copied into NewtonScript memory). Only for // "application/form" parts, the InstallScripts are EnsureInternaled when the package // is installed. By referencing them like partFrame.theForm.myFormats, the formats // are not referenced by the installScript itself and will not be unnecessarily copied. installScript := func(partFrame) begin local myFormats := partFrame.theForm.myFormats; RegisterViewDef(myFormats.myPrintFormat, kMyDataClass); RegisterViewDef(myFormats.myFrameFormat, kMyDataClass); end; removeScript := func(partFrame) begin UnRegisterViewDef(kMyPrintFormatSym, kMyDataClass); UnRegisterViewDef(kMyFrameFormatSym, kMyDataClass); end; // End of text file Install & Remove Scripts