<> <> <> <> <> <<>> 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; <> 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.SelectEntireOutline[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.SelectEntireOutline[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.SelectEntireOutline[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; selectedGen: EntityGenerator; IF GGSelect.NoSelections[ggData.scene, normal] THEN RETURN; bBox _ GGBoundBox.BoundBoxOfSelected[ggData.scene, normal]; selectedGen _ GGSelect.SelectedStuff[ggData.scene, normal]; FOR next: REF ANY _ GGScene.NextEntity[selectedGen], GGScene.NextEntity[selectedGen] UNTIL next=NIL DO WITH next SELECT FROM outlineD: OutlineDescriptor => outlineD.slice.class.setDefaults[outlineD.slice, outlineD.parts, ggData.defaults]; sliceD: SliceDescriptor => sliceD.slice.class.setDefaults[sliceD.slice, sliceD.parts, ggData.defaults]; ENDCASE => ERROR; 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[traj: newTraj, fillColor: firstOutline.fillColor]; 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]; }; AreaSelectNewAndDelete: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { ggData: GGData _ NARROW[clientData]; <> trajGen: TrajGenerator _ GGScene.TrajsInScene[ggData.scene]; GGSelect.DeselectAll[ggData.scene, normal]; FOR traj: Traj _ GGScene.NextTraj[trajGen], GGScene.NextTraj[trajGen] UNTIL traj=NIL DO segGen: SegmentGenerator _ GGSequence.SegmentsInTraj[traj]; FOR next: GGSequence.SegAndIndex _ GGSequence.NextSegmentAndIndex[segGen], GGSequence.NextSegmentAndIndex[segGen] UNTIL next.seg=NIL DO IF next.seg.lo.x=next.seg.hi.x AND next.seg.lo.y=next.seg.hi.y THEN { seq: Sequence _ GGSequence.CreateFromSegments[traj, next.index, next.index]; GGSelect.SelectSequence[seq, ggData.scene, normal]; }; ENDLOOP; ENDLOOP; GGWindow.RestoreScreenAndInvariants[paintAction: $SelectionChanged, ggData: ggData, remake: none, backgndOK: TRUE, edited: FALSE, okToClearFeedback: TRUE]; }; 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: EntityGenerator; sceneGen: EntityGenerator; IF GGSelect.NoSelections[ggData.scene, normal] THEN RETURN; selectedGen _ GGSelect.SelectedStuff[ggData.scene, normal]; IF new THEN GGSelect.DeselectAll[ggData.scene, normal]; -- get rid of old selection <> FOR nextSelected: REF ANY _ GGScene.NextEntity[selectedGen], GGScene.NextEntity[selectedGen] UNTIL nextSelected=NIL DO sBox: BoundBox; currentEntity: REF ANY; WITH nextSelected SELECT FROM outlineD: OutlineDescriptor => { sBox _ outlineD.slice.class.getBoundBox[outlineD.slice, outlineD.parts]; currentEntity _ outlineD.slice; }; sliceD: SliceDescriptor => { sBox _ sliceD.slice.class.getBoundBox[sliceD.slice, sliceD.parts]; currentEntity _ sliceD.slice; }; ENDCASE => ERROR; <> sceneGen _ GGScene.TopLevelEntitiesInScene[ggData.scene]; FOR nextEntity: REF ANY _ GGScene.NextEntity[sceneGen], GGScene.NextEntity[sceneGen] UNTIL nextEntity=NIL DO IF nextEntity=currentEntity THEN LOOP; IF NOT GGSelect.IsSelectedInFull[nextEntity, ggData.scene, normal] THEN -- don't reprocess WITH nextEntity SELECT FROM outline: Outline => { IF Within[outline.class.getBoundBox[outline, NIL], sBox] THEN { GGSelect.SelectEntireOutline[outline, ggData.scene, normal]; }; }; slice: Slice => { IF Within[slice.class.getBoundBox[slice, NIL], sBox] THEN { GGSelect.SelectSlice[slice.class.newParts[slice, NIL, topLevel], ggData.scene, normal ]; }; }; ENDCASE => ERROR; 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]; GGSlice.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.