File: SVMouseEventImplB.mesa
Last edited by Bier on May 26, 1987 8:30:22 pm PDT
Copyright © 1984 by Xerox Corporation. All rights reserved.
Contents: Procedures for responding to button clicks made in a solidviewer.
DIRECTORY
CodeTimer, SVGraphics, Feedback, Imager, ImagerBackdoor, ImagerPath, IO, Matrix3d, Rope, SV2d, SV3d, SVAlign, SVAssembly, SVBasicTypes, SVDescribe, SVGravity, SVInterfaceTypes, SVModelTypes, SVMouseEvent, SVRayTypes, SVRefresh, SVScene, SVSceneTypes, SVSelect, SVSelections, SVState, SVWindow, TIPUser, ViewerClasses;
SVMouseEventImplB:
CEDAR PROGRAM
IMPORTS CodeTimer, SVGraphics, Feedback, Imager, ImagerBackdoor, Matrix3d, Rope, SVAlign, SVAssembly, SVDescribe, SVGravity, SVRefresh, SVScene, SVSelect, SVSelections, SVState, SVWindow
EXPORTS SVMouseEvent =
BEGIN
ArtworkToolData: TYPE = SVInterfaceTypes.ArtworkToolData;
Slice: TYPE = SVSceneTypes.Slice;
BoundBox: TYPE = SVBasicTypes.BoundBox;
Camera: TYPE = SVModelTypes.Camera;
Classification: TYPE = SVRayTypes.Classification;
CoordSystem: TYPE = SVModelTypes.CoordSystem;
EditToolData: TYPE = SVInterfaceTypes.EditToolData;
FeatureData: TYPE = SVInterfaceTypes.FeatureData;
FileCamera: TYPE = SVSceneTypes.FileCamera;
FrameBox: TYPE = SVModelTypes.FrameBox;
MasterObject: TYPE = SVSceneTypes.MasterObject;
Matrix4by4: TYPE = SV3d.Matrix4by4;
Point2d: TYPE = SV2d.Point2d;
Point3d: TYPE = SV3d.Point3d;
Primitive: TYPE = SVRayTypes.Primitive;
Ray: TYPE = SVRayTypes.Ray;
Scene: TYPE = SVSceneTypes.Scene;
Selection: TYPE = SVInterfaceTypes.Selection;
SelectionGenerator: TYPE = SVInterfaceTypes.SelectionGenerator;
SelectMode: TYPE = SVSceneTypes.SelectMode;
SkitterMode: TYPE = SVSceneTypes.SkitterMode;
SliceDescriptor: TYPE = SVSceneTypes.SliceDescriptor;
ToolData: TYPE = SVSceneTypes.ToolData;
TrigLine: TYPE = SV2d.TrigLine;
Vector3d: TYPE = SV3d.Vector3d;
SVData: TYPE = SVInterfaceTypes.SVData;
MouseProc: TYPE = SVMouseEvent.MouseProc;
StartProc: TYPE = SVMouseEvent.StartProc;
Problem: SIGNAL [msg: Rope.ROPE] = Feedback.Problem;
FrameUpLeft:
PUBLIC StartProc = {
Controlpoint is in camera coordinates.
camera: Camera ← svData.camera;
camera.frame.fullScreen ← FALSE;
camera.frame.downLeft[1] ← cameraPoint[1];
camera.frame.upRight[2] ← cameraPoint[2];
camera.frame.downLeft[2] ← cameraPoint[2] - 50.0; -- Just to give the frame an initial size.
camera.frame.upRight[1] ← cameraPoint[1] + 50.0;
SVWindow.RestoreScreenAndInvariants[$DuringMotion, svData];
};
FrameDownRightMove:
PUBLIC MouseProc = {
Controlpoint is in camera coordinates.
camera: Camera ← svData.camera;
DoDrawFrame:
PROC [dc: Imager.Context] = {
Imager.SetColor[dc, ImagerBackdoor.invert];
SVGraphics.DrawFrame [dc, camera];
};
camera.frame.downLeft[2] ← cameraPoint[2];
camera.frame.upRight[1] ← cameraPoint[1];
Draw the new frame.
SVWindow.RestoreScreenAndInvariants[$DuringMotion, svData];
};
FrameDownRightEnd:
PUBLIC MouseProc = {
camera: Camera ← svData.camera;
fileCamera: FileCamera;
success: BOOL;
FrameDownRightMove[event, svData, cameraPoint];
Once last update with the final position.
Tell the appropriate file camera about the new frame.
[fileCamera, success] ← SVScene.FindFileCameraFromName[camera.viewName, svData.scene];
IF success
THEN {
fileCamera.frame.downLeft ← camera.frame.downLeft;
fileCamera.frame.upRight ← camera.frame.upRight;
fileCamera.frame.fullScreen ← FALSE;
};
};
DeleteFrame:
PUBLIC MouseProc = {
camera: Camera ← svData.camera;
frame: FrameBox ← camera.frame;
DoDrawFrame:
PROC [dc: Imager.Context] = {
Imager.SetColor[dc, ImagerBackdoor.invert];
SVGraphics.DrawFrame [dc, camera];
};
Erase the old frame.
SVWindow.RestoreScreenAndInvariants[$FrameChanged, svData];
frame.fullScreen ← TRUE;
};
SaveSavedState:
PROC [svData: SVData] = {
SVScene.SaveSelections[svData.scene];
SVWindow.SaveCaretPos[gargoyleData];
SVCaret.Copy[from: svData.caret, to: svData.drag.savedCaret];
};
Selection Procs
StartSelectJoint:
PUBLIC StartProc = {
svData.drag.selectState ← joint;
StartSelectAux[svData, cameraPoint];
DuringSelect[NIL, svData, cameraPoint];
};
StartSelectSegment:
PUBLIC StartProc = {
svData.drag.selectState ← segment;
StartSelectAux[svData, cameraPoint];
DuringSelect[NIL, svData, cameraPoint];
};
StartSelectTraj:
PUBLIC StartProc = {
svData.drag.selectState ← traj;
StartSelectAux[svData, cameraPoint];
DuringSelect[NIL, svData, cameraPoint];
};
StartSelectTopLevel:
PUBLIC StartProc = {
svData.drag.selectState ← topLevel;
StartSelectAux[svData, cameraPoint];
DuringSelect[NIL, svData, cameraPoint];
};
StartSelectAux:
PROC [svData: SVData, cameraPoint: Point2d] = {
IF NOT SVRefresh.EmptyOverlay[svData] THEN ERROR;
SaveSavedState[svData];
};
DuringSelect:
PUBLIC MouseProc = {
While a joint, segment, traj, or top level object is being selected, gravity is forced to be StrictDistance. The object bag should consist only of trajectories and slices. The caret is moved to the segment endpoint of the nearest segment or traj as appropriate or tracks the cursor if none are nearby. Feedback is in the form of highlighted joints.
opRope: Rope.ROPE = "Selecting ";
worldPt: Point3d;
normalVec: Vector3d;
feature: FeatureData;
hitData: REF ANY;
scene: Scene ← svData.scene;
selectMode: SelectMode ← SVState.GetSelectMode[svData];
IF selectMode = joint
THEN
[worldPt, normalVec, feature, hitData] ← SVGravity.PointsPreferred[cameraPoint, svData.hitTest.criticalR, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData, TRUE]
ELSE [worldPt, normalVec, feature, hitData] ← SVGravity.StrictDistance[cameraPoint, svData.hitTest.criticalR, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData, TRUE];
SetCaretAttractorEndpoint[svData, cameraPoint, worldPt, normalVec, feature, hitData];
SVSelect.DeselectAll[scene, normal];
IF feature#NIL THEN SelectAndDescribeSlicePart[feature, hitData, worldPt, svData, selectMode, opRope] ELSE DescribeOperationOnNothing[svData, opRope];
SVWindow.RestoreScreenAndInvariants[paintAction: $DuringSelect, svData: svData, remake: none, backgndOK: TRUE, edited: FALSE, okToClearFeedback: FALSE];
}; -- end DuringSelect
SelectAndDescribeSlicePart:
PUBLIC
PROC [feature: FeatureData, hitData:
REF
ANY, hitPoint: Point3d, svData: SVData, mode: SelectMode, opRope: Rope.
ROPE] = {
selectedD: REF ANY ← SelectSlicePart[feature, hitData, hitPoint, svData, mode];
description: Rope.
ROPE ←
WITH selectedD
SELECT
FROM
sliceD: SliceDescriptor => SVAssembly.Describe[sliceD],
ENDCASE => SVDescribe.DescribeFeature[feature, hitData, svData];
Feedback.PutFHerald[svData.feedback, oneLiner, "%g %g", [rope[opRope]], [rope[description]] ];
};
SelectSlicePart:
PUBLIC
PROC [feature: FeatureData, hitData:
REF
ANY, hitPoint: Point3d, svData: SVData, mode: SelectMode]
RETURNS [selectedD:
REF
ANY] = {
Find out which point is being selected and highlight it.
SELECT feature.type
FROM
slice => {
slice: Slice ← NARROW[feature.shape, SliceDescriptor].slice;
selectedSliceD: SliceDescriptor;
selectedSliceD ← SVAssembly.NewParts[slice, hitData, hitPoint, mode];
SVSelect.SelectSlice[selectedSliceD, svData.scene, normal];
selectedD ← selectedSliceD;
};
slopeLine, angleLine, distanceLine, intersectionPoint, radiiCircle, midpoint => ERROR;
ENDCASE => ERROR Problem[msg: "unimplemented result type"];
};
DescribeOperationOnNothing:
PUBLIC
PROC [svData: SVData, opRope: Rope.
ROPE] = {
Feedback.PutFHerald[svData.feedback, oneLiner, "%g %g", [rope[opRope]], [rope["nothing"]] ];
};
SetCaretAttractorEndpoint:
PUBLIC
PROC [svData: SVData, cameraPoint: Point2d, worldPt: Point3d, normal: Vector3d, feature: FeatureData, hitData:
REF
ANY] = {
assembly: Slice;
assembly ← IF feature = NIL THEN NIL ELSE NARROW[feature.shape, SliceDescriptor].slice;
IF feature=
NIL
THEN [] ← SVSelections.PositionSkitter[cameraPoint, worldPt, normal, assembly, svData]
ELSE {
shape: REF ANY ← feature.shape;
SELECT feature.type
FROM
slice => {
jointPos: Point3d;
jointNormal: Vector3d;
sliceD: SliceDescriptor ← NARROW[shape];
jointD: SliceDescriptor;
[jointD, jointPos, jointNormal] ← SVAssembly.ClosestJointToHitData[sliceD, worldPt, normal, hitData];
[] ← SVSelections.PositionSkitter[cameraPoint, jointPos, jointNormal, assembly, svData];
};
ENDCASE => [] ← SVSelections.PositionSkitter[cameraPoint, worldPt, normal, assembly, svData];
};
};
EndSelect:
PUBLIC MouseProc = {
pointWORLD: Point3d;
normalWORLD: Vector3d;
feature: FeatureData;
hitData: REF ANY;
scene: Scene ← svData.scene;
selectMode: SelectMode ← SVState.GetSelectMode[svData];
IF selectMode = joint
THEN
[pointWORLD, normalWORLD, feature, hitData] ← SVGravity.PointsPreferred[cameraPoint, svData.hitTest.criticalR, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData, TRUE]
ELSE [pointWORLD, normalWORLD, feature, hitData] ← SVGravity.StrictDistance[cameraPoint, svData.hitTest.criticalR, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData, TRUE];
SetCaretAttractorEndpoint[svData, cameraPoint, pointWORLD, normalWORLD, feature, hitData];
SVWindow.NewCaretPos[svData];
SVSelect.DeselectAll[scene, normal];
SELECT selectMode
FROM
joint => EndSelectAux[svData, cameraPoint, feature, hitData, pointWORLD, joint, "joint"];
segment => EndSelectAux[svData, cameraPoint, feature, hitData, pointWORLD, segment, "segment"];
traj => EndSelectAux[svData, cameraPoint, feature, hitData, pointWORLD, traj, "trajectory"];
topLevel => EndSelectAux[svData, cameraPoint, feature, hitData, pointWORLD, topLevel, "object"];
ENDCASE => ERROR;
SVState.SetSelectMode[svData, none]; -- added to help DescribeFeature work. KAP.
}; -- end EndSelect
SitTheCaret: PROC [caret: Caret, outlineD: OutlineDescriptor, hitData: REF ANY, mode: SelectMode] = {
SELECT mode FROM
joint => GGCaret.SitOn[caret, outlineD];
segment, traj, topLevel => {
jointParts: SliceParts;
jointSeq: Sequence;
jointD: OutlineDescriptor;
jointNum: NAT;
traj: Traj;
IF outlineD.slice.class.type = $Outline THEN {
[jointNum, traj] ← GGOutline.NearestJointToHitData[hitData];
jointSeq ← GGSequence.CreateFromJoint[traj, jointNum];
jointParts ← GGOutline.PartsFromSequence[outlineD.slice, jointSeq];
jointD ← GGOutline.DescriptorFromParts[outlineD.slice, jointParts];
GGCaret.SitOn[caret, jointD];
}
ELSE GGCaret.SitOn[caret, NIL];
};
ENDCASE => ERROR;
};
EndSelectAux:
PROC [svData: SVData, cameraPoint: Point2d, feature: FeatureData, hitData:
REF
ANY, hitPoint: Point3d, mode: SelectMode, opName: Rope.
ROPE] = {
Prepare for a subsequent Add operation and for Extend.
IF feature =
NIL
THEN {
GGCaret.SitOn[svData.caret, NIL];
Feedback.PutFHerald[svData.feedback, oneLiner, "No near %g found.", [rope[opName]]];
}
ELSE {
Make Selection and Prepare for Extend.
SELECT mode
FROM
joint => SVState.SetExtendMode[svData, joint];
segment => SVState.SetExtendMode[svData, segmentRange];
traj => SVState.SetExtendMode[svData, traj];
topLevel => SVState.SetExtendMode[svData, topLevel];
ENDCASE => ERROR;
SELECT feature.type
FROM
slice => {
sliceD: SliceDescriptor ← NARROW[SelectSlicePart[feature, hitData, hitPoint, svData, mode]];
IF mode = traj OR mode = topLevel THEN GGCaret.SitOn[svData.caret, NIL]
ELSE GGCaret.SitOn[svData.caret, sliceD];
Feedback.AppendHerald[svData.feedback, Rope.Concat[SVAssembly.Describe[sliceD], " selected"], oneLiner];
SVState.SetSliceToExtend[svData, sliceD];
};
ENDCASE => ERROR Problem[msg: "Unexpected feature type"];
};
SVWindow.RestoreScreenAndInvariants[paintAction: $SelectionChanged, svData: svData, remake: none, backgndOK: TRUE, edited: FALSE, okToClearFeedback: FALSE];
}; -- end EndSelectAux
Extend selection procs.
StartExtend
SelectJoint:
PUBLIC StartProc = {
svData.drag.extendMode ← joint;
RETURN[StartExtendSelection[event, svData, cameraPoint]];
};
StartExtend
SelectSegment:
PUBLIC StartProc = {
svData.drag.extendMode ← segment;
RETURN[StartExtendSelection[event, svData, cameraPoint]];
};
StartExtend
SelectTraj:
PUBLIC StartProc = {
svData.drag.extendMode ← traj;
RETURN[StartExtendSelection[event, svData, cameraPoint]];
};
StartExtend
SelectTopLevel:
PUBLIC StartProc = {
svData.drag.extendMode ← topLevel;
RETURN[StartExtendSelection[event, svData, cameraPoint]];
};
StartExtendSelection:
PUBLIC StartProc = {
IF NOT SVRefresh.EmptyOverlay[svData] THEN ERROR;
SaveSavedState[svData]; -- must do this before any possible aborts occur
svData.drag.currentPoint ← cameraPoint;
svData.drag.transform ← Matrix3d.Identity[];
DuringExtendSelection[NIL, svData, cameraPoint];
};
DuringExtendSelection:
PUBLIC MouseProc= {
opRope: Rope.ROPE = "Extending to ";
surfacePtWORLD: Point3d;
normalWORLD: Vector3d;
feature: FeatureData;
hitData: REF ANY;
scene: Scene ← svData.scene;
CodeTimer.StartInt[$DuringExtendSelection, $Solidviews];
IF SVState.GetExtendMode[svData] = joint
THEN
[surfacePtWORLD, normalWORLD, feature, hitData] ← SVGravity.PointsPreferred[cameraPoint, svData.hitTest.criticalR, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData, TRUE]
ELSE [surfacePtWORLD, normalWORLD, feature, hitData] ← SVGravity.StrictDistance[cameraPoint, svData.hitTest.criticalR, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData, TRUE];
Put Caret on a joint (if any).
SetCaretAttractorEndpoint[svData, cameraPoint, surfacePtWORLD, normalWORLD, feature, hitData];
Reselect all.
SVSelect.DeselectAll[scene, normal];
SVScene.RestoreSelections[scene];
IF feature#
NIL
THEN {
SELECT svData.drag.extendMode
FROM
joint, segment, segmentRange, traj, topLevel => DuringExtendSelectionFeedback[feature, hitData, surfacePtWORLD, svData];
slice, none => NULL;
ENDCASE => ERROR;
}
ELSE DescribeOperationOnNothing[svData, opRope];
SVWindow.RestoreScreenAndInvariants[paintAction: $DuringSelect, svData: svData, remake: none, backgndOK: TRUE, edited: FALSE, okToClearFeedback: FALSE];
CodeTimer.StopInt[$DuringExtendSelection, $Solidviews];
}; -- end DuringExtendSelection
DuringExtendSelectionFeedback:
PROC [feature: FeatureData, hitData:
REF
ANY, hitPoint: Point3d, svData: SVData] = {
depending on extend mode, check if feature is in that mode, then select the new feature.
opRope: Rope.ROPE ← "Extending to ";
SELECT svData.drag.extendMode
FROM
joint, segment, traj, topLevel => [] ← SelectAndDescribeSlicePart[feature, hitData, hitPoint, svData, SVState.GetExtendMode[svData], opRope];
segmentRange => {
GOTO RegularSelectMechanism;
EXITS
RegularSelectMechanism => [] ← SelectAndDescribeSlicePart[feature, hitData, hitPoint, svData, segment, opRope];
};
ENDCASE => ERROR; -- should have been weeded about before calling this Proc
};
End
ExtendSelection:
PUBLIC MouseProc = {
SVWindow.RestoreScreenAndInvariants[paintAction: $SelectionChanged, svData: svData, remake: none, backgndOK: TRUE, edited: FALSE, okToClearFeedback: FALSE];
}; -- end EndExtendSelection
InitStats:
PROC [] = {
interval: CodeTimer.Interval;
interval ← CodeTimer.CreateInterval[$DuringExtendSelection];
CodeTimer.AddInt[interval, $Solidviews];
};
END.