// Text of project slimFaxPicker written on 4/23/97 at 1:59 PM // Beginning of text file Constants.f /* ** Newton Developer Technical Support Sample Code ** ** slimPicker, A slimmer listPicker ** ** by Jeremy Wyld, Newton Toolbox Engineering ** Maurice Sharp, 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. */ // Constants for the slimPicker proto // Values for the visibleChildrenFlags slot constant vNewButton := (1 << 0); // 1 - bit to show New button constant vScrollers := (1 << 1); // 2 - bit to show scrollers constant vAZTabs := (1 << 2); // 4 - bit to show AZTabs constant vFolderTab := (1 << 3); // 8 - bit to show FolderTab constant vSelectionOnly := (1 << 4); // 16 - bit to show SelectionOnly checkbox constant vCloseBox := (1 << 5); // 32 - bit to show CloseBox constant vCounter := (1 << 6); // 64 - bit to show selection counter DefConst('vNOTVisible, BNOT(vVisible)); DefConst('vDivider, // \ vNewButton + // \__ The existance of any of these vSelectionOnly + // / forces the divider to be visible. vCloseBox + // / vCounter); // / // used by the selection counter DefConst('kCounterStyle, { transferMode: modeCopy, // This is so the new count blasts over the old. penPattern: vfNone, // This is so the empty rect shape covers the old. fillPattern: vfWhite, // For the empty rect. font: ROM_fontSystem9, // I think you understand. justification: 'right // Ditto. }); // End of text file Constants.f // Beginning of file protoSlimPicker // Before Script for "base" /* ** Newton Developer Technical Support Sample Code ** ** slimPicker, A slimmer listPicker ** ** by Jeremy Wyld, Newton Toolbox Engineering ** Maurice Sharp, 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. */ base := { DrawSelectedText: /************************************************************************\ * * * Creates the counter's text and draws it. If nothing is selected, a * * white rect is drawn to wipe the old counter shape. * * * \************************************************************************/ func() begin :CreateSelectedText(); // Creates the counter shape. if counter then // Was one created (none created for no selections)? base:DrawShape(counter, kCounterStyle); // Draw the counter. end, viewSetupDoneScript: /************************************************************************\ * * * Based upon the slot set, updates the respective piece of the * * * \************************************************************************/ func() begin if BAND(visibleChildrenFlags, vCounter) <> 0 then :CreateSelectedText(); end, viewFormat: 33555025, viewLineSpacing: 14 // Developer Slot. // This can be used to change the line height used for the list. // Can be set with SetValue(view, 'viewLineSpacing, ) , UpdateSelectedText: /************************************************************************\ * * * Developer API. * * * * Updates the counter and redraws it. * * * \************************************************************************/ func() begin :DrawSelectedText(); // Hmmm... explains itself. end, viewDrawScript: /************************************************************************\ * * * If there is a counter and the counter is a valid child, draw it. * * * \************************************************************************/ func() begin if BAND(visibleChildrenFlags, vCounter) <> 0 AND counter then // Header says it all! :DrawShape(counter, kCounterStyle); end, counter: NIL // Shape for the "X Selected" counter string , visibleChildrenFlags: /************************************************************************\ * * * Developer Slot. * * * * Bit flags which control the visible children of the listpicker. The * * default is all elements visible. * * * * vNewButton - Controls the "New" button. * * vScrollers - UpDownScroller. * * vAZTabs - AZTabs. * * vFolderTab - FolderTab. * * vSelectionOnly - The "Selections Only" checkbox. * * vCloseBox - Closebox. * * vCounter - "X Selected" counter. * * * \************************************************************************/ vNewButton + vScrollers + vAZTabs + vFolderTab + vSelectionOnly + vCloseBox + vCounter, viewFlags: 1, reviewSelections: NIL // Developer Slot. // Needs set before the viewSetupFormScript for the selectionsCheckbox fires. // Can be set with SetValue(view, 'reviewSelections, ) , RefreshPicker: /************************************************************************\ * * * Developer API. * * * * Causes the picker to redraw, therefore causing the arrows to update, * * the AZTabs to update, and all shapes to update. * * * \************************************************************************/ func() begin picker:RedoChildren(); // The picker's viewSetupChildrenScript does everything. end, viewBounds: {left: 2, top: -240, right: -2, bottom: -2}, viewChangedScript: /************************************************************************\ * * * Based upon the slot set, updates the respective piece of the * * listpicker. The slots supported for SetValue(...) are * * 'folderTabTitle, 'reviewSelections, and 'viewLineSpacing. * * * \************************************************************************/ func(slot, view) begin if slot = 'folderTabTitle AND Visible(folderTab) then begin // The folder tab's title and is the tab even open? folderTab.text := folderTabTitle; // Set the text of the tab. folderTab:RedoText(); // Tell it to update. end; // if slot = 'folderTabTitle AND Visible(folderTab)... else if slot = 'reviewSelections then begin // The value of reviewSelections? SetValue(selectionCheckbox, 'viewValue, reviewSelections); // Force the update of the checkbox. end; // if slot = 'reviewSelections... else if slot = 'viewLineSpacing then // Did the line height change? :RefreshPicker(); // Update the picker. TRUE; end, cursor: NIL // The cursor on which the listpicker is operating. , viewJustify: 176, declareSelf: 'base, viewSetupFormScript: /************************************************************************\ * * * Set the vVisible flags based upon the visibleChildrenFlags. If a * * bit is on, the view is considered to be visible. * * * \************************************************************************/ func() begin local visibility := visibleChildrenFlags; // Grab locally for multiple lookups. if BAND(visibility, vNewButton) = 0 then newButton.viewFlags := BAND(newButton.viewFlags, vNOTVisible); if BAND(visibility, vAZTabs) = 0 then azTabs.viewFlags := BAND(azTabs.viewFlags, vNOTVisible); if BAND(visibility, vFolderTab) = 0 then folderTab.viewFlags := BAND(folderTab.viewFlags, vNOTVisible); if BAND(visibility, vSelectionOnly) = 0 then selectionCheckbox.viewFlags := BAND(selectionCheckbox.viewFlags, vNOTVisible); if BAND(visibility, vCloseBox) = 0 then closeBox.viewFlags := BAND(closeBox.viewFlags, vNOTVisible); if BAND(visibility, vScrollers) = 0 then scrollers.viewFlags := BAND(scrollers.viewFlags, vNOTVisible); end, viewClass: 74, folderTabTitle: NIL // Developer Slot. // This can be used to place a title in the folder tab (e.g. "Faxes"). // Can be set with SetValue(view, 'folderTabTitle, ) , CreateSelectedText: /************************************************************************\ * * * This method finds the number selected and creates the proper shape * * required for drawing the "X Selected" in the lower right corner of * * the picker. If no items are selected, white rect is created to * * erase the old counter text. * * * \************************************************************************/ func() begin local numSelections := :GetNumSelected(); // Developer needs to provide the number selected since they track selections. local numText; // This is the number selected in str form (NIL by default). if numSelections > 0 then // More than no selections? numText := NumberStr(numSelections); // Only show if there are selections. Make the text from the number. local box := base:LocalBox(); // Need the box in order to find the lower right draw area. local rightAdjuster := 26; // In the normal case, the text will be shifted to the left by this. if BAND(visibleChildrenFlags, vCloseBox) = 0 then // Is there a close box? rightAdjuster := 5; // No so bump right. All of this could be done at viewSetupFormScript time. if numText then // So was there text (selections)? base.counter := MakeText( // Build the text shape. ParamStr("^0 Selected", [numText]), box.right - 90, box.bottom - 22, box.right - rightAdjuster, box.bottom - 8); else base.counter := MakeRect( // Build the rect shape. box.right - 90, box.bottom - 22, box.right - rightAdjuster, box.bottom - 8); end, debug: "base" }; folderTab := { viewSetupFormScript: /************************************************************************\ * * * Sets the left-hand text of the folder tab to the developer's set * * value in 'folderTabTitle. * * * \************************************************************************/ func() begin self.text := folderTabTitle; // Grab the text and set locally. inherited:?viewSetupFormScript(); // Continue opening. end, text: NIL, debug: "folderTab", _proto: @669 }; AddStepForm(base, folderTab); StepDeclare(base, folderTab, 'folderTab); picker := {viewBounds: {left: 2, top: -200, right: -2, bottom: -24}, viewJustify: 176, viewSetupFormScript: /************************************************************************\ * * * Sets the bounds based upon visible siblings. If the folder tab and * * AZTabs aren't visible, the picker should go all the way to the top. * * If the divider isn't visible, the picker should go all the way to * * the bottom. If the divider is visible, it is created. * * * \************************************************************************/ func() begin // Need to bounce bounds in order to accomadate // lack of visibility of folder tab and AZ tabs. local visibility := visibleChildrenFlags; // Grab locally. local bounds := viewBounds; // Local. local top := -200; // Default. local bottom := -24; // Default. if BAND(visibility, vDivider) = 0 then // Is the divider there? bottom := -2; // Bump to the bottom. if BAND(visibility, vFolderTab) = 0 then // Folder tab? top := top - 20; // Gain on the top. if BAND(visibility, vAZTabs) = 0 then // AZTabs? top := top - 20; // Gain some more. self.viewBounds := SetBounds(2, top, -2, bottom); // Reset the bounds. local box := :LocalBox(); // Get the bounds. Does the right thing even though the bounds // JUST got set. if BAND(visibleChildrenFlags, vDivider) <> 0 then // Is the divider visible? self.divider := MakeLine(3, box.bottom, box.right - 3, box.bottom); // Create the shape and cache it. end, divider: NIL // The divider line between the picker and the bottom buttons. , viewSetupChildrenScript: /************************************************************************\ * * * Sets the line height for the overview and figures the scroll amounts * * for the arrows. This is performed here since the developer may * * dynamically change the viewLineSpacing and the scroll will have to * * dynamically change too. After this is done, the picker is put * * together. The developer should have set the value of cursor by this * * point. * * * \************************************************************************/ func() begin lineHeight := viewLineSpacing; local box := :LocalBox(); local scroll := (box.bottom DIV lineHeight) - 1; scrollers.scrollAmounts := [scroll, scroll, scroll]; :UpdatePickerValues(cursor:Clone()); end, Scroller: /************************************************************************\ * * * Scroll the amount, update the tabs, and the picker. This method * * doesn't allow scrolling off of either end. There will always be one * * entry left on screen for the user. * * * \************************************************************************/ func(dir) begin if dir > 0 AND scrollers:GetArrow('down) = 'normal then // Is the user trying to go down and not supposed to? return; // Bail. This is possible through drag scrolling. local c := cursor; // Grab the cursor locally. local entry := c:Move(dir); // Move the cursor the number of entries. if NOT entry then begin // Did it go off of an end? if dir < 0 then // Yes but did it go off the head or the tail? The head? entry := c:Next(); // Yes, so go to the first entry. else // Nope, went off the tail. entry := c:Prev(); // Go to the last entry. end; // if NOT entry... :UpdatePickerValues(c:Clone()); // Update the tabs, picker, and scroller. :Dirty(); // Redraw the picker. end, viewDrawScript: /************************************************************************\ * * * Simply draw the divider if it exists. * * * \************************************************************************/ func() begin if divider then // Does the divider exist? :DrawShape(divider, NIL); // Draw it. inherited:?ViewDrawScript(); // this method is defined internally end, viewFlags: 513, GetHiliteShape: /************************************************************************\ * * * Calls the developer :GetHiliteShape() method should it exist. If * * the developer method doesn't exist or if it returns NIL, the * * inherited method is performed. This will build the shape that the * * overview should use for hiliting the current box. The developer * * should provide the method for doing multi-column pickers. * * * \************************************************************************/ func(x, box) begin local shape; // NIL shape by default. local s := selectIndent; if x > s then begin // Only call the developer if the user isn't trying to hit the checkboxes. local bbox := Clone(box); // Prepare to normalize the coords. bbox.left := bbox.left + s; // Place left edge at selectIndent. x := x - s; // Normalize the x coordinate. shape := :Parent():?GetHiliteShape(x, bbox); // Get the shape from the developer. end; // if x > selectIndent... if NOT shape then // Did the developer not return a shape? inherited:?GetHiliteShape(x, box); // Do the default thing and return it (returns a black rect). else shape; // Return the developer's shape. end, HitItem: /************************************************************************\ * * * Called when a item gets the final tap in the overview. This method * * is NOT called while tracking the hilite. It is only called after an * * chosen. It will then call the developer's :HitListItem() method if * * the inherited one returns NIL. The inherited method returns NIL in * * the case where it didn't handle the hit (e.g. not on the checkbox). * * * \************************************************************************/ func(index, xcoord, ycoord) begin if NOT inherited:HitItem(index, xcoord, ycoord) then // Did the tap happen in the checkbox area? :?HitListItem(index, xcoord, ycoord); // No, call the developer method. end, IsSelected: /************************************************************************\ * * * Need this here since the overview only checks down the proto chain. * * Kind of hokey but need the developer to tell whether an item is * * selected or not. The developer method should return TRUE or NIL. * * * \************************************************************************/ func(entry) begin :Parent():IsSelected(entry); // Call the developer method. end, autoDeselect: true, UpdatePickerValues: /************************************************************************\ * * * Updates the hilite for the AZTabs, recreates the shapes for the * * picker, and updates the state of the scroller. * * * \************************************************************************/ func(c) begin azTabs:UpdateHilite(c:Entry()); // Update the AZTabs for the first entry. local states := ['more, 'normal]; // Default is more before the list and none after the list. if NOT c:Prev() then // Are there items before the first item in the list? states[0] := 'normal; // No, so set the arrow to normal state (no scroll). c:Next(); // Since the cursor bumped -1, put it back. :SetupAbstracts(c); // Perform the overview's abstract thing to make the shapes. if c:Next() then // Are there items after the last item in the list? states[1] := 'more; // Yes, so mark the state as having more. if Visible(scrollers) then // Are the scrollers visible? They are not when this fires in the scrollers:UpdateArrowStates(states); // viewSetupChildrenScript. Visible, so update them now. else AddDeferredSend(scrollers, 'UpdateArrowStates, [states]); // Update them when they will be visible. end, debug: "picker", _proto: @191 }; AddStepForm(base, picker); StepDeclare(base, picker, 'picker); azTabs := {viewBounds: {left: -1, top: -20, right: 1, bottom: 0}, viewJustify: 16442, PickLetterScript: /************************************************************************\ * * * Perform the developer's action for going to a letter and refresh the * * picker. * * * \************************************************************************/ func(letter) begin :Parent():PickLetterScript(letter); // Tell the developer to reposition their cursor. :RefreshPicker(); // Update the picker. end, UpdateHilite: /************************************************************************\ * * * Update the hilite on the tabs. To do this the developer is asked * * for the alpha character which should be hilited based upon the given * * entry. * * * \************************************************************************/ func(entry) begin if Visible(self) then AddDeferredSend(self, 'SetLetter, [(:AlphaCharacter(entry)), NIL]); end, debug: "azTabs", _proto: @617 }; AddStepForm(base, azTabs); StepDeclare(base, azTabs, 'azTabs); newButton := { buttonClickScript: /************************************************************************\ * * * Call the developer's "New" method. * * * \************************************************************************/ func() begin :CreateNewItem(); // Read the header. end, text: "New", viewBounds: {left: 0, top: -18, right: 50, bottom: -5}, viewJustify: 8388758, viewSetupFormScript: /************************************************************************\ * * * Simply set the bounds based upon the text of the button. * * * \************************************************************************/ func() begin self.viewBounds := SetBounds(0, -18, StdButtonWidth(text), -5); // Set the bounds correctly. inherited:?viewSetupFormScript(); // Do the inherited thing. end, debug: "newButton", _proto: @226 }; AddStepForm(base, newButton); StepDeclare(base, newButton, 'newButton); closeBox := {debug: "closeBox", _proto: @163}; AddStepForm(base, closeBox); StepDeclare(base, closeBox, 'closeBox); selectionCheckbox := {text: "Selected Only", viewBounds: {left: 3, top: -20, right: 93, bottom: -4}, viewJustify: 132, valueChanged: /************************************************************************\ * * * Set the value of 'reviewSelections and inform the developer. After * * informing, update the picker. * * * \************************************************************************/ func() begin :Parent().reviewSelections := viewValue; // Force the change to review the selections. :ToggleShowSelections(viewValue); // Tell the developer to update for reviewing selections. :RefreshPicker(); // Update the picker. end, viewSetupFormScript: /************************************************************************\ * * * The value of the checkbox is set according to the value in the * * 'reviewSelections slot. * * * \************************************************************************/ func() begin self.viewValue := reviewSelections; // Set the check value. inherited:?viewSetupFormScript(); // Continue opening. end, debug: "selectionCheckbox", _proto: @164 }; AddStepForm(base, selectionCheckbox); StepDeclare(base, selectionCheckbox, 'selectionCheckbox); scrollers := { ViewScroll2DScript: /************************************************************************\ * * * Scrolls the picker the scroll amount and updates the view. * * * \************************************************************************/ func(direction, extras) begin if :GetArrow(direction) <> 'normal then begin // Can the user even scroll? picker:Scroller(extras.amount); // Tell the picker to scroll. RefreshViews(); // Update to cause the scroll effect. end; // if :GetArrow(direction) <> 'normal... inherited:?ViewScroll2DScript(direction, extras); // Do whatever the proto does. end, UpdateArrowStates: /************************************************************************\ * * * Update the scroll arrows based upon the incoming states. The states * * is an array with the first element being the value for the up arrow, * * and the second element being the value for the down arrow. The * * possible values are those listed in the NPG for arrow states. * * * \************************************************************************/ func(arrowStates) begin :SetArrow('up, arrowStates[0]); // Set the up arrow state. :SetArrow('down, arrowStates[1]); // Set the down arrow state. AddDeferredSend(self, 'Dirty, NIL); // The picker's refresh conflicts with the dirty of these, so // do the dirty deferred. end, debug: "scrollers", _proto: @656 }; AddStepForm(base, scrollers); StepDeclare(base, scrollers, 'scrollers); constant |layout_protoSlimPicker| := base; // End of file protoSlimPicker // Beginning of file NewPersonSlip.t // Before Script for "base" /* ** Newton Developer Technical Support Sample Code ** ** slimPicker, A slimmer listPicker ** ** by Jeremy Wyld, Newton Toolbox Engineering ** Maurice Sharp, 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. */ base := {viewBounds: {left: 0, top: 10, right: 223, bottom: 290}, dataCursor: nil, dataSoup: "Names", target: NIL, soupQuery: nil, listPicker: nil, viewQuitScript: func() begin local p := whichPhone; local result := inherited:?viewQuitScript(); if IsArray(target.phones) AND Length(target.phones) > whichPhone AND StrFilled(target.phones[p]) then begin local entry := target; if NOT IsSoupEntry(entry) then entry := GetRoot().cardfile:AddCard('person, target); local i := LSearch(listPicker.selections, entry, 0, '|=|, 'entry); if NOT i then AddArraySlot(listPicker.selections, {entry: entry, phone: p}); else listPicker.selections[i].phone := p; listPicker:UpdateSelectedText(); listPicker.cursor:Goto(entry); listPicker:RefreshPicker(); end; listPicker.openSlip := NIL; end, reason: 'person, viewSetupFormScript: func() begin if reason <> 'person then begin self.viewBounds := Clone(viewBounds); viewBounds.bottom := viewBounds.bottom - (32 * 3); end; inherited:?viewSetupFormScript(); end, whichPhone: 0, debug: "base", _proto: @179 }; title := {title: "New Person", viewBounds: {left: 10, top: 2, right: 130, bottom: 10}, viewSetupFormScript: func() begin if reason <> 'person then title := "New Phone"; inherited:?viewSetupFormScript(); // this method is defined internally end, debug: "title", _proto: @229 }; AddStepForm(base, title); StepDeclare(base, title, 'title); _view000 := {viewBounds: {left: 0, top: 20, right: 0, bottom: 148}, viewJustify: 48, viewSetupChildrenScript: func() begin if reason <> 'person then begin self.stepChildren := Clone(stepChildren); ArrayRemoveCount(stepChildren, 0, 3); end; inherited:?viewSetupChildrenScript(); end, viewSetupFormScript: func() begin if reason <> 'person then begin self.viewBounds := Clone(viewBounds); viewBounds.bottom := viewBounds.top + 32; end; inherited:?viewSetupFormScript(); end, _proto: @652 }; AddStepForm(base, _view000); _view001 := {path: '[pathExpr: name, first], viewJustify: 8240, viewBounds: {left: 0, top: 0, right: 0, bottom: 32}, label: "First", viewSetupDoneScript: func() begin SetKeyView(entryLine, 9999); inherited:?viewSetupDoneScript(); end, entryFlags: 12597761, _proto: @422 }; AddStepForm(_view000, _view001); _view002 := {path: '[pathExpr: name, last], viewJustify: 8240, viewBounds: {left: 0, top: 0, right: 0, bottom: 32}, label: "Last", memory: 'lastname, entryFlags: 12597761, _proto: @422 }; AddStepForm(_view000, _view002); _view003 := {path: '[pathExpr: name, honorific], viewJustify: 8240, viewBounds: {left: 0, top: 0, right: 0, bottom: 32}, label: "Ms./Mr.", labelCommands: ["Ms.", "Mrs.", "Mr.", "Dr."], _proto: @422 }; AddStepForm(_view000, _view003); _view004 := {path: '[pathExpr: phones, 0], viewJustify: 8240, viewBounds: {left: 0, top: 0, right: 0, bottom: 32}, label: "Fax", viewSetupFormScript: func() begin if target.phones then begin path := Clone(path); path[1] := Length(target.phones); whichPhone := path[1]; end; if NOT target.(path) then SetLength(target.phones, path[1] + 1); inherited:?viewSetupFormScript(); end, viewQuitScript: func() begin if NOT StrFilled(target.(path)) then ArrayRemoveCount(target.phones, path[1], 1); inherited:?viewQuitScript(); // this method is defined internally end, _proto: @425 }; AddStepForm(_view000, _view004); _view005 := {_proto: @163}; AddStepForm(base, _view005); _view006 := {viewBounds: {left: 0, top: -110, right: 225, bottom: -30}, viewJustify: 144, _proto: @375 }; AddStepForm(base, _view006); _view007 := {_recogPopup: '[recogText, recogInkText, pickseparator, recToggleSettings], viewBounds: {left: 2, top: -18, right: 20, bottom: -5}, viewJustify: 134, _proto: @234 }; AddStepForm(base, _view007); constant |layout_NewPersonSlip.t| := base; // End of file NewPersonSlip.t // Beginning of file slimFaxPicker.t // Before Script for "_view008" /* ** Newton Developer Technical Support Sample Code ** ** slimPicker, A slimmer listPicker ** ** by Jeremy Wyld, Newton Toolbox Engineering ** Maurice Sharp, 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. */ _view008 := { HitListItem: func(index, xcoord, ycoord) begin if xcoord < xColumn then begin :SelectItem(index); :RefreshPicker(); end; // if xcoord < xColumn... else begin local c := cursor:Clone(); local e := c:Move(index); if e.phones AND Length(e.phones) > 0 then begin local phones := currentPickList := Clone(e.phones); currentActiveItem := e; for i := 0 to Length(phones) - 1 do phones[i] := MakeDisplayPhone(phones[i]); AddArraySlot(phones, 'pickseparator); AddArraySlot(phones, "New Phone"); DoPopup(phones, xColumn + 12, (index + 1) * viewLineSpacing, picker); end; // if e.phones AND Length(e.phones) > 0... else :EditPerson(e); // Need to edit the item. end; // if xcoord < xColumn...else... end, appObjectUnfiled: "Unfiled Names", viewLineSpacing: 15, SelectItem: func(itemIndex) begin local c := cursor:Clone(); local e := c:Move(itemIndex); local i := LSearch(selections, e, 0, '|=|, 'entry); if i then ArrayRemoveCount(selections, i, 1); else begin if e.phones AND Length(e.phones) > 0 then begin local phone := 0; foreach i, p in e.phones do begin if IsInstance(p, 'faxPhone) then begin phone := i; break; end; // if IsInstance(p, 'faxPhone)... end; // foreach i, p in e.phones... AddArraySlot(selections, {entry: e, phone: phone}); end; end; // if i...else... :UpdateSelectedText(); end, viewQuitScript: func() begin if openSlip then openSlip:Close(); UnRegSoupChange("Names", kAppSymbol); local d := GetDataDefs('|nameRef.fax|); for i := 0 to Length(selections) - 1 do begin local item := selections[i]; selections[i] := d:MakeNameRef(item.entry, '|nameRef.fax|); selections[i].phone := item.entry.phones[item.phone]; end; print(selections); inherited:?viewQuitScript(); end, appAll: "All Names", hideSound: ROM_DrawerClose, visibleChildrenFlags: vNewButton + vScrollers + vAZTabs + vFolderTab + vSelectionOnly + vCloseBox + vCounter, SetupCursor: func() begin local spec := Clone(querySpec); spec.validTest := func( entry ) begin local class := ClassOf(entry); IsSubClass(class, 'person) OR IsSubClass(class, 'company) OR IsSubClass(class, 'owner); end; if NOT labelsFilter then spec.tagSpec := {none: GetFolderList(appSymbol, NIL)}; else if labelsFilter <> '_all then spec.tagSpec := {all: labelsFilter}; if stalledCursor then spec.validTest := func(entry) begin LSearch(selections, entry, 0, '|=|, 'entry); end; GetUnionSoup("Names"):Query(spec); end, viewFlags: 5, showSound: ROM_DrawerOpen, GetNumSelected: func() begin Length(selections); end, selections: NIL, ReorientToScreen: ROM_DefRotateFunc, CreateNewItem: func() begin if openSlip then return; local view := BuildContext(GetLayout("NewPersonSlip.t")); view.target := SetClass({phones: []}, 'person); if labelsFilter AND labelsFilter <> '_all then view.target.labels := labelsFilter; view.dataCursor := cursor:Clone(); view.soupQuery := querySpec; view.listPicker := base; openSlip := view; view:Open(); end, Abstract: func(item, bounds) begin local columnMark := xColumn; if NOT columnMark then columnMark := xColumn := bounds.left + ((bounds.right - bounds.left) DIV 2); local text := "--"; local phone := "--"; if IsInstance(item, 'company) then text := StyledStrTruncate(item.company, columnMark - bounds.left, tsSize(10) + tsBold); else if item.name then text := StyledStrTruncate( ParamStr("^?0^0^?1, ||||^1", [item.name.last, item.name.first]), columnMark - bounds.left, tsSize(10) + tsBold); text := MakeText(text, bounds.left, bounds.top, columnMark, bounds.bottom - 1); // Bump the baseline up slightly if item.phones AND Length(item.phones) > 0 then begin local i := LSearch(selections, item, 0, '|=|, 'entry); if i then phone := kPopChar && MakeDisplayPhone(item.phones[selections[i].phone]); else begin phone := kPopChar && MakeDisplayPhone(item.phones[0]); foreach p in item.phones do begin if IsInstance(p, 'faxPhone) then begin phone := kPopChar && MakeDisplayPhone(p); break; end; // foreach p in item.phones... end; // if IsInstance(p, 'faxPhone)... end; // if i...else... phone := StyledStrTruncate(phone, columnMark - bounds.left, tsSize(10) + tsBold); end; // if item.phones... phone := MakeText(phone, columnMark, bounds.top, bounds.right, bounds.bottom - 1); [text, phone]; end, viewBounds: {left: 0, top: -240, right: 236, bottom: -2}, _proto: base, stalledCursor: NIL, labelsFilter: NIL, ValidateSelections: func() begin local s := selections; for index := Length(s) - 1 to 0 by -1 do begin if NOT IsSoupEntry(s[index].entry) then ArrayRemoveCount(s, index, 1); end; // for index := Length(s) - 1 to 0 by -1... end, appSymbol: 'cardfile, viewJustify: 144, pickCancelledScript: func() begin currentActiveItem := NIL; currentPickList := NIL; end, currentPickList: nil, querySpec: '{ type: index, indexPath: sorton, }, viewSetupFormScript: func() begin self.cursor := :SetupCursor(); self.selections := []; self.targetView := self; RegSoupChange("Names", kAppSymbol, func(a, b, c, d) begin :SoupChange(a, b, c, d); end); inherited:?viewSetupFormScript(); end, currentActiveItem: NIL, GetHiliteShape: func(xcoord, bbox) begin local shape; if xcoord < xColumn then shape := MakeRect(bbox.left, bbox.top, xColumn, bbox.bottom); else shape := MakeRect(xColumn, bbox.top, bbox.right, bbox.bottom); [{ transferMode: modeXor, penPattern: vfNone, fillPattern: vfBlack }, shape]; end, NewFilingFilter: func(why) begin local key := " "; local e := cursor:Entry(); if e then key := e.sorton; cursor := :SetupCursor(); cursor:GotoKey(key); if NOT cursor:Entry() then cursor:Prev(); :RefreshPicker(); end, EditPerson: func(entry) begin if openSlip then return; local view := BuildContext(GetLayout("NewPersonSlip.t")); view.target := entry; view.dataCursor := cursor:Clone(); view.soupQuery := querySpec; view.listPicker := base; view.reason := 'phone; openSlip := view; view:Open(); end, viewEffect: 133120, pickActionScript: func(itemSelected) begin if itemSelected = Length(currentPickList) - 1 then :EditPerson(currentActiveItem); else begin local i := LSearch(selections, currentActiveItem, 0, '|=|, 'entry); if i then selections[i].phone := itemSelected; else AddArraySlot(selections, {entry: currentActiveItem, phone: itemSelected}); :UpdateSelectedText(); :RefreshPicker(); end; currentActiveItem := NIL; currentPickList := NIL; end, ToggleShowSelections: func(on) begin local key := " "; local e := cursor:Entry(); if e then key := e.sorton; if on then begin stalledCursor := cursor; cursor := :SetupCursor(); end; else begin cursor := stalledCursor; stalledCursor := NIL; end; cursor:GotoKey(key); if NOT cursor:Entry() then cursor:Prev(); end, AlphaCharacter: func(item) begin if item AND StrLen(item.sorton) > 0 then item.sorton[0]; else $\u0020; end, folderTabTitle: "Faxes", targetView: nil, SoupChange: func(soupName, appSymbol, changeType, changeData) begin :ValidateSelections(); :RefreshPicker(); end, xColumn: nil, openSlip: nil, PickLetterScript: func(letter) begin local entry := cursor:GotoKey(letter); if NOT entry then entry := cursor:Prev(); end, IsSelected: func(entry) begin if LSearch(selections, entry, 0, '|=|, 'entry) then TRUE; end }; constant |layout_slimFaxPicker.t| := _view008; // End of file slimFaxPicker.t