<> <> <> <> <> <> <> <> <> DIRECTORY FS, GGBasicTypes, AtomButtons, GGCircleCache, GGContainer, GGEditTool, SlackProcess, GGError, GGEvent, GGGraphicsButton, GGInterfaceTypes, GGMenus, GGModelTypes, GGMouseEvent, GGSegmentTypes, GGStatistics, GGSessionLog, GGUserInput, GGWindow, IO, Menus, PopUpSelection, Rope, Rules, TiogaMenuOps, VFonts, ViewerClasses, ViewerOps, ViewerTools; GGMenusImpl: CEDAR PROGRAM IMPORTS FS, AtomButtons, GGCircleCache, GGEvent, SlackProcess, GGContainer, GGEditTool, GGError, GGGraphicsButton, GGMouseEvent, GGStatistics, GGSessionLog, GGUserInput, GGWindow, IO, Rope, PopUpSelection, Rules, TiogaMenuOps, VFonts, ViewerOps, ViewerTools EXPORTS GGMenus = BEGIN Caret: TYPE = REF CaretObj; CaretObj: TYPE = GGInterfaceTypes.CaretObj; 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; GargoyleData: 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; <> <> <> 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, gargoyleData: GargoyleData, 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.MenuNotify[gargoyleData, entries.first.input]; EXIT; }; index _ index - 1; REPEAT FINISHED => ERROR; ENDLOOP; IF onceOnly THEN RETURN; ENDLOOP; }; BuildControlPanel: PUBLIC PROC [gargoyleData: GargoyleData, windowMenu: Menus.Menu] = { BuildFileMenuLine[gargoyleData, windowMenu]; BuildMasterMenuLine[gargoyleData]; BuildStyleMenuLine[gargoyleData]; BuildGravityLine[gargoyleData]; BuildSlopeLine[gargoyleData]; BuildAngleLine[gargoyleData]; BuildRadiusLine[gargoyleData]; BuildDistanceLine[gargoyleData]; BuildMeasureLine[gargoyleData]; BuildFeedbackLine[gargoyleData]; AddARule[gargoyleData]; }; AddARule: PROC [gargoyleData: GargoyleData] = { rule: Rules.Rule; rule _ Rules.Create[[ parent: gargoyleData.outer, wy: gargoyleData.height, ww: gargoyleData.outer.cw, wh: 2 ]]; GGContainer.ChildXBound[gargoyleData.outer, rule]; gargoyleData.height _ gargoyleData.height + rule.wh + entryVSpace; }; -- end of AddARule fudgeX: INTEGER _ 2; <<>> <> <<>> BuildFileMenuLine: PROC [gargoyleData: GargoyleData, windowMenu: Menus.Menu] = { <> nextX: INTEGER _ AtomButtons.BuildButtonLine [gargoyleData.outer, 0, gargoyleData.height, gargoyleData, GGUserInput.MenuNotify, LIST[ ["Clear", button, LIST[$Clear], NIL, 0, FALSE, ConfirmClear], ["Restore", button, LIST[$Reset], NIL, 0, FALSE, ConfirmReset], ["Get", button, LIST[$Get], NIL, 0, FALSE, ConfirmGet], -- guarded in spite of Tioga viewers menus ["Merge", button, LIST[$Merge], NIL, 0, FALSE, ConfirmMerge], ["Store", button, LIST[$Store], NIL, 0, FALSE, ConfirmStore], ["Save", button, LIST[$Save]], <<["Split", button, LIST[$Split]],>> ["Stuff", button, LIST[$Stuff], NIL, 0, FALSE, NIL, NIL, LIST[$StuffScreen]] -- KAP. 8/11/86 ]]; nextX _ nextX+fudgeX; nextX _ AtomButtons.BuildUnQueuedButtonLine [gargoyleData.outer, nextX, gargoyleData.height, gargoyleData, LIST[ ["Interpress", button, InterpressMenu, NIL, 0, FALSE, NIL, boldFont], ["Script", button, ScriptMenu, NIL, 0, FALSE, NIL, boldFont], ]]; gargoyleData.height _ gargoyleData.height + entryHeight; }; BuildMasterMenuLine: PROC [gargoyleData: GargoyleData] = { <> nextX: INTEGER _ AtomButtons.BuildUnQueuedButtonLine [gargoyleData.outer, 0, gargoyleData.height, gargoyleData, LIST[ ["Hierarchy", button, HierarchyMenu, NIL, 0, FALSE, NIL, boldFont], ["Transform", button, TransformMenu, NIL, 0, FALSE, NIL, boldFont], ["Overlap", button, OverlapMenu, NIL, 0, FALSE, NIL, boldFont], ["Curves", button, CurveTypeMenu, NIL, 0, FALSE, NIL, boldFont], ["Shapes", button, ShapesMenu, NIL, 0, FALSE, NIL, boldFont], ["Text", button, TextOpsMenu, NIL, 0, FALSE, NIL, boldFont], ["Fonts", button, FontOpsMenu, NIL, 0, FALSE, NIL, boldFont], ["Groups", button, GroupOpsMenu, NIL, 0, FALSE, NIL, boldFont], ["Debug", button, DebugMenu, NIL, 0, FALSE, NIL, boldFont], ["Refresh!", button, RefreshButton], <<["Abort!", button, AbortButton],>> ["Revive!", button, ReviveButton], ["Help!", button, HelpMenu] ]]; gargoyleData.height _ gargoyleData.height + entryHeight; }; BuildStyleMenuLine: PROC [gargoyleData: GargoyleData] = { <> nextX: INTEGER _ AtomButtons.BuildUnQueuedButtonLine[gargoyleData.outer, 0, gargoyleData.height, gargoyleData, LIST[ ["Width", button, LineWidthMenu, NIL, 0, FALSE, NIL, boldFont], ["Color", button, LineColorMenu, NIL, 0, FALSE, NIL, boldFont], <<["Arrows", button, ArrowsMenu, NIL, 0, FALSE, NIL, boldFont],>> ["Fill", button, AreaColorMenu, NIL, 0, FALSE, NIL, boldFont], ["Select", button, AreaSelectMenu, NIL, 0, FALSE, NIL, boldFont], ["Edit", button, EditMenu, NIL, 0, FALSE, NIL, boldFont], ["HotSpots", button, HotSpotsMenu, NIL, 0, FALSE, NIL, boldFont], ["Units", button, UnitsMenu, NIL, 0, FALSE, NIL, boldFont] ]]; [gargoyleData.refresh.showColors, nextX] _ AtomButtons.BuildTwoStateButton[viewer: gargoyleData.outer, x: nextX + entryHSpace, y: gargoyleData.height, clientData: gargoyleData, handleProc: GGUserInput.MenuNotify, name: "ShowColors", action: LIST[$ToggleShowColors], init: off]; gargoyleData.refresh.screenStyle _ AtomButtons.BuildEnumTypeSelection[viewer: gargoyleData.outer, x: nextX + entryHSpace, y: gargoyleData.height, maxWidth: 144, clientData: gargoyleData, handleProc: GGUserInput.MenuNotify, title: "ScreenStyle:", default: "PrintFonts", borderOnButtons: TRUE, style: flipThru, allInOneRow: TRUE, buttonNames: LIST["PrintFonts", "ScreenFonts", "WYSIWYG"], atom: $ScreenChoiceChange]; gargoyleData.height _ gargoyleData.height + entryHeight + entryVSpace; }; BuildGravityLine: PROC [gargoyleData: GargoyleData] = { nextX: NAT _ 0; gargoyleData.hitTest.gravityTypeMenu _ AtomButtons.BuildEnumTypeSelection[viewer: gargoyleData.outer, x: 0, y: gargoyleData.height, maxWidth: 144, clientData: gargoyleData, handleProc: GGUserInput.MenuNotify, title: "GravType:", default: "PreferPoints", borderOnButtons: TRUE, style: flipThru, allInOneRow: TRUE, buttonNames: LIST["StrictDistance", "PreferPoints"], atom: $GravityChoiceChange]; gargoyleData.hitTest.gravityType _ innerCircle; nextX _ gargoyleData.hitTest.gravityTypeMenu.nextx; nextX _ AtomButtons.BuildButtonLine[ gargoyleData.outer, nextX + entryHSpace, gargoyleData.height, gargoyleData, GGUserInput.MenuNotify, LIST[ ["GravExtent:", label]]]; nextX _ GGGraphicsButton.BuildGraphicsButton[ viewer: gargoyleData.outer, x: nextX + entryHSpace, y: gargoyleData.height, w: 60, -- changed from 72 to make more room in line h: entryHeight, name: "GravExtent", atom: $GravityExtentChange, initValue: GGEditTool.GetDefaultGravityExtent[], clientData: gargoyleData]; [gargoyleData.hitTest.gravButton, nextX] _ AtomButtons.BuildTwoStateButton[viewer: gargoyleData.outer, x: nextX + 2*entryHSpace, y: gargoyleData.height, clientData: gargoyleData, handleProc: GGUserInput.MenuNotify, name: "Gravity", action: LIST[$ToggleGravity], init: on]; [gargoyleData.refresh.alignments, nextX] _ AtomButtons.BuildTwoStateButton[viewer: gargoyleData.outer, x: nextX + entryHSpace, y: gargoyleData.height, clientData: gargoyleData, handleProc: GGUserInput.MenuNotify, name: "Alignments", action: LIST[$ToggleAlignments], init: on]; [gargoyleData.hitTest.midpointButton, nextX] _ AtomButtons.BuildTwoStateButton[viewer: gargoyleData.outer, x: nextX + entryHSpace, y: gargoyleData.height, clientData: gargoyleData, handleProc: GGUserInput.MenuNotify, name: "Midpoints", action: LIST[$ToggleMidpoints], init: off]; [gargoyleData.hitTest.heuristicsButton, nextX] _ AtomButtons.BuildTwoStateButton[viewer: gargoyleData.outer, x: nextX + entryHSpace, y: gargoyleData.height, clientData: gargoyleData, handleProc: GGUserInput.MenuNotify, name: "Heuristics", action: LIST[$ToggleHeuristics], init: IF GGEditTool.GetDefaultHeuristics[] THEN on ELSE off]; gargoyleData.height _ gargoyleData.height + entryHeight; }; BuildSlopeLine: PROC [gargoyleData: GargoyleData] = { buttonHandle: AtomButtons.ScalarButtonHandle; nextX: NAT _ AtomButtons.BuildButtonLine[gargoyleData.outer, 0, gargoyleData.height, gargoyleData, GGUserInput.MenuNotify,LIST[ ["Slope:", button, LIST[$SlopePrompt]], ["Get!", button, LIST[$GetSlope]], ["Add!", button, LIST[$AddSlope]], ["Delete!", button, LIST[$DeleteSlope]] ]]; buttonHandle _ AtomButtons.CreateScalarButtonViewer[gargoyleData.outer, nextX, gargoyleData.height]; gargoyleData.hitTest.slopeHeader _ buttonHandle; GGEvent.StandardSlopes[LIST[$StandardSlopes], gargoyleData]; gargoyleData.height _ gargoyleData.height + entryHeight; }; BuildAngleLine: PROC [gargoyleData: GargoyleData] = { buttonHandle: AtomButtons.ScalarButtonHandle; nextX: NAT _ AtomButtons.BuildButtonLine[gargoyleData.outer, 0, gargoyleData.height, gargoyleData, GGUserInput.MenuNotify,LIST[ ["Angle:", button, LIST[$AnglePrompt]], ["Get!", button, LIST[$GetAngle]], ["Add!", button, LIST[$AddAngle]], ["Delete!", button, LIST[$DeleteAngle]] ]]; buttonHandle _ AtomButtons.CreateScalarButtonViewer[gargoyleData.outer, nextX, gargoyleData.height]; gargoyleData.hitTest.angleHeader _ buttonHandle; GGEvent.StandardAngles[LIST[$StandardAngles], gargoyleData]; gargoyleData.height _ gargoyleData.height + entryHeight; }; BuildRadiusLine: PROC [gargoyleData: GargoyleData] = { buttonHandle: AtomButtons.ScalarButtonHandle; nextX: NAT _ AtomButtons.BuildButtonLine[gargoyleData.outer, 0, gargoyleData.height, gargoyleData, GGUserInput.MenuNotify, LIST[ ["Radius:", button, LIST[$RadiusPrompt]], ["Get!", button, LIST[$GetRadius]], ["Add!", button, LIST[$AddRadius]], ["Delete!", button, LIST[$DeleteRadius]] ]]; buttonHandle _ AtomButtons.CreateScalarButtonViewer[gargoyleData.outer, nextX, gargoyleData.height]; gargoyleData.hitTest.radiusHeader _ buttonHandle; GGEvent.StandardRadii[LIST[$StandardRadii], gargoyleData]; gargoyleData.hitTest.radiusCircleCache _ GGCircleCache.Create[]; gargoyleData.height _ gargoyleData.height + entryHeight; }; BuildDistanceLine: PROC [gargoyleData: GargoyleData] = { buttonHandle: AtomButtons.ScalarButtonHandle; nextX: NAT _ AtomButtons.BuildButtonLine[gargoyleData.outer, 0, gargoyleData.height, gargoyleData, GGUserInput.MenuNotify, LIST[ ["LineDistance:", button, LIST[$DistancePrompt]], ["Get!", button, LIST[$GetDistance]], ["Add!", button, LIST[$AddDistance]], ["Delete!", button, LIST[$DeleteDistance]] ]]; buttonHandle _ AtomButtons.CreateScalarButtonViewer[gargoyleData.outer, nextX, gargoyleData.height]; gargoyleData.hitTest.distanceHeader _ buttonHandle; GGEvent.StandardDistances[LIST[$StandardDistances], gargoyleData]; gargoyleData.height _ gargoyleData.height + entryHeight; }; BuildMeasureLine: PROC [gargoyleData: GargoyleData] = { nextX: NAT _ AtomButtons.BuildButtonLine[gargoyleData.outer, 0, gargoyleData.height, gargoyleData, GGUserInput.MenuNotify, LIST[ ["SlopeValue:", button, LIST[$MeasureSlopeHit]], ["0.0", text, NIL, SlopeViewInGGData, smallNumberSize], ["AngleValue:", button, LIST[$MeasureAngleHit]], ["0.0", text, NIL, AngleViewInGGData, smallNumberSize], ["RadiusValue:", button, LIST[$MeasureRadiusHit]], ["0.0", text, NIL, DistanceViewInGGData, smallNumberSize], ["LineDistanceValue:", button, LIST[$MeasureLineDistHit]], ["0.0", text, NIL, LineDistViewInGGData, smallNumberSize] ]]; gargoyleData.height _ gargoyleData.height + entryHeight; }; BuildFeedbackLine: PROC [gargoyleData: GargoyleData] = { nextX: NAT _ AtomButtons.BuildButtonLine[gargoyleData.outer, 0, gargoyleData.height, gargoyleData, GGUserInput.MenuNotify, LIST[ ["Feedback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Line", label, NIL, FeedbackLineInGGData, column3] ]]; gargoyleData.height _ gargoyleData.height + entryHeight; }; Dummy: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; GGError.AppendHerald[gargoyleData.feedback, "Menu Level: This feature not yet implemented", oneLiner]; GGError.Blink[gargoyleData.feedback]; }; <> InterpressMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ 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, gargoyleData, mouseButton#blue]; }; ScriptMenu: Menus.ClickProc = { <> gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry _ LIST [ ["OpenScript", LIST [$ScriptAction, $Open]], ["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 => ERROR; =0 => RETURN; =1 => OpenSessionLog[parent, clientData, mouseButton, shift, control]; =2 => CloseSessionLog[parent, clientData, mouseButton, shift, control]; =3 => PlaybackLog[parent, clientData, mouseButton, shift, control]; =4 => FastPlaybackLog[parent, clientData, mouseButton, shift, control]; ENDCASE => ERROR; }; ConfirmClear: PROC [clientData: REF ANY] = { gargoyleData: GargoyleData _ NARROW[clientData]; GGError.AppendHerald[gargoyleData.feedback, "Confirm deletion of all objects", oneLiner]; }; ConfirmReset: PROC [clientData: REF ANY] = { gargoyleData: GargoyleData _ NARROW[clientData]; GGError.AppendHerald[gargoyleData.feedback, "Confirm reset to original file", oneLiner]; }; ConfirmGet: PROC [clientData: REF ANY] = { gargoyleData: GargoyleData _ NARROW[clientData]; filename: Rope.ROPE _ ViewerTools.GetSelectionContents[]; GGError.AppendHerald[gargoyleData.feedback, Rope.Cat["Confirm getting of file ", filename, " to the current scene."], oneLiner]; }; ConfirmMerge: PROC [clientData: REF ANY] = { gargoyleData: GargoyleData _ NARROW[clientData]; filename: Rope.ROPE _ ViewerTools.GetSelectionContents[]; GGError.AppendHerald[gargoyleData.feedback, Rope.Cat["Confirm addition of file ", filename, " to the current scene."], oneLiner]; }; ConfirmStore: PROC [clientData: REF ANY] = { gargoyleData: GargoyleData _ NARROW[clientData]; fullName, msg: Rope.ROPE; success, exists: BOOL; [fullName, success] _ GetGargoyleFileName[gargoyleData]; 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]]]; GGError.AppendHerald[gargoyleData.feedback, msg, oneLiner]; }; GetGargoyleFileName: PROC [gargoyleData: GargoyleData] RETURNS [fullName: Rope.ROPE _ NIL, success: BOOL _ TRUE] = { cp: FS.ComponentPositions; fileName: Rope.ROPE _ ViewerTools.GetSelectionContents[]; IF Rope.Length[fileName]=0 OR Rope.Equal[fileName, ""] THEN RETURN[NIL, FALSE]; [fullName, cp, ] _ FS.ExpandName[fileName, gargoyleData.currentWDir ! FS.Error => { GGError.Append[gargoyleData.feedback, " FS Error during name expansion", oneLiner]; GGError.Blink[gargoyleData.feedback]; success _ FALSE; CONTINUE; } ]; IF success AND cp.ext.length=0 THEN fullName _ Rope.Concat[fullName, ".gargoyle"]; -- add gargoyle extension }; 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 = { gargoyleData: GargoyleData _ 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, gargoyleData, mouseButton#blue]; }; TransformMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ 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, gargoyleData, mouseButton#blue]; }; OverlapMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["Top", LIST [$Top]], ["Bottom", LIST [$Bottom]], ["UpOne", LIST [$UpOne]], ["DownOne", LIST [$DownOne]] ]; QueuePopUpMenuAction["Overlap", menu, gargoyleData, mouseButton#blue]; }; ShapesMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ 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, gargoyleData, mouseButton#blue]; }; DebugMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["Typescript", LIST [$Typescript]], ["Draw Tight Boxes", LIST [$DrawTightBoxes]], ["Draw Bounding Boxes", LIST [$DrawBoundBoxes]], ["Draw Outline Boxes", LIST [$DrawOutlineBoxes]], ["Draw Selection Box", LIST [$DrawSelectionBox]], ["Draw Moving Box", LIST [$DrawMovingBox]], ["Test Gravity", LIST [$TestGravity]], ["ToIPTestGravity", LIST [$ToIPTestGravity]], ["Performance Stats", LIST [$Statistics]], ["Reset Stats", 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, gargoyleData, mouseButton#blue]; }; HelpMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; openHeight: INTEGER _ 140; help: ViewerClasses.Viewer; name: Rope.ROPE _ "GGHelp.Tioga"; IF (help _ ViewerOps.FindViewer[FS.ExpandName[name, gargoyleData.originalWDir].fullFName])#NIL THEN { -- viewer already exists IF help.column#right THEN ViewerOps.ChangeColumn[help, right]; } ELSE { help _ ViewerOps.CreateViewer[flavor: $Text, info: [iconic: TRUE, column: right, openHeight: openHeight], paint: FALSE]; TiogaMenuOps.Load[viewer: help, fileName: Rope.Concat[gargoyleData.originalWDir, "GGHelp.Tioga"]]; }; ViewerOps.SetOpenHeight[viewer: help, clientHeight: openHeight]; ViewerOps.OpenIcon[icon: help, bottom: FALSE, paint: FALSE]; -- must do Open before Top ViewerOps.TopViewer[viewer: help, paint: FALSE]; ViewerOps.ComputeColumn[right]; -- repaint right column }; RefreshButton: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; GGWindow.RestoreScreenAndInvariants[paintAction: $PaintEntireScene, gargoyleData: gargoyleData, remake: triggerBag, backgndOK: FALSE, edited: FALSE, okToClearFeedback: TRUE] }; AbortButton: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; gargoyleData.aborted _ ALL[TRUE]; }; ReviveButton: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; GGMouseEvent.ResetMouseMachinery[gargoyleData]; GGStatistics.ResetTable[GGStatistics.GlobalTable[]]; SlackProcess.Restart[gargoyleData.slackHandle]; gargoyleData.refresh.suppressRefresh _ FALSE; gargoyleData.aborted _ ALL[FALSE]; IF mouseButton#blue THEN GGWindow.RestoreScreenAndInvariants[paintAction: $PaintEntireScene, gargoyleData: gargoyleData, remake: triggerBag, backgndOK: FALSE, edited: FALSE, okToClearFeedback: TRUE] }; <<>> <