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]], ["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], ["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], ["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]], ["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] }; LineWidthMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["0 pt (LOOK 0)", LIST[$LineWidth, NEW[REAL _ 0.0]]], ["1 pt (LOOK 1)", LIST[$LineWidth, NEW[REAL _ 1.0]]], ["2 pt (LOOK 2)" , LIST[$LineWidth, NEW[REAL _ 2.0]]], ["3 pt (LOOK 3)", LIST[$LineWidth, NEW[REAL _ 3.0]]], ["4 pt (LOOK 4)", LIST[$LineWidth, NEW[REAL _ 4.0]]], ["FromSelection", LIST[$LineWidth]], ["ShowValue", LIST[$PrintLineWidth]], ["DashesFromSelection", LIST[$DashesFromSelection]], ["DashesOff", LIST[$DashesOff]], ["FindMatching", LIST[$SelectMatchingWidth]] ]; QueuePopUpMenuAction["Line Width", menu, gargoyleData, mouseButton#blue]; }; LineColorMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["none", LIST[$LineColorNone]], ["black" , LIST[$LineColorBlack]], ["white", LIST[$LineColorWhite]], ["gray", LIST[$LineColorGray]], ["FromColorTool", LIST[$LineColorFromColorTool]], ["FollowColorTool", LIST[$LineColorFollowColorTool]], ["ToColorTool", LIST[$LineColorToColorTool]], ["FromSelectedName", LIST[$LineColorFromSelectedName]], ["FromSelectedRGB", LIST[$LineColorFromSelectedRGB]], ["ShowValue", LIST[$PrintLineColor]], ["FindMatchingName", LIST[$SelectMatchingLineCNS]], ["FindMatchingRGB", LIST[$SelectMatchingLineRGB]] ]; QueuePopUpMenuAction["Line Color", menu, gargoyleData, mouseButton#blue]; }; AreaColorMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["none", LIST[$AreaColorNone]], ["black" , LIST[$AreaColorBlack]], ["white", LIST[$AreaColorWhite]], ["gray", LIST[$AreaColorGray]], ["FromColorTool", LIST[$AreaColorFromColorTool]], ["FollowColorTool", LIST[$AreaColorFollowColorTool]], ["ToColorTool", LIST[$AreaColorToColorTool]], ["FromSelectedName", LIST[$AreaColorFromSelectedName]], ["FromSelectedRGB", LIST[$AreaColorFromSelectedRGB]], ["ShowValue", LIST[$PrintAreaColor]], ["FindMatchingName", LIST[$SelectMatchingAreaCNS]], ["FindMatchingRGB", LIST[$SelectMatchingAreaRGB]] ]; QueuePopUpMenuAction["Fill", menu, gargoyleData, mouseButton#blue]; }; ArrowsMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["none", LIST[$Arrows, NEW[INT _ 0]]], ["left/down", LIST[$Arrows, NEW[INT _ 1]]], ["right/up" , LIST[$Arrows, NEW[INT _ 2]]], ["both", LIST[$Arrows, NEW[INT _ 3]]] ]; QueuePopUpMenuAction["Arrows", menu, gargoyleData, mouseButton#blue]; }; AreaSelectMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["New", LIST [$AreaSelectNew]], ["NewWithDelete", LIST [$AreaSelectNewAndDelete]], ["Extend", LIST [$AreaSelectExtend]], ["All (^d)", LIST [$AreaSelectAll]], ["Degenerate", LIST [$AreaSelectDegenerate]] ]; QueuePopUpMenuAction["Area Select", menu, gargoyleData, mouseButton#blue]; }; TextOpsMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["AddText", LIST [$AddText]], ["DropShadowOn 1 pt", LIST [$DropShadowOn, NEW[REAL _ -1.0], NEW[REAL _ -1.0]]], ["DropShadowOn 2 pt", LIST [$DropShadowOn, NEW[REAL _ -2.0], NEW[REAL _ -2.0]]], ["DropShadowOn 3 pt", LIST [$DropShadowOn, NEW[REAL _ -3.0], NEW[REAL _ -3.0]]], ["DropShadowOff", LIST [$DropShadowOff]], ["AmplifySpaceFromSelection", LIST [$AmplifySpaceFromSelection]], ["ShowAmplifySpace", LIST [$PrintAmplifySpace]] ]; QueuePopUpMenuAction["Text", menu, gargoyleData, mouseButton#blue]; }; FontOpsMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["SetPressFont", LIST [$SetPressFont]], ["SetScreenFont", LIST [$SetScreenFont]], ["SetPrintFont", LIST [$SetPrintFont]], ["ChangeFont", LIST [$ChangeFont]], ["MakeLookAlikes", LIST [$SetLookAlikes]], ["MakeDefault", LIST [$SetDefaultFontValues]], ["SetFontDetailed", LIST [$SetFontDetailed]], ["SetFontLiteral", LIST [$SetFontLiteral]], ["ShowValues", LIST [$ShowFontValues]], ["ShowValuesLiteral", LIST [$ShowFontValuesLiteral]], ["ShowDefaultValues", LIST [$ShowDefaultFontValues]], ["FindTextMatchingSelected", LIST[$FindTextMatchingSelected]], ["FindTextMatchingValues", LIST[$FindTextMatchingValues]], ["FindTextMatchingFamily", LIST[$FindTextMatchingFamily]] ]; QueuePopUpMenuAction["Fonts", menu, gargoyleData, mouseButton#blue]; }; GroupOpsMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["AddToGroup", LIST [$AddToGroup]], ["FindGroup", LIST [$SelectGroup]], ["RemoveFromGroup", LIST [$RemoveFromGroup]], ["PrintGroupsOfSelected", LIST [$PrintGroupsOfSelected]], ["PrintAllGroups", LIST [$PrintAllGroups]] ]; QueuePopUpMenuAction["Groups", menu, gargoyleData, mouseButton#blue]; }; CurveTypeMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["Line (LOOK l)", LIST [$SetStraight]], ["Arc (LOOK a)", LIST [$SetArc]], ["Conic (LOOK c)", LIST [$SetConic]], ["Bezier (LOOK z)", LIST [$SetBezier]], ["B-Spline (LOOK b)", LIST [$SetBSpline]], ["Natural Spline (LOOK n)", LIST [$SetNaturalSpline]], ["FindMatching", LIST [$SelectMatchingCurve]] ]; QueuePopUpMenuAction["Curves", menu, gargoyleData, mouseButton#blue]; }; EditMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["Close (^c)", LIST [$Close]], ["Weld (^w)", LIST [$Weld]], ["Add CP (^p)", LIST [$AddControlPoint]], ["Delete CP (^P)", LIST [$DeleteControlPoint]], ["Add Joint (^j)", LIST [$AddJoint]], ["ReplaceSegment", LIST [$SplitSegment]], ["Splice", LIST [$Splice]] ]; QueuePopUpMenuAction["Edit", menu, gargoyleData, mouseButton#blue]; }; OpenSessionLog: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; name: Rope.ROPE _ ViewerTools.GetSelectionContents[]; GGSessionLog.OpenSessionLog[name, gargoyleData]; [] _ SlackProcess.EnableSessionLogging[gargoyleData.slackHandle]; }; CloseSessionLog: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; [] _ SlackProcess.DisableSessionLogging[gargoyleData.slackHandle]; GGSessionLog.CloseSessionLog[gargoyleData]; }; PlaybackLog: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; name: Rope.ROPE _ ViewerTools.GetSelectionContents[]; GGSessionLog.PlaybackFromFile[name, gargoyleData]; }; FastPlaybackLog: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; name: Rope.ROPE _ ViewerTools.GetSelectionContents[]; GGUserInput.MenuNotify[gargoyleData, LIST[$DisableRefresh]]; GGSessionLog.PlaybackFromFile[name, gargoyleData]; GGUserInput.MenuNotify[gargoyleData, LIST[$EnableRefresh]]; GGUserInput.MenuNotify[gargoyleData, LIST[$Refresh, $DoNotClearFeedback]]; }; HotSpotsMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["Make Hot (^s)", LIST[$MakeHot]], ["Make All Hot (^ss)", LIST[$MakeAllHot]], ["Make Cold (^S)" , LIST[$MakeCold]], ["Make All Cold (^SS)" , LIST[$MakeAllCold]], ["Show Hot", LIST [$ShowHot]], ["Hide Hot", LIST [$HideHot]], ["Drop Anchor (^a)" , LIST[$DropAnchor]], ["Lift Anchor (^A)" , LIST[$LiftAnchor]], ["Standard Alignments" , LIST[$StandardAlignments]] ]; QueuePopUpMenuAction["Hot Spots", menu, gargoyleData, mouseButton#blue]; }; UnitsMenu: Menus.ClickProc = { gargoyleData: GargoyleData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["FromSegment", LIST[$RadiusUnitFromSegment]], ["FromRadiusValue", LIST[$RadiusUnitFromValue]], ["FromSelection", LIST[$RadiusUnitFromSelection]], ["Inches", LIST[$InchScaleUnit]], ["Centimeters", LIST[$CentimeterScaleUnit]], ["PrintCurrent", LIST[$PrintScaleUnit]] ]; QueuePopUpMenuAction["Units", menu, gargoyleData, mouseButton#blue]; }; Caret2InGGData: AtomButtons.UpdateProc = { gargoyleData: GargoyleData _ NARROW[clientData]; gargoyleData.measure.caret2_ button; }; SlopeViewInGGData: AtomButtons.UpdateProc = { gargoyleData: GargoyleData _ NARROW[clientData]; gargoyleData.measure.slopeView _ button; }; AngleViewInGGData: AtomButtons.UpdateProc = { gargoyleData: GargoyleData _ NARROW[clientData]; gargoyleData.measure.angleView _ button; }; DistanceViewInGGData: AtomButtons.UpdateProc = { gargoyleData: GargoyleData _ NARROW[clientData]; gargoyleData.measure.radiusView _ button; }; LineDistViewInGGData: AtomButtons.UpdateProc = { gargoyleData: GargoyleData _ NARROW[clientData]; gargoyleData.measure.lineDistView _ button; }; FeedbackLineInGGData: AtomButtons.UpdateProc = { gargoyleData: GargoyleData _ NARROW[clientData]; gargoyleData.feedback _ button; }; DistanceOfInterest: Menus.ClickProc = { }; Init: PROC = { boldFont _ VFonts.EstablishFont[family: "Helvetica", size: 10, bold: TRUE, italic: FALSE, defaultOnFailure: TRUE]; }; Init[]; END. HFile: GGMenusImpl.mesa Author: Eric Bier on June 5, 1985 11:34:50 pm PDT Copyright c 1985 by Xerox Corporation. All rights reserved. Last edited by Bier on January 28, 1987 3:03:16 pm PST Contents: Code to create a Gargoyle window. Calls GGContainer to make the container and adds menus at the top. The graphics part of the Gargoyle window is a new viewer of class $ActionArea. The paint proc for a $ActionArea is defined herein. Stone, July 15, 1985 11:39:29 am PDT Pier, February 3, 1987 12:48:47 pm PST Jcbeatty, March 10, 1986 8:17:31 pm PST Kurlander August 24, 1986 1:02:25 pm PDT nameSize: CARDINAL = 140; numberSize: CARDINAL = 80; bigNumberSize: CARDINAL = 160; Non-destructive (copies the menu names). Build All of the Control Panel Menus Files: Clear, Reset, Get, Store, Save, Split, Interpress ["Split", button, LIST[$Split]], Master: Hierarchy Curve Transform Overlap EditCurve View Debug Abort Revive ["Abort!", button, AbortButton], Style: LineEnds LineWidth LineColor Fill TextAlign Font ["Arrows", button, ArrowsMenu, NIL, 0, FALSE, NIL, boldFont], File Line: ClickProc: TYPE = PROC [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE]; QueuePopUpMenuAction["Script", menu, gargoyleData, mouseButton#blue]; Master Line: ["Extend Select (^v)", LIST [$ExtendSelect]], ["Undo (SHIFT-ESC)", LIST [$Undo]], ["Redo (ESC)", LIST [$Redo]], ["Cluster", LIST [$Cluster]], ["Un Cluster", LIST [$UnCluster]], The first parameter is shaft length. The second is barb length. Both in inches. Style Line: ["Drop Shadow From Selection", LIST [$DropShadowFromSelection]], Alignment Line: Distance Line: gargoyleData.hitTest.slopeText _ button; gargoyleData.hitTest.angleText _ button; gargoyleData.hitTest.radiusText _ button; gargoyleData.hitTest.distanceText _ button; Κμ˜Icodešœ™Kšœ1™1Kšœ<™Kšœ#œœœ ˜AKšœœœœ ˜9Kšœ#œœœ ˜AKšœœœœ ˜:K˜K˜—šœρœ ˜•K˜—Kšœžœ œœE˜žKšœF˜FK˜K˜—šžœœ!˜7Kšœœ˜Kšœ'˜'šœk˜kKšœ˜K˜#Kšœ,˜,Kšœœ œ˜:Kšœ œ#˜4Kšœ˜—Kšœ/˜/K˜Kšœ3˜3šœ$˜$šœdœ˜iKšœΟb œ ˜—K˜—šœ-˜-Kšœ˜Kšœ˜Kšœ˜KšœŸ,˜3Kšœ˜K˜Kšœ˜K˜0Kšœ˜K˜—Kšœ*˜*šœm˜mKšœ˜K˜#Kšœ œ˜Kšœœ˜Kšœ ˜ K˜—Kšœ*˜*šœk˜kKšœ˜K˜#Kšœ  œ˜Kšœœ˜ Kšœ ˜ K˜—Kšœ.˜.šœk˜kKšœ˜K˜#Kšœ  œ˜Kšœœ˜Kšœ ˜ K˜—Kšœ0˜0šœk˜kKšœ˜K˜#Kšœ  œ˜Kšœœ˜ Kšœœ#œœ˜=K˜—Kšœ8˜8K˜K˜—šžœœ!˜5Kšœ-˜-šœœpœ˜Kšœœ˜'Kšœœ ˜"Kšœœ ˜"Kšœœ˜'K˜—Kšœd˜dKšœ0˜0Kšœœ!˜K˜—šœ˜Kšœ<œ1œ˜xKšœb˜bK˜—Kšœ@˜@Kšœ'œ œŸ˜WKšœ)œ˜0Kšœ Ÿ˜7K˜K˜—š‘ œ˜"Kšœœ ˜0Kšœœ œœ˜­K˜K˜—š‘ œ˜ Kšœœ ˜0Kšœœœ˜!K˜K˜—š‘ œ˜!Kšœœ ˜0Kšœ/˜/K˜4Kšœ/˜/Kšœ'œ˜-Kšœœœ˜"Kš œœ€œ œœ˜ΖK˜—K™K™ K™šž œ˜"Kšœœ ˜0Kšœœœ˜šœœ˜ Kšœœ œœ ˜5Kšœœ œœ ˜5Kšœœ œœ ˜6Kšœœ œœ ˜5Kšœœ œœ ˜5Kšœœ˜$Kšœœ˜%Kšœœ˜4Kšœœ˜ Kšœœ˜,K˜—KšœI˜IK˜K˜—š‘ œ˜"Kšœœ ˜0Kšœœœ˜šœœ˜ Kšœ œ˜Kšœ œ˜"Kšœ œ˜!Kšœ œ˜Kšœœ˜1Kšœœ˜5Kšœœ˜-Kšœœ˜7Kšœœ˜5Kšœœ˜%Kšœœ˜3Kšœœ˜1K˜—KšœI˜IK˜K˜—š‘ œ˜"Kšœœ ˜0Kšœœœ˜šœœ˜ Kšœ œ˜Kšœ œ˜"Kšœ œ˜!Kšœ œ˜Kšœœ˜1Kšœœ˜5Kšœœ˜-Kšœœ˜7Kšœœ˜5Kšœœ˜%Kšœœ˜3Kšœœ˜1K˜—KšœC˜CK˜K˜—š‘ œ˜Kšœœ ˜0Kšœœœ˜šœœ˜ Kšœ œ œœ˜&Kšœœ œœ˜+Kšœœ œœ˜+Kšœ œ œœ˜%K˜—KšœE˜EK˜K˜—š‘œ˜#Kšœœ ˜0Kšœœœ˜šœœ˜ Kšœœ˜Kšœœ˜2Kšœ œ˜%Kšœ œ˜$Kšœœ˜,K˜—KšœJ˜JK˜K˜—š‘ œ˜ Kšœœ ˜0Kšœœœ˜šœœ˜ Kšœ œ ˜Kš œœœœ œœ ˜PKš œœœœ œœ ˜PKš œœœœ œœ ˜PKšœœ™@Kšœœ˜)Kšœœ˜AKšœœ˜/K˜—KšœC˜CK˜K˜—šž œ˜ Kšœœ ˜0Kšœœœ˜šœœ˜ Kšœœ˜'Kšœœ˜)Kšœœ˜'Kšœœ˜#Kšœœ˜*Kšœœ˜.Kšœœ˜-Kšœœ˜+Kšœœ˜'Kšœœ˜5Kšœœ˜5Kšœœ˜>Kšœœ˜:Kšœœ˜9Kšœ˜—KšœD˜DKšœ˜K˜—š‘ œ˜!Kšœœ ˜0Kšœœœ˜šœœ˜ Kšœœ˜#Kšœœ˜#Kšœœ˜-Kšœœ˜9Kšœœ˜*K˜—KšœE˜EK˜K˜—š‘ œ˜"Kšœœ ˜0Kšœœœ˜šœœ˜ Kšœœ˜'Kšœœ ˜!Kšœœ˜%Kšœœ˜'Kšœœ˜*Kšœœ˜6Kšœœ˜-K˜—KšœE˜EK˜K˜—š‘œ˜Kšœœ ˜0Kšœœœ˜šœœ˜ Kšœœ ˜Kšœœ ˜Kšœœ˜)Kšœœ˜/Kšœœ˜%Kšœœ˜)Kšœ œ ˜K˜—KšœC˜CK˜K˜—š‘œ˜#Kšœœ ˜0Kšœ œ&˜5Kšœ0˜0KšœA˜AK˜K˜—š‘œ˜$Kšœœ ˜0KšœB˜BKšœ+˜+K˜K˜—š‘ œ˜ Kšœœ ˜0Kšœ œ&˜5Kšœ2˜2K˜K˜—š‘œ˜$Kšœœ ˜0Kšœ œ&˜5Kšœ%œ˜