<> <> <> <> <<>> DIRECTORY AtomButtons, AtomButtonsTypes, CodeTimer, Feedback, FS, GraphicsButton, Imager, IO, Menus, PopUpSelection, Rope, SlackProcess, SV2d, SV3d, SVDraw, SVEditUser, SVEvent, SVFiles, SVInterfaceTypes, SVMenus, SVModelTypes, SVMouseEvent, SVSceneTypes, SVState, SVUserInput, SVWindow, VFonts, ViewerClasses, ViewerTools; SVMenusImpl: CEDAR PROGRAM IMPORTS AtomButtons, CodeTimer, Feedback, FS, GraphicsButton, Imager, IO, PopUpSelection, Rope, SlackProcess, SVDraw, SVEditUser, SVEvent, SVFiles, SVMouseEvent, SVState, SVUserInput, SVWindow, VFonts, ViewerTools EXPORTS SVMenus = BEGIN Camera: TYPE = SVModelTypes.Camera; CoordSystem: TYPE = SVModelTypes.CoordSystem; EditToolData: TYPE = SVInterfaceTypes.EditToolData; FeedbackData: TYPE = AtomButtonsTypes.FeedbackData; FileCamera: TYPE = SVSceneTypes.FileCamera; GravityExtentData: TYPE = REF GravityExtentDataObj; GravityExtentDataObj: TYPE = SVInterfaceTypes.GravityExtentDataObj; MouseButton: TYPE = Menus.MouseButton; Plane: TYPE = SV3d.Plane; Point2d: TYPE = SV2d.Point2d; Scene: TYPE = SVSceneTypes.Scene; TwoState: TYPE = AtomButtonsTypes.TwoState; Viewer: TYPE = ViewerClasses.Viewer; SVData: TYPE = SVInterfaceTypes.SVData; 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; scalarButtonColumn: CARDINAL = 180; getScalarColumn: CARDINAL = 75; newScalarColumn: CARDINAL = 40; fullColumn: CARDINAL = 600; -- the width of the standard large left column. boldFont: VFonts.Font; -- initialized in Init below; popUpFont: 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, svData: SVData, 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 { SVUserInput.EventNotify[svData, entries.first.input]; EXIT; }; index _ index - 1; REPEAT FINISHED => ERROR; ENDLOOP; IF onceOnly THEN RETURN; ENDLOOP; }; BuildControlPanel: PUBLIC PROC [svData: SVData, windowMenu: Menus.Menu, workingDirectory: Rope.ROPE] = { BuildFileMenuLine[svData]; BuildMasterMenuLine[svData]; BuildStyleMenuLine[svData]; BuildGravityLine[svData]; BuildAzimuthLine[svData]; BuildSlopeLine[svData]; BuildSlopeLineLine[svData]; BuildSlopePlaneLine[svData]; BuildRadiusLine[svData]; BuildMeasureLine[svData]; BuildFeedbackLine[svData]; }; <> <<>> BuildFileMenuLine: PROC [svData: SVData] = { <> nextX: INTEGER; interpressMenu: AtomButtons.ButtonLineEntry _ [popUpButton[ "Interpress", LIST[ [LIST[$ToIP], "ToIP", "Writes an interpress master to selected filename", boldFont], [LIST[$StorePoly], "StorePoly", "Stores a polygonal scene representation to selected filename"] ], -1, FALSE, popUpFont]]; svData.height _ svData.height + entryVSpace; <> nextX _ AtomButtons.BuildButtonLine [svData.outer, 0, svData.height, svData, SVUserInput.EventNotify, LIST[ [button["Clear", LIST[LIST[$Clear]], -1, FALSE, NIL, ConfirmClear]], [button["Restore", LIST[LIST[$Restore]], -1, FALSE, NIL, ConfirmReset]], [button["Get", LIST[LIST[$Get]], -1, FALSE, NIL, ConfirmGet]], [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[LIST[$Split]]]], [button["Erase", LIST[LIST[$Erase]]]], interpressMenu ]]; nextX _ AtomButtons.BuildUnQueuedButtonLine [svData.outer, nextX + entryHSpace, svData.height, svData, LIST[ ["Script", button, ScriptMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["CastRays", button, CastRaysMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Revive!", button, ReviveButton] ]]; nextX _ AtomButtons.BuildButtonLine [svData.outer, nextX + entryHSpace, svData.height, svData, SVUserInput.EventNotify, LIST[ [button["Refresh!", LIST[LIST[$DrawSceneButton]]]] ]]; svData.height _ svData.height + entryVSpace + entryHeight; }; BuildMasterMenuLine: PROC [svData: SVData] = { << This section implements a set of buttons, text windows, and options listers in this format:>> <> nextX: INTEGER; transformMenu: AtomButtons.ButtonLineEntry _ [popUpButton["Transform", LIST [ [LIST [$RotX, $Do], "RotX", "Rotate selected objects about anchor's x axis"], [LIST [$RotY, $Do], "RotY", "Rotate selected objects about anchor's y axis"], [LIST [$RotZ, $Do], "RotZ", "Rotate selected objects about anchor's z axis"], [LIST [$RotX, $Undo], "UnRotX", "Rotate selected objects about anchor's x axis by negated angle"], [LIST [$RotY, $Undo], "UnRotY", "Rotate selected objects about anchor's y axis by negated angle"], [LIST [$RotZ, $Undo], "UnRotZ", "Rotate selected objects about anchor's z axis by negated angle"], [LIST [$Trans, $Do], "Translate", "Translate selected objects relative to anchor"], [LIST [$Align], "Align", "Rotate selected objects to anchor's orientation or 90 degrees from it"], [LIST [$EvenScale, $Do], "EvenScale", "Scale selected objects about anchor's origin"], [LIST [$Trans, $Undo], "UnTranslate", "Translate selected objects relative to anchor by negated vector"], [LIST [$NoOp], "", "There is no undo for Align."], [LIST [$EvenScale, $Undo], "UnEvenScale", "Scale selected objects about anchor's origin by reciprocal scalar"], [LIST [$Abut], "Abut", "Translate selected objects to anchor's origin"], [LIST [$NormalizeRot], "NormalizeRot", "Rotate selected objects to anchor's orientation"], [LIST [$Normalize], "Normalize", "Move selected objects to anchor's position & orientation"], [LIST [$AbutX], "AbutX", "Translate selected objects to anchor's x=0 plane"], [LIST [$AbutY], "AbutY", "Translate selected objects to anchor's y=0 plane"], [LIST [$AbutZ], "AbutZ", "Translate selected objects to anchor's z=0 plane"] ], -1, FALSE, NIL]]; nextX _ AtomButtons.BuildButtonLine [svData.outer, 0, svData.height, svData, SVUserInput.EventNotify, LIST[ [button["DrawColor", LIST[LIST[$DrawColor]]]], [button["DrawB&W", LIST[LIST[$DrawBlackAndWhite]]]], transformMenu ]]; nextX _ AtomButtons.BuildUnQueuedButtonLine [svData.outer, nextX + entryHSpace, svData.height, svData, LIST[ ["Shapes", button, ShapesMenu, NIL, 0, -1, FALSE, NIL, boldFont], ["Debug", button, DebugMenu, NIL, 0, -1, FALSE, NIL, boldFont] ]]; svData.height _ svData.height + entryVSpace + entryHeight; }; -- end of BuildMasterMenuLine BuildStyleMenuLine: PROC [svData: SVData] = { nextX: INTEGER; smallStringSize: NAT _ VFonts.StringWidth["WireframeStyle"]; noOpChoice: AtomButtons.PopUpChoice _ [LIST [$NoOp], "", "no-op" ]; quickClickMode: BOOL _ SVState.GetQuickClickMode[]; colorMenu: AtomButtons.ButtonLineEntry _ [popUpButton["Color", LIST [ [LIST [$StrokeColorFromColorTool], "FromColorTool [G]", "Make selected strokes have the color in the ColorTool"], [LIST [$PrintStrokeColor], "ShowStrokeColor [G]", "Print stroke color of selected stroke"], [LIST [$StrokeColorToColorTool], "ToColorTool [G]", "Send the stroke color of the selected stroke to the ColorTool"], [LIST [$StrokeColorNone], "none [G]", "Make selected strokes have no color (invisible)"], [LIST [$StrokeColorFollowColorTool], "FollowColorTool [G]", "Selected stroke colors will track the ColorTool. Any mouse click terminates FollowColorTool"], [LIST [$StrokeColorGray, NEW[REAL_1.0]], "white [G]", "Make selected strokes have color white"], [LIST [$StrokeColorFromSelectedName], "FromSelectedName [GT]", "Make selected strokes have the color named in the Tioga selection (e.g. vivid green)"], [LIST [$SelectMatchingStrokeCNS], "MatchSelectedName [T]", "Select strokes whose color match the name in the Tioga selection (e.g. vivid green)"], [LIST [$StrokeColorGray, NEW[REAL_0.0]], "black [G]", "Make selected strokes have color black"], [LIST [$StrokeColorFromSelectedRGB], "FromSelectedRGB [GT]", "Make selected strokes have the RGB specified in the Tioga selection (e.g. r: 0.5 g: 0.9 b: 0.67)"], [LIST [$SelectMatchingStrokeRGB], "MatchSelectedRGB [T]", "Select strokes whose color match the RGB in the Tioga selection (e.g. r: 0.5 g: 0.9 b: 0.67)"], [LIST [$StrokeColorGray], "gray [G]", "Make selected strokes have color gray"], noOpChoice, [LIST [$ShowDefaultStrokeColor], "ShowDefault", "Print default stroke color"], [LIST [$SetDefaultStrokeColor], "MakeDefault [G]", "Set the default stroke color from the currently selected stroke"] ], -1, FALSE, popUpFont, NIL, quickClickMode]]; fillMenu: AtomButtons.ButtonLineEntry _ [popUpButton["Fill", LIST [ [LIST [$AreaColorFromColorTool], "FromColorTool [G]", "Make selected objects have the fill color in the ColorTool"], [LIST [$PrintAreaColor], "ShowFillColor [G]", "Print fill color of selected object"], [LIST [$AreaColorToColorTool], "ToColorTool [G]", "Send the fill color of the selected object to the ColorTool"], [LIST [$AreaColorNone], "none [G]", "Make selected objects have no fill color"], [LIST [$AreaColorFollowColorTool], "FollowColorTool [G]", "Selected fill colors will track the ColorTool. Any mouse click terminates FollowColorTool"], [LIST [$AreaColorGray, NEW[REAL_1.0]], "white [G]", "Make selected objects have fill color white"], [LIST [$AreaColorFromSelectedName], "FromSelectedName [GT]", "Make selected objects have the fill color named in the Tioga selection (e.g. vivid green)"], [LIST [$SelectMatchingAreaCNS], "MatchSelectedName [T]", "Select objects whose fill color matches the name in the Tioga selection (e.g. vivid green)"], [LIST [$AreaColorGray, NEW[REAL_0.0]], "black [G]", "Make selected objects have fill color black"], [LIST [$AreaColorFromSelectedRGB], "FromSelectedRGB [GT]", "Make selected objects have the fill RGB specified in the Tioga selection (e.g. r: 0.5 g: 0.9 b: 0.67)"], [LIST [$SelectMatchingAreaRGB], "MatchSelectedRGB [T]", "Select objects whose fill color match the RGB in the Tioga selection (e.g. r: 0.5 g: 0.9 b: 0.67)"], [LIST [$AreaColorGray, NEW[REAL_0.5]], "gray [G]", "Make selected objects have fill color gray"], noOpChoice, [LIST [$ShowDefaultFillColor], "ShowDefault", "Print default fill color"], [LIST [$SetDefaultFillColor], "MakeDefault [G]", "Set the default fill color from the currently selected object"] ], -1, FALSE, popUpFont, NIL, quickClickMode]]; selectMenu: AtomButtons.ButtonLineEntry _ [popUpButton["Select", LIST [ [LIST [$CycleSelection, $Forward], "CycleSelection", "Select a different object that is near the selected one."], noOpChoice, [LIST [$CycleSelection, $Backward], "UnCycleSelection", "Select a different object that is near the selected one."], [LIST [$BlockSelectNew], "New [G]", "Select all objects within the bounding box of the current selection"], [LIST [$BlockSelectNewAndDelete], "NewAndDelete [G]", "Select all objects within the bounding block of the current selection and delete the original selection"], [LIST [$BlockSelectExtend], "Extend [G]", "Add all objects within the bounding block of the current selection to the current selection"], [LIST [$SelectAll], "All (^d)", "Select every object in the scene"], noOpChoice, noOpChoice ], -1, FALSE, popUpFont, NIL, quickClickMode]]; hotSpotsMenu: AtomButtons.ButtonLineEntry _ [popUpButton["MakeHot", LIST [ [LIST [$MakeHot], "Make Hot (^s) [G]", "Make all selected objects hot"], noOpChoice, [LIST [$MakeCold], "Make Cold (^S) [G]", "Make all selected objects cold"], [LIST [$DropAnchor], "Drop Anchor (^a)", "Drop anchor at caret"], noOpChoice, [LIST [$LiftAnchor], "Lift Anchor (^A)", "Remove anchor"], [LIST [$MakeAllHot], "Make All Hot (^ss)", "Make all objects hot"], noOpChoice, [LIST [$MakeAllCold], "Make All Cold (^SS)", "Make all objects cold"], [LIST [$StandardAlignments], "Standard Alignments", "Restore standard alignments"] ], -1, FALSE, popUpFont, NIL, quickClickMode]]; unitsMenu: AtomButtons.ButtonLineEntry _ [popUpButton["Units", LIST [ [LIST [$InchScaleUnit], "Inches", "Set unit value to 1 inch"], [LIST [$PrintScaleUnit], "ShowValue", "Print current unit value"], [LIST [$PointsScaleUnit], "Points", "Set unit value to 1 point"], [LIST [$RadiusUnitFromSegment], "FromSegment [G]", "Set unit value to length of selected segment"], [LIST [$RadiusUnitFromValue], "FromRadiusValue", "Set unit value from number in RadiusValue"], [LIST [$RadiusUnitFromSelection], "FromSelection [T]", "Set unit value from number in the Tioga selection"], [LIST [$CentimeterScaleUnit], "Centimeters", "Set unit value to 1 centimeter"] ], -1, FALSE, popUpFont, NIL, quickClickMode]]; nextX _ AtomButtons.BuildButtonLine [svData.outer, 0, svData.height, svData, SVUserInput.EventNotify, LIST[ colorMenu, fillMenu, selectMenu, hotSpotsMenu, unitsMenu, [twoState["ShowColors", LIST[$ToggleShowColors], FALSE, ShowColorsInit]], [button["ViewStyle:", LIST[LIST[$StylePrompt]] ]], [label["Shaded", ViewStyleInSVData, smallStringSize]], [button["Selected", LIST[LIST[$Selected]], -1, FALSE, NIL, NIL, SelectedInSVData]] ]]; svData.height _ svData.height + entryVSpace + entryHeight; }; BuildGravityLine: PROC [svData: SVData] = { nextX: NAT _ 0; svData.hitTest.gravityTypeMenu _ AtomButtons.BuildEnumTypeSelection[viewer: svData.outer, x: 0, y: svData.height, maxWidth: 144, clientData: svData, handleProc: SVUserInput.EventNotify, title: "GravType:", default: "PreferPoints", borderOnButtons: TRUE, style: flipThru, allInOneRow: TRUE, buttonNames: LIST["PreferFaces", "PreferLines", "PreferPoints"], atom: $GravityChoiceChange]; svData.hitTest.gravityType _ pointsPreferred; nextX _ svData.hitTest.gravityTypeMenu.nextx; nextX _ AtomButtons.BuildButtonLine[ svData.outer, nextX + entryHSpace, svData.height, svData, SVUserInput.EventNotify, LIST[ [label["GravExtent:"]] ]]; nextX _ GraphicsButton.BuildGraphicsButton[ container: svData.outer, x: nextX + entryHSpace, y: svData.height, w: 60, -- changed from 72 to make more room in line h: entryHeight, clientData: svData, choices: LIST[ [LIST[$GravityExtentChange, $ValueUp]], [LIST[$GravityExtentChange, $InitialValue]], [LIST[$GravityExtentChange, $ValueDown]]], handleProc: SVUserInput.EventNotify, repaintProc: GravityExtentRepaint, buttonData: NEW[GravityExtentDataObj _ [extent: SVEditUser.GetDefaultGravityExtent[]]], updateProc: GravityExtentInSVData ]; nextX _ AtomButtons.BuildButtonLine[ svData.outer, nextX + 2*entryHSpace, svData.height, svData, SVUserInput.EventNotify, LIST[ [twoState["Gravity", LIST[$ToggleGravity], TRUE, GravityButtonInit]], [twoState["Midpoints", LIST[$ToggleMidpoints], FALSE, MidpointsButtonInit]], [twoState["Heuristics", LIST[$ToggleHeuristics], SVState.GetDefaultHeuristics[], HeuristicsButtonInit]] ]]; svData.height _ svData.height + entryHeight; }; BuildSpecial3DLine: PROC [svData: SVData] = { nextX: INTEGER; bigStringSize: NAT _ VFonts.StringWidth["///Users/Name.pa/Solidviews/PictureName.pic"]; threeNumberSize: NAT _ VFonts.StringWidth["18, 18, 18"]; nextX _ AtomButtons.BuildButtonLine [svData.outer, 0, svData.height, svData, SVUserInput.EventNotify, LIST[ [button["CoordsMode", LIST[LIST[$ShowCoordsMode]], -1, FALSE, NIL, NIL, ShowCoordsInSVData]], [button["x,y,z:", LIST[LIST[$XYZPrompt]]]], [text["0, 0, 0", XYZViewInSVData, threeNumberSize]] ]]; svData.height _ svData.height + entryVSpace + entryHeight; }; -- end of BuildSpecial3DLine BuildAzimuthLine: PROC [svData: SVData] = { buttonHandle: AtomButtons.SortedButtonHandle; nextX: NAT _ AtomButtons.BuildButtonLine[svData.outer, 0, svData.height, svData, SVUserInput.EventNotify, LIST[ [button["Azimuth:", LIST[LIST[$AzimuthPrompt]] ]], [button["Get!", LIST[LIST[$GetAzimuth]], getScalarColumn ]], [button["Add!", LIST[LIST[$AddAzimuth]] ]], [button["Delete!", LIST[LIST[$DeleteAzimuth]] ]] ]]; buttonHandle _ AtomButtons.CreateSortedButtonViewer[svData.outer, scalarButtonColumn, svData.height]; svData.hitTest.azimuthHandle _ buttonHandle; SVEvent.StandardAzimuths[LIST[$InitStandardAzimuths], svData]; svData.height _ svData.height + entryHeight; }; BuildSlopeLine: PROC [svData: SVData] = { buttonHandle: AtomButtons.SortedButtonHandle; nextX: NAT _ AtomButtons.BuildButtonLine[svData.outer, 0, svData.height, svData, SVUserInput.EventNotify, LIST[ [button["Slope:", LIST[LIST[$SlopePrompt]] ]], [button["Get!", LIST[LIST[$GetSlope]], getScalarColumn ]], [button["Add!", LIST[LIST[$AddSlope]] ]], [button["Delete!", LIST[LIST[$DeleteSlope]] ]] ]]; buttonHandle _ AtomButtons.CreateSortedButtonViewer[svData.outer, scalarButtonColumn, svData.height]; svData.hitTest.slopeHandle _ buttonHandle; SVEvent.StandardSlopes[LIST[$InitStandardSlopes], svData]; svData.height _ svData.height + entryHeight; }; BuildSlopeLineLine: PROC [svData: SVData] = { buttonHandle: AtomButtons.SortedButtonHandle; nextX: NAT _ AtomButtons.BuildButtonLine[svData.outer, 0, svData.height, svData, SVUserInput.EventNotify, LIST[ [button["Line:", LIST[LIST[$SlopeLinePrompt]] ]], [button["New!", LIST[LIST[$NewSlopeLine]], newScalarColumn ]], [button["Get!", LIST[LIST[$GetLine]], getScalarColumn ]], [button["Add!", LIST[LIST[$AddSlopeLine]] ]], [button["Delete!", LIST[LIST[$DeleteSlopeLine]] ]] ]]; buttonHandle _ AtomButtons.CreateSortedButtonViewer[svData.outer, scalarButtonColumn, svData.height]; svData.hitTest.slopeLineHandle _ buttonHandle; SVEvent.StandardSlopeLines[LIST[$InitStandardSlopeLines], svData]; svData.height _ svData.height + entryHeight; }; BuildSlopePlaneLine: PROC [svData: SVData] = { buttonHandle: AtomButtons.SortedButtonHandle; nextX: NAT _ AtomButtons.BuildButtonLine[svData.outer, 0, svData.height, svData, SVUserInput.EventNotify, LIST[ [button["Plane:", LIST[LIST[$SlopePlanePrompt]] ]], [button["New!", LIST[LIST[$NewSlopePlane]], newScalarColumn ]], [button["Get!", LIST[LIST[$GetLine]], getScalarColumn ]], [button["Add!", LIST[LIST[$AddSlopePlane]] ]], [button["Delete!", LIST[LIST[$DeleteSlopePlane]] ]] ]]; buttonHandle _ AtomButtons.CreateSortedButtonViewer[svData.outer, scalarButtonColumn, svData.height]; svData.hitTest.slopePlaneHandle _ buttonHandle; SVEvent.StandardSlopePlanes[LIST[$InitStandardSlopePlanes], svData]; svData.height _ svData.height + entryHeight; }; BuildRadiusLine: PROC [svData: SVData] = { buttonHandle: AtomButtons.SortedButtonHandle; nextX: NAT _ AtomButtons.BuildButtonLine[svData.outer, 0, svData.height, svData, SVUserInput.EventNotify, LIST[ [button["Radius:", LIST[LIST[$RadiusPrompt]] ]], [button["Get!", LIST[LIST[$GetRadius]], getScalarColumn ]], [button["Add!", LIST[LIST[$AddRadius]] ]], [button["Delete!", LIST[LIST[$DeleteRadius]] ]] ]]; buttonHandle _ AtomButtons.CreateSortedButtonViewer[svData.outer, scalarButtonColumn, svData.height]; svData.hitTest.radiusHandle _ buttonHandle; SVEvent.StandardRadii[LIST[$InitStandardRadii], svData]; svData.height _ svData.height + entryHeight; }; BuildMeasureLine: PROC [svData: SVData] = { nextX: NAT _ AtomButtons.BuildButtonLine[svData.outer, 0, svData.height, svData, SVUserInput.EventNotify, LIST[ [button["AzimuthValue:", LIST[LIST[$MeasureAzimuthHit]] ]], [text["0.0", AzimuthViewInSVData, smallNumberSize]], [button["SlopeValue:", LIST[LIST[$MeasureSlopeHit]] ]], [text["0.0", SlopeViewInSVData, smallNumberSize]], [button["RadiusValue:", LIST[LIST[$MeasureRadiusHit]] ]], [text["0.0", RadiusViewInSVData, smallNumberSize]] ]]; svData.height _ svData.height + entryHeight; }; BuildFeedbackLine: PROC [svData: SVData] = { nextX: NAT _ AtomButtons.BuildButtonLine[svData.outer, 0, svData.height, svData, SVUserInput.EventNotify, LIST[ [label["Feedback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Line", FeedbackLineInSVData, fullColumn]] ]]; svData.height _ svData.height + entryHeight; }; <<>> <> ConfirmClear: PUBLIC PROC [clientData: REF ANY] = { svData: SVData _ NARROW[clientData]; scene: Scene _ svData.scene; rope: Rope.ROPE; dirty: BOOL; dirty _ svData.outer.newVersion; IF dirty THEN rope _ "Confirm discard of edits" ELSE rope _ "Confirm emptying of viewer"; Feedback.AppendHerald[svData.feedback, rope, oneLiner]; }; ConfirmReset: PUBLIC PROC [clientData: REF ANY] = { svData: SVData _ NARROW[clientData]; scene: Scene _ svData.scene; dirty: BOOL; dirty _ svData.outer.newVersion; IF dirty THEN Feedback.PutFHerald[svData.feedback, oneLiner, "Confirm discard of edits"] ELSE Feedback.PutFHerald[svData.feedback, oneLiner, "Confirm reset of %g", [rope[scene.name]]]; }; -- end of ConfirmReset ConfirmSave: PUBLIC PROC [clientData: REF ANY] = { svData: SVData _ NARROW[clientData]; scene: Scene _ svData.scene; exists: BOOL; rope: Rope.ROPE; exists _ SVFiles.FileExists[scene.name]; IF exists THEN rope _ IO.PutFR["Confirm Save to %g [Old File]", [rope[scene.name]]] ELSE { rope _ IO.PutFR["%g doesn't exist. Use Store", [rope[scene.name]]]; Feedback.Blink[svData.feedback] }; Feedback.Append[svData.feedback, rope, oneLiner]; }; ConfirmStore: PUBLIC PROC [clientData: REF ANY] = { svData: SVData _ NARROW[clientData]; editToolData: EditToolData _ NARROW[svData.editToolData]; scene: Scene _ svData.scene; picName: Rope.ROPE _ ViewerTools.GetSelectionContents[]; fullName, wdir: Rope.ROPE; exists: BOOL; success: BOOL _ TRUE; rope: Rope.ROPE; IF Rope.Length[picName] = 0 THEN { Feedback.Append[svData.feedback, "Please select a file name.", oneLiner]; Feedback.Blink[svData.feedback]; RETURN; }; wdir _ editToolData.originalWorkingDirectory; [fullName,,] _ FS.ExpandName[picName, wdir ! FS.Error => IF error.group = user THEN { Feedback.Append[svData.feedback, Rope.Concat["Store: ", error.explanation], oneLiner]; success _ FALSE; CONTINUE; } ]; exists _ SVFiles.FileExists[fullName]; IF exists THEN rope _ IO.PutFR["Confirm Store of %g [Old File]", [rope[fullName]]] ELSE rope _ IO.PutFR["Confirm Store to %g [New File]", [rope[fullName]]]; Feedback.AppendHerald[svData.feedback, rope, oneLiner]; }; ConfirmGet: PUBLIC PROC [clientData: REF ANY] = { svData: SVData _ NARROW[clientData]; editToolData: EditToolData _ NARROW[svData.editToolData]; scene: Scene _ svData.scene; picName: Rope.ROPE _ ViewerTools.GetSelectionContents[]; fullName, wdir: Rope.ROPE; success: BOOL _ TRUE; dirty: BOOL; IF Rope.Length[picName] = 0 THEN { Feedback.Append[svData.feedback, "Please select a file name.", oneLiner]; Feedback.Blink[svData.feedback]; RETURN; }; wdir _ editToolData.originalWorkingDirectory; [fullName,,] _ FS.ExpandName[picName, wdir ! FS.Error => IF error.group = user THEN { Feedback.Append[svData.feedback, Rope.Concat["Get: ", error.explanation], oneLiner]; success _ FALSE; CONTINUE; } ]; IF NOT success THEN RETURN; dirty _ svData.outer.newVersion; IF dirty THEN Feedback.PutF[svData.feedback, oneLiner, "Confirm discard of edits and load of %g", [rope[fullName]]] ELSE Feedback.PutF[svData.feedback, oneLiner, "Confirm load of %g", [rope[fullName]]]; }; -- end of ConfirmGet ConfirmMerge: PROC [clientData: REF ANY] = { svData: SVData _ NARROW[clientData]; filename: Rope.ROPE _ ViewerTools.GetSelectionContents[]; Feedback.AppendHerald[svData.feedback, Rope.Cat["Confirm addition of file ", filename, " to the current scene."], oneLiner]; }; <> ShapesMenu: Menus.ClickProc = { svData: SVData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["Block", LIST [$AddBlock, $Add]] ]; QueuePopUpMenuAction["Shapes", menu, svData, mouseButton#blue]; }; DebugMenu: Menus.ClickProc = { svData: SVData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry; menu _ LIST [ ["DrawBoundBoxes", LIST [$DrawBoundBoxes]], ["DrawBoundSpheres", LIST [$DrawBoundSpheres]], ["DrawCoordSystems", LIST [$DrawCoordSystems]], ["DrawPoint", LIST [$DrawPoint]], ["Draw Selection Box", LIST [$DrawSelectionBox]], ["CrossHairs", LIST [$CrossHairs]], ["KillSelections", LIST [$KillSelectionsButton]], ["DeleteJacks", LIST [$DeleteJacksButton]], ["TestGravity", LIST [$TestGravity]], ["Reset Statistics", LIST [$ResetStatistics]], ["Print Statistics", LIST [$PrintStatistics]], ["Raise SIGNAL", LIST [$RaiseSIGNAL]] ]; QueuePopUpMenuAction["Debug", menu, svData, mouseButton#blue]; }; CastRaysMenu: Menus.ClickProc = { svData: SVData _ NARROW[clientData]; menu: LIST OF PopUpMenuEntry _ LIST [ ["RayCast", LIST [$RayCast]], ["RayCastColor", LIST [$RayCastColor]], ["StopRays", LIST [$StopRays]], ["ARay", LIST [$ARay]] ]; choices: LIST OF Rope.ROPE _ ExtractChoiceList[menu]; index: NAT _ PopUpSelection.Request[header: "SVCastRays", choice: choices]; SELECT index FROM =0 => RETURN; =1 => SVEvent.RayCast[LIST[$RayCast], svData]; =2 => SVEvent.RayCast[LIST[$RayCastColor], svData]; =3 => SVEvent.StopRays[LIST[$StopRays], svData]; =4 => SVEvent.ARay[LIST[$ARay], svData]; ENDCASE => ERROR; <> }; ScriptMenu: Menus.ClickProc = { svData: SVData _ 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 => SVEvent.OpenScript[parent, clientData, mouseButton, shift, control]; =2 => SVEvent.AppendToScript[parent, clientData, mouseButton, shift, control]; =3 => SVEvent.CloseScript[parent, clientData, mouseButton, shift, control]; =4 => SVEvent.PlaybackScript[parent, clientData, mouseButton, shift, control]; =5 => SVEvent.FastPlayScript[parent, clientData, mouseButton, shift, control]; ENDCASE => ERROR; }; ConfirmRayCast: PUBLIC PROC [clientData: REF ANY] = { svData: SVData _ NARROW[clientData]; exists: BOOL; aisFileRope: Rope.ROPE; redRope: Rope.ROPE _ Rope.Concat[SVFiles.FilenameMinusExtension[aisFileRope], "-red.ais"]; greenRope: Rope.ROPE _ Rope.Concat[SVFiles.FilenameMinusExtension[aisFileRope], "-green.ais"]; blueRope: Rope.ROPE _ Rope.Concat[SVFiles.FilenameMinusExtension[aisFileRope], "-blue.ais"]; rope: Rope.ROPE; <> exists _ SVFiles.FileExists[aisFileRope]; rope _ IO.PutFR["Confirm raycast to %g.", [rope[aisFileRope]]]; IF exists THEN rope _ Rope.Concat[rope, " [Old File]"] ELSE rope _ Rope.Concat[rope, " [New File]"]; <<}>> <> <> <> <> <> <<};>> Feedback.AppendHerald[svData.feedback, rope, oneLiner]; }; ReviveButton: Menus.ClickProc = { svData: SVData _ NARROW[clientData]; SVMouseEvent.ResetMouseMachinery[svData]; CodeTimer.ResetTable[CodeTimer.GetTable[$Solidviews]]; SlackProcess.Restart[svData.slackHandle]; svData.refresh.suppressRefresh _ FALSE; svData.aborted _ ALL[FALSE]; IF mouseButton#blue THEN SVWindow.RestoreScreenAndInvariants[paintAction: $PaintEntireScene, svData: svData, remake: triggerBag, backgndOK: FALSE, edited: FALSE, okToClearFeedback: TRUE] }; <<>> <