<<>> <> <> <> <> <> <<>> DIRECTORY Atom, Commander, CommanderOps, Icons, Imager, ImagerFont, InputFocus, IO, MessageWindow, PFS, Process, Rope, TIPUser, ViewerClasses, ViewerOps; SimpleViewerImpl: CEDAR PROGRAM IMPORTS Atom, Commander, CommanderOps, Icons, Imager, ImagerFont, InputFocus, IO, MessageWindow, PFS, Process, Rope, TIPUser, ViewerOps ~ BEGIN <> SimpleViewerData: TYPE ~ RECORD [pos, oldPos: Imager.VEC ¬ [10.0, 10.0]]; ViewerCmd: Commander.CommandProc ~ { d: REF SimpleViewerData ¬ NEW[SimpleViewerData]; ViewerOps.OpenIcon[ViewerOps.CreateViewer[ flavor: $SimpleViewer, info: [name: "SimpleViewer", icon: icon, data: d]]]; }; ViewerPaint: ViewerClasses.PaintProc ~ { d: REF SimpleViewerData ¬ NARROW[self.data]; IF whatChanged = $Move THEN { Imager.SetColor[context, Imager.white]; Imager.MaskRectangle[context, [d.oldPos.x, d.oldPos.y, 25, 25]]; }; Imager.SetColor[context, Imager.black]; Imager.MaskRectangle[context, [d.pos.x, d.pos.y, 25, 25]]; d.oldPos ¬ d.pos; }; ViewerNotify: ViewerClasses.NotifyProc ~ { d: REF SimpleViewerData ¬ NARROW[self.data]; mouse: TIPUser.TIPScreenCoords ¬ NARROW[input.first]; InputFocus.SetInputFocus[self]; d.pos ¬ [mouse.mouseX, mouse.mouseY]; SELECT input.rest.first FROM $move => ViewerOps.PaintViewer[self, client, FALSE, $Move]; $jump => { MessageWindow.Append["jump . . . "]; ViewerOps.PaintViewer[self, client, FALSE, $Move]; }; $time => { MessageWindow.Append[IO.PutFR1["The time is %g", IO.time[]], TRUE]; MessageWindow.Blink[]; }; ENDCASE; }; <> TipTestCmd: Commander.CommandProc ~ { ENABLE PFS.Error => { IF error.group = user THEN CommanderOps.Failed[error.explanation] }; argv: CommanderOps.ArgumentVector ¬ CommanderOps.Parse[cmd]; IF argv.argc # 2 THEN CommanderOps.Failed[cmd.procData.doc] ELSE { t: REF TIPUser.TIPScreenCoordsRec ¬ NEW[TIPUser.TIPScreenCoordsRec ¬ [10,10,FALSE]]; atom: ATOM ¬ Atom.MakeAtom[argv[1]]; info: ViewerOps.ViewerRec ¬ [name: Rope.Concat["TipTest ", argv[1]], icon: icon, data: t]; path: PFS.PATH ~ PFS.AbsoluteName[PFS.PathFromRope[argv[1]]]; ViewerOps.RegisterViewerClass[atom, NEW[ViewerClasses.ViewerClassRec ¬ [ paint: TipTestPaint, notify: TipTestNotify, tipTable: TIPUser.InstantiateNewTIPTable[PFS.RopeFromPath[path]] ]]]; IF atom # NIL THEN ViewerOps.OpenIcon[ViewerOps.CreateViewer[atom, info]]; }; }; TipTestPaint: ViewerClasses.PaintProc ~ { t: REF TIPUser.TIPScreenCoordsRec ¬ NARROW[self.data]; WITH whatChanged SELECT FROM r: Rope.ROPE => { Imager.SetFont[context, ImagerFont.Find["xerox/tiogafonts/helvetica10"]]; Imager.SetXY[context, [t.mouseX, t.mouseY]]; Imager.ShowRope[context, r]; }; ENDCASE; }; TipTestNotify: ViewerClasses.NotifyProc ~ TRUSTED { -- Process.Detach is unsafe t: REF TIPUser.TIPScreenCoordsRec ¬ NARROW[self.data]; msg: Rope.ROPE ¬ NIL; InputFocus.SetInputFocus[self]; FOR list: LIST OF REF ANY ¬ input, list.rest UNTIL list = NIL DO WITH list.first SELECT FROM a: ATOM => msg ¬ Rope.Cat[msg, " ", Atom.GetPName[a]]; z: TIPUser.TIPScreenCoords => t­ ¬ z­; ENDCASE => ERROR; ENDLOOP; Process.Detach[FORK ViewerOps.PaintViewer[self, client, TRUE, msg]]; }; <> icon: Icons.IconFlavor ¬ Icons.NewIconFromFile["SimpleViewer.icon", 0]; ViewerOps.RegisterViewerClass[ $SimpleViewer, NEW[ViewerClasses.ViewerClassRec ¬ [ paint: ViewerPaint, notify: ViewerNotify, tipTable: TIPUser.InstantiateNewTIPTable["SimpleViewer.tip"] ]] ]; Commander.Register["SimpleViewer", ViewerCmd, "Viewer demo: ^T: time, ^J: jump"]; Commander.Register["SimpleTipTest", TipTestCmd, "usage: SimpleTipTest "]; END.