<> <> <> <> <> <> <> <> <<>> DIRECTORY Atom, BasicTime, BiScrollers, CodeTimer, Convert, Feedback, GGActive, GGBasicTypes, GGControlPanelTypes, GGCoreOps, GGCoreTypes, GGEmbedTypes, GGEvent, GGFont, GGInterfaceTypes, GGModelTypes, GGScrollMonitor, GGSlice, GGState, GGTransform, GGUserInput, GGUserProfile, GGViewerOps, GGWindow, GGWorld, Imager, ImagerTransformation, InputFocus, IO, List, Menus, Process, Real, RealFns, RefTab, Rope, ScreenCoordsTypes, SlackProcess, TIPUser, UserProfile, Vector2, ViewerClasses; GGUserImpl: CEDAR MONITOR IMPORTS Atom, BasicTime, BiScrollers, CodeTimer, Convert, Feedback, GGActive, GGCoreOps, GGEvent, GGFont, GGScrollMonitor, GGSlice, GGState, GGTransform, GGUserInput, GGViewerOps, GGWindow, ImagerTransformation, InputFocus, IO, List, Process, RealFns, RefTab, Rope, SlackProcess, UserProfile EXPORTS GGInterfaceTypes, GGUserInput, GGUserProfile = BEGIN Camera: TYPE = GGModelTypes.Camera; ControlsObj: PUBLIC TYPE = GGControlPanelTypes.ControlsObj; -- exported to GGInterfaceTypes EmbedDataObj: PUBLIC TYPE = GGEmbedTypes.EmbedDataObj; -- exported to GGInterfaceTypes Event: TYPE = GGCoreTypes.Event; EventListt: TYPE = GGCoreTypes.EventListt; External: TYPE = GGUserInput.External; ExternalRec: TYPE = GGUserInput.ExternalRec; FeatureData: TYPE = GGModelTypes.FeatureData; FontData: TYPE = GGModelTypes.FontData; GGData: TYPE = GGInterfaceTypes.GGData; Point: TYPE = GGBasicTypes.Point; RawInputHandlerProc: TYPE = GGUserInput.RawInputHandlerProc; Scene: TYPE = GGModelTypes.Scene; SlackHandle: TYPE = SlackProcess.SlackHandle; Slice: TYPE = GGModelTypes.Slice; SliceDescriptor: TYPE = GGModelTypes.SliceDescriptor; Transformation: TYPE = ImagerTransformation.Transformation; UserInputProc: TYPE = GGUserInput.UserInputProc; VEC: TYPE = Imager.VEC; XVEC: TYPE = RECORD [x, y: REAL]; Viewer: TYPE = ViewerClasses.Viewer; Problem: PUBLIC SIGNAL [msg: Rope.ROPE] = Feedback.Problem; externalCV: CONDITION; <> WaitExternal: PUBLIC ENTRY PROC [External] = { WAIT externalCV; }; BroadcastExternal: PUBLIC ENTRY PROC [External] = { BROADCAST externalCV; }; NotifyExternal: PUBLIC ENTRY PROC [External] = { NOTIFY externalCV; }; <> <> EventNotify: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData ¬ NARROW[clientData]; <> ProcessAndQueueEvent[event, ggData]; }; UnQueuedEventNotify: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { <> ggData: GGData ~ NARROW[clientData]; atom: ATOM ~ NARROW[event.first]; regEvent: RegisteredEvent ~ FetchAction[atom]; IF regEvent=NIL THEN { NotYetImplementedMessage[atom, ggData]; } ELSE { event ¬ GetAnyArguments[event, regEvent, ggData]; TRUSTED {Process.Detach[FORK regEvent.eventProc[ggData, event] ]; }; }; }; <> PlayAction: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData ¬ NARROW[clientData]; IF event.first = $Version OR event.first = $Store OR event.first = $Save OR event.first = $ToIP OR event.first = $ToIPScreen OR event.first = $ToIPLit OR event.first = $IPToTioga OR event.first = $IPToTiogaBordered OR event.first = $IPToTiogaFit OR event.first = $IPToTiogaBorderedAndFit OR event.first = $IPToTiogaAlt OR event.first = $StuffToTioga OR event.first = $StuffToFile OR event.first = $MergeFromTioga OR event.first = $StuffToTiogaBordered OR event.first = $StuffToFileAlt OR event.first = $GrabFromTioga OR event.first = $StuffToTiogaFit OR event.first = $GetFromTioga OR event.first = $StuffToTiogaBorderedAndFit OR event.first = $MergeFromGargoyle OR event.first = $StuffToTiogaAlt THEN RETURN; ProcessAndQueueEvent[event, ggData]; }; <> <<>> gRawInputHandler: GGUserInput.RawInputHandlerProc ¬ GGActive.ActiveInputHandler; InputNotify: PUBLIC ViewerClasses.NotifyProc = { <> ggData: GGData ~ NARROW[BiScrollers.ClientDataOfViewer[self]]; notify: PROC [input: LIST OF REF] ~ { InputFocus.SetInputFocus[ggData.controls.actionArea]; <> ProcessAndQueueEvent[input, ggData]; }; gRawInputHandler[self, ggData, input, notify]; }; BiScrollerInputNotify: PUBLIC PROC [ggData: GGData, event: LIST OF REF] = { <> BiScrollerQueue: PROC [event: LIST OF REF ANY, ggData: GGData] = { first: ATOM ¬ NARROW[event.first]; IF first=$Shift THEN { vec: REF VEC _ NARROW[event.rest.first]; -- Shift VECTOR xVec: REF XVEC ¬ NEW[XVEC ¬ [vec.x, vec.y] ]; -- put it in a record different from type VEC event ¬ LIST[$Shift, xVec]; }; ProcessAndQueueEvent[event, ggData]; }; IF ISTYPE[event.first, LIST OF REF] THEN { FOR list: LIST OF REF _ event, list.rest UNTIL list = NIL DO sublist: REF ¬ list.first; IF ISTYPE[sublist, LIST OF REF] THEN BiScrollerQueue[NARROW[sublist], ggData]; ENDLOOP; } ELSE BiScrollerQueue[event, ggData]; }; finishText: LIST OF REF ANY ~ LIST[$SawTextFinish]; finishMouse: LIST OF REF ANY ~ LIST[$SawMouseFinish]; ProcessAndQueueEvent: PROC [event: LIST OF REF ANY, ggData: GGData] = { <> <<1) LIST[REF CHAR].>> <<2) LIST[ATOM, ... ].>> IF ggData.embed.beingBorn THEN RETURN; -- don't handle events while the window is being created WITH event.first SELECT FROM refChar: REF CHAR => { <> myRefChar: REF CHAR ~ NEW[CHAR ¬ refChar­]; event ¬ LIST[$AddChar, myRefChar]; }; atom: ATOM => { regEvent: RegisteredEvent ~ FetchAction[atom]; IF regEvent=NIL THEN NotYetImplementedMessage[atom, ggData] ELSE { atomName: Rope.ROPE ~ Atom.GetPName[atom]; startAction: BOOL ~ Rope.Equal[Rope.Substr[atomName, 0, 5], "Start", TRUE]; <> IF startAction THEN QueueInput[ggData, finishText]; -- need this before selection changes IF regEvent.causeMouseEventsToComplete THEN QueueInput[ggData, finishMouse]; event ¬ GetAnyArguments[event, regEvent, ggData]; IF atom = $OneScroll THEN { IF event.rest # NIL THEN BEGIN x, y: INTEGER ¬ 0; WITH event.rest.first SELECT FROM change: REF Imager.VEC => { GGScrollMonitor.ConcatToDue[ggData, ImagerTransformation.Translate[[change.x, change.y]] ]; GOTO EasyCase; }; i: REF INTEGER => x ¬ i­; ENDCASE; IF event.rest.rest # NIL THEN { WITH event.rest.rest.first SELECT FROM i: REF INTEGER => y ¬ i­; ENDCASE; }; GGScrollMonitor.ConcatToDue[ggData, ImagerTransformation.Translate[[x, y]] ]; EXITS EasyCase => NULL; END; } ELSE IF atom = $OneZoom THEN { originViewer: Point; x: INTEGER ¬ 0; fx, scalar: REAL; viewport: Imager.Rectangle ¬ GGState.GetViewport[ggData]; originViewer ¬ [viewport.x+(viewport.w/2.0), viewport.y+(viewport.h/2.0)]; IF event.rest # NIL THEN { WITH event.rest.first SELECT FROM i: REF INTEGER => x ¬ i­; ENDCASE; }; fx ¬ x; -- convert to float scalar ¬ RealFns.Power[base: 2.0, exponent: fx/50.0]; -- fifty clicks of the track ball gives a factor of two <> GGScrollMonitor.ConcatToDue[ggData, GGTransform.ScaleAboutPoint[originViewer, scalar] ]; }; }; }; ENDCASE => ERROR; QueueInput[ggData, event, NIL]; }; Timestamp: TYPE = REF TimestampObj; TimestampObj: TYPE = RECORD [ startTime: CARD32 ]; timeQueue: BOOL ¬ FALSE; QueueInput: PROC [ggData: GGData, event: LIST OF REF ANY, optimizeHint: REF ANY ¬ NIL] ~ { handle: SlackHandle ~ ggData.slackHandle; GGEvent.PrintAllInput[ggData, event]; -- KAP IF timeQueue THEN event ¬ List.Nconc1[event, NEW[TimestampObj ¬ [NowInMilliseconds[]]] ]; -- for timing how much time is spent on the queue SlackProcess.QueueAction[handle, Dispatch, event, ggData, optimizeHint]; }; GetAnyArguments: PROC [event: LIST OF REF ANY, regEvent: RegisteredEvent, ggData: GGData] RETURNS [newEvent: LIST OF REF ANY] = { atom: ATOM ¬ NARROW[event.first]; SELECT regEvent.argType FROM none => newEvent ¬ event; <> < {>> <> <> <> <> <> <> <> <<}>> <> <> <> <<};>> rope => newEvent ¬ CheckForSelectedRope[atom, event]; rope2 => newEvent ¬ CheckForSelectedRope2[atom, event]; refReal => newEvent ¬ CheckForSelectedReal[atom, event]; refInt => newEvent ¬ CheckForSelectedInt[atom, event]; refCard => newEvent ¬ CheckForSelectedCard[atom, event]; refExt => newEvent ¬ CheckForActualExt[atom, event]; ENDCASE => ERROR; }; RegisterRawInputHandler: PUBLIC PROC [rawInputHandler: RawInputHandlerProc] = { gRawInputHandler ¬ rawInputHandler; }; <> <<>> NowInMilliseconds: PROC RETURNS [CARD32] = { RETURN[(BasicTime.PulsesToMicroseconds[BasicTime.GetClockPulses[]]+500)/1000]; }; PrintUserTrace: PROC [ggData: GGInterfaceTypes.GGData, eventProc: GGUserInput.UserInputProc, event: LIST OF REF ANY] ~ { <> <> <> <> procName: Rope.ROPE ¬ "?"; moduleName: Rope.ROPE ¬ "?"; thisArgName: Rope.ROPE; allArgs: Rope.ROPE; FOR list: LIST OF REF ANY ¬ event, list.rest UNTIL list = NIL DO thisArgName ¬ IO.PutFR1["%g", [refAny[list.first]] ]; IF allArgs = NIL THEN allArgs ¬ thisArgName ELSE allArgs ¬ Rope.Cat[allArgs, ", ", thisArgName]; ENDLOOP; Feedback.PutFL[ggData.router, oneLiner, $Typescript, "%g.%g[%g]", LIST[[rope[moduleName]], [rope[procName]], [rope[allArgs]]] ]; }; Dispatch: PROC [clientData: REF ANY, inputAction: REF] = { ggData: GGData ~ NARROW[clientData]; atom: ATOM; startTime, endTime: CARD32; startTimeRef: REF; regEvent: RegisteredEvent; event: LIST OF REF ¬ NARROW[inputAction]; UpdateCoords: PROC [input: LIST OF REF] RETURNS [o: LIST OF REF] = { i, l: LIST OF REF; viewerToClient: Transformation _ GGState.GetBiScrollersTransforms[ggData].viewerToClient; IF input.first = $AlignFracs OR (input.rest # NIL AND input.rest.first = $AlignFracs) THEN RETURN[input]; -- because BiScrollers uses REF Vector2.VEC for the shift amount FOR i ¬ input, i.rest WHILE i # NIL DO l ¬ IF l = NIL THEN o ¬ CONS[i.first, NIL] ELSE l.rest ¬ CONS[i.first, NIL]; WITH l.first SELECT FROM z: TIPUser.TIPScreenCoords => { l.first ¬ NEW [Vector2.VEC ¬ viewerToClient.Transform[[z.mouseX, z.mouseY]]]; }; v: REF Vector2.VEC => { l.first _ NEW [Vector2.VEC _ viewerToClient.Transform[v^]]; }; z: REF XVEC => { l.first _ NEW [Vector2.VEC _ [z.x, z.y] ]; }; ENDCASE; ENDLOOP; }; event ¬ UpdateCoords[event]; -- perform the BiScrollers transform IF timeQueue THEN { startTimeRef ¬ List.NthElement[event, -1]; WITH startTimeRef SELECT FROM timeStamp: Timestamp => { startTime ¬ timeStamp.startTime; event ¬ List.DRemove[startTimeRef, event]; endTime ¬ NowInMilliseconds[]; CodeTimer.SetIntMilliseconds[$TimeOnQueue, startTime, endTime, $Gargoyle]; }; ENDCASE; }; atom ¬ NARROW[event.first]; regEvent ¬ FetchAction[atom]; IF regEvent=NIL THEN NotYetImplementedMessage[atom, ggData] ELSE { IF event.first=$Again THEN { IF NOT GGCoreOps.NoEvents[ggData.lastEvents] THEN { FOR list: LIST OF Event ¬ ggData.lastEvents.list, list.rest UNTIL list = NIL DO thisEvent: LIST OF REF ANY ~ list.first; thisAtom: ATOM ~ NARROW[thisEvent.first]; thisRegEvent: RegisteredEvent ~ FetchAction[thisAtom]; IF thisRegEvent=NIL THEN NotYetImplementedMessage[thisAtom, ggData] ELSE thisRegEvent.eventProc[ggData, thisEvent]; ENDLOOP; } ELSE {}; -- there is nothing to do again } ELSE { SELECT GetEventClass[atom] FROM select => ggData.justSawSelect ¬ TRUE; action => { IF ggData.justSawSelect THEN { GGCoreOps.FlushEventListt[ggData.lastEvents]; ggData.justSawSelect ¬ FALSE; }; GGCoreOps.AppendEvent[event, ggData.lastEvents]; }; suppress => {}; -- $During. Ignore it. neutral => { IF ggData.justSawSelect THEN {} -- this is the during or end of a select operation ELSE GGCoreOps.AppendEvent[event, ggData.lastEvents]; }; ENDCASE => ERROR; IF GGUserInput.GetUserTraceOn[] THEN PrintUserTrace[ggData, regEvent.eventProc, event]; regEvent.eventProc[ggData, event]; }; }; }; EventClass: TYPE = {select, neutral, action, suppress}; GetEventClass: PROC [atom: ATOM] RETURNS [eventClass: EventClass] = { <> <> <<) THEN RETURN [suppress];>> IF ( atom = $During OR atom = $GuardUp OR atom = $MouseUp OR atom = $AllUp OR atom = $SawTextFinish OR atom = $SawMouseFinish ) THEN RETURN [neutral]; IF ( atom = $StartSelectWithBox OR atom = $StartSelectJoint OR atom = $StartExtSelectJoint OR atom = $StartSelectSegment OR atom = $StartExtSelectSegment OR atom = $StartSelectTrajectory OR atom = $StartExtSelectTrajectory OR atom = $StartSelectTopLevel OR atom = $StartExtSelectTopLevel OR atom = $StartExtendSelection OR atom = $StartDeselectJoint OR atom = $StartDeselectSegment OR atom = $StartDeselectTrajectory OR atom = $StartDeselectTopLevel OR atom = $CycleSelection OR atom = $AreaSelectNew OR atom = $AreaSelectNewAndDelete OR atom = $SelectAll OR atom = $AreaSelectDegenerate OR atom = $SelectCoincident OR atom = $SelectUnseeableSegs OR atom = $SelectUnseeableObjs ) THEN RETURN [select]; IF ( atom = $StartCaretPos OR atom = $StartAdd OR atom = $StartBox OR atom = $StartDrag OR atom = $StartCopyAndDrag OR atom = $StartAddAndDrag OR atom = $StartRotate OR atom = $StartScale OR atom = $StartSixPoint ) THEN RETURN [action]; IF ( atom = $OneZoom OR atom = $OneScroll ) THEN RETURN [suppress]; -- added November 4, 1992. KAP. RETURN [action]; }; <> <<>> NotYetImplementedMessage: PROC [atom: ATOM, ggData: GGData] = { Feedback.Append[ggData.router, begin, $Warning, "User event "]; Feedback.Append[ggData.router, middle, $Warning, Atom.GetPName[atom]]; Feedback.Append[ggData.router, end, $Warning, " is not yet implemented"]; }; CheckForSelectedRope: PROC [atom: ATOM, event: LIST OF REF ANY] RETURNS [newAction: LIST OF REF ANY] = { IF event.rest = NIL THEN { -- interactive call r: Rope.ROPE ¬ GGViewerOps.GetSelectionContents[]; newAction ¬ LIST[atom, r]; } ELSE IF ISTYPE[event.rest.first, REF TEXT] THEN { -- TIP table call newAction ¬ CONS[atom, CONS[Rope.FromRefText[NARROW[event.rest.first]], event.rest.rest]]; } ELSE newAction ¬ event; -- SessionLog call }; CheckForSelectedRope2: PROC [atom: ATOM, event: LIST OF REF ANY] RETURNS [newAction: LIST OF REF ANY] = { <> IF event.rest = NIL THEN ERROR; IF event.rest.rest = NIL THEN { -- interactive call r: Rope.ROPE ¬ GGViewerOps.GetSelectionContents[]; newAction ¬ LIST[atom, event.rest.first, r]; } ELSE IF ISTYPE[event.rest.rest.first, REF TEXT] THEN { -- TIP table call newAction ¬ LIST[atom, event.rest.first, Rope.FromRefText[NARROW[event.rest.rest.first]], event.rest.rest.rest]; } ELSE newAction ¬ event; -- SessionLog call }; CheckForSelectedReal: PROC [atom: ATOM, event: LIST OF REF ANY] RETURNS [newAction: LIST OF REF ANY] = { rope: Rope.ROPE; real: REAL; IF event.rest = NIL THEN { -- interactive call rope ¬ GGViewerOps.GetSelectionContents[]; real ¬ Convert.RealFromRope[rope ! Convert.Error => {real ¬ Real.LargestNumber; CONTINUE}]; newAction ¬ LIST[atom, NEW[REAL ¬ real]]; } ELSE IF ISTYPE[event.rest.first, REF TEXT] THEN { -- TIP table call rope ¬ Rope.FromRefText[NARROW[event.rest.first]]; real ¬ Convert.RealFromRope[rope ! Convert.Error => {real ¬ Real.LargestNumber; CONTINUE}]; newAction ¬ LIST[atom, NEW[REAL ¬ real]]; } ELSE newAction ¬ event; -- SessionLog call }; CheckForSelectedCard: PROC [atom: ATOM, event: LIST OF REF ANY] RETURNS [newAction: LIST OF REF ANY] = { rope: Rope.ROPE; card: CARD; IF event.rest = NIL THEN { -- interactive call rope ¬ GGViewerOps.GetSelectionContents[]; card ¬ IO.GetCard[IO.RIS[rope] ! IO.EndOfStream, IO.Error => {card ¬ LAST[CARD]; CONTINUE}]; newAction ¬ LIST[atom, NEW[CARD ¬ card]]; } ELSE IF ISTYPE[event.rest.first, REF CARD] THEN { -- TIP table call or SessionLog call newAction ¬ event; } ELSE ERROR; }; CheckForSelectedInt: PROC [atom: ATOM, event: LIST OF REF ANY] RETURNS [newAction: LIST OF REF ANY] = { rope: Rope.ROPE; int: INT; IF event.rest = NIL THEN { -- interactive call rope ¬ GGViewerOps.GetSelectionContents[]; int ¬ IO.GetInt[IO.RIS[rope] ! IO.EndOfStream, IO.Error => {int ¬ LAST[INT]; CONTINUE}]; newAction ¬ LIST[atom, NEW[INT ¬ int]]; } ELSE { WITH event.rest.first SELECT FROM int: REF INT => newAction ¬ event; -- TIP table call or SessionLog call card: REF CARD => newAction ¬ List.Append[LIST[atom, NEW[INT ¬ card­]], event.rest.rest]; -- type coersion ENDCASE => ERROR; }; }; CheckForActualExt: PROC [atom: ATOM, event: LIST OF REF ANY] RETURNS [newAction: LIST OF REF ANY] = { IF event.rest=NIL OR NOT ISTYPE[event.rest.first, REF GGUserInput.ExternalRec] THEN ERROR; newAction ¬ event; }; RegisteredEvent: TYPE = REF RegisteredEventObj; RegisteredEventObj: TYPE = RECORD [ eventProc: UserInputProc, argType: GGUserInput.ArgumentType, causeMouseEventsToComplete: BOOL ]; RegisterAction: PUBLIC PROC [atom: ATOM, eventProc: UserInputProc, argType: GGUserInput.ArgumentType, causeMouseEventsToComplete: BOOL ¬ TRUE, ensureUnique: BOOL ¬ TRUE] = { <> regEvent: RegisteredEvent ¬ NEW[RegisteredEventObj ¬ [eventProc, argType, causeMouseEventsToComplete]]; justInserted: BOOL ¬ RefTab.Insert[eventTable, atom, regEvent]; IF NOT justInserted THEN <> <> [] ¬ RefTab.Replace[eventTable, atom, regEvent]; }; FetchAction: PROC [atom: ATOM] RETURNS [RegisteredEvent] ~ { WITH RefTab.Fetch[eventTable, atom].val SELECT FROM regEvent: RegisteredEvent => RETURN[regEvent]; ENDCASE => RETURN[NIL]; }; <> LookAtProfile: PUBLIC UserProfile.ProfileChangedProc = { <<[reason: UserProfile.ProfileChangeReason]>> gravExtent: REAL; -- in inches defaultHistorySize: INT; heuristics: BOOL ¬ UserProfile.Boolean[key: "Gargoyle.Heuristics", default: FALSE]; quickClickMode: BOOL ¬ UserProfile.Boolean[key: "Gargoyle.QuickClickEnable", default: FALSE]; useLatestIPVersion: BOOL ¬ UserProfile.Boolean[key: "Gargoyle.UseLatestIPVersion", default: FALSE]; autoOpenTypescript: BOOL ¬ UserProfile.Boolean[key: "Gargoyle.AutoOpenTypescript", default: TRUE]; autoOpenHistory: BOOL ¬ UserProfile.Boolean[key: "Gargoyle.AutoOpenHistory", default: TRUE]; autoScriptingOn: BOOL ¬ UserProfile.Boolean[key: "Gargoyle.AutoScriptingOn", default: FALSE]; separateControlPanel: BOOL ¬ UserProfile.Boolean[key: "Gargoyle.SeparateControlPanel", default: FALSE]; defaultIncludeIPBy: Rope.ROPE ¬ UserProfile.Token[key: "Gargoyle.DefaultIncludeIPBy", default: "Reference"]; holdThatTiger: BOOL ¬ UserProfile.Boolean[key: "Gargoyle.HoldThatTiger", default: FALSE]; newBoxesUnfilled: BOOL ¬ UserProfile.Boolean[key: "Gargoyle.NewBoxesUnfilled", default: FALSE]; defaultHistorySize ¬ Convert.IntFromRope[UserProfile.Token[key: "Gargoyle.DefaultHistorySize", default: "40"] ! Convert.Error => IF reason = syntax THEN {defaultHistorySize ¬ -1; CONTINUE;} ELSE REJECT]; gravExtent ¬ Convert.RealFromRope[UserProfile.Token[key: "Gargoyle.GravityExtent", default: "-1.0"] ! Convert.Error => IF reason = syntax THEN {gravExtent ¬ -1.0; CONTINUE;} ELSE REJECT]; IF gravExtent=-1.0 THEN gravExtent ¬ 25.0/72.0; IF defaultHistorySize<1 THEN defaultHistorySize ¬ IF defaultHistorySize=0 THEN 1 ELSE 40; SetDefaultHeuristics[on: heuristics]; SetDefaultGravityExtent[inches: gravExtent]; GGState.SetQuickClickMode[quickClickMode]; SetDefaultUseLatestIPVersion[useLatestIPVersion]; SetAutoOpenTypescript[autoOpenTypescript]; SetAutoOpenHistory[autoOpenHistory]; SetDefaultHistorySize[defaultHistorySize]; SetAutoScriptingOn[autoScriptingOn]; SetSeparateControlPanel[separateControlPanel]; SetHoldThatTiger[holdThatTiger]; SetNewBoxesUnfilled[newBoxesUnfilled]; SetDefaultIncludeIPByValue[Rope.Equal[defaultIncludeIPBy, "Value", FALSE]]; BEGIN -- set the default default font description: Rope.ROPE ¬ UserProfile.Token[key: "Gargoyle.DefaultDefaultFont", default: NIL]; descriptionStream: IO.STREAM; defaultFont: FontData; IF description = NIL THEN description ¬ "xerox/xc1-2-2/helvetica [r1: 0.0 s: [10.0 10.0] r2: 0.0] 1.0 1.0"; <> descriptionStream ¬ IO.RIS[description]; defaultFont ¬ GGFont.ParseFontData[inStream: descriptionStream, literalP: TRUE, transformP: TRUE, storedSizeP: TRUE, designSizeP: TRUE]; SetDefaultDefaultFont[defaultFont]; END; IF reason#firstTime THEN GGWindow.InitIcons[]; -- don't do this on first registering this proc }; <> MasterData: TYPE = REF MasterDataObj; MasterDataObj: TYPE = RECORD [ defaultGravityExtent: REAL ¬ 25.0, -- in screen dots defaultHeuristics: BOOL ¬ TRUE, objectsBeingCopied: LIST OF REF ANY, -- for copying objects from viewer to viewer, defaultDefaultFont: FontData, autoOpenTypescript: BOOL ¬ TRUE, autoOpenHistory: BOOL ¬ TRUE, defaultHistorySize: INT ¬ 40, autoScriptingOn: BOOL ¬ TRUE, separateControlPanel: BOOL ¬ FALSE, defaultIncludeIPByValue: BOOL ¬ FALSE, holdThatTiger: BOOL ¬ FALSE, newBoxesUnfilled: BOOL ¬ FALSE, turboOn: BOOL ¬ FALSE, userTraceOn: BOOL ¬ FALSE ]; SetUserTraceOn: PUBLIC PROC [on: BOOL] = { masterData.userTraceOn ¬ on; }; GetUserTraceOn: PUBLIC PROC RETURNS [on: BOOL] = { on ¬ masterData.userTraceOn; }; SetDefaultHeuristics: PUBLIC PROC [on: BOOL] = { <> masterData.defaultHeuristics ¬ on; }; GetDefaultHeuristics: PUBLIC PROC RETURNS [on: BOOL] = { <> on ¬ masterData.defaultHeuristics; }; <<>> SetDefaultGravityExtent: PUBLIC PROC [inches: REAL] = { <> masterData.defaultGravityExtent ¬ inches*72.0; }; GetDefaultGravityExtent: PUBLIC PROC RETURNS [screenDots: REAL] = { <> screenDots ¬ masterData.defaultGravityExtent; }; SetDefaultUseLatestIPVersion: PUBLIC PROC [useLatestIPVersion: BOOL] = { GGSlice.SetDefaultUseLatestIPVersion[useLatestIPVersion]; }; GetDefaultUseLatestIPVersion: PUBLIC PROC [] RETURNS [useLatestIPVersion: BOOL] = { RETURN[GGSlice.GetDefaultUseLatestIPVersion[]]; }; <<>> SetDefaultDefaultFont: PUBLIC PROC [font: FontData] = { masterData.defaultDefaultFont ¬ font; }; GetDefaultDefaultFont: PUBLIC PROC RETURNS [font: FontData] = { font ¬ masterData.defaultDefaultFont; }; SetAutoOpenTypescript: PUBLIC PROC [autoOpenTypescript: BOOL] = { masterData.autoOpenTypescript ¬ autoOpenTypescript; }; GetAutoOpenTypescript: PUBLIC PROC [] RETURNS [autoOpenTypescript: BOOL] = { autoOpenTypescript ¬ masterData.autoOpenTypescript; }; SetAutoOpenHistory: PUBLIC PROC [autoOpenHistory: BOOL] = { masterData.autoOpenHistory ¬ autoOpenHistory; }; GetAutoOpenHistory: PUBLIC PROC [] RETURNS [autoOpenHistory: BOOL] = { autoOpenHistory ¬ masterData.autoOpenHistory; }; SetDefaultHistorySize: PUBLIC PROC [defaultHistorySize: INT] = { masterData.defaultHistorySize ¬ defaultHistorySize; }; GetDefaultHistorySize: PUBLIC PROC RETURNS [defaultHistorySize: INT] = { defaultHistorySize ¬ masterData.defaultHistorySize; }; SetAutoScriptingOn: PUBLIC PROC [autoScriptingOn: BOOL] = { masterData.autoScriptingOn ¬ autoScriptingOn; }; GetAutoScriptingOn: PUBLIC PROC [] RETURNS [autoScriptingOn: BOOL] = { autoScriptingOn ¬ masterData.autoScriptingOn; }; SetSeparateControlPanel: PUBLIC PROC [separateControlPanel: BOOL] = { masterData.separateControlPanel ¬ separateControlPanel; }; GetSeparateControlPanel: PUBLIC PROC [] RETURNS [separateControlPanel: BOOL] = { separateControlPanel ¬ masterData.separateControlPanel; }; SetDefaultIncludeIPByValue: PUBLIC PROC [defaultIncludeIPByValue: BOOL] = { masterData.defaultIncludeIPByValue ¬ defaultIncludeIPByValue; }; GetDefaultIncludeIPByValue: PUBLIC PROC [] RETURNS [defaultIncludeIPByValue: BOOL] = { defaultIncludeIPByValue ¬ masterData.defaultIncludeIPByValue; }; SetHoldThatTiger: PUBLIC PROC [holdThatTiger: BOOL] = { masterData.holdThatTiger ¬ holdThatTiger; }; GetHoldThatTiger: PUBLIC PROC [] RETURNS [holdThatTiger: BOOL] = { holdThatTiger ¬ masterData.holdThatTiger; }; SetNewBoxesUnfilled: PUBLIC PROC [newBoxesUnfilled: BOOL] = { masterData.newBoxesUnfilled ¬ newBoxesUnfilled; }; GetNewBoxesUnfilled: PUBLIC PROC [] RETURNS [newBoxesUnfilled: BOOL] = { newBoxesUnfilled ¬ masterData.newBoxesUnfilled; }; masterData: MasterData; eventTable: RefTab.Ref; masterData ¬ NEW[MasterDataObj]; UserProfile.CallWhenProfileChanges[LookAtProfile]; eventTable ¬ RefTab.Create[255]; <> <> END.