SVStateImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Last edited by Bier on March 30, 1987 12:52:26 pm PST
Contents: Routines for getting and setting the state or "modes" of the Solidviews interface.
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;
GetAzimuthValue: PUBLIC PROC [svData: SVData] RETURNS [degrees: REAL, success: BOOLTRUE] = {
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;
};
Put the most accurate value we have into variable distance
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: BOOLFALSE] = {
real: REALNARROW[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: BOOLFALSE] = {
real: REALNARROW[value, REF REAL]^;
IF state THEN {
degrees ← real;
done ← success ← TRUE;
};
};
success: BOOLFALSE;
AtomButtons.ReadSortedButtons[svData.hitTest.azimuthHandle, FindScalar];
IF NOT success THEN ERROR;
};
AddAzimuth: PUBLIC PROC [svData: SVData, degrees: REAL, on: BOOLTRUE] 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;
};
DeleteSelected: PROC [state: BOOL, name: Rope.ROPE, value: REF ANY, clientData: REF ANY] RETURNS [found: BOOL, done: BOOLFALSE] = {
found ← state;
};
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: BOOLFALSE] = {
real: REALNARROW[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: BOOLTRUE] = {
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];
Only positive slopes, please.
IF degrees<0.0 THEN degrees ← degrees+180.0;
IF degrees=360.0 THEN degrees ← 0.0;
Return the most accurate value we have.
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: BOOLFALSE] = {
real: REALNARROW[value, REF REAL]^;
IF state THEN {
degrees ← real;
done ← success ← TRUE;
};
};
success: BOOLFALSE;
AtomButtons.ReadSortedButtons[svData.hitTest.slopeHandle, FindScalar];
IF NOT success THEN ERROR;
};
AddSlope: PUBLIC PROC [svData: SVData, degrees: REAL, on: BOOLTRUE] 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] = {
};
GetRadiusValue: PUBLIC PROC [svData: SVData] RETURNS [radius: REAL, success: BOOLTRUE] = {
};
AddRadius: PUBLIC PROC [svData: SVData, radius: REAL, on: BOOLTRUE] RETURNS [alreadyThere: BOOL] = {
alreadyThere ← TRUE;
};
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: BOOLFALSE] = {
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: BOOLTRUE] 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];
};
TidyReal: PROC [r: REAL] RETURNS [name: Rope.ROPE] = {
name ← IO.PutFR["%1.2f", [real[r]]];
Strip off trailing zeroes
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;
Strip off trailing decimal point
IF Rope.Fetch[base: name, index: Rope.Length[name]-1] = '. THEN name ← Rope.Substr[base: name, start: 0, len: Rope.Length[name]-1];
};
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: BOOLFALSE] = {
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: BOOLTRUE] 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];
};
Refresh Parameters
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;
};
Gravity and Alignments
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] = {
in units of 1/72 of an inch
RETURN[svData.hitTest.scaleUnit];
};
SetScaleUnit: PUBLIC PROC [svData: SVData, unit: REAL] = {
in units of 1/72 of an inch
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
};
Other
GetSliceToExtend: PUBLIC PROC [svData: SVData] RETURNS [sliceD: SliceDescriptor] = {
RETURN[svData.drag.sliceToExtend];
RETURN[NIL];
};
SetSliceToExtend: PUBLIC PROC [svData: SVData, sliceD: SliceDescriptor] = {
svData.drag.sliceToExtend ← sliceD;
};
GetSelectionCycler: PUBLIC PROC [svData: SVData] RETURNS [featureCycler: FeatureCycler] = {
featureCycler ← svData.select.cycler;
};
SetSelectionCycler: PUBLIC PROC [svData: SVData, featureCycler: FeatureCycler] = {
svData.select.cycler ← featureCycler;
};
Hidden State (yuk)
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: BOOLTRUE;
Peculiar to 3D
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: BOOLFALSE] = {
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: BOOLFALSE] = {
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] = {
};
Defaults
GetDefaultHeuristics: PUBLIC PROC [] RETURNS [BOOL] = {
RETURN[TRUE];
};
END.