File: SVMouseEventImplB.mesa
Last edited by Bier on July 10, 1987 12:17:54 pm PDT
Copyright © 1984 by Xerox Corporation. All rights reserved.
Contents: Procedures for responding to button clicks made in a solidviewer.
Bloomenthal, June 16, 1987 7:29:53 pm PDT
DIRECTORY
CodeTimer, Feedback, Imager, ImagerBackdoor, ImagerPath, IO, Matrix3d, Rope, SV2d, SV3d, SVAlign, SVAssembly, SVBasicTypes, SVCaret, SVDescribe, SVGraphics, SVGravity, SVInterfaceTypes, SVModelTypes, SVMouseEvent, SVRefresh, SVScene, SVSceneTypes, SVSelect, SVState, SVWindow, TIPUser, ViewerClasses;
SVMouseEventImplB: CEDAR PROGRAM
IMPORTS CodeTimer, SVGraphics, Feedback, Imager, ImagerBackdoor, Matrix3d, Rope, SVAlign, SVAssembly, SVCaret, SVDescribe, SVGravity, SVRefresh, SVScene, SVSelect, SVState, SVWindow
EXPORTS SVMouseEvent =
BEGIN
ArtworkToolData: TYPE = SVInterfaceTypes.ArtworkToolData;
BoundBox: TYPE = SVBasicTypes.BoundBox;
Camera: TYPE = SVModelTypes.Camera;
Classification: TYPE = SVSceneTypes.Classification;
CoordSystem: TYPE = SVModelTypes.CoordSystem;
EditToolData: TYPE = SVInterfaceTypes.EditToolData;
ExtendMode: TYPE = SVSceneTypes.ExtendMode;
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 = SVSceneTypes.Primitive;
Ray: TYPE = SVSceneTypes.Ray;
Scene: TYPE = SVSceneTypes.Scene;
Selection: TYPE = SVInterfaceTypes.Selection;
SelectionGenerator: TYPE = SVInterfaceTypes.SelectionGenerator;
SelectMode: TYPE = SVSceneTypes.SelectMode;
Skitter: TYPE = SVSceneTypes.Skitter;
SkitterMode: TYPE = SVSceneTypes.SkitterMode;
Slice: TYPE = SVSceneTypes.Slice;
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];
SELECT selectMode FROM
joint => [worldPt, normalVec, feature, hitData] ← SVGravity.PointsPreferred[cameraPoint, svData.hitTest.t, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData, TRUE];
segment => [worldPt, normalVec, feature, hitData] ← SVGravity.LinesPreferred[cameraPoint, svData.hitTest.t, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData, TRUE];
traj, topLevel => [worldPt, normalVec, feature, hitData] ← SVGravity.FacesPreferred[cameraPoint, svData.hitTest.t, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData];
ENDCASE => ERROR;
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.ROPEWITH 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] = {
sliceD: SliceDescriptor;
skitter: Skitter ← svData.editToolData.skitter;
sliceD ← IF feature = NIL THEN NIL ELSE NARROW[feature.shape];
IF feature=NIL THEN SVCaret.SetAttractor[skitter, cameraPoint, worldPt, normal, sliceD]
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];
SVCaret.SetAttractor[skitter, cameraPoint, jointPos, jointNormal, sliceD];
};
ENDCASE => SVCaret.SetAttractor[skitter, cameraPoint, worldPt, normal, sliceD];
};
};
EndSelect: PUBLIC MouseProc = {
pointWorld: Point3d;
normalWorld: Vector3d;
feature: FeatureData;
hitData: REF ANY;
scene: Scene ← svData.scene;
featureCycler: SVGravity.FeatureCycler;
selectMode: SelectMode ← SVState.GetSelectMode[svData];
SELECT selectMode FROM
joint => featureCycler ← SVGravity.PointsPreferredCycler[cameraPoint, svData.hitTest.t, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData, TRUE, 1];
segment => featureCycler ← SVGravity.LinesPreferredCycler[cameraPoint, svData.hitTest.t, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData, TRUE, 1];
traj, topLevel => {
featureCycler ← SVGravity.FacesPreferredCycler[cameraPoint, svData.hitTest.t, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData];
};
ENDCASE => ERROR;
[pointWorld, normalWorld, feature, hitData] ← SVGravity.FirstFeature[featureCycler];
SVState.SetSelectionCycler[svData, featureCycler];
SelectFromFeature[svData, cameraPoint, pointWorld, normalWorld, feature, hitData];
}; -- end EndSelect
SelectFromFeature: PUBLIC PROC [svData: SVData, cameraPt: Point2d, pointWorld: Point3d, normalWorld: Vector3d, feature: FeatureData, hitData: REF ANY] = {
selectMode: SelectMode ← SVState.GetSelectMode[svData];
scene: Scene ← svData.scene;
SetCaretAttractorEndpoint[svData, cameraPt, pointWorld, normalWorld, feature, hitData];
SVWindow.NewCaretPos[svData];
SVSelect.DeselectAll[scene, normal];
SELECT selectMode FROM
joint => EndSelectAux[svData, cameraPt, feature, hitData, pointWorld, joint, "joint"];
segment => EndSelectAux[svData, cameraPt, feature, hitData, pointWorld, segment, "segment"];
traj => EndSelectAux[svData, cameraPt, feature, hitData, pointWorld, traj, "trajectory"];
topLevel => EndSelectAux[svData, cameraPt, feature, hitData, pointWorld, topLevel, "object"];
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]];
featureCycler: SVGravity.FeatureCycler ← SVState.GetSelectionCycler[svData];
cycleCount: NAT ← featureCycler.count;
IF mode = traj OR mode = topLevel THEN GGCaret.SitOn[svData.caret, NIL]
ELSE GGCaret.SitOn[svData.caret, sliceD];
IF cycleCount > 1 THEN Feedback.PutFHerald[svData.feedback, oneLiner, Rope.Concat[SVAssembly.Describe[sliceD], " selected (%g more)"], [integer[cycleCount-1]]]
ELSE 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.
StartExtendSelectJoint: PUBLIC StartProc = {
svData.drag.extendMode ← joint;
RETURN[StartExtendSelection[event, svData, cameraPoint]];
};
StartExtendSelectSegment: PUBLIC StartProc = {
svData.drag.extendMode ← segment;
RETURN[StartExtendSelection[event, svData, cameraPoint]];
};
StartExtendSelectTraj: PUBLIC StartProc = {
svData.drag.extendMode ← traj;
RETURN[StartExtendSelection[event, svData, cameraPoint]];
};
StartExtendSelectTopLevel: 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;
extendMode: ExtendMode ← SVState.GetExtendMode[svData];
CodeTimer.StartInt[$DuringExtendSelection, $Solidviews];
SELECT extendMode FROM
joint => {
[surfacePtWorld, normalWorld, feature, hitData] ← SVGravity.PointsPreferred[cameraPoint, svData.hitTest.t, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData, TRUE];
};
segment, segmentRange => {
[surfacePtWorld, normalWorld, feature, hitData] ← SVGravity.LinesPreferred[cameraPoint, svData.hitTest.t, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData, TRUE];
};
traj, slice, topLevel => {
[surfacePtWorld, normalWorld, feature, hitData] ← SVGravity.FacesPreferred[cameraPoint, svData.hitTest.t, SVAlign.emptyAlignBag, svData.hitTest.sceneBag, svData];
};
ENDCASE => ERROR;
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 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
};
EndExtendSelection: 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];
};
InitStats[];
END.