<> <> <> <> <<>> DIRECTORY Angles2d, AtomButtons, AtomButtonsTypes, Basics, Feedback, GraphicsButton, Imager, IO, Real, RealFns, Rope, SV2d, SVInterfaceTypes, SVModelTypes, SVSceneTypes, SVState, SVViewerTools, SVWindow; SVStateImpl: CEDAR PROGRAM IMPORTS Angles2d, AtomButtons, Feedback, GraphicsButton, IO, Real, RealFns, Rope, SVViewerTools, SVWindow EXPORTS SVState = BEGIN DisplayStyle: TYPE = SVModelTypes.DisplayStyle; ExtendMode: TYPE = SVSceneTypes.ExtendMode; FeatureCycler: TYPE = SVInterfaceTypes.FeatureCycler; GravityType: TYPE = SVInterfaceTypes.GravityType; SearchDepth: TYPE = SVSceneTypes.SearchDepth; SelectMode: TYPE = SVSceneTypes.SelectMode; Skitter: TYPE = SVSceneTypes.Skitter; SliceDescriptor: TYPE = SVSceneTypes.SliceDescriptor; SortedButtonHandle: TYPE = AtomButtonsTypes.SortedButtonHandle; SVData: TYPE = SVInterfaceTypes.SVData; TwoState: TYPE = AtomButtonsTypes.TwoState; Vector2d: TYPE = SV2d.Vector2d; Problem: PUBLIC SIGNAL [msg: Rope.ROPE] = Feedback.Problem; DeleteSelected: PROC [state: BOOL, name: Rope.ROPE, value: REF ANY, clientData: REF ANY] RETURNS [found: BOOL, done: BOOL _ FALSE] = { found _ state; }; TidyReal: PROC [r: REAL] RETURNS [name: Rope.ROPE] = { name _ IO.PutFR["%1.2f", [real[r]]]; <> UNTIL Rope.Fetch[base: name, index: Rope.Length[name]-1]# '0 DO name _ Rope.Substr[base: name, start: 0, len: Rope.Length[name]-1]; ENDLOOP; <> IF Rope.Fetch[base: name, index: Rope.Length[name]-1] = '. THEN name _ Rope.Substr[base: name, start: 0, len: Rope.Length[name]-1]; }; GetAzimuthValue: PUBLIC PROC [svData: SVData] RETURNS [degrees: REAL, success: BOOL _ TRUE] = { degrees _ SVViewerTools.GetReal[svData.measure.azimuthView, Real.LargestNumber]; IF degrees=Real.LargestNumber THEN { Feedback.Append[svData.feedback, "Attempt to use illegal azimuth value", oneLiner]; Feedback.Blink[svData.feedback]; degrees _ 0.0; success _ FALSE; RETURN; }; <> IF RealFns.AlmostEqual[degrees, svData.measure.azimuthViewValue, -10] THEN degrees _ svData.measure.azimuthViewValue ELSE svData.measure.azimuthViewValue _ degrees; }; GetAzimuthAlignments: PUBLIC PROC [svData: SVData] RETURNS [values: LIST OF REAL, on: LIST OF BOOL] = { AddAzimuth: PROC [state: BOOL, name: Rope.ROPE, value: REF ANY, clientData: REF ANY] RETURNS [done: BOOL _ FALSE] = { real: REAL _ NARROW[value, REF REAL]^; values _ CONS[real, values]; on _ CONS[state, on]; }; AtomButtons.ReadSortedButtons[svData.hitTest.azimuthHandle, AddAzimuth]; }; GetAzimuth: PUBLIC PROC [svData: SVData] RETURNS [degrees: REAL] = { FindScalar: PROC [state: BOOL, name: Rope.ROPE, value: REF ANY, clientData: REF ANY] RETURNS [done: BOOL _ FALSE] = { real: REAL _ NARROW[value, REF REAL]^; IF state THEN { degrees _ real; done _ success _ TRUE; }; }; success: BOOL _ FALSE; AtomButtons.ReadSortedButtons[svData.hitTest.azimuthHandle, FindScalar]; IF NOT success THEN ERROR; }; AddAzimuth: PUBLIC PROC [svData: SVData, degrees: REAL, on: BOOL _ TRUE] RETURNS [alreadyThere: BOOL] = { oldFoundButton: AtomButtons.SortedButtonClient; AtomButtons.SetAllScalarStates[svData, svData.hitTest.azimuthHandle, FALSE]; oldFoundButton _ AtomButtons.AddScalarSorted[clientData: svData, handle: svData.hitTest.azimuthHandle, button: [NIL, degrees, LIST[LIST[$ToggleAzimuth, NEW[REAL _ degrees]]], on], order: incr]; alreadyThere _ oldFoundButton # NIL; }; DeleteAzimuth: PUBLIC PROC [svData: SVData] = { AtomButtons.DeleteSortedButtons[svData, svData.hitTest.azimuthHandle, DeleteSelected]; }; GetSlopeAlignments: PUBLIC PROC [svData: SVData] RETURNS [values: LIST OF REAL, on: LIST OF BOOL] = { AddSlope: PROC [state: BOOL, name: Rope.ROPE, value: REF ANY, clientData: REF ANY] RETURNS [done: BOOL _ FALSE] = { real: REAL _ NARROW[value, REF REAL]^; values _ CONS[real, values]; on _ CONS[state, on]; }; AtomButtons.ReadSortedButtons[svData.hitTest.slopeHandle, AddSlope]; }; GetSlopeValue: PUBLIC PROC [svData: SVData] RETURNS [degrees: REAL, success: BOOL _ TRUE] = { degrees _ SVViewerTools.GetReal[svData.measure.slopeView, Real.LargestNumber]; IF degrees = Real.LargestNumber THEN { Feedback.Append[svData.feedback, "Attempt to use illegal slope value", oneLiner]; Feedback.Blink[svData.feedback]; degrees _ 0.0; success _ FALSE; RETURN; }; degrees _ Angles2d.Normalize[degrees]; <> IF degrees<0.0 THEN degrees _ degrees+180.0; IF degrees=360.0 THEN degrees _ 0.0; <> IF RealFns.AlmostEqual[degrees, svData.measure.slopeViewValue, -10] THEN degrees _ svData.measure.slopeViewValue ELSE svData.measure.slopeViewValue _ degrees; }; GetSlope: PUBLIC PROC [svData: SVData] RETURNS [degrees: REAL] = { FindScalar: PROC [state: BOOL, name: Rope.ROPE, value: REF ANY, clientData: REF ANY] RETURNS [done: BOOL _ FALSE] = { real: REAL _ NARROW[value, REF REAL]^; IF state THEN { degrees _ real; done _ success _ TRUE; }; }; success: BOOL _ FALSE; AtomButtons.ReadSortedButtons[svData.hitTest.slopeHandle, FindScalar]; IF NOT success THEN ERROR; }; AddSlope: PUBLIC PROC [svData: SVData, degrees: REAL, on: BOOL _ TRUE] RETURNS [alreadyThere: BOOL] = { oldFoundButton: AtomButtons.SortedButtonClient; AtomButtons.SetAllScalarStates[svData, svData.hitTest.slopeHandle, FALSE]; oldFoundButton _ AtomButtons.AddScalarSorted[svData, svData.hitTest.slopeHandle, [NIL, degrees, LIST[LIST[$ToggleSlope, NEW[REAL _ degrees]]], on], decr]; alreadyThere _ oldFoundButton # NIL; }; DeleteSlope: PUBLIC PROC [svData: SVData] = { AtomButtons.DeleteSortedButtons[svData, svData.hitTest.slopeHandle, DeleteSelected]; }; GetRadiusAlignments: PUBLIC PROC [svData: SVData] RETURNS [values: LIST OF REAL, on: LIST OF BOOL] = { AddRadius: PROC [state: BOOL, name: Rope.ROPE, value: REF ANY, clientData: REF ANY] RETURNS [done: BOOL _ FALSE] = { radius: REAL _ NARROW[value, REF REAL]^; values _ CONS[radius, values]; on _ CONS[state, on]; }; AtomButtons.ReadSortedButtons[svData.hitTest.radiusHandle, AddRadius]; }; GetRadiusValue: PUBLIC PROC [svData: SVData] RETURNS [radius: REAL, success: BOOL _ TRUE] = { radius _ SVViewerTools.GetReal[svData.measure.radiusView, Real.LargestNumber]; IF radius = Real.LargestNumber THEN { Feedback.Append[svData.feedback, "Attempt to use illegal radius value", oneLiner]; Feedback.Blink[svData.feedback]; radius _ 0.0; success _ FALSE; RETURN; }; <> IF RealFns.AlmostEqual[radius, svData.measure.radiusViewValue, -10] THEN radius _ svData.measure.radiusViewValue ELSE svData.measure.radiusViewValue _ radius; }; AddRadius: PUBLIC PROC [svData: SVData, radius: REAL, on: BOOL _ TRUE] RETURNS [alreadyThere: BOOL] = { oldFoundButton: AtomButtons.SortedButtonClient; AtomButtons.SetAllScalarStates[svData, svData.hitTest.radiusHandle, FALSE]; oldFoundButton _ AtomButtons.AddScalarSorted[svData, svData.hitTest.radiusHandle, [NIL, radius, LIST[LIST[$ToggleRadius, NEW[REAL _ radius]]], on], incr]; alreadyThere _ oldFoundButton # NIL; }; DeleteRadii: PUBLIC PROC [svData: SVData] = { AtomButtons.DeleteSortedButtons[svData, svData.hitTest.radiusHandle, DeleteSelected]; }; GetSlopeLineAlignments: PUBLIC PROC [svData: SVData] RETURNS [azimuths: LIST OF REAL, slopes: LIST OF REAL, on: LIST OF BOOL] = { AddSlopeLine: PROC [state: BOOL, name: Rope.ROPE, value: REF ANY, clientData: REF ANY] RETURNS [done: BOOL _ FALSE] = { vector: Vector2d _ NARROW[value, REF Vector2d]^; azimuths _ CONS[vector[1], azimuths]; slopes _ CONS[vector[2], slopes]; on _ CONS[state, on]; }; AtomButtons.ReadSortedButtons[svData.hitTest.slopeLineHandle, AddSlopeLine]; }; CompareSlopeAzimuth: PROC [aName: Rope.ROPE, aValue: REF ANY, bName: Rope.ROPE, bValue: REF ANY] RETURNS [compare: Basics.Comparison] = { aVector, bVector: Vector2d; aVector _ NARROW[aValue, REF Vector2d]^; bVector _ NARROW[bValue, REF Vector2d]^; compare _ Real.CompareREAL[aVector[1], bVector[1]]; IF compare # equal THEN RETURN; compare _ Real.CompareREAL[aVector[2], bVector[2]]; }; AddSlopeLine: PUBLIC PROC [svData: SVData, azimuth: REAL, slope: REAL, on: BOOL _ TRUE] RETURNS [alreadyThere: BOOL] = { name: Rope.ROPE; value: REF Vector2d; oldClient: AtomButtonsTypes.SortedButtonClient; name _ IO.PutFR["(%g %g)", [rope[TidyReal[azimuth]]], [rope[TidyReal[slope]]]]; value _ NEW[Vector2d_[azimuth,slope]]; oldClient _ AtomButtons.AddSortedButton[svData, svData.hitTest.slopeLineHandle, [name, value, LIST[LIST[$ToggleSlopeLine, value]], TRUE], CompareSlopeAzimuth]; }; DeleteSlopeLines: PUBLIC PROC [svData: SVData] = { AtomButtons.DeleteSortedButtons[svData, svData.hitTest.slopeLineHandle, DeleteSelected]; }; GetSlopePlaneAlignments: PUBLIC PROC [svData: SVData] RETURNS [azimuths: LIST OF REAL, slopes: LIST OF REAL, on: LIST OF BOOL] = { AddSlopePlane: PROC [state: BOOL, name: Rope.ROPE, value: REF ANY, clientData: REF ANY] RETURNS [done: BOOL _ FALSE] = { vector: Vector2d _ NARROW[value, REF Vector2d]^; azimuths _ CONS[vector[1], azimuths]; slopes _ CONS[vector[2], slopes]; on _ CONS[state, on]; }; AtomButtons.ReadSortedButtons[svData.hitTest.slopePlaneHandle, AddSlopePlane]; }; AddSlopePlane: PUBLIC PROC [svData: SVData, azimuth: REAL, slope: REAL, on: BOOL _ TRUE] RETURNS [alreadyThere: BOOL] = { name: Rope.ROPE; value: REF Vector2d; oldClient: AtomButtonsTypes.SortedButtonClient; name _ IO.PutFR["(%g %g)", [rope[TidyReal[azimuth]]], [rope[TidyReal[slope]]]]; value _ NEW[Vector2d_[azimuth,slope]]; oldClient _ AtomButtons.AddSortedButton[svData, svData.hitTest.slopePlaneHandle, [name, value, LIST[LIST[$ToggleSlopePlane, value]], TRUE], CompareSlopeAzimuth]; }; DeleteSlopePlanes: PUBLIC PROC [svData: SVData] = { AtomButtons.DeleteSortedButtons[svData, svData.hitTest.slopePlaneHandle, DeleteSelected]; }; <<>> <> GetDisplayStyle: PUBLIC PROC [svData: SVData] RETURNS [DisplayStyle] = { RETURN[svData.camera.displayStyle]; }; SetDisplayStyle: PUBLIC PROC [svData: SVData, displayStyle: DisplayStyle] = { SIGNAL Problem["Not yet implemented."]; }; GetShowAlignments: PUBLIC PROC [svData: SVData] RETURNS [BOOL] = { RETURN[TRUE]; }; SetShowAlignments: PUBLIC PROC [svData: SVData, showAlignments: BOOL] = { }; GetShowColors: PUBLIC PROC [svData: SVData] RETURNS [BOOL] = { RETURN[AtomButtons.GetBinaryState[svData.refresh.showColors]]; }; SetShowColors: PUBLIC PROC [svData: SVData, showColors: BOOL] = { AtomButtons.SetBinaryState[svData.refresh.showColors, showColors]; }; GetViewport: PUBLIC PROC [svData: SVData] RETURNS [Imager.Rectangle] = { RETURN[[-1000, -1000, 2000, 2000]]; }; GetSuppressRefresh: PUBLIC PROC [svData: SVData] RETURNS [BOOL] = { RETURN[svData.refresh.suppressRefresh]; }; SetSuppressRefresh: PUBLIC PROC [svData: SVData, suppressRefresh: BOOL] = { svData.refresh.suppressRefresh _ suppressRefresh; }; <<>> <> GetAnchor: PUBLIC PROC [svData: SVData] RETURNS [Skitter] = { RETURN[svData.scene.anchor]; }; GetGravity: PUBLIC PROC [svData: SVData] RETURNS [gravityOn: BOOL] = { gravityOn _ AtomButtons.GetBinaryState[svData.hitTest.gravButton]; }; SetGravity: PUBLIC PROC [svData: SVData, gravityOn: BOOL] = { AtomButtons.SetBinaryState[svData.hitTest.gravButton, gravityOn]; }; ToggleGravity: PUBLIC PROC [svData: SVData] = { stateInfo: TwoState _ svData.hitTest.gravButton; AtomButtons.SwitchBinaryState[stateInfo]; UpdateCursorLooks[svData]; }; UpdateCursorLooks: PROC [svData: SVData] = { SELECT GetGravity[svData] FROM TRUE => SELECT GetGravityType[svData] FROM facesPreferred => SVWindow.SetCursorLooks[facesPreferred, svData]; linesPreferred => SVWindow.SetCursorLooks[linesPreferred, svData]; pointsPreferred => SVWindow.SetCursorLooks[pointsPreferred, svData]; ENDCASE => ERROR; FALSE => SVWindow.SetCursorLooks[type: pointsPreferred, svData: svData, on: FALSE]; ENDCASE => ERROR; }; GetGravityExtent: PUBLIC PROC [svData: SVData] RETURNS [inches: REAL] = { screenDots: REAL; graphicsState: AtomButtonsTypes.GraphicsState _ svData.hitTest.gravityExtentButton; ged: SVInterfaceTypes.GravityExtentData; ged _ NARROW[GraphicsButton.GetValue[graphicsState].buttonData]; screenDots _ ged.extent; inches _ screenDots/72.0; }; SetGravityExtent: PUBLIC PROC [svData: SVData, inches: REAL] = { screenDots: REAL; graphicsState: AtomButtonsTypes.GraphicsState _ svData.hitTest.gravityExtentButton; ged: SVInterfaceTypes.GravityExtentData; screenDots _ inches*72.0; Feedback.PutF[svData.feedback, oneLiner, "Gravity extent is now %g inches.", [real[inches]] ]; ged _ NEW[SVInterfaceTypes.GravityExtentDataObj _ [extent: screenDots]]; GraphicsButton.SetButtonValueAndPaint[graphicsState, svData, ged]; svData.hitTest.t _ screenDots; }; GetGravityType: PUBLIC PROC [svData: SVData] RETURNS [gravityType: GravityType] = { gravityType _ svData.hitTest.gravityType; }; SetGravityType: PUBLIC PROC [svData: SVData, gravityType: GravityType] = { svData.hitTest.gravityType _ gravityType; }; CycleGravityType: PUBLIC PROC [svData: SVData, forward: BOOL] = { info: AtomButtons.EnumTypeRef _ svData.hitTest.gravityTypeMenu; name: Rope.ROPE; IF forward THEN AtomButtons.TimeToFlipThru[LIST[$FlipForward, info]] ELSE AtomButtons.TimeToFlipThru[LIST[$FlipBackward, info]]; name _ info.flipLabel.name; SELECT TRUE FROM Rope.Equal[name, "PreferFaces", TRUE] => SetGravityType[svData, facesPreferred]; Rope.Equal[name, "PreferLines", TRUE] => SetGravityType[svData, linesPreferred]; Rope.Equal[name, "PreferPoints", TRUE] => SetGravityType[svData, pointsPreferred]; ENDCASE => ERROR; UpdateCursorLooks[svData]; }; GetHeuristics: PUBLIC PROC [svData: SVData] RETURNS [BOOL] = { RETURN[FALSE]; }; SetHeuristics: PUBLIC PROC [svData: SVData, heuristicsOn: BOOL] = { }; GetMidpoints: PUBLIC PROC [svData: SVData] RETURNS [midpointsOn: BOOL] = { midpointsOn _ AtomButtons.GetBinaryState[svData.hitTest.midpointButton]; }; SetMidpoints: PUBLIC PROC [svData: SVData, midpointsOn: BOOL] = { AtomButtons.SetBinaryState[svData.hitTest.midpointButton, midpointsOn]; }; ToggleMidpoints: PUBLIC PROC [svData: SVData] = { stateInfo: TwoState _ svData.hitTest.midpointButton; AtomButtons.SwitchBinaryState[stateInfo]; SVWindow.RestoreScreenAndInvariants[paintAction: $None, svData: svData]; }; GetScaleUnit: PUBLIC PROC [svData: SVData] RETURNS [REAL] = { <> RETURN[svData.hitTest.scaleUnit]; }; SetScaleUnit: PUBLIC PROC [svData: SVData, unit: REAL] = { <> IF unit <=0.0 THEN { Feedback.AppendHerald[svData.feedback, "Zero or Illegal unit value. Set Scale Units ignored.", oneLiner]; Feedback.Blink[svData.feedback]; } ELSE svData.hitTest.scaleUnit _ unit; -- in screen dots }; <<>> <> GetSliceToExtend: PUBLIC PROC [svData: SVData] RETURNS [sliceD: SliceDescriptor] = { <> RETURN[NIL]; }; SetSliceToExtend: PUBLIC PROC [svData: SVData, sliceD: SliceDescriptor] = { <> }; GetSelectionCycler: PUBLIC PROC [svData: SVData] RETURNS [featureCycler: FeatureCycler] = { featureCycler _ svData.select.cycler; }; SetSelectionCycler: PUBLIC PROC [svData: SVData, featureCycler: FeatureCycler] = { svData.select.cycler _ featureCycler; }; <> GetSelectMode: PUBLIC PROC [svData: SVData] RETURNS [selectMode: SelectMode] = { RETURN[svData.drag.selectState]; }; SetSelectMode: PUBLIC PROC [svData: SVData, selectMode: SelectMode] = { svData.drag.selectState _ selectMode; }; GetExtendMode: PUBLIC PROC [svData: SVData] RETURNS [extendMode: ExtendMode] = { RETURN[svData.drag.extendMode]; }; SetExtendMode: PUBLIC PROC [svData: SVData, extendMode: ExtendMode] = { svData.drag.extendMode _ extendMode; }; GetQuickClickMode: PUBLIC PROC RETURNS [on: BOOL] = { RETURN[quickClickMode]; }; SetQuickClickMode: PUBLIC PROC [on: BOOL] = { quickClickMode _ on; }; <<>> quickClickMode: BOOL _ FALSE; <<>> <> GetSearchDepth: PUBLIC PROC [svData: SVData] RETURNS [searchDepth: SearchDepth] = { searchDepth _ first; }; SetSearchDepth: PUBLIC PROC [svData: SVData, searchDepth: SearchDepth] = { SIGNAL Problem[msg: "Can't set searchDepth yet"]; }; GetSelectedAzimuth: PUBLIC PROC [svData: SVData] RETURNS [azimuth: REAL] = { azimuthHandle: SortedButtonHandle; ReadScalar: PROC [state: BOOL, name: Rope.ROPE, value: REF ANY, clientData: REF ANY] RETURNS [done: BOOL _ FALSE] = { IF state THEN { azimuth _ NARROW[value, REF REAL]^; done _ TRUE; }; }; azimuthHandle _ svData.hitTest.azimuthHandle; AtomButtons.ReadSortedButtons[azimuthHandle, ReadScalar, svData]; }; SetSelectedAzimuth: PUBLIC PROC [svData: SVData, azimuth: REAL] = { }; GetSelectedSlope: PUBLIC PROC [svData: SVData] RETURNS [slope: REAL] = { slopeHandle: SortedButtonHandle; ReadScalar: PROC [state: BOOL, name: Rope.ROPE, value: REF ANY, clientData: REF ANY] RETURNS [done: BOOL _ FALSE] = { IF state THEN { slope _ NARROW[value, REF REAL]^; done _ TRUE; }; }; slopeHandle _ svData.hitTest.slopeHandle; AtomButtons.ReadSortedButtons[slopeHandle, ReadScalar, svData]; }; SetSelectedSlope: PUBLIC PROC [svData: SVData, slope: REAL] = { }; <<>> <<>> <> GetDefaultHeuristics: PUBLIC PROC [] RETURNS [BOOL] = { RETURN[TRUE]; }; END.