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;
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]]];
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];
};
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;
};
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:
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];
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:
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;
};
Return the most accurate value we have.
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];
};
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: BOOL ← FALSE;
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:
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] = {
};
Defaults
GetDefaultHeuristics:
PUBLIC
PROC []
RETURNS [
BOOL] = {
RETURN[TRUE];
};
END.