DIRECTORY BufferedRefresh, CoordSys, Cursors, Feedback, FileNames, FunctionCache, FS, Icons, Imager, Matrix3d, Menus, Rope, SlackProcess, SV2d, SV3d, SVAlign, SVBoundBox, SVCaret, SVDrawMonitor, SVGravity, SVInterfaceTypes, SVMeasure, SVMenus, SVModelTypes, SVMouseEvent, SVRefresh, SVScene, SVSceneTypes, SVSessionLog, SVState, SVTransforms, SVUserInput, SVVector3d, SVViewerTool, SVViewerTools, SVWindow, Terminal, TIPUser, ViewerClasses, ViewerOps; SVWindowImpl: CEDAR PROGRAM IMPORTS BufferedRefresh, CoordSys, Cursors, Feedback, FileNames, FunctionCache, FS, Icons, Imager, Matrix3d, Menus, Rope, SlackProcess, SVAlign, SVBoundBox, SVCaret, SVGravity, SVMeasure, SVMenus, SVMouseEvent, SVRefresh, SVScene, SVSessionLog, SVState, SVTransforms, SVUserInput, SVVector3d, SVViewerTool, SVViewerTools, Terminal, TIPUser, ViewerOps EXPORTS SVWindow SHARES ViewerClasses = BEGIN Camera: TYPE = SVModelTypes.Camera; CoordSystem: TYPE = SVModelTypes.CoordSystem; EditToolData: TYPE = SVInterfaceTypes.EditToolData; FileCamera: TYPE = SVSceneTypes.FileCamera; Filters: TYPE = SVInterfaceTypes.Filters; FiltersObj: TYPE = SVInterfaceTypes.FiltersObj; ForegroundParts: TYPE = SVWindow.ForegroundParts; Matrix4by4: TYPE = SV3d.Matrix4by4; MouseButton: TYPE = Menus.MouseButton; Plane: TYPE = SV3d.Plane; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = SV3d.Point3d; Scene: TYPE = SVSceneTypes.Scene; SkitterObj: TYPE = SVInterfaceTypes.SkitterObj; Viewer: TYPE = ViewerClasses.Viewer; SVData: TYPE = REF SVDataObj; SVDataObj: TYPE = SVInterfaceTypes.SVDataObj; PlaceOrigin: PROC [viewer: Viewer] = { originX, originY: REAL; transMat: Matrix4by4; svData: SVData _ NARROW[viewer.data]; screenCS: CoordSystem; camera: Camera _ svData.camera; screenCS _ camera.screenCS; originX _ viewer.cw;-- convert window width to real originY _ viewer.ch;-- convert window height to real originX _ originX/2.0;-- find the midpoint in window coords originY _ originY/2.0; transMat _ Matrix3d.MakeTranslateMat[-originX,-originY,0]; SVTransforms.AbsTransfScreen[screenCS, transMat]; BufferedRefresh.FitSandwichToScreen[svData.refresh.sandwich, viewer.cw, viewer.ch]; }; -- end of PlaceOrigin SVActionAreaPaint: PROC [self: Viewer, context: Imager.Context, whatChanged: REF ANY, clear: BOOL] RETURNS [quit: BOOL _ FALSE] = { PaintEntireViewer: PROC = { PlaceOrigin[self]; RestoreScreenAndInvariants[paintAction: $PaintEntireScene, svData: svData, remake: none, backgndOK: TRUE, edited: FALSE, okToClearFeedback: FALSE]; }; svData: SVData; IF whatChanged = NIL THEN { --we are being called by Window Manager svData _ NARROW[self.data]; PlaceOrigin[self]; Imager.SetFont[context, svData.editToolData.screenFont]; RestoreScreenAndInvariants[paintAction: $ViewersPaintEntireScene, svData: svData, remake: none, backgndOK: TRUE, edited: FALSE, okToClearFeedback: FALSE]; } ELSE { svData _ NARROW[whatChanged]; Imager.SetFont[context, svData.editToolData.screenFont]; SELECT svData.refresh.paintAction FROM $PaintEntireViewer => PaintEntireViewer[]; $CallAProc => { paintProc: SVInterfaceTypes.DisplayContextProc _ svData.refresh.paintProc; paintProc[context]; }; ENDCASE => SVRefresh.ActionAreaPaint[context, svData.refresh.paintAction, svData]; }; }; RestoreScreenAndInvariants: PUBLIC PROC [paintAction: ATOM, svData: SVData, remake: ForegroundParts _ triggerBag, backgndOK: BOOL _ FALSE, edited: BOOL _ TRUE, okToClearFeedback: BOOL _ TRUE] = { SELECT remake FROM none => NULL; triggerBag => { SVAlign.SetStaticBags[svData]; BufferedRefresh.SetLayerOK[svData.refresh.sandwich, $Foreground, FALSE]; }; alignBag => { SVAlign.FlushAlignBag[svData.hitTest.alignBag]; SVAlign.FillStaticAlignBag[svData.hitTest.triggerBag, svData.hitTest.sceneBag, svData.hitTest, NOT SVState.GetShowAlignments[svData], SVState.GetMidpoints[svData], svData.hitTest.alignBag]; BufferedRefresh.SetLayerOK[svData.refresh.sandwich, $Foreground, FALSE]; }; bitMap => { BufferedRefresh.SetLayerOK[svData.refresh.sandwich, $Foreground, FALSE]; }; sceneBag => { SVAlign.FlushTriggerBag[svData.hitTest.sceneBag]; SVAlign.FillStaticSceneBag[svData.scene, svData.hitTest.sceneBag]; }; ENDCASE => ERROR; svData.refresh.paintAction _ paintAction; ViewerOps.PaintViewer[ viewer: svData.actionArea, hint: client, whatChanged: svData, clearClient: FALSE] }; RawPaint: PUBLIC PROC [paintProc: SVInterfaceTypes.DisplayContextProc, svData: SVData] = { scene: Scene _ svData.scene; camera: Camera _ svData.camera; svData.refresh.paintProc _ paintProc; svData.refresh.paintAction _ $CallAProc; ViewerOps.PaintViewer[viewer: svData.actionArea, hint: client, whatChanged: svData, clearClient: FALSE]; }; CreateWindow: PUBLIC PROC [editToolData: EditToolData, scene: Scene, iconic: BOOL, paint: BOOL, workingDirectory: Rope.ROPE] RETURNS [svData: SVData, viewerPicture: Viewer] = { screenCS, worldCS: CoordSystem; success: BOOL; fileCamera: FileCamera; iconFileName: Rope.ROPE; windowMenu: Menus.Menu; svData _ NEW[SVDataObj]; svData.currentWDir _ workingDirectory; svData.originalWDir _ originalWDir; --global windowMenu _ Menus.CreateMenu[0]; svData.editToolData _ NARROW[editToolData]; svData.scene _ scene; iconFileName _ Rope.Concat[editToolData.originalWorkingDirectory, "SolidViews.icons"]; svData.outer _ SVViewerTool.Create[ info: [ name: Rope.Concat["Solid Scene: ", svData.scene.name], menu: windowMenu, data: svData, iconic: TRUE, column: left, scrollable: FALSE, icon: Icons.NewIconFromFile[iconFileName, 0] ], paint: FALSE]; screenCS _ CoordSys.CreateRoot["SCREEN"]; IF scene.cameraOrder # NIL THEN [fileCamera, ----] _ SVScene.FindFileCameraFromName[scene.cameraOrder.first, svData.scene] ELSE { [fileCamera, success] _ SVScene.FindFileCameraFromName["Front", svData.scene]; IF NOT success THEN ERROR; }; worldCS _ scene.coordSysRoot; svData.slackHandle _ SlackProcess.Create[queueSize: 50, logSize: 50, optimizeProc: OptimizeQueue, loggingProc: SVSessionLog.EnterAction, abortProc: NIL, abortData: NIL, abortViewer: NIL]; SVMouseEvent.InitializeFSM[svData]; svData.drag.savedCaret _ NEW[SkitterObj]; svData.camera _ SVScene.CreateCamera[worldCS, screenCS, shaded]; SVScene.StuffCameraFromFileCamera[svData.camera, fileCamera, shaded, scene]; svData.sceneStyleIndex _ 2; -- shaded svData.mode _ cast; svData.showCoordSys _ FALSE; svData.refresh.startBoundBox _ SVBoundBox.NullBoundBox[]; svData.refresh.sandwich _ SVRefresh.CreateSandwich[]; svData.hitTest _ NEW[FiltersObj]; svData.hitTest.triggerBag _ SVAlign.CreateTriggerBag[svData.scene]; svData.hitTest.sceneBag _ SVAlign.CreateTriggerBag[svData.scene]; svData.hitTest.alignBag _ SVAlign.CreateAlignBag[]; svData.refresh.lineCache _ FunctionCache.Create[maxEntries: 200]; svData.gravityPool _ SVGravity.NewGravityPool[]; SVMenus.BuildControlPanel[svData, windowMenu, workingDirectory]; BuildPictureSection[svData]; viewerPicture _ svData.actionArea; IF NOT iconic THEN ViewerOps.OpenIcon[icon: svData.outer, closeOthers: FALSE, bottom: FALSE, paint: TRUE]; }; OptimizeQueue: SlackProcess.OptimizeProc = { atom, nextAtom: ATOM; optimizeHint: REF ANY; hintList: LIST OF REF ANY; IF actionsOnQueue < 2 THEN RETURN [0]; skipActions _ 0; FOR i: NAT IN [0..actionsOnQueue-2] DO [----, optimizeHint, ----] _ SlackProcess.GetQueueEntry[qeGen, i]; hintList _ IF optimizeHint = NIL THEN NIL ELSE NARROW[optimizeHint]; atom _ IF hintList = NIL THEN $None ELSE NARROW[hintList.first]; [----, optimizeHint, ----] _ SlackProcess.GetQueueEntry[qeGen, i+1]; hintList _ IF optimizeHint = NIL THEN NIL ELSE NARROW[optimizeHint]; nextAtom _ IF hintList = NIL THEN $None ELSE NARROW[hintList.first]; IF atom = $During AND nextAtom = $During THEN { skipActions _ skipActions + 1; } ELSE RETURN; ENDLOOP; }; BuildPictureSection: PRIVATE PROC [svData: SVData] = { svData.actionArea _ ViewerOps.CreateViewer[ flavor: $SolidWindow, info: [ parent: svData.outer, wx: 0, wy: svData.height, ww: svData.outer.ww, wh: svData.outer.wh, -- only initial values for ww and wh. They are constrained below data: svData, -- contains the current scene scrollable: FALSE ] ]; SVViewerTool.ChildXBound[svData.outer, svData.actionArea]; SVViewerTool.ChildYBound[svData.outer, svData.actionArea]; svData.height _ svData.height + svData.actionArea.wh; }; -- end of BuildDrawSection ReloadTipTable: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { newTable: TIPUser.TIPTable; editToolData: EditToolData _ NARROW[svData.editToolData]; solidviewer: ViewerClasses.Viewer; bad: BOOL _ FALSE; tableName, msg: Rope.ROPE; Feedback.Append[svData.feedback, "Reloading tip table...", begin]; tableName _ Rope.Concat[editToolData.originalWorkingDirectory, "Solidviews.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[svData.feedback, msg, oneLiner]; RETURN}; Feedback.Append[svData.feedback, "Done.", end]; IF newTable = NIL THEN ERROR; solidviewer _ svData.actionArea; solidviewer.tipTable _ newTable; }; SetCursorLooks: PUBLIC PROC [type: SVInterfaceTypes.GravityType, svData: SVData, on: BOOL _ TRUE] = { newCursor: Cursors.CursorType; mouseViewer: ViewerClasses.Viewer; client: BOOL; terminal: Terminal.Virtual _ Terminal.Current[]; mousePos: Terminal.Position _ Terminal.GetMousePosition[terminal]; -- mouse origin in upper left tipScreenCoords: TIPUser.TIPScreenCoords _ NEW[TIPUser.TIPScreenCoordsRec _ [mouseX: mousePos.x, mouseY: mousePos.y, color: svData.actionArea.column=color] ]; tipScreenCoords.mouseY _ IF svData.actionArea.column=color THEN terminal.colorHeight-mousePos.y ELSE terminal.bwHeight-mousePos.y; -- move mouse origin to lower left [mouseViewer, client] _ ViewerOps.MouseInViewer[tipScreenCoords]; svData.actionArea.class.cursor _ newCursor _ IF NOT on THEN offCursor ELSE SELECT type FROM pointsPreferred => pointsPreferredCursor, linesPreferred => strictDistanceCursor, facesPreferred => offCursor, ENDCASE => ERROR; IF mouseViewer=svData.actionArea AND client THEN Cursors.SetCursor[newCursor]; }; NewCaretPos: PUBLIC PROC [svData: SVData] = { caret0, caret1, caret2Pos: Point3d; slope, azimuth: REAL; editToolData: EditToolData _ svData.editToolData; caret0 _ svData.measure.caret0; caret1 _ svData.measure.caret1; caret2Pos _ SVVector3d.Scale[SVCaret.GetPoint[editToolData.skitter], 1.0/svData.hitTest.scaleUnit]; svData.measure.caret2Value _ caret2Pos; SVViewerTools.SetPoint[svData.measure.caret2, caret2Pos]; [azimuth, slope] _ SVMeasure.AzimuthAndSlopeOfPoints[caret1, caret2Pos]; svData.measure.azimuthViewValue _ azimuth; SVViewerTools.SetReal[svData.measure.azimuthView, azimuth]; svData.measure.slopeViewValue _ slope; SVViewerTools.SetReal[svData.measure.slopeView, slope]; }; SaveCaretPos: PUBLIC PROC [svData: SVData] = { editToolData: EditToolData _ svData.editToolData; caret2Pos: Point3d _ SVVector3d.Scale[SVCaret.GetPoint[editToolData.skitter], 1.0/svData.hitTest.scaleUnit]; svData.measure.caret2Value _ caret2Pos; SVViewerTools.SetPoint[svData.measure.caret2, caret2Pos]; svData.measure.caret0 _ svData.measure.caret1; svData.measure.caret1 _ caret2Pos; }; BuildCursors: PROC [] = { pointsPreferredArray: Cursors.CursorArray = [600B+1100B, 600B+1100B+2040B, 2040B+4020B, 4020B+10010B, 10010B+20004B, 20004B+40002B, 40002B+100001B, 40002B+100001B, 40002B+100001B, 40002B+100001B, 20004B+40002B, 10010B+20004B, 4020B+10010B, 2040B+4020B, 600B+1100B+2040B, 600B+1100B]; -- diamond strictDistanceArray: Cursors.CursorArray = [100001B+40002B, 40002B+20004B, 20004B+10010B, 10010B+4020B, 4020B+2040B, 2040B, 0, 0, 0, 0, 2040B, 4020B+2040B, 10010B+4020B, 20004B+10010B, 40002B+20004B, 100001B+40002B]; -- folded diamond offArray: Cursors.CursorArray = [177777B, 177777B, 140003B, 140003B, 140003B, 140003B, 140003B, 140003B, 140003B, 140003B, 140003B, 140003B, 140003B, 140003B, 177777B, 177777B]; -- square pointsPreferredCursor _ Cursors.NewCursor[bits: pointsPreferredArray, hotX: -8, hotY: -6]; strictDistanceCursor _ Cursors.NewCursor[bits: strictDistanceArray, hotX: -8, hotY: -5]; offCursor _ Cursors.NewCursor[bits: offArray, hotX: -8, hotY: -6]; }; Init: PROC = { solidWindowClass: ViewerClasses.ViewerClass; solidWindowClass _ NEW[ViewerClasses.ViewerClassRec _ [ paint: SVActionAreaPaint, notify: SVUserInput.InputNotify, tipTable: TIPUser.InstantiateNewTIPTable["SolidViews.TIP"] ]]; ViewerOps.RegisterViewerClass[$SolidWindow, solidWindowClass]; BuildCursors[]; originalWDir _ FileNames.CurrentWorkingDirectory[]; }; offCursor: Cursors.CursorType; -- filled in by BuildCursors pointsPreferredCursor: Cursors.CursorType; -- filled in by BuildCursors strictDistanceCursor: Cursors.CursorType; -- filled in by BuildCursors originalWDir: Rope.ROPE _ NIL; -- filled in by Init Init[]; END. θFile: SVWindowImpl.mesa Author: Eric Bier on July 2, 1983 5:03 pm Copyright c 1984 by Xerox Corporation. All rights reserved. Last edited by Bier on July 12, 1987 1:54:53 pm PDT Contents: Code to create a solid viewer. Calls SVViewerTool to make the container and adds menus at the top. The 3D part of the solid viewer is a new viewer of class $SolidWindow. The paint proc for a $SolidWindow is defined herein. viewer is the viewerPicture Find the center of the solid window in solid window coordinates. ViewerClasses.PaintProc whatChanged is a SVData. self is a ViewerPicture. Rebuild bags as requested. Refresh the screen. parent is the EditTool Create the Container and the top menu which looks like this: Clear, Reset, Get, Store, Save, Split, Erase, Raycast, Stop, Aray, Press, Extend, Move #BBox #Scene #Coords #Point #Cross #Color #B&W Coords Construct the outer container. Find the current scene. PROC [qeGen: QueueEntryGenerator, actionsOnQueue: NAT] RETURNS [skipActions: NAT]; Notice that skipActions will be at most summary.count -1; The most recent action on the queue will be done if nothing else is appropriate. Always do the last During. Create a SolidWindow which fills the bottom of the container The following is a hack and is NOT the right way to do business. Unfortunately, the cursor data lives in a viewer CLASS rec instead of a viewer INSTANCE rec so their is no easy way to keep an instance-specific cursor. change the cursor immediately if the mouse is in the action area Κ J– "cedar" style˜Iheadšœ™Iprocšœ)™)Jšœ Οmœ1™˜>M˜Mšœ3˜3Lšœ˜L˜—Mšœ ‘˜