constant kAppSymbol := '|Runner:SOAPNOTES|; constant kPackageName :="Runner:SOAPNOTES"; constant kAppObject := '["mile", "miles", "minute", "minutes", "month", "months","year", "years"]; constant kSoupName := kPackageName; constant kSoupIndexes := '[{structure: slot, path: rundate, type:int}]; //RemoveScript:= func(partFrame) //begin //foreach store in GetStores() do begin //local soup :=store:GetSoup(kSoupName); //if soup then soup:RemoveFromStore(); //end; //end; // ---- End Project Data ---- RunBase := {title: "Runner's Log", viewBounds: {left: 2, top: 2, right: 242, bottom: 337}, viewflags: 516, documentation: "This sample app shows how to create a mostly working clMonthView based date\npickerlike the one in the preferences or dates applications. It uses bitmaps in\nthe system ROMs for left and right buttons, has a month/year display that\nupdates, and should size itself appropriately for the view that it's been dragged\nout in.\n\nThe meat is now a nice user proto. Feel free to use all or part of it in your apps.\n\n --Bob (for PIE DTS)" , viewSetupFormScript: func() begin selectedDates := [Time()]; :RegisterCardSoup(kSoupName, kSoupIndexes, kAppSymbol, kAppObject); end, RegisterCardSoup: func(SoupName, SoupIndexes, AppSymbol, AppObject) begin if functions.RegisterCardSoup then return RegisterCardSoup(SoupName, SoupIndexes, AppSymbol, AppObject); CreateAppSoup(SoupName, SoupIndexes, EnsureInternal([AppSymbol]), EnsureInternal(AppObject)); AddArraySlot(CardSoups, SoupName); AddArraySlot(CardSoups, SoupIndexes); local store; foreach store in GetStores() do if NOT Store:IsReadOnly() AND NOT store:HasSoup(SoupName) then store:CreateSoup(SoupName, SoupIndexes); end, UnRegisterCardSoup: func(soupName) begin if functions.UnRegisterCardSoup then return UnRegisterCardSoup(SoupName); local pos := ArrayPos(CardSoups, SoupName, 0, func(x,y) ClassOf(y) ='String AND StrEqual(x,y)); if pos then ArrayRemoveCount(CardSoups, pos, 2); end, viewQuitScript: func() begin selectedDates := nil; :UnRegisterCardSoup(kSoupName); end , selectedDates: [], _proto: protoApp, debug: "RunBase" }; protoDatePicker := {viewflags: 1, viewFormat: nil, viewBounds: {left: 0, top: 0, right: 120, bottom: 100}, monthChangedScript: func() begin // This will be inherited by the child month view and called every time // the user taps on a new day. It *must* be here because the user can // tap on days at the end or beginning of the previous or next month // (the blank spaces on the view) and actually change the date! // If this script isn't here to update the view and the title string, // the month with change but the display won't--confusing the heck out of // people. :Dirty(); :SetTitle(); end, monthYearSpec: GetDateStringSpec([ [kElementMonth, kFormatLong], [kElementYear, kFormatLong]]), SetTitle: // This function updates the month/year label. It should be called // whenever the user changes the date. func() begin SetValue(monthYearLabel, 'text, LongDateStr(selectedDates[0], monthYearSpec)); end, viewSetupDoneScript: func() begin if NOT selectedDates exists then self.selectedDates := [Time()]; // initialize selectedDates to current :SetTitle(); end, Refresh: // This allows scripts outside the proto to have a nice entry point for // getting the picker refreshed when the selectedDates array changes. func() begin monthView:Dirty(); :SetTitle(); end, viewclass: 74, debug: "protoDatePicker" }; monthYearLabel := /* child of protoDatePicker */ {text: "", viewBounds: {left: 0, top: 0, right: 0, bottom: 15}, viewflags: 3, viewJustify: 8388662, _proto: protoStaticText, debug: "monthYearLabel" }; // View monthYearLabel is accesible from protoDatePicker previousMonthButton := /* child of protoDatePicker */ {viewBounds: {left: 0, top: 0, right: 15, bottom: 15}, viewSetupFormScript: func() begin // initialize the icon from the system bitmap via a magic pointer. self.icon := @325; // leftBitmap end, viewflags: 515, viewJustify: 6, viewFormat: 1, buttonPressedScript: func() begin // move to the previous month, and make sure the views redraw. selectedDates[0] := IncrementMonth(selectedDates[0], -1); monthView:dirty(); :SetTitle(); // have to call RefreshViews because this is the buttonPressedScript, // the view otherwise wouldn't get refreshed until the user lifted the // pen! If you had done this in the buttonClickScript instead, you // could skip the RefreshViews() call. RefreshViews(); end, icon: nil, _proto: protoPictureButton, debug: "previousMonthButton" }; nextMonthButton := /* child of protoDatePicker */ {icon: nil, viewBounds: {top: 0, left: -15, right: 0, bottom: 15}, viewSetupFormScript: func() begin // initialize the bitmap from the system ROMs via a magic pointer. self.icon := @326; // rightBitmap end, viewflags: 515, viewFormat: 1, viewJustify: 38, buttonPressedScript: func() begin // move to the previous month, and make sure the views redraw. selectedDates[0] := IncrementMonth(selectedDates[0], 1); monthView:dirty(); :SetTitle(); // have to call RefreshViews because this is the buttonPressedScript, // the view otherwise wouldn't get refreshed until the user lifted the // pen! If you had done this in the buttonClickScript instead, you // could skip the RefreshViews() call. RefreshViews(); end, _proto: protoPictureButton, debug: "nextMonthButton" }; monthView := /* child of protoDatePicker */ {viewBounds: {top: 15, left: 1, right: -1, bottom: -1}, viewflags: 513, viewFormat: nil, labelFont: ROM_fontSystem9Bold, dateFont: ROM_fontSystem9, viewJustify: 246, singleDay: true, viewclass: 80, debug: "monthView" }; // View monthView is accesible from protoDatePicker datePicker := /* child of RunBase */ {viewBounds: {left: 25, top: 209, right: 145, bottom: 297}, viewFormat: 336, _proto: protoDatePicker, debug: "datePicker" }; // View datePicker is accesible from RunBase _view000 := /* child of RunBase */ {text: "Today", buttonClickScript: func() begin selectedDates := [Time()]; datePicker:Refresh(); RunMonth:SyncView(); RunYear:SyncView(); end, viewBounds: {left: 178, top: 242, right: 222, bottom: 262}, _proto: protoTextButton }; _view001 := /* child of RunBase */ {text: "Minutes", viewBounds: {left: 72, top: 56, right: 120, bottom: 72}, _proto: protoStaticText }; _view002 := /* child of RunBase */ {text: "Miles", viewBounds: {left: 144, top: 56, right: 176, bottom: 72}, _proto: protoStaticText }; _view003 := /* child of _view002 */ {viewBounds: {left: 32, top: 16, right: 72, bottom: 32}, viewflags: 10753, _proto: protoInputLine }; _view004 := /* child of RunBase */ {text: "Totals Month", viewBounds: {left: 8, top: 144, right: 80, bottom: 160}, _proto: protoStaticText }; _view005 := /* child of RunBase */ {text: "Totals Year", viewBounds: {left: 152, top: 144, right: 216, bottom: 160}, _proto: protoStaticText }; _view006 := /* child of RunBase */ {text: "Save", buttonClickScript: func() begin entry :={rundate: selectedDates[0], miles: Runmiles.text, minutes: Runminutes.text}; soup := GetUnionSoup(kSoupName); soup:AddToDefaultStore(entry); EntryChange(entry); SetValue(Runmiles, 'text, ""); SetValue(Runminutes, 'text, ""); RunMonth:SyncView(); RunYear:SyncView(); end, viewBounds: {left: 178, top: 274, right: 222, bottom: 294}, _proto: protoTextButton }; Runminutes := /* child of RunBase */ {viewBounds: {left: 72, top: 80, right: 112, bottom: 104}, viewflags: 10757, _proto: protoInputLine, debug: "Runminutes" }; // View Runminutes is accesible from RunBase Runmiles := /* child of RunBase */ {viewBounds: {left: 136, top: 80, right: 176, bottom: 104}, viewflags: 10757, _proto: protoInputLine, debug: "Runmiles" }; // View Runmiles is accesible from RunBase RunMonth := /* child of RunBase */ {text: "", viewBounds: {left: 16, top: 168, right: 80, bottom: 192}, viewflags: 7, viewDrawScript: func() begin local runtemp :=(Date(selectedDates[0])); local runmonth := runtemp.month; local runyear := runtemp.year; mysoup := GetUnionSoup(kSoupName); local cursor := Query(mysoup, {type: 'index, indexPath: 'rundate, validTest: func(e) (Date(e.rundate)).year = runyear AND (Date(e.rundate)).month = runmonth}); local entry := cursor:Entry(); local vcounter := 0; local mcounter := 0; while entry do begin vcounter := vcounter + StringToNumber(entry.miles); mcounter := mcounter + StringToNumber(entry.minutes); entry := cursor:Next(); end; SetValue(self, 'text, NumberStr(mcounter) && "/" && NumberStr(vcounter)); end, _proto: protoStaticText, debug: "RunMonth" }; // View RunMonth is accesible from RunBase RunYear := /* child of RunBase */ {text: "", viewBounds: {left: 152, top: 168, right: 216, bottom: 192}, viewflags: 7, viewDrawScript: func() begin local runtemp :=(Date(selectedDates[0])); local runmonth := runtemp.month; local runyear := runtemp.year; mysoup := GetUnionSoup(kSoupName); local cursor := Query(mysoup, {type: 'index, indexPath: 'rundate, validTest: func(e) (Date(e.rundate)).year = runyear}); local entry := cursor:Entry(); local vcounter := 0; local mcounter := 0; while entry do begin vcounter := vcounter + StringToNumber(entry.miles); mcounter := mcounter + StringToNumber(entry.minutes); entry := cursor:Next(); end; SetValue(self, 'text, NumberStr(mcounter) && "/" && NumberStr(vcounter)); end, _proto: protoStaticText, debug: "RunYear" }; // View RunYear is accesible from RunBase CreditLink := /* child of RunBase */ {viewBounds: {left: 0, top: 102, right: 228, bottom: 290}, _proto: protoFloatNGo, debug: "CreditLink" }; _view007 := /* child of CreditLink */ {viewflags: 1, viewFormat: 257, viewLineSpacing: 20, viewfont: Rom_FontSystem9, viewBounds: {left: 0, top: 0, right: 240, bottom: 168}, text: "Runner is freeware by S.O.A.P. Notes, Inc.\nLincoln, Nebr. 1994 based on Mike Eberts PDK demo of the protodatePicker\nIf you make changes to improve it send us a copy\n3140 \"O\" Street\nLincoln, Ne 68510\n(800) 635-2481\n" , viewclass: 81 }; // View CreditLink is accesible from RunBase ShowCredits := /* child of RunBase */ {text: "?", buttonClickScript: func() begin CreditLink:open() end, viewBounds: {left: 114, top: 306, right: 130, bottom: 322}, viewFormat: 251658833, viewfont: ROM_fontSystem12Bold, _proto: protoTextButton, debug: "ShowCredits" };