<<>> <> <> <> <> <> <> <> <> <> <<>> DIRECTORY Atom, Basics, CodeTimer, ColorTool, Feedback, FeedbackTypes, GGAlign, GGBasicTypes, GGCaret, GGDescribe, GGDragTypes, GGEvent, GGHistory, GGHistoryTypes, GGInterfaceTypes, GGModelTypes, GGMouseEvent, GGMultiGravity, GGOutline, GGParent, GGRefresh, GGRefreshTypes, GGScene, GGSegment, GGSegmentTypes, GGSelect, GGSequence, GGSlice, GGSliceOps, GGState, GGTraj, GGUserInput, GGUtility, GGWindow, Imager, ImagerTransformation, InputFocus, IO, Menus, RealFns, Rope, Vectors2d; GGMouseEventImplB: CEDAR PROGRAM IMPORTS Basics, CodeTimer, ColorTool, Feedback, GGAlign, GGCaret, GGDescribe, GGEvent, GGHistory, GGMouseEvent, GGMultiGravity, GGOutline, GGParent, GGRefresh, GGScene, GGSegment, GGSelect, GGSequence, GGSlice, GGSliceOps, GGState, GGTraj, GGUserInput, GGUtility, GGWindow, ImagerTransformation, IO, Rope, Vectors2d EXPORTS GGMouseEvent, GGInterfaceTypes = BEGIN DragDataObj: PUBLIC TYPE = GGDragTypes.DragDataObj; AlignBag: TYPE = GGInterfaceTypes.AlignBag; AlignmentPoint: TYPE = GGInterfaceTypes.AlignmentPoint; BoundBox: TYPE = GGModelTypes.BoundBox; Caret: TYPE = GGInterfaceTypes.Caret; Color: TYPE = Imager.Color; DefaultData: TYPE = GGModelTypes.DefaultData; ExtendMode: TYPE = GGInterfaceTypes.ExtendMode; FeatureCycler: TYPE = GGInterfaceTypes.FeatureCycler; FeatureData: TYPE = GGModelTypes.FeatureData; GravityType: TYPE = GGInterfaceTypes.GravityType; MsgRouter: TYPE = FeedbackTypes.MsgRouter; GGData: TYPE = GGInterfaceTypes.GGData; HistoryEvent: TYPE = GGHistoryTypes.HistoryEvent; Joint: TYPE = GGModelTypes.Joint; MouseButton: TYPE = Menus.MouseButton; MouseProc: TYPE = GGMouseEvent.MouseProc; Point: TYPE = GGBasicTypes.Point; RefreshDataObj: PUBLIC TYPE = GGRefreshTypes.RefreshDataObj; ROPE: TYPE = Rope.ROPE; Scene: TYPE = GGModelTypes.Scene; Segment: TYPE = GGSegmentTypes.Segment; SelectMode: TYPE = GGModelTypes.SelectMode; Sequence: TYPE = GGModelTypes.Sequence; Slice: TYPE = GGModelTypes.Slice; SliceClass: TYPE = GGModelTypes.SliceClass; SliceDescriptor: TYPE = GGModelTypes.SliceDescriptor; SliceDescriptorGenerator: TYPE = GGModelTypes.SliceDescriptorGenerator; SliceGenerator: TYPE = GGModelTypes.SliceGenerator; SliceParts: TYPE = GGModelTypes.SliceParts; StartProc: TYPE = GGMouseEvent.StartProc; TouchGroup: TYPE = GGSegmentTypes.TouchGroup; Traj: TYPE = GGModelTypes.Traj; TrajData: TYPE = GGModelTypes.TrajData; TrajEnd: TYPE = GGModelTypes.TrajEnd; TrajParts: TYPE = GGModelTypes.TrajParts; TrajPartType: TYPE = GGModelTypes.TrajPartType; TriggerBag: TYPE = GGAlign.TriggerBag; UserInputProc: TYPE = GGUserInput.UserInputProc; Vector: TYPE = GGBasicTypes.Vector; Problem: SIGNAL [msg: Rope.ROPE] = Feedback.Problem; SetCaretAttractorEndpoint: PUBLIC PROC [ggData: GGData, mapPoint: Point, normal: Vector, testPoint: Point, feature: FeatureData, hitData: REF ANY] = { IF feature=NIL THEN GGCaret.SetAttractor[ggData.caret, mapPoint, normal, NIL] ELSE { shape: REF ANY ¬ feature.shape; SELECT feature.type FROM slice => { pos: Point; sliceD: SliceDescriptor ¬ NARROW[shape]; jointD: SliceDescriptor; [jointD, pos, normal] ¬ GGSliceOps.ClosestJointToHitData[sliceD, mapPoint, testPoint, hitData]; IF Vectors2d.MagnitudeSquared[normal] = 0 THEN { normal ¬ [0, -1];}; GGCaret.SetAttractor[ggData.caret, pos, normal, jointD]; }; ENDCASE => GGCaret.SetAttractor[ggData.caret, mapPoint, normal, NIL]; }; }; <> SetStrokeColorRemote: PUBLIC PROC [ggData: GGData, sliceD: SliceDescriptor] RETURNS [doNormalBehavior: BOOL ¬ FALSE, done: BOOL ¬ FALSE] = { theirData: GGData ¬ GGState.GetGGInputFocus[]; theirScene: Scene; ourColor: Imager.Color; success: BOOL ¬ FALSE; IF theirData = NIL THEN { Feedback.Append[ggData.router, oneLiner, $Complaint, "SetStrokeColorRemote failed: Place input focus in a Gargoyle viewer"]; RETURN; } <> <> <> <<}>> ELSE theirScene ¬ theirData.scene; [ourColor, success] ¬ GGSliceOps.GetStrokeColor[sliceD.slice, sliceD.parts]; IF success THEN { GGEvent.LineColorAux[theirData, ourColor, GGDescribe.ColorToRope[ourColor], TRUE, $Set]; SendColorToColorTool[ggData, ourColor]; } ELSE { Feedback.Append[ggData.router, oneLiner, $Complaint, "SetStrokeColorRemote: Select an object with a unique stroke color"]; }; }; SetFillColorRemote: PUBLIC PROC [ggData: GGData, sliceD: SliceDescriptor] RETURNS [doNormalBehavior: BOOL ¬ FALSE, done: BOOL ¬ FALSE] = { theirData: GGData ¬ GGState.GetGGInputFocus[]; theirScene: Scene; ourColor: Imager.Color; success: BOOL ¬ FALSE; IF theirData = NIL THEN { Feedback.Append[ggData.router, oneLiner, $Complaint, "SetFillColorRemote failed: Place input focus in a Gargoyle viewer"]; RETURN; } <> <> <> <<}>> ELSE theirScene ¬ theirData.scene; [ourColor, success] ¬ GGSliceOps.GetFillColor[sliceD.slice, sliceD.parts]; IF success THEN { GGEvent.AreaColorAux[theirData, ourColor, GGDescribe.ColorToRope[ourColor], TRUE, $Set]; SendColorToColorTool[ggData, ourColor]; } ELSE { Feedback.Append[ggData.router, oneLiner, $Complaint, "SetFillColorRemote failed: Select an object with a unique fill color"]; }; }; LocalSymbols: TYPE = REF LocalSymbolsObj; LocalSymbolsObj: TYPE = RECORD [ sliceD: SliceDescriptor, rotation: ImagerTransformation.Transformation, ggData: GGData, currentEvent: HistoryEvent ]; SendColorToColorTool: PROC [ggData: GGData, color: Color] = { IF Basics.IsBound[ColorTool.SetColor] THEN { IF color=NIL THEN Feedback.Append[ggData.router, oneLiner, $Complaint, "NIL fill colornot sent to ColorTool"] ELSE { noColorTool: BOOL ¬ FALSE; ColorTool.SetColor[color, NIL ! ColorTool.NoColorToolViewer => { noColorTool ¬ TRUE; CONTINUE }]; }; }; }; <<>> <> <<>> StartSelect: PUBLIC StartProc = { SELECT input.first FROM $StartSelectJoint => ggData.drag.selectState ¬ joint; $StartSelectSegment => ggData.drag.selectState ¬ segment; $StartSelectTrajectory => ggData.drag.selectState ¬ traj; $StartSelectTopLevel => ggData.drag.selectState ¬ topLevel; ENDCASE => ERROR; IF NOT GGRefresh.EmptyOverlay[ggData] THEN ERROR; GGMouseEvent.SaveSavedState[ggData]; DuringSelect[NIL, ggData, worldPt]; }; DuringSelect: PUBLIC MouseProc = { <> opRope: Rope.ROPE = "Selecting"; resultPoint: Point; normal: Vector; feature: FeatureData; hitData: REF ANY; CodeTimer.StartInt[$DuringSelect, $Gargoyle]; GGRefresh.SetStartBox[ggData: ggData, dragInProgress: FALSE, caret: TRUE, selectedCPs: TRUE, attractor: TRUE]; SELECT GGState.GetSelectMode[ggData] FROM joint => [resultPoint, normal, feature, hitData] ¬ GGMultiGravity.PointsPreferred[worldPt, ggData.hitTest.t, GGAlign.emptyAlignBag, ggData.hitTest.sceneBag, ggData, FALSE]; segment, segmentRange => [resultPoint, normal, feature, hitData] ¬ GGMultiGravity.LinesPreferred[worldPt, ggData.hitTest.t, GGAlign.emptyAlignBag, ggData.hitTest.sceneBag, ggData]; traj, topLevel, slice => [resultPoint, normal, feature, hitData] ¬ GGMultiGravity.FacesPreferred[worldPt, ggData.hitTest.t, GGAlign.emptyAlignBag, ggData.hitTest.sceneBag, ggData]; none => { resultPoint ¬ worldPt; normal ¬ [0, -1]; feature ¬ NIL; hitData ¬ NIL; }; ENDCASE => ERROR; GGMouseEvent.SetCaretAttractorEndpoint[ggData, resultPoint, normal, worldPt, feature, hitData]; GGSelect.DeselectAll[ggData.scene, normal]; IF feature#NIL THEN [] ¬ SelectAndDescribeSlicePart[feature, hitData, ggData, ggData.drag.selectState, opRope] ELSE Feedback.PutF[ggData.router, oneLiner, $DuringMouse, "%g nothing", [rope[opRope]]]; GGWindow.RestoreScreenAndInvariants[paintAction: $DuringSelect, ggData: ggData, remake: none, edited: FALSE, selectionChanged: TRUE, okToSkipCapture: TRUE]; CodeTimer.StopInt[$DuringSelect, $Gargoyle]; }; -- end DuringSelect EndSelect: PUBLIC MouseProc = { resultPoint: Point; normal: Vector; feature: FeatureData; hitData: REF ANY; featureCycler: GGInterfaceTypes.FeatureCycler; SELECT GGState.GetSelectMode[ggData] FROM joint => featureCycler ¬ GGMultiGravity.PointsPreferredCycler[worldPt, ggData.hitTest.t, GGAlign.emptyAlignBag, ggData.hitTest.sceneBag, ggData, FALSE]; segment => featureCycler ¬ GGMultiGravity.LinesPreferredCycler[worldPt, ggData.hitTest.t, GGAlign.emptyAlignBag, ggData.hitTest.sceneBag, ggData]; ENDCASE => featureCycler ¬ GGMultiGravity.FacesPreferredCycler[worldPt, ggData.hitTest.t, GGAlign.emptyAlignBag, ggData.hitTest.sceneBag, ggData]; GGState.SetSelectionCycler[ggData, featureCycler]; [resultPoint, normal, feature, hitData] ¬ GGMultiGravity.FirstFeature[featureCycler]; <> GGMouseEvent.SetCaretAttractorEndpoint[ggData, resultPoint, normal, worldPt, feature, hitData]; GGWindow.NewCaretPos[ggData]; <> GGSelect.DeselectAll[ggData.scene, normal]; <> EndSelectAux[ggData, resultPoint, feature, hitData, ggData.drag.selectState, RopeFromSelectMode[ggData.drag.selectState]]; <