// Text of project HelpURL2.9 written on 11/25/96 at 8:33 AM // Beginning of file protoAboutText // Before Script for "_userproto000" begin constant kNewtsCapeSymbol := '|Newtscape:Newtscape|; DefConst('kBuild20, platformVersion.platformFile <> '|MessagePad|); DefConst('kFixupHREFtext, func(template) // used in instance's afterScript begin // extract&remove HREF info, emphasize URLs with underline // this version assumes syntactically correct URLs (no extra/missing chars) // label // e.g., home page // e.g., email addr local ARRAY styles := [], hrefs := []; local text := template.text, href; local regfont := template.viewFont, urlfont; if isFrame(regfont) then begin urlfont := Clone(regfont); urlfont.face := BOR(urlfont.face, kFaceUnderline); end else urlfont := BOR(regfont,tsUnderLine); local spos, qpos, epos := 0; while spos := StrPos(text, " epos then begin AddArraySlot(styles, spos-epos); AddArraySlot(styles, regfont); end; // extract href string: "http:..." qpos := StrPos(text,"\"",spos)+1; epos := StrPos(text,"\"",qpos); href := SubStr(text,qpos,epos-qpos); // remove HTML before label: epos := StrPos(text, ">", epos); StrMunger(text,spos,epos+1-spos, nil,0,nil); // remove HTML after label: epos := StrPos(text,"",spos); StrMunger(text,epos,4, nil,0,nil); // highlight label AddArraySlot(styles, epos-spos); AddArraySlot(styles, urlfont); // save href (for viewClickScript) AddArraySlot(hrefs, [href, spos, epos]); end; // any regular text at end? if epos < StrLen(text) then begin AddArraySlot(styles,StrLen(text)-epos); AddArraySlot(styles, regfont); end; if kDebugOn then begin Print("about text:"); Print(text); Print("about hrefs:"); Print(hrefs); end; template.styles := styles; template.hrefs := hrefs; template.text := text; RemoveSlot(template,'viewFont); end); end _userproto000 := {viewBounds: {left: 1, top: 1, right: -1, bottom: -15}, viewFlags: 513, viewFont: simpleFont10 // note: this will be replaced by styles. coord with linespacing , viewFormat: 257, viewLineSpacing: 12, text: "", viewClickScript: func(unit) begin /* this finds the HREF that's clicked on (precomputed in afterScript) highlights it dispatches via urlCop or Newt's Cape unhighlights */ local hrefentry, href, options := {}, spos, epos, app; local INT cpos := :MyPointToCharOffset(GetPoint(firstX,unit), GetPoint(firstY,unit)); //Print(cpos); //if cpos >=0 then Print(text[cpos]); if cpos >= 0 then foreach hrefentry in hrefs // e.g., [["http:...", 10,20],...] do if (spos := hrefentry[1]) <= cpos and cpos <= (epos := hrefentry[2]) then begin :SetHilite(spos, epos, true); href := hrefEntry[0]; // dispatch using urlCop if installed (and url type is registered) if (app := GetRoot().urlCop:?PreferredApp(href, 'getURL, {})) and app <> kNewtsCapeSymbol then GetRoot().urlCop:getURL(href,options) // .(app): ? else if GetRoot().(kNewtsCapeSymbol) // Newt's Cape installed? then begin if BeginsWith(href,"mailto:") then begin options.subject := title; // from app options.name := SubStr(text,spos,epos-spos); options.body := "I really like" && title; end; //else options.noStatus := not kDebugOn; // hidden for end users? GetRoot().(kNewtsCapeSymbol):getURL(href,options); end else if kDebugOn then Print(href); break :SetHilite(cpos,cpos,true); // would be nice to get rid of the caret too end; TRUE; // handled click end, viewJustify: 240, MyPointToCharOffset: func(x,y) if kBuild20 or HasVariable(self, 'PointToCharOffset) then :PointToCharOffset(x,y) else begin // 1.x definition local gb := :GlobalBox(); x := x - gb.left; y := y - gb.top; //Print([x,y]); local spos, epos := -1; local INT i, linenum := y div viewLineSpacing; if linenum < 0 then return -1; // find the line // assume all cr-delimited with no wrapping for i:=0 to linenum do if epos then begin spos := epos+1; epos := StrPos(text,"\n",spos); end else return -1; local newstr := { viewFont: styles[1], msg: Functions.StrTruncate}:msg(SubStr(text,spos,epos), x); spos + StrLen(newstr)-1; // I on end end, viewClass: 81 }; constant |layout_protoAboutText| := _userproto000; // End of file protoAboutText // Beginning of file aboutURLLayout // Before Script for "aboutURLLayout" /* this is an example aboutBox. aboutText is based on protoAboutText. you can include simple expressions in text. be sure to call kFixUpHREFText in afterScript note: for 1.x use, text lines must be short (each end in return, no wrapping) */ aboutURLLayout := {viewBounds: {left: 4, top: 4, right: -4, bottom: -4}, viewJustify: 240, _proto: @180 }; aboutText := { text: "Steve Weyer\n17 Timber Knoll Dr.\nWashington Crossing, PA 18977-1052\ninternet: weyer@netaxs.com\nAOL: SteveWeyer\nCIS: 74603,2051\nhttp://www.netaxs.com/~weyer/newton/releases.html" , _proto: _userproto000 }; AddStepForm(aboutURLLayout, aboutText); // After Script for "aboutText" thisView := aboutText; call kFixupHREFtext with (thisView) constant |layout_aboutURLLayout| := aboutURLLayout; // End of file aboutURLLayout // Beginning of file myProtoInfoButton // Before Script for "_userproto001" DefConst('kFixupInfoItems, func(template) begin local items := template.AppInfoItems := []; if HasSlot(template, 'DoInfoAbout) then AddArraySlot(items, "About"); if HasSlot(template, 'DoInfoHelp) then AddArraySlot(items, "Help"); if HasSlot(template, 'DoInfoPrefs) then AddArraySlot(items, "Prefs"); local auxItems := template:?GenInfoAuxItems(); if isArray(auxItems) and Length(auxItems) > 0 and HasSlot(template,'DoInfoAux) then begin AddArraySlot(items, 'pickSeparator); template.AuxOffset := Length(items); ArrayMunger( items, Length(items), 0, auxItems, 0, nil); end; end) _userproto001 := {icon: GetPictAsBits("info icon", nil), viewBounds: {left: 6, top: 0, right: 19, bottom: 12}, viewFlags: 513, viewFormat: 67109457, viewJustify: 17446, viewClickScript: func(unit) if :TrackHilite(unit) then if kBuild20 or HasVariable(:Parent(),'PopupMenu) then :PopupMenu(AppInfoItems, {left: 0, top: 0}) else begin local l := :LocalBox(); DoPopUp(AppInfoItems, l.right+3, l.top, self); end, pickActionScript: func(index) begin // MUST do this :Hilite(nil); if auxOffset and index >= auxOffset then :DoInfoAux(:GenInfoAuxItems(), index - auxOffset) else Perform(self, '{ About: DoInfoAbout, Help: DoInfoHelp, Prefs: DoInfoPrefs}.(Intern(AppInfoItems[index])), []); end, pickCancelledScript: func() :Hilite(nil), AppInfoItems: [] // set in afterScript , auxOffset: nil, viewClass: 76 }; constant |layout_myProtoInfoButton| := _userproto001; // End of file myProtoInfoButton // Beginning of file HelpURLMain // Before Script for "aboutHelpURLMain" /* this example shows how to include aboutText with embedded URLs that can be tapped. and also create a dynamic help book using Newt's Cape. this will also work on 1.x with some limitations: - it assumes that each 'about line' is short: ends with a return and does not wrap (long lines ok in help books since Newt's Cape does the text measurement/bounds computation) - web pages would be retrieved using WebMail rather than NIE */ constant kDragRadius := 4; aboutHelpURLMain := {viewBounds: {left: 0, top: 30, right: 215, bottom: 160}, title: "HelpURL", helpISBN: "helpurl.htm", helpText: "\n\n^0 Help\t\t\t\n \t\n \t\n\n\n\n\n\n\n\n\n

Describe HelpURL

\n

\nHelpURL shows how to\n

    \n
  1. add URLs to an about box\n
  2. create a dynamic help book from HTML\n
\n\n

\nThis works best with\nNewt's Cape\ninstalled on NOS 2.0 (though it will also work on 1.x).\n\n\n\n

Develop an About Box with URLs

\n
    \n
  1. Use the protoAboutText object\n
  2. Modify text, viewFont, etc. as appropriate.\n
  3. Text slot can contain simple HREF expressions only (see example).\n(For 1.x compatibility, use short lines with no wrapping.)\n
  4. This is processed at compile-time\n
\n\n\n

Use the About Box

\n
    \n
  1. Users should install URLcop\nand/or Newt's Cape\n
  2. User taps on a URL in your About box\n
  3. It dispatches according to protocol types registered with URLcop;\nor, if just Newt's Cape is installed:\n\t\n
\n\n\n

Develop a Help Book with URLs

\n\n
    \n
  1. Create helpText (like this)\n
  2. Set helpISBN slot (see afterScript for automatic substitution)\n
  3. Copy DoInfoHelp method to your app's infoButton\n
  4. install Newt's Cape\n
  5. select Help in your application (possibly making modifications iteratively)\n
  6. optionally, Save the help book using Newt's Cape; upload and distribute with your application\n
\n\n\n

Use the Help Book

\n\n
    \n
  1. User installs either\n\t\n
  2. Selects your i:Help button\n
  3. Help book opens (or Newt's Cape processes HTML to create help book dynamically)\n
  4. URLs to regular books and to web pages should work (links within help books might not work).\n
\n\n\n\n

Understand the Code

\n

\nPrerequisites: familiarity with both NewtonScript and HTML.\n\n

To customize appearance, modify the Tag Prefs in Newt's Cape,\nor you can add document-specific style preferences --\nsee the Newt's Cape documentation for further details.\n\n\n

Distribute HelpURL

\n

\nHelpURL is freeware, and may be distributed freely as long as all of the\nfiles are included and unmodified. You are free to make modifications for\nyour own use. I would appreciate your references to the Newt's Cape URL:\nhttp://www.netaxs.com/~weyer/newton/newtscape.html\n\n

\n© Copyright 1996, S. Weyer. All Rights Reserved Worldwide.\n\n\n

Contact Author

\n\n
Steve Weyer\n17 Timber Knoll Drive\nWashington Crossing, PA 18977-1052\nInternet: weyer@netaxs.com\nAmerica Online: SteveWeyer\nCompuserve: 74603,2051\nGreg Simon -- Newt's Cape co-developer\nhttp://www.netaxs.com/~weyer/newton/releases.html\n\nGaia Home page -- info about intranet wireless handheld solutions\n(re-using Newt's Cape technology).\n
\n\n\n" , ReorientToScreen: func() // ROM_DefRotateFunc begin :SyncView(); :RedoChildren(); end, viewFlags: 608, viewClickScript: func(unit) // not needed for 2.0 (removed in afterScript) self=helpURL and ABS(GetPoint(firstY, unit) - :GlobalBox().top) <= kDragRadius and ABS(GetPoint(firstX, unit) - :GlobalBox().left - ((viewBounds.right - viewBounds.left) div 2)) <= kDragRadius and :Drag(unit,nil), viewSetupFormScript: func() // not needed for 2.0 (removed in afterScript) begin self.helpurl := self; // for drag test inherited:?viewSetupFormScript(); end, viewDrawScript: func() // not needed for 2.0 (removed in afterScript) begin constant y := -1; local INT x := (viewBounds.right - viewBounds.left) div 2; :DrawShape( MakeOval(x-kDragRadius, y-kDragRadius, x+kDragRadius, y+kDragRadius), {transferMode: modeCopy, fillPattern: vfFillWhite, penSize: 2, }); end, viewFormat: 83952897, _proto: @180 }; _view000 := {title: "HelpURL", viewBounds: {left: 0, top: 2, right: 112, bottom: 18}, _proto: @229 }; AddStepForm(aboutHelpURLMain, _view000); aboutView := LinkedSubview(aboutURLLayout, {viewBounds: {left: 34, top: 26, right: 138, bottom: 34}}); AddStepForm(aboutHelpURLMain, aboutView); StepDeclare(aboutHelpURLMain, aboutView, 'aboutView); _view001 := {_proto: @220}; AddStepForm(aboutHelpURLMain, _view001); _view002 := { DoInfoAbout: func() AboutView:open(), DoInfoHelp: func() if isInstance(helpISBN,'string) then begin local libook := GetRoot().copperfield:whereIsBook(helpISBN); // help book installed? local libentry := // undocumented checking/workaround if libook and isFrame(libook.bookSoup) then libook.bookSoup; // NOS 2.0 bug: bad pkg ref after previous book removed if libentry then begin local ttim := GetRoot().TinyTim, viewer := ttim; local helpbook := libentry.book; // even more undocumented if kBuild20 or GetVariable(ttim,'openHelpBook) then ttim:close() // 2.0 else viewer := BuildContext({_proto: ttim, bookRef: helpBook}); // 1.x viewer:openManual(helpbook); end else GetRoot().(kNewtsCapeSymbol):?dispatchFile( // create it dynamically "text/html", helpISBN, helpText, {pageSize: 'help, // help book size //noStatus: not kDebugOn, // Newt's Cape invisible for end users? }); end, _proto: _userproto001 }; AddStepForm(_view001, _view002); // After Script for "_view002" thisView := _view002; // note: this button will work on either 2.0 or 1.x if kBuild20 then thisView._proto := protoInfoButton // discard myProtoInfoButton else call kFixupInfoItems with (thisView) // After Script for "aboutHelpURLMain" thisView := aboutHelpURLMain; begin // this substitutes title and isbn into the HTML helpText // could do this via ParamStr except it doesn't work on very large strings StrReplace(thisView.helpText, "^0", thisView.title, nil); StrReplace(thisView.helpText, "^1", thisView.helpISBN, nil); if kBuild20 then begin // not needed since functionality provided automatically RemoveSlot(thisView,'viewSetupFormScript); Removeslot(thisView,'viewClickScript); Removeslot(thisView,'viewDrawScript); thisView.viewFormat := Bor(thisView.viewFormat, 208); //vfFrameDragger); end else thisView.viewFormat := Bor(thisView.viewFormat, vfFrameMatte); end constant |layout_HelpURLMain| := aboutHelpURLMain; // End of file HelpURLMain