<> <> <> <> <> DIRECTORY BufferedRefresh, CoordSys, Cursors, Feedback, FileNames, FS, Icons, Imager, Matrix3d, Menus, Rope, SlackProcess, SV2d, SV3d, SVAlign, SVBoundBox, SVDrawMonitor, SVInterfaceTypes, SVMenus, SVModelTypes, SVMouseEvent, SVRefresh, SVScene, SVSceneTypes, SVSessionLog, SVTransforms, SVUserInput, SVWindow, SVViewerTool, Terminal, TIPUser, ViewerClasses, ViewerOps; SVWindowImpl: CEDAR PROGRAM IMPORTS BufferedRefresh, CoordSys, Cursors, Feedback, FileNames, FS, Icons, Imager, Matrix3d, Menus, Rope, SlackProcess, SVAlign, SVBoundBox, SVMenus, SVMouseEvent, SVRefresh, SVScene, SVSessionLog, SVTransforms, SVUserInput, SVViewerTool, 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; Scene: TYPE = SVSceneTypes.Scene; SkitterObj: TYPE = SVInterfaceTypes.SkitterObj; Viewer: TYPE = ViewerClasses.Viewer; SVData: TYPE = REF SVDataObj; SVDataObj: TYPE = SVInterfaceTypes.SVDataObj; PlaceOrigin: PROC [viewer: Viewer] = { <> << Find the center of the solid window in solid window coordinates.>> 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, bitMap => NULL; triggerBag, objectBag, 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]; }; CreateViewerTool: PUBLIC PROC [parentData: REF ANY, scene: Scene, iconic: BOOL, paint: BOOL, workingDirectory: Rope.ROPE] RETURNS [svData: SVData, viewerPicture: Viewer] = { <> <> <> <<#BBox #Scene #Coords #Point #Cross #Color #B&W Coords>> screenCS, worldCS: CoordSystem; success: BOOL; fileCamera: FileCamera; editToolData: EditToolData; iconFileName: Rope.ROPE; windowMenu: Menus.Menu; svData _ NEW[SVDataObj]; svData.currentWDir _ workingDirectory; svData.originalWDir _ originalWDir; --global windowMenu _ Menus.CreateMenu[0]; svData.editToolData _ NARROW[parentData]; svData.scene _ scene; editToolData _ NARROW[parentData]; 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.doubleBuffer _ TRUE; svData.refresh.startBoundBox _ SVBoundBox.NullBoundBox[]; svData.refresh.sandwich _ SVRefresh.CreateSandwich[]; svData.hitTest _ NEW[FiltersObj]; svData.hitTest.sceneBag _ SVAlign.CreateTriggerBag[svData.scene]; 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] = { <> 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 _ SELECT type FROM pointsPreferred => pointsPreferredCursor, linesPreferred => strictDistanceCursor, strictDistance => offCursor, off => offCursor, ENDCASE => ERROR; <> IF mouseViewer=svData.actionArea AND client THEN Cursors.SetCursor[newCursor]; }; NewCaretPos: PUBLIC PROC [svData: SVData] = { <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> }; SaveCaretPos: PUBLIC PROC [svData: SVData] = { <> <> <> <> <> }; 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.