<> <> <> <> <> DIRECTORY AtomButtons, AtomButtonsTypes, CodeTimer, Feedback, FS, GGBasicTypes, GGCircleCache, GGContainer, GGEditTool, GGEvent, GGInterfaceTypes, GGMenus, GGModelTypes, GGMouseEvent, GGSegmentTypes, GGSessionLog, GGShapes, GGUserInput, GGUtility, GGWindow, GraphicsButton, Imager, IO, Menus, PopUpSelection, Rope, Rules, SlackProcess, VFonts, ViewerClasses, ViewerTools; GGMenusImpl: CEDAR PROGRAM IMPORTS AtomButtons, CodeTimer, Feedback, FS, GGCircleCache, GGContainer, GGEditTool, GGEvent, GGMouseEvent, GGSessionLog, GGShapes, GGUserInput, GGUtility, GGWindow, GraphicsButton, Imager, IO, PopUpSelection, Rope, Rules, SlackProcess, VFonts, ViewerTools EXPORTS GGMenus = BEGIN Caret: TYPE = REF CaretObj; CaretObj: TYPE = GGInterfaceTypes.CaretObj; FeedbackData: TYPE = AtomButtonsTypes.FeedbackData; ImagerProc: TYPE = GGInterfaceTypes.ImagerProc; MouseButton: TYPE = Menus.MouseButton; Outline: TYPE = GGModelTypes.Outline; Point: TYPE = GGBasicTypes.Point; Scene: TYPE = REF SceneObj; SceneObj: TYPE = GGModelTypes.SceneObj; Segment: TYPE = GGSegmentTypes.Segment; Sequence: TYPE = GGModelTypes.Sequence; Traj: TYPE = GGModelTypes.Traj; GGData: TYPE = REF GargoyleDataObj; GargoyleDataObj: TYPE = GGInterfaceTypes.GargoyleDataObj; Viewer: TYPE = ViewerClasses.Viewer; entryHeight: CARDINAL = 15; -- height of a line of items entryVSpace: CARDINAL = 2; -- vertical leading between lines entryHSpace: CARDINAL = 2; -- horizontal space between items on a line column1: CARDINAL = 200; -- horizontal space between margin and column 1; column2: CARDINAL = 250; -- horizontal space between margin and column 2. column3: CARDINAL = 500; -- horizontal space between margin and column 3; fullColumn: CARDINAL = 600; -- the width of the standard large left column. <> <> <> smallNumberSize: CARDINAL = 60; pointSize: CARDINAL = 160; boldFont: VFonts.Font; -- initialized in Init below; PopUpMenuEntry: TYPE = RECORD [ name: Rope.ROPE, input: LIST OF REF ANY ]; ExtractChoiceList: PROC [menu: LIST OF PopUpMenuEntry] RETURNS [choices: LIST OF Rope.ROPE] = { pos: LIST OF Rope.ROPE; newCell: LIST OF Rope.ROPE; <> IF menu = NIL THEN ERROR; choices _ CONS[menu.first.name, NIL]; pos _ choices; FOR l: LIST OF PopUpMenuEntry _ menu.rest, l.rest UNTIL l = NIL DO newCell _ CONS[l.first.name, NIL]; pos.rest _ newCell; pos _ newCell; ENDLOOP; }; QueuePopUpMenuAction: PROC [label: Rope.ROPE, menu: LIST OF PopUpMenuEntry, ggData: GGData, onceOnly: BOOL _ TRUE] = { index: NAT; choices: LIST OF Rope.ROPE _ ExtractChoiceList[menu]; DO index _ PopUpSelection.Request[header: label, choice: choices]; IF index < 0 THEN ERROR; IF index = 0 THEN RETURN; FOR entries: LIST OF PopUpMenuEntry _ menu, entries.rest UNTIL entries = NIL DO IF index = 1 THEN { GGUserInput.EventNotify[ggData, entries.first.input]; EXIT; }; index _ index - 1; REPEAT FINISHED => ERROR; ENDLOOP; IF onceOnly THEN RETURN; ENDLOOP; }; BuildControlPanel: PUBLIC PROC [ggData: GGData, windowMenu: Menus.Menu] = { BuildFileMenuLine[ggData, windowMenu]; BuildMasterMenuLine[ggData]; BuildStyleMenuLine[ggData]; BuildGravityLine[ggData]; BuildSlopeLine[ggData]; BuildAngleLine[ggData]; BuildRadiusLine[ggData]; BuildDistanceLine[ggData]; BuildMeasureLine[ggData]; BuildFeedbackLine[ggData]; AddARule[ggData]; }; AddARule: PROC [ggData: GGData] = { rule: Rules.Rule; rule _ Rules.Create[[ parent: ggData.outer, wy: ggData.height, ww: ggData.outer.cw, wh: 2 ]]; GGContainer.ChildXBound[ggData.outer, rule]; ggData.height _ ggData.height + rule.wh + entryVSpace; }; -- end of AddARule fudgeX: INTEGER _ 2; <<>> <> <<>> BuildFileMenuLine: PROC [ggData: GGData, windowMenu: Menus.Menu] = { <> nextX: INTEGER _ AtomButtons.BuildButtonLine [ggData.outer, 0, ggData.height, ggData, GGUserInput.EventNotify, LIST[ [button["Clear", LIST[LIST[$Clear]], -1, FALSE, NIL, ConfirmClear]], [button["Restore", LIST[LIST[$Reset]], -1, FALSE, NIL, ConfirmReset]], [button["Get", LIST[LIST[$Get]], -1, FALSE, NIL, ConfirmGet]], -- guarded in spite of Tioga viewers menus [button["Merge", LIST[LIST[$Merge]], -1, FALSE, NIL, ConfirmMerge]], [button["Store", LIST[LIST[$Store]], -1, FALSE, NIL, ConfirmStore]], [button["Save", LIST[LIST[$Save]] ]], <<[button["Split", LIST[$Split] ]],>> [button["Stuff", LIST[LIST[$Stuff],NIL,LIST[$StuffScreen]] ]] ]]; nextX _ nextX+fudgeX; nextX _ AtomButtons.BuildUnQueuedButtonLine [ggData.outer, nextX, ggData.height, ggData, LIST[ ["Interpress", button, InterpressMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Script", button, ScriptMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Help", button, HelpMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Revive!", button, ReviveButton] ]]; nextX _ nextX+fudgeX; nextX _ AtomButtons.BuildButtonLine [ggData.outer, nextX, ggData.height, ggData, GGUserInput.EventNotify, LIST[ [button["Refresh", LIST[LIST[$Refresh]] ]], [button["Typescript", LIST[LIST[$Typescript]] ]] ]]; ggData.height _ ggData.height + entryHeight; }; BuildMasterMenuLine: PROC [ggData: GGData] = { <> overlapMenu: AtomButtons.ButtonLineEntry _ [popUpButton["Overlap", LIST [ [LIST [$Top], "Top", "Move selected objects to the front"], [LIST [$NoOp], "", "Does nothing"], [LIST [$Bottom], "Bottom", "Move selected objects to the back"], [LIST [$UpOne], "UpOne", "Move selected objects one layer toward the front"], [LIST [$NoOp], "", "Does nothing"], [LIST [$DownOne], "DownOne", "Move selected objects one layer toward the back"] ], -1, FALSE, NIL]]; nextX: INTEGER _ AtomButtons.BuildUnQueuedButtonLine [ggData.outer, 0, ggData.height, ggData, LIST[ ["Hierarchy", button, HierarchyMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Transform", button, TransformMenu, NIL, 0, -1, FALSE, NIL, boldFont] ]]; nextX _ AtomButtons.BuildButtonLine[ggData.outer, nextX+entryHSpace, ggData.height, ggData, GGUserInput.EventNotify, LIST[ overlapMenu ]]; nextX _ AtomButtons.BuildUnQueuedButtonLine [ggData.outer, nextX+entryHSpace, ggData.height, ggData, LIST[ <<["Overlap", button, OverlapMenu, NIL, 0, -1, FALSE, NIL, boldFont],>> ["Curves", button, CurveTypeMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Shapes", button, ShapesMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Text", button, TextOpsMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Fonts", button, FontOpsMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Groups", button, GroupOpsMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Debug", button, DebugMenu, NIL, 0, -1, FALSE, NIL, boldFont] ]]; ggData.height _ ggData.height + entryHeight; }; BuildStyleMenuLine: PROC [ggData: GGData] = { <> nextX: INTEGER _ AtomButtons.BuildUnQueuedButtonLine[ggData.outer, 0, ggData.height, ggData, LIST[ ["Stroke", button, LineWidthMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Color", button, LineColorMenu, NIL, 0, -1, FALSE, NIL, boldFont], <<["Arrows", button, ArrowsMenu, NIL, 0, -1, FALSE, NIL, boldFont],>> ["Fill", button, AreaColorMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Edit", button, EditMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Select", button, AreaSelectMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["HotSpots", button, HotSpotsMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Units", button, UnitsMenu, NIL, 0, -1, FALSE, NIL, boldFont] ]]; [ggData.refresh.showColors, nextX] _ AtomButtons.BuildTwoStateButton[viewer: ggData.outer, x: nextX + entryHSpace, y: ggData.height, clientData: ggData, handleProc: GGUserInput.EventNotify, name: "ShowColors", action: LIST[$ToggleShowColors], init: off]; ggData.refresh.screenStyle _ AtomButtons.BuildEnumTypeSelection[viewer: ggData.outer, x: nextX + entryHSpace, y: ggData.height, maxWidth: 144, clientData: ggData, handleProc: GGUserInput.EventNotify, title: "ScreenStyle:", default: "PrintFonts", borderOnButtons: TRUE, style: flipThru, allInOneRow: TRUE, buttonNames: LIST["PrintFonts", "ScreenFonts", "WYSIWYG"], atom: $ScreenChoiceChange]; ggData.height _ ggData.height + entryHeight + entryVSpace; }; GravityExtentData: TYPE = REF GravityExtentDataObj; GravityExtentDataObj: TYPE = GGInterfaceTypes.GravityExtentDataObj; GravityExtentRepaint: PROC [dc: Imager.Context, clientData: REF ANY, buttonData: REF ANY, button: Viewer] = { caretPoint: Point; ged: GravityExtentData _ NARROW[buttonData]; extent: REAL _ ged.extent; Imager.TranslateT[dc, [button.ww, button.wh/2.0]]; caretPoint _ [-extent, 0.0]; GGShapes.DrawCaret[dc, caretPoint]; }; BuildGravityLine: PROC [ggData: GGData] = { nextX: NAT _ 0; ggData.hitTest.gravityTypeMenu _ AtomButtons.BuildEnumTypeSelection[viewer: ggData.outer, x: 0, y: ggData.height, maxWidth: 144, clientData: ggData, handleProc: GGUserInput.EventNotify, title: "GravType:", default: "PreferPoints", borderOnButtons: TRUE, style: flipThru, allInOneRow: TRUE, buttonNames: LIST["StrictDistance", "PreferPoints"], atom: $GravityChoiceChange]; ggData.hitTest.gravityType _ innerCircle; nextX _ ggData.hitTest.gravityTypeMenu.nextx; nextX _ AtomButtons.BuildButtonLine[ ggData.outer, nextX + entryHSpace, ggData.height, ggData, GGUserInput.EventNotify, LIST[ [label["GravExtent:"]] ]]; nextX _ GraphicsButton.BuildGraphicsButton[ container: ggData.outer, x: nextX + entryHSpace, y: ggData.height, w: 60, -- changed from 72 to make more room in line h: entryHeight, clientData: ggData, choices: LIST[ [LIST[$GravityExtentChange, $ValueUp]], [LIST[$GravityExtentChange, $InitialValue]], [LIST[$GravityExtentChange, $ValueDown]]], handleProc: GGUserInput.EventNotify, repaintProc: GravityExtentRepaint, buttonData: NEW[GravityExtentDataObj _ [extent: GGEditTool.GetDefaultGravityExtent[]]], updateProc: GravityExtentInGGData ]; [ggData.hitTest.gravButton, nextX] _ AtomButtons.BuildTwoStateButton[viewer: ggData.outer, x: nextX + 2*entryHSpace, y: ggData.height, clientData: ggData, handleProc: GGUserInput.EventNotify, name: "Gravity", action: LIST[$ToggleGravity], init: on]; [ggData.refresh.alignments, nextX] _ AtomButtons.BuildTwoStateButton[viewer: ggData.outer, x: nextX + entryHSpace, y: ggData.height, clientData: ggData, handleProc: GGUserInput.EventNotify, name: "Alignments", action: LIST[$ToggleAlignments], init: on]; [ggData.hitTest.midpointButton, nextX] _ AtomButtons.BuildTwoStateButton[viewer: ggData.outer, x: nextX + entryHSpace, y: ggData.height, clientData: ggData, handleProc: GGUserInput.EventNotify, name: "Midpoints", action: LIST[$ToggleMidpoints], init: off]; [ggData.hitTest.heuristicsButton, nextX] _ AtomButtons.BuildTwoStateButton[viewer: ggData.outer, x: nextX + entryHSpace, y: ggData.height, clientData: ggData, handleProc: GGUserInput.EventNotify, name: "Heuristics", action: LIST[$ToggleHeuristics], init: IF GGEditTool.GetDefaultHeuristics[] THEN on ELSE off]; ggData.height _ ggData.height + entryHeight; }; BuildSlopeLine: PROC [ggData: GGData] = { buttonHandle: AtomButtons.ScalarButtonHandle; nextX: NAT _ AtomButtons.BuildButtonLine[ggData.outer, 0, ggData.height, ggData, GGUserInput.EventNotify,LIST[ [button["Slope:", LIST[LIST[$SlopePrompt]] ]], [button["Get!", LIST[LIST[$GetSlope]] ]], [button["Add!", LIST[LIST[$AddSlope]] ]], [button["Delete!", LIST[LIST[$DeleteSlope]] ]] ]]; buttonHandle _ AtomButtons.CreateScalarButtonViewer[ggData.outer, nextX, ggData.height]; ggData.hitTest.slopeHeader _ buttonHandle; GGEvent.StandardSlopes[ggData, LIST[$StandardSlopes]]; ggData.height _ ggData.height + entryHeight; }; BuildAngleLine: PROC [ggData: GGData] = { buttonHandle: AtomButtons.ScalarButtonHandle; nextX: NAT _ AtomButtons.BuildButtonLine[ggData.outer, 0, ggData.height, ggData, GGUserInput.EventNotify,LIST[ [button["Angle:", LIST[LIST[$AnglePrompt]] ]], [button["Get!", LIST[LIST[$GetAngle]] ]], [button["Add!", LIST[LIST[$AddAngle]] ]], [button["Delete!", LIST[LIST[$DeleteAngle]] ]] ]]; buttonHandle _ AtomButtons.CreateScalarButtonViewer[ggData.outer, nextX, ggData.height]; ggData.hitTest.angleHeader _ buttonHandle; GGEvent.StandardAngles[ggData, LIST[$StandardAngles]]; ggData.height _ ggData.height + entryHeight; }; BuildRadiusLine: PROC [ggData: GGData] = { buttonHandle: AtomButtons.ScalarButtonHandle; nextX: NAT _ AtomButtons.BuildButtonLine[ggData.outer, 0, ggData.height, ggData, GGUserInput.EventNotify, LIST[ [button["Radius:", LIST[LIST[$RadiusPrompt]] ]], [button["Get!", LIST[LIST[$GetRadius]] ]], [button["Add!", LIST[LIST[$AddRadius]] ]], [button["Delete!", LIST[LIST[$DeleteRadius]] ]] ]]; buttonHandle _ AtomButtons.CreateScalarButtonViewer[ggData.outer, nextX, ggData.height]; ggData.hitTest.radiusHeader _ buttonHandle; GGEvent.StandardRadii[ggData, LIST[$StandardRadii]]; ggData.hitTest.radiusCircleCache _ GGCircleCache.Create[]; ggData.height _ ggData.height + entryHeight; }; BuildDistanceLine: PROC [ggData: GGData] = { buttonHandle: AtomButtons.ScalarButtonHandle; nextX: NAT _ AtomButtons.BuildButtonLine[ggData.outer, 0, ggData.height, ggData, GGUserInput.EventNotify, LIST[ [button["LineDistance:", LIST[LIST[$DistancePrompt]] ]], [button["Get!", LIST[LIST[$GetDistance]] ]], [button["Add!", LIST[LIST[$AddDistance]] ]], [button["Delete!", LIST[LIST[$DeleteDistance]] ]] ]]; buttonHandle _ AtomButtons.CreateScalarButtonViewer[ggData.outer, nextX, ggData.height]; ggData.hitTest.distanceHeader _ buttonHandle; GGEvent.StandardDistances[ggData, LIST[$StandardDistances]]; ggData.height _ ggData.height + entryHeight; }; BuildMeasureLine: PROC [ggData: GGData] = { nextX: NAT _ AtomButtons.BuildButtonLine[ggData.outer, 0, ggData.height, ggData, GGUserInput.EventNotify, LIST[ [button["SlopeValue:", LIST[LIST[$MeasureSlopeHit]] ]], [text["0.0", SlopeViewInGGData, smallNumberSize]], [button["AngleValue:", LIST[LIST[$MeasureAngleHit]] ]], [text["0.0", AngleViewInGGData, smallNumberSize]], [button["RadiusValue:", LIST[LIST[$MeasureRadiusHit]] ]], [text["0.0", DistanceViewInGGData, smallNumberSize]], [button["LineDistanceValue:", LIST[LIST[$MeasureLineDistHit]] ]], [text["0.0", LineDistViewInGGData, smallNumberSize]] ]]; ggData.height _ ggData.height + entryHeight; }; BuildFeedbackLine: PROC [ggData: GGData] = { nextX: NAT _ AtomButtons.BuildButtonLine[ggData.outer, 0, ggData.height, ggData, GGUserInput.EventNotify, LIST[ [label["Feedback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Line", FeedbackLineInGGData, fullColumn]] ]]; ggData.height _ ggData.height + entryHeight; }; Dummy: Menus.ClickProc = { ggData: GGData _ NARROW[clientData]; Feedback.AppendHerald[ggData.feedback, "Menu Level: This feature not yet implemented", oneLiner]; Feedback.Blink[ggData.feedback]; }; <> InterpressMenu: Menus.ClickProc = { ggData: GGData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["MergeIPEditable", LIST [$MergeIPEditable]], ["MergeIPSlice", LIST [$MergeIPSlice]], ["ToIP", LIST [$ToIP]], ["ToIPScreen", LIST [$ToIPScreen]], ["IncludeIPByReference", LIST[$IncludeIPByReference]], ["IncludeIPByValue", LIST[$IncludeIPByValue]], ["ShowIPIncludeMode", LIST[$ShowIPIncludeMode]] ]; QueuePopUpMenuAction["Interpress", menu, ggData, mouseButton#blue]; }; ScriptMenu: Menus.ClickProc = { <> ggData: GGData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry _ LIST [ ["OpenScript", LIST [$ScriptAction, $Open]], ["AppendToScript", LIST [$ScriptAction, $Append]], ["CloseScript", LIST [$ScriptAction, $Close]], ["PlaybackScript", LIST [$ScriptAction, $Playback]], ["FastPlayScript", LIST [$ScriptAction, $FastPlay]] ]; <> choices: LIST OF Rope.ROPE _ ExtractChoiceList[menu]; index: NAT _ PopUpSelection.Request[header: "Script", choice: choices]; SELECT index FROM =0 => RETURN; =1 => OpenScript[parent, clientData, mouseButton, shift, control]; =2 => AppendToScript[parent, clientData, mouseButton, shift, control]; =3 => CloseScript[parent, clientData, mouseButton, shift, control]; =4 => PlaybackScript[parent, clientData, mouseButton, shift, control]; =5 => FastPlayScript[parent, clientData, mouseButton, shift, control]; ENDCASE => ERROR; }; ConfirmClear: PROC [clientData: REF ANY] = { ggData: GGData _ NARROW[clientData]; Feedback.AppendHerald[ggData.feedback, "Confirm deletion of all objects", oneLiner]; }; ConfirmReset: PROC [clientData: REF ANY] = { ggData: GGData _ NARROW[clientData]; Feedback.AppendHerald[ggData.feedback, "Confirm reset to original file", oneLiner]; }; ConfirmGet: PROC [clientData: REF ANY] = { ggData: GGData _ NARROW[clientData]; filename: Rope.ROPE _ ViewerTools.GetSelectionContents[]; Feedback.AppendHerald[ggData.feedback, Rope.Cat["Confirm getting of file ", filename, " to the current scene."], oneLiner]; }; ConfirmMerge: PROC [clientData: REF ANY] = { ggData: GGData _ NARROW[clientData]; filename: Rope.ROPE _ ViewerTools.GetSelectionContents[]; Feedback.AppendHerald[ggData.feedback, Rope.Cat["Confirm addition of file ", filename, " to the current scene."], oneLiner]; }; ConfirmStore: PROC [clientData: REF ANY] = { ggData: GGData _ NARROW[clientData]; fullName, msg: Rope.ROPE; success, exists: BOOL; [fullName, success, ----] _ GGUtility.GetGargoyleFileName[ViewerTools.GetSelectionContents[], ggData.currentWDir, ggData.feedback, FALSE]; IF NOT success THEN RETURN; exists _ FileExists[fullName]; IF exists THEN msg _ IO.PutFR["Confirm Store of %g [Old File]", [rope[fullName]]] ELSE msg _ IO.PutFR["Confirm Store to %g [New File]", [rope[fullName]]]; Feedback.AppendHerald[ggData.feedback, msg, oneLiner]; }; FileExists: PROC [fileName: Rope.ROPE] RETURNS [answer: BOOL] = { answer _ TRUE; [----, ----, ----, ----] _ FS.FileInfo[fileName ! FS.Error => {IF error.code = $unknownFile THEN {answer _ FALSE; CONTINUE} ELSE ERROR}]; }; <<>> <> <<>> HierarchyMenu: Menus.ClickProc = { ggData: GGData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["Delete (DEL)", LIST [$Delete]], ["UnDelete", LIST [$Undelete]], ["AddHoles (^h)", LIST [$AddHoles]], ["UnionCombine", LIST [$UnionCombine]], <<["Extend Select (^v)", LIST [$ExtendSelect]],>> <<["Undo (SHIFT-ESC)", LIST [$Undo]],>> <<["Redo (ESC)", LIST [$Redo]],>> <<["Cluster", LIST [$Cluster]],>> <<["Un Cluster", LIST [$UnCluster]],>> ["DescribeSelected", LIST [$DescribeCurve, $Selected]] ]; QueuePopUpMenuAction["Hierarchy", menu, ggData, mouseButton#blue]; }; TransformMenu: Menus.ClickProc = { ggData: GGData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["Rotate", LIST [$Rotate]], ["Scale", LIST [$Scale]], ["ScaleX", LIST [$ScaleX]], ["ScaleY", LIST [$ScaleY]], ["TranslateX", LIST [$TranslateX]], ["TranslateY", LIST [$TranslateY]], ["SixPoint", LIST [$SixPointTransform]], ["FourPoint", LIST [$FourPointTransform]] ]; QueuePopUpMenuAction["Transform", menu, ggData, mouseButton#blue]; }; <> <> <> <> <<["Top", ],>> <<["Bottom", LIST [$Bottom]],>> <<["UpOne", LIST [$UpOne]],>> <<["DownOne", LIST [$DownOne]]>> <<];>> <> <<};>> <<>> ShapesMenu: Menus.ClickProc = { ggData: GGData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["Triangle", LIST [$PolygonInCircle, NEW[INT _ 3] ]], ["Square", LIST [$PolygonInCircle, NEW[INT _ 4] ]], ["Pentagon", LIST [$PolygonInCircle, NEW[INT _ 5] ]], ["Hexagon", LIST [$PolygonInCircle, NEW[INT _ 6] ]], ["Octagon", LIST [$PolygonInCircle, NEW[INT _ 8] ]], ["FromSelectedCount", LIST [$PolygonInCircle, NEW[INT _ -1] ]], ["Knotched Line", LIST [$KnotchedLine, NEW[REAL _ 4.0], NEW[INT _ 8]] ], ["Box", LIST [$NewBox, NEW[REAL _ 1.0] ]], ["Circle", LIST [$NewCircle, NEW[REAL _ 1.0] ]], ["Arrow", LIST [$NewArrow, NEW[REAL _ 0.5], NEW[REAL _ 0.125] ]], <> ["8.5 by 11", LIST [$Frame, NEW[REAL _ 8.5*72.0], NEW[REAL _ 11.0*72.0] ]], ["11 by 14", LIST [$Frame, NEW[REAL _ 11.0*72.0], NEW[REAL _ 14.0*72.0] ]], ["38 by 50.66 (Versatec)", LIST [$Frame, NEW[REAL _ 38.0*72.0], NEW[REAL _ 50.666667*72.0] ]], ["640 x 480", LIST [$Frame, NEW[REAL _ 640.0], NEW[REAL _ 480.0] ]], ["1024 x 768", LIST [$Frame, NEW[REAL _ 1024.0], NEW[REAL _ 768.0] ]] ]; QueuePopUpMenuAction["Shapes", menu, ggData, mouseButton#blue]; }; DebugMenu: Menus.ClickProc = { ggData: GGData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["Draw Tight Boxes", LIST [$DrawTightBoxes]], ["Draw Bounding Boxes", LIST [$DrawBoundBoxes]], ["Draw Outline Boxes", LIST [$DrawOutlineBoxes]], ["Draw Selection Box", LIST [$DrawSelectionBox]], ["Draw Background Box", LIST [$DrawBackgroundBox]], ["Draw Overlay Box", LIST [$DrawOverlayBox]], ["Draw Rubber Box", LIST [$DrawRubberBox]], ["Draw Drag Box", LIST [$DrawDragBox]], ["Test Gravity", LIST [$TestGravity]], ["ToIPTestGravity", LIST [$ToIPTestGravity]], ["Print Statistics", LIST [$Statistics]], ["Print Selected Statistic", LIST [$PrintSelectedStatistic]], ["Reset Statistics", LIST [$ResetStatistics]], ["SlackLog", LIST [$SlackLog]], ["Describe Caret Object", LIST [$DescribeCaretObject]], ["FSM Info", LIST [$FSMInfo]], ["Print All Input", LIST [$PrintAllInput]], ["Reset All Input", LIST [$ResetAllInput]], ["CauseAnError", LIST [$CauseAnError]] ]; QueuePopUpMenuAction["Debug", menu, ggData, mouseButton#blue]; }; HelpMenu: Menus.ClickProc = { ggData: GGData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["Mouse Actions", LIST[$Help, $MouseActions]], ["Fonts", LIST[$Help, $Fonts]] ]; QueuePopUpMenuAction["Help", menu, ggData, mouseButton#blue]; }; RefreshButton: Menus.ClickProc = { ggData: GGData _ NARROW[clientData]; GGWindow.RestoreScreenAndInvariants[paintAction: $PaintEntireScene, ggData: ggData, remake: triggerBag, backgndOK: FALSE, edited: FALSE, okToClearFeedback: TRUE] }; ReviveButton: Menus.ClickProc = { ggData: GGData _ NARROW[clientData]; GGMouseEvent.ResetMouseMachinery[ggData]; CodeTimer.ResetTable[CodeTimer.GetTable[$Gargoyle]]; SlackProcess.Restart[ggData.slackHandle]; ggData.refresh.suppressRefresh _ FALSE; ggData.aborted _ ALL[FALSE]; IF mouseButton#blue THEN GGWindow.RestoreScreenAndInvariants[paintAction: $PaintEntireScene, ggData: ggData, remake: triggerBag, backgndOK: FALSE, edited: FALSE, okToClearFeedback: TRUE] }; <<>> <> <<>> GravityExtentInGGData: GraphicsButton.UpdateGraphicsButtonProc = { ggData: GGData _ NARROW[clientData]; ggData.hitTest.gravityExtentButton _ stateInfo; }; <