<> <> <> <> <> <<>> DIRECTORY AtomButtons, AtomButtonsTypes, BasicTime, CodeTimer, ColorTool, CubicSplines, Feedback, FS, GGAlign, GGBasicTypes, GGBoundBox, GGBuiltinShapes, GGCaret, GGEvent, GGInterface, GGInterfaceTypes, GGModelTypes, GGOutline, GGParseIn, GGRefresh, GGScene, GGSegment, GGSegmentTypes, GGSelect, GGSequence, GGSlice, GGState, GGTraj, GGTransform, GGUtility, GGWindow, Imager, ImagerArtwork, ImagerInterpress, ImagerTransformation, IO, List, Rope, TiogaMenuOps, TIPUser, Vectors2d, ViewerClasses, ViewerOps, ViewerTools; GGEventImplC: CEDAR PROGRAM IMPORTS BasicTime, CodeTimer, ColorTool, Feedback, FS, GGAlign, GGBoundBox, GGBuiltinShapes, GGCaret, GGEvent, GGInterface, GGOutline, GGParseIn, GGRefresh, GGScene, GGSegment, GGSelect, GGSequence, GGSlice, GGState, GGTraj, GGTransform, GGUtility, GGWindow, Imager, ImagerArtwork, ImagerInterpress, ImagerTransformation, IO, List, Rope, TiogaMenuOps, TIPUser, Vectors2d, ViewerOps, ViewerTools EXPORTS GGEvent = BEGIN BitVector: TYPE = GGModelTypes.BitVector; BoundBox: TYPE = GGModelTypes.BoundBox; ControlPointGenerator: TYPE = GGModelTypes.ControlPointGenerator; EntityGenerator: TYPE = GGModelTypes.EntityGenerator; GGData: TYPE = GGInterfaceTypes.GGData; Joint: TYPE = GGSegmentTypes.Joint; JointGenerator: TYPE = GGModelTypes.JointGenerator; Outline: TYPE = GGModelTypes.Outline; OutlineDescriptor: TYPE = GGModelTypes.OutlineDescriptor; Point: TYPE = GGBasicTypes.Point; ScalarButtonClient: TYPE = AtomButtons.ScalarButtonClient; ScalarButtonHandle: TYPE = AtomButtons.ScalarButtonHandle; Scene: TYPE = GGModelTypes.Scene; Segment: TYPE = GGSegmentTypes.Segment; SegmentGenerator: TYPE = GGModelTypes.SegmentGenerator; Sequence: TYPE = GGModelTypes.Sequence; SequenceGenerator: TYPE = GGModelTypes.SequenceGenerator; Slice: TYPE = GGModelTypes.Slice; SliceDescriptor: TYPE = GGModelTypes.SliceDescriptor; SliceDescriptorGenerator: TYPE = GGModelTypes.SliceDescriptorGenerator; SliceGenerator: TYPE = GGModelTypes.SliceGenerator; SliceParts: TYPE = GGModelTypes.SliceParts; Traj: TYPE = GGModelTypes.Traj; TrajEnd: TYPE = GGModelTypes.TrajEnd; TrajGenerator: TYPE = GGModelTypes.TrajGenerator; TrajPartType: TYPE = GGModelTypes.TrajPartType; TwoState: TYPE = AtomButtons.TwoState; Vector: TYPE = GGBasicTypes.Vector; Viewer: TYPE = ViewerClasses.Viewer; WalkProc: TYPE = GGModelTypes.WalkProc; <> SetGravityExtent: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; graphicsState: AtomButtonsTypes.GraphicsState _ ggData.hitTest.gravityExtentButton; inches: REAL _ NARROW[event.rest.first, REF REAL]^; GGWindow.SetGravityExtent[ggData, inches]; }; SetShowColors: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; boolRope: Rope.ROPE _ NARROW[event.rest.first]; showColors: BOOL _ GGUtility.RopeToBool[boolRope]; GGState.SetShowColors[ggData, showColors]; }; SetGravity: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; boolRope: Rope.ROPE _ NARROW[event.rest.first]; setGravity: BOOL _ GGUtility.RopeToBool[boolRope]; GGState.SetGravity[ggData, setGravity]; }; SetMidpoints: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; boolRope: Rope.ROPE _ NARROW[event.rest.first]; setMidpoints: BOOL _ GGUtility.RopeToBool[boolRope]; GGState.SetMidpoints[ggData, setMidpoints]; }; SetHeuristics: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; boolRope: Rope.ROPE _ NARROW[event.rest.first]; setHeuristics: BOOL _ GGUtility.RopeToBool[boolRope]; GGState.SetHeuristics[ggData, setHeuristics]; }; SetDefaultFont: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; fontRope: Rope.ROPE _ NARROW[event.rest.first]; <> }; <> PolygonInCircle: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { outline: Outline; bBox: BoundBox; ggData: GGData _ NARROW[clientData]; caretPoint: Point _ GGCaret.GetPoint[ggData.caret]; sideCount: INT _ NARROW[event.rest.first, REF INT]^; IF sideCount=-1 THEN { rRope: Rope.ROPE _ ViewerTools.GetSelectionContents[]; sideCount _ IO.GetInt[IO.RIS[rRope] ! IO.EndOfStream, IO.Error => sideCount _ -1]; }; IF sideCount<=0 THEN RETURN; outline _ GGBuiltinShapes.PolygonInCircle[sideCount, caretPoint, ggData.hitTest.scaleUnit, ggData.defaults]; GGScene.AddOutline[ggData.scene, outline, -1]; GGSelect.DeselectAll[ggData.scene, normal]; GGSelect.SelectEntireSlice[outline, ggData.scene, normal]; bBox _ GGBoundBox.BoundBoxOfSelected[ggData.scene, normal]; ggData.refresh.startBoundBox^ _ bBox^; ggData.refresh.addedObject _ outline; GGWindow.RestoreScreenAndInvariants[paintAction: $ObjectAdded, ggData: ggData, remake: sceneBag, backgndOK: FALSE, edited: TRUE, okToClearFeedback: TRUE]; }; NewBox: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { slice: Slice; sliceParts: SliceDescriptor; bBox: BoundBox; ggData: GGData _ NARROW[clientData]; caretPoint: Point _ GGCaret.GetPoint[ggData.caret]; sideLength: REAL _ NARROW[event.rest.first, REF REAL]^; slice _ GGBuiltinShapes.Box[caretPoint, sideLength*ggData.hitTest.scaleUnit, ggData.defaults]; GGScene.AddSlice[ggData.scene, slice, -1]; GGSelect.DeselectAll[ggData.scene, normal]; sliceParts _ slice.class.newParts[slice, NIL, slice]; GGSelect.SelectSlice[sliceParts, ggData.scene, normal]; bBox _ GGBoundBox.BoundBoxOfSelected[ggData.scene, normal]; ggData.refresh.startBoundBox^ _ bBox^; ggData.refresh.addedObject _ slice; GGWindow.RestoreScreenAndInvariants[paintAction: $ObjectAdded, ggData: ggData, remake: sceneBag, backgndOK: FALSE, edited: TRUE, okToClearFeedback: TRUE]; }; NewCircle: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { slice: Slice; sliceParts: SliceDescriptor; bBox: BoundBox; ggData: GGData _ NARROW[clientData]; caretPoint: Point _ GGCaret.GetPoint[ggData.caret]; radius: REAL _ NARROW[event.rest.first, REF REAL]^; slice _ GGBuiltinShapes.Circle[caretPoint, radius*ggData.hitTest.scaleUnit, ggData.defaults]; GGScene.AddSlice[ggData.scene, slice, -1]; GGSelect.DeselectAll[ggData.scene, normal]; sliceParts _ slice.class.newParts[slice, NIL, slice]; GGSelect.SelectSlice[sliceParts, ggData.scene, normal]; bBox _ GGBoundBox.BoundBoxOfSelected[ggData.scene, normal]; ggData.refresh.startBoundBox^ _ bBox^; ggData.refresh.addedObject _ slice; GGWindow.RestoreScreenAndInvariants[paintAction: $ObjectAdded, ggData: ggData, remake: sceneBag, backgndOK: FALSE, edited: TRUE, okToClearFeedback: TRUE]; }; NewKnotchedLine: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { outline: Outline; bBox: BoundBox; ggData: GGData _ NARROW[clientData]; caretPoint: Point _ GGCaret.GetPoint[ggData.caret]; length: REAL _ NARROW[event.rest.first, REF REAL]^; segCount: INT _ NARROW[event.rest.rest.first, REF INT]^; p1: Point; p1 _ Vectors2d.Add[caretPoint, [length*ggData.hitTest.scaleUnit, 0.0]]; outline _ GGBuiltinShapes.KnotchedLine[p0: caretPoint, p1: p1, segmentCount: segCount]; GGScene.AddOutline[ggData.scene, outline, -1]; GGSelect.DeselectAll[ggData.scene, normal]; GGSelect.SelectEntireSlice[outline, ggData.scene, normal]; bBox _ GGBoundBox.BoundBoxOfSelected[ggData.scene, normal]; ggData.refresh.startBoundBox^ _ bBox^; ggData.refresh.addedObject _ outline; GGWindow.RestoreScreenAndInvariants[paintAction: $ObjectAdded, ggData: ggData, remake: sceneBag, backgndOK: FALSE, edited: TRUE, okToClearFeedback: TRUE]; }; NewArrow: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { OPEN Vectors2d; outline: Outline; traj: Traj; seg: Segment; bBox: BoundBox; success: BOOL; ggData: GGData _ NARROW[clientData]; shaftLength: REAL _ NARROW[event.rest.first, REF REAL]^; barbLength: REAL _ NARROW[event.rest.rest.first, REF REAL]^; shaftBottom, shaftTop, barbLeft, barbRight: Point; shaftBottom _ GGCaret.GetPoint[ggData.caret]; shaftLength _ shaftLength * ggData.hitTest.scaleUnit; -- convert to screen dots. barbLength _ barbLength * ggData.hitTest.scaleUnit; -- convert to screen dots. shaftTop _ Add[shaftBottom, [0.0, shaftLength]]; barbLeft _ Add[shaftBottom, Scale[Normalize[[-1.0,1.0]], barbLength]]; barbRight _ Add[shaftBottom, Scale[Normalize[[1.0,1.0]], barbLength]]; traj _ GGTraj.CreateTraj[shaftTop]; seg _ GGSegment.MakeLine[shaftTop, shaftBottom, NIL]; success _ GGTraj.AddSegment[traj, hi, seg, lo]; IF NOT success THEN ERROR; seg _ GGSegment.MakeLine[shaftBottom, barbLeft, NIL]; success _ GGTraj.AddSegment[traj, hi, seg, lo]; IF NOT success THEN ERROR; seg _ GGSegment.MakeLine[barbLeft, shaftBottom, NIL]; success _ GGTraj.AddSegment[traj, hi, seg, lo]; IF NOT success THEN ERROR; seg _ GGSegment.MakeLine[shaftBottom, barbRight, NIL]; success _ GGTraj.AddSegment[traj, hi, seg, lo]; IF NOT success THEN ERROR; outline _ GGOutline.CreateOutline[traj: traj, fillColor: Imager.black]; GGScene.AddOutline[ggData.scene, outline, -1]; GGSelect.DeselectAll[ggData.scene, normal]; GGSelect.SelectEntireSlice[outline, ggData.scene, normal]; bBox _ GGBoundBox.BoundBoxOfSelected[ggData.scene, normal]; ggData.refresh.startBoundBox^ _ bBox^; ggData.refresh.addedObject _ outline; GGWindow.RestoreScreenAndInvariants[paintAction: $ObjectAdded, ggData: ggData, remake: sceneBag, backgndOK: FALSE, edited: TRUE, okToClearFeedback: TRUE]; }; Frame: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { <> ggData: GGData _ NARROW[clientData]; halfStrokeWidth: REAL = 9.0/2.0; frameWidth: REAL _ NARROW[event.rest.first, REF REAL]^; -- in Gargoyle units (points) frameLength: REAL _ NARROW[event.rest.rest.first, REF REAL]^; -- in Gargoyle units (points) box: GGBoundBox.BoundBox _ GGBoundBox.CreateBoundBox[0.0-halfStrokeWidth, 0.0-halfStrokeWidth, frameWidth+halfStrokeWidth, frameLength+halfStrokeWidth]; sliceD: SliceDescriptor _ GGSlice.MakeBoxSlice[box, none, GGTransform.Identity[]]; [] _ sliceD.slice.class.setStrokeWidth[sliceD.slice, sliceD.parts, 9.0]; GGScene.AddSlice[ggData.scene, sliceD.slice, -1]; ggData.refresh.startBoundBox^ _ sliceD.slice.boundBox^; ggData.refresh.addedObject _ sliceD.slice; GGWindow.RestoreScreenAndInvariants[paintAction: $ObjectAdded, ggData: ggData, remake: sceneBag, backgndOK: FALSE, edited: TRUE, okToClearFeedback: TRUE]; }; <<>> <> ApplyAllDefaults: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; bBox: BoundBox; sliceDescGen: SliceDescriptorGenerator; IF GGSelect.NoSelections[ggData.scene, normal] THEN RETURN; bBox _ GGBoundBox.BoundBoxOfSelected[ggData.scene, normal]; sliceDescGen _ GGSelect.SelectedSlices[ggData.scene, normal]; FOR sliceD: SliceDescriptor _ GGSelect.NextSliceDescriptor[sliceDescGen], GGSelect.NextSliceDescriptor[sliceDescGen] UNTIL sliceD=NIL DO sliceD.slice.class.setDefaults[sliceD.slice, sliceD.parts, ggData.defaults]; ENDLOOP; GGBoundBox.EnlargeByBox[bBox: bBox, by: GGBoundBox.BoundBoxOfSelected[ggData.scene, normal]]; ggData.refresh.startBoundBox^ _ bBox^; GGWindow.RestoreScreenAndInvariants[paintAction: $ObjectChangedBoundBoxProvided, ggData: ggData, remake: none, backgndOK: FALSE, edited: TRUE, okToClearFeedback: FALSE]; }; SetAllDefaults: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { <> <> <> <> <> }; ShowAllDefaults: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; Feedback.AppendTypescript[ggData.feedback, "--------------------------------------------", oneLiner]; GGEvent.ShowDefaultFontValues[clientData, event]; GGEvent.ShowDefaultLineColor[clientData, event]; GGEvent.ShowDefaultFillColor[clientData, event]; GGEvent.ShowDefaultStrokeValues[clientData, event]; Feedback.AppendTypescript[ggData.feedback, "--------------------------------------------", oneLiner]; }; StandardDefaults: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; ggData.defaults^ _ [ strokeWidth: 2.0, strokeJoint: round, strokeEnd: round, dashed: FALSE, pattern: NIL, offset: 0.0, length: 0.0, strokeColor: Imager.black, fillColor: GGOutline.fillColor, font: ggData.defaults.font ]; ShowAllDefaults[clientData, event]; }; Weld: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; <> outSeqGen: GGSelect.OutlineSequenceGenerator; firstTraj, secondTraj, newTraj: Traj; firstOutline, secondOutline, newOutline: Outline; firstOutSeq, secondOutSeq: GGSelect.OutlineSequence; weldPoint: Point; firstEnd, secondEnd: TrajEnd; firstBox, secondBox, newBox: BoundBox; success: BOOL; outSeqGen _ GGSelect.SelectedOutlineSequences[ggData.scene, normal]; [firstOutSeq, secondOutSeq, firstTraj, secondTraj, success] _ GetWeldArguments[ggData, outSeqGen]; IF NOT success THEN RETURN; IF secondOutSeq = NIL THEN {WeldToSelf[ggData, firstTraj]; RETURN;}; [firstEnd, secondEnd] _ ClosestEnds[firstTraj, secondTraj]; firstOutline _ GGOutline.OutlineOfTraj[firstTraj]; secondOutline _ GGOutline.OutlineOfTraj[secondTraj]; <> newTraj _ GGTraj.Concat[firstTraj, firstEnd, secondTraj, secondEnd]; newOutline _ GGOutline.CreateOutline[newTraj, firstOutline.class.getFillColor[firstOutline]]; GGInterface.DeleteOutline[firstOutline, ggData.scene]; GGInterface.DeleteOutline[secondOutline, ggData.scene]; GGScene.AddOutline[ggData.scene, newOutline, -1]; <> AreaSelectAux[ggData, TRUE, TRUE]; }; AreaSelectExtend: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; <> AreaSelectAux[ggData, FALSE, TRUE]; }; <> <> <> IF GGSelect.NoSelections[ggData.scene, normal] THEN RETURN ELSE { -- there were some original selections oldSelectedGen: SliceDescriptorGenerator _ GGSelect.SelectedSlices[ggData.scene, normal]; -- save original selection startBox: BoundBox _ GGBoundBox.BoundBoxOfSelected[ggData.scene, normal]; AreaSelectAux[ggData: ggData, new: TRUE, paint: FALSE]; FOR sliceD: SliceDescriptor _ GGSelect.NextSliceDescriptor[oldSelectedGen], GGSelect.NextSliceDescriptor[oldSelectedGen] UNTIL sliceD=NIL DO GGSelect.DeselectEntityAllClasses[sliceD.slice, ggData.scene]; GGScene.DeleteSlice[ggData.scene, sliceD.slice]; ENDLOOP; GGCaret.NoAttractor[ggData.caret]; GGCaret.SitOn[ggData.caret, NIL]; ggData.refresh.startBoundBox^ _ startBox^; GGWindow.RestoreScreenAndInvariants[paintAction: $ObjectChangedBoundBoxProvided, ggData: ggData, remake: triggerBag, backgndOK: TRUE, edited: FALSE, okToClearFeedback: TRUE]; }; }; AreaSelectDegenerate: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; <> sliceGen: SliceGenerator _ GGScene.SlicesInScene[ggData.scene]; GGSelect.DeselectAll[ggData.scene, normal]; FOR slice: Slice _ GGScene.NextSlice[sliceGen], GGScene.NextSlice[sliceGen] UNTIL slice = NIL DO -- for every slice in the scene DegenerateProc: WalkProc = { <> RETURN [seg.lo.x=seg.hi.x AND seg.lo.y=seg.hi.y]; }; sliceD: SliceDescriptor _ GGSlice.WalkSegments[slice, DegenerateProc]; -- get a descriptor of degenerate (zero length) segments IF sliceD#NIL THEN GGSelect.SelectSlice[sliceD, ggData.scene, normal]; -- and select it IF GGSlice.IsWhitespace[slice] THEN GGSelect.SelectEntireSlice[slice, ggData.scene, normal]; ENDLOOP; Feedback.PutFHerald[ggData.feedback, oneLiner, "Degenerate segments and strings selected"]; GGWindow.RestoreScreenAndInvariants[paintAction: $SelectionChanged, ggData: ggData, remake: none, backgndOK: TRUE, edited: FALSE, okToClearFeedback: TRUE]; }; <> <> <= bound.loX AND test.hiY <= bound.hiY AND test.loY >= bound.loY ];>> <<};>> <> <> <> <> <> <> <> <> <> <> < {>> <> <> <<};>> < {>> <> <> <<};>> < ERROR;>> <> <> <> <> <> <> < {>> <> <> <<};>> <<};>> < {>> <> <> <<};>> <<};>> < ERROR;>> <> <> <> <<}; -- end AreaSelectAux>> <<>> AreaSelectAux: PROC [ggData: GGData, new: BOOL _ TRUE, paint: BOOL _ TRUE] = { Within: PROC [test, bound: GGBoundBox.BoundBox] RETURNS [BOOL] = { RETURN [ test.hiX <= bound.hiX AND test.loX >= bound.loX AND test.hiY <= bound.hiY AND test.loY >= bound.loY ]; }; selectedGen: SliceDescriptorGenerator; sceneGen: SliceGenerator; IF GGSelect.NoSelections[ggData.scene, normal] THEN RETURN; selectedGen _ GGSelect.SelectedSlices[ggData.scene, normal]; IF new THEN GGSelect.DeselectAll[ggData.scene, normal]; -- get rid of old selection <> FOR sliceD: SliceDescriptor _ GGSelect.NextSliceDescriptor[selectedGen], GGSelect.NextSliceDescriptor[selectedGen] UNTIL sliceD=NIL DO sBox: BoundBox _ sliceD.slice.class.getBoundBox[sliceD.slice, sliceD.parts]; <> sceneGen _ GGScene.TopLevelSlicesInScene[ggData.scene]; FOR next: Slice _ GGScene.NextSlice[sceneGen], GGScene.NextSlice[sceneGen] UNTIL next=NIL DO IF next=sliceD.slice THEN LOOP; IF NOT GGSelect.IsSelectedInFull[next, ggData.scene, normal] AND Within[next.class.getBoundBox[next, NIL], sBox] THEN GGSelect.SelectEntireSlice[next, ggData.scene, normal]; ENDLOOP; ENDLOOP; IF paint THEN GGWindow.RestoreScreenAndInvariants[paintAction: $SelectionChanged, ggData: ggData, remake: none, backgndOK: TRUE, edited: FALSE, okToClearFeedback: TRUE]; }; -- end AreaSelectAux <<>> <> StuffIt: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { StuffItAux[event, clientData, print]; }; StuffItScreen: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { StuffItAux[event, clientData, screen]; }; StuffItAux: PROC [event: LIST OF REF ANY, clientData: REF ANY, displayStyle: GGInterfaceTypes.DisplayStyle] = { <> DoStuff: PROC [context: Imager.Context] = { DoIt: PROC = { tempQuality: GGInterfaceTypes.QualityMode _ ggData.camera.quality; tempStyle: GGInterfaceTypes.DisplayStyle _ ggData.camera.displayStyle; ggData.camera.quality _ quality; ggData.camera.displayStyle _ displayStyle; context.TranslateT[t: [-bRect.x, -bRect.y]]; GGRefresh.InterpressEntireScene[context, ggData]; ggData.camera.quality _ tempQuality; ggData.camera.displayStyle _ tempStyle; }; Imager.DoSaveAll[context, DoIt]; }; ggData: GGData _ NARROW[clientData]; bRect: Imager.Rectangle _ GGBoundBox.RectangleFromBoundBox[GGBoundBox.BoundBoxOfSelected[ggData.scene, normal] ]; IF GGSelect.NoSelections[ggData.scene, normal] THEN { Feedback.AppendHerald[ggData.feedback, "Select some objects for stuffing", oneLiner]; Feedback.Blink[ggData.feedback]; } ELSE { ImagerArtwork.PasteArtwork[action: DoStuff, bounds: [0.0, 0.0, bRect.w, bRect.h], m: ImagerArtwork.Points[], clip: TRUE]; }; }; Refresh: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; doNotClear: BOOL _ event#NIL AND event.rest#NIL AND event.rest.first=$DoNotClearFeedback; GGWindow.RestoreScreenAndInvariants[paintAction: $PaintEntireScene, ggData: ggData, remake: none, backgndOK: FALSE, edited: FALSE, okToClearFeedback: NOT doNotClear]; }; OpenTypescript: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; [] _ Feedback.OpenTypescript["Gargoyle Typescript", $Gargoyle, 120]; }; Help: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; category: ATOM _ NARROW[event.rest.first]; openHeight: INTEGER _ 140; help: ViewerClasses.Viewer; name: Rope.ROPE; SELECT category FROM $MouseActions => {name _ "GGHelp.Tioga"; openHeight _ 140}; $Fonts => {name _ "GGFontSampler.Tioga"; openHeight _ 210}; ENDCASE => {name _ "GargoyleDoc.Tioga"; openHeight _ 115}; IF (help _ ViewerOps.FindViewer[FS.ExpandName[name, ggData.originalWDir].fullFName])#NIL THEN { -- viewer already exists IF help.column#right THEN ViewerOps.ChangeColumn[help, right]; } ELSE { help _ ViewerOps.CreateViewer[flavor: $Text, info: [iconic: TRUE, column: right, openHeight: openHeight], paint: FALSE]; TiogaMenuOps.Load[viewer: help, fileName: Rope.Concat[ggData.originalWDir, name]]; }; ViewerOps.SetOpenHeight[viewer: help, clientHeight: openHeight]; ViewerOps.OpenIcon[icon: help, bottom: FALSE, paint: FALSE]; -- must do Open before Top ViewerOps.TopViewer[viewer: help, paint: FALSE]; ViewerOps.ComputeColumn[right]; -- repaint right column }; <<>> <> IPSnapShot: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; <> <> <> DoMakeInterpress: PROC [dc: Imager.Context] = { Imager.ScaleT[dc, pixelsPerMeter]; tempStyle _ ggData.camera.displayStyle; ggData.camera.displayStyle _ print; GGRefresh.SnapShot[dc, ggData]; ggData.camera.displayStyle _ tempStyle; }; tempStyle: GGInterfaceTypes.DisplayStyle; ipRef: ImagerInterpress.Ref; fullName: Rope.ROPE; success: BOOL; pixelsPerMeter: REAL = 0.0254/72.0; startTime: BasicTime.GMT; endTime: BasicTime.GMT; totalTime: INT; msgRope: Rope.ROPE; [fullName, success] _ GGUtility.GetInterpressFileName["snapshot.ip", ggData.currentWDir, ggData.feedback]; IF NOT success THEN RETURN; ipRef _ ImagerInterpress.Create[fullName]; msgRope _ IO.PutFR["Writing to IP file: %g . . . ", [rope[fullName]]]; Feedback.Append[ggData.feedback, msgRope, begin]; startTime _ BasicTime.Now[]; ImagerInterpress.DoPage[ipRef, DoMakeInterpress, 1.0]; ImagerInterpress.Close[ipRef]; endTime _ BasicTime.Now[]; totalTime _ BasicTime.Period[startTime, endTime]; msgRope _ IO.PutFR[" Done in time (%r)", [integer[totalTime]]]; Feedback.Append[ggData.feedback, msgRope, end]; }; <> ReloadTipTable: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; newTable: TIPUser.TIPTable; actionArea: ViewerClasses.Viewer; bad: BOOL _ FALSE; tableName, msg: Rope.ROPE; Feedback.Append[ggData.feedback, "Reloading tip table...", begin]; tableName _ Rope.Concat[ggData.originalWDir, "Gargoyle.TIP"]; newTable _ TIPUser.InstantiateNewTIPTable[tableName ! FS.Error => { bad _ TRUE; msg _ Rope.Concat["Cannot read TIP table file: ", tableName]; CONTINUE}; TIPUser.InvalidTable => { bad _ TRUE; msg _ Rope.Concat["Error(s) saved on TIP.Errors for: ", tableName]; CONTINUE}]; IF bad THEN {Feedback.Append[ggData.feedback, msg, oneLiner]; RETURN}; Feedback.Append[ggData.feedback, "Done.", end]; IF newTable = NIL THEN ERROR; actionArea _ ggData.actionArea; actionArea.tipTable _ newTable; }; tryIncrementalUpdate: BOOL _ TRUE; SawTextFinish: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; slice: Slice _ ggData.refresh.textInProgress; CodeTimer.StartInt[$SawTextFinish, $Gargoyle]; IF slice#NIL AND Rope.Length[GGSlice.GetText[slice: slice]]=0 THEN { -- backspaced to nothing GGSelect.DeselectEntityAllClasses[slice, ggData.scene]; GGScene.DeleteSlice[ggData.scene, slice]; }; IF ggData.refresh.textInProgress#NIL THEN { -- fix up alignment triggers IF tryIncrementalUpdate THEN GGAlign.UpdateBagsForNewSlices[LIST[slice], ggData] -- the text is not necessarily new, but I believe this will work anyway. Bier, April 20, 1987 ELSE GGWindow.RestoreScreenAndInvariants[paintAction: $NewAlignmentsSelected, ggData: ggData, remake: triggerBag, backgndOK: FALSE, edited: TRUE, okToClearFeedback: FALSE]; ggData.refresh.textInProgress _ NIL; -- terminates typed input }; <> IF ggData.refresh.areaFollowColorTool THEN { GGEvent.AreaColorFromColorTool[clientData, event]; ColorTool.RemoveProc[$GG, ViewerOps.FindViewer["ColorTool"]]; ggData.refresh.areaFollowColorTool _ FALSE; }; IF ggData.refresh.lineFollowColorTool THEN { GGEvent.LineColorFromColorTool[clientData, event]; ColorTool.RemoveProc[$GG, ViewerOps.FindViewer["ColorTool"]]; ggData.refresh.lineFollowColorTool _ FALSE; }; CodeTimer.StopInt[$SawTextFinish, $Gargoyle]; }; PrintRope: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; rope: Rope.ROPE _ NARROW[event.rest.first]; Feedback.Append[feedback: ggData.feedback, msg: rope, msgType: oneLiner] }; InitStats: PROC [] = { interval: CodeTimer.Interval; interval _ CodeTimer.CreateInterval[$AddChar]; CodeTimer.AddInt[interval, $Gargoyle]; interval _ CodeTimer.CreateInterval[$SawTextFinish]; CodeTimer.AddInt[interval, $Gargoyle]; }; InitStats[]; END.