<> <> <> <> DIRECTORY Atom, Convert, CoordSys, Feedback, Imager, IO, Menus, RefTab, Rope, SlackProcess, SV2d, SV3d, SVBasicTypes, SVEvent, SVInterfaceTypes, SVModelTypes, SVMouseEvent, SVRayTypes, SVSceneTypes, SVSessionLog, SVUserInput, SVWindow, TIP, TIPUser, ViewerClasses, ViewerTools; SVUserInputImpl: CEDAR PROGRAM IMPORTS Atom, Convert, CoordSys, Feedback, IO, RefTab, Rope, SlackProcess, SVEvent, SVMouseEvent, SVSessionLog, SVWindow, ViewerTools EXPORTS SVUserInput = BEGIN Artwork: TYPE = SVModelTypes.Artwork; ArtworkToolData: TYPE = SVInterfaceTypes.ArtworkToolData; Slice: TYPE = SVSceneTypes.Slice; SliceList: TYPE = SVSceneTypes.SliceList; BoundBox: TYPE = SVBasicTypes.BoundBox; BoundSphere: TYPE = SVBasicTypes.BoundSphere; Camera: TYPE = SVModelTypes.Camera; Classification: TYPE = SVRayTypes.Classification; Color: TYPE = Imager.Color; CSGTree: TYPE = SVRayTypes.CSGTree; EditToolData: TYPE = SVInterfaceTypes.EditToolData; EventProc: TYPE = SVUserInput.EventProc; FileCamera: TYPE = SVSceneTypes.FileCamera; FrameBox: TYPE = SVModelTypes.FrameBox; MasterObject: TYPE = SVSceneTypes.MasterObject; Point2d: TYPE = SV2d.Point2d; Primitive: TYPE = SVRayTypes.Primitive; Ray: TYPE = SVRayTypes.Ray; Scene: TYPE = SVSceneTypes.Scene; Selection: TYPE = SVInterfaceTypes.Selection; Shape: TYPE = SVSceneTypes.Shape; SlackHandle: TYPE = SlackProcess.SlackHandle; TrigLine: TYPE = SV2d.TrigLine; Vector3d: TYPE = SV3d.Vector3d; SVData: TYPE = SVInterfaceTypes.SVData; Problem: SIGNAL [msg: Rope.ROPE] = Feedback.Problem; <> InputNotify: PUBLIC PROC [self: ViewerClasses.Viewer, input: LIST OF REF ANY] = { <> <> svData: SVData _ NARROW[self.data]; ProcessAndQueueEvent[input, svData]; }; EventNotify: PUBLIC PROC [clientData: REF ANY, event: LIST OF REF ANY] = { WITH clientData SELECT FROM editToolData: EditToolData => ProcessAndQueueEvent[event, editToolData.currentSVData]; svData: SVData => ProcessAndQueueEvent[event, svData]; ENDCASE => ERROR; }; ProcessAndQueueEvent: PROC [event: LIST OF REF ANY, svData: SVData] = { <> <<1) LIST[REF CHAR].>> <<2) LIST[ATOM, ... ].>> handle: SlackHandle _ svData.slackHandle; optimizeHint: REF ANY; WITH event.first SELECT FROM atom: ATOM => { atomName: Rope.ROPE; atomName _ Atom.GetPName[atom]; IF atom = $During THEN optimizeHint _ LIST[$During]; <> <> <> <<};>> event _ GetAnyArguments[event, svData]; }; ENDCASE => ERROR; IF printAllInput THEN PrintAllInput[event, svData]; SlackProcess.QueueInputAction[handle, Dispatch, event, svData, optimizeHint]; }; GetAnyArguments: PROC [event: LIST OF REF ANY, svData: SVData] RETURNS [newEvent: LIST OF REF ANY] = { atom: ATOM; found: BOOL; regEvent: RegisteredEvent; refAny: REF ANY; camera: Camera _ svData.camera; atom _ NARROW[event.first]; [found, refAny] _ RefTab.Fetch[eventTable, atom]; regEvent _ NARROW[refAny]; IF NOT found THEN { NotYetImplementedMessage[atom, svData]; newEvent _ event; } ELSE { SELECT regEvent.argType FROM none => { IF event.rest # NIL AND ISTYPE[event.rest.first, TIP.TIPScreenCoords] THEN { mousePlace: TIP.TIPScreenCoords _ NARROW[event.rest.first]; point: Point2d _ CoordSys.ScreenToCamera[[mousePlace.mouseX, mousePlace.mouseY], camera.screenCS]; refPoint: REF Imager.VEC _ NEW[Imager.VEC _ [point[1], point[2]]]; newEvent _ LIST[event.first, refPoint]; } ELSE newEvent _ event; }; refReal => newEvent _ CheckForSelectedReal[atom, event]; refInt => newEvent _ CheckForSelectedInt[atom, event]; rope => newEvent _ CheckForSelectedRope[atom, event]; ENDCASE => ERROR; }; }; <> Dispatch: PROC [clientData: REF ANY, event: LIST OF REF ANY] = { svData: SVData _ NARROW[clientData]; atom: ATOM _ NARROW[event.first]; found: BOOL; regEvent: RegisteredEvent; refAny: REF ANY; [found, refAny] _ RefTab.Fetch[eventTable, atom]; regEvent _ NARROW[refAny]; IF NOT found THEN NotYetImplementedMessage[atom, svData] ELSE regEvent.eventProc[event, svData]; }; <> printAllInput: BOOL _ FALSE; -- controlled by Debug menu PrintAllInput: PROC [event: LIST OF REF ANY, clientData: REF ANY] = { svData: SVData _ NARROW[clientData]; FOR list: LIST OF REF ANY _ event, list.rest UNTIL list = NIL DO WITH list.first SELECT FROM atom: ATOM => Feedback.AppendTypescript[svData.feedback, Atom.GetPName[atom], oneLiner]; int: REF INT => Feedback.AppendTypescript[svData.feedback, IO.PutFR["%g ", [integer[int^]]], oneLiner]; refChar: REF CHAR => Feedback.AppendTypescript[svData.feedback, IO.PutFR["%g ", [character[refChar^]]], oneLiner]; coords: TIP.TIPScreenCoords => Feedback.AppendTypescript[svData.feedback, IO.PutFR["(%g, %g) ", [real[coords.mouseX]], [real[coords.mouseY]]], oneLiner]; ENDCASE => ERROR; ENDLOOP; }; NotYetImplementedMessage: PROC [atom: ATOM, svData: SVData] = { Feedback.PutF[svData.feedback, oneLiner, "User action %g is not yet implemented", [rope[Atom.GetPName[atom]]]]; Feedback.Blink[svData.feedback]; }; CheckForSelectedReal: PROC [atom: ATOM, action: LIST OF REF ANY] RETURNS [newAction: LIST OF REF ANY] = { rope: Rope.ROPE; real: REAL; IF action.rest = NIL THEN { -- interactive call rope _ ViewerTools.GetSelectionContents[]; real _ Convert.RealFromRope[rope ! Convert.Error => {real _ -1.0; CONTINUE}]; newAction _ LIST[atom, NEW[REAL _ real]]; } ELSE IF ISTYPE[action.rest.first, REF TEXT] THEN { -- TIP table call rope _ Rope.FromRefText[NARROW[action.rest.first]]; real _ Convert.RealFromRope[rope ! Convert.Error => {real _ -1.0; CONTINUE}]; newAction _ LIST[atom, NEW[REAL _ real]]; } ELSE newAction _ action; -- SessionLog call }; CheckForSelectedInt: PROC [atom: ATOM, action: LIST OF REF ANY] RETURNS [newAction: LIST OF REF ANY] = { rope: Rope.ROPE; int: INT; IF action.rest = NIL THEN { -- interactive call rope _ ViewerTools.GetSelectionContents[]; int _ IO.GetInt[IO.RIS[rope] ! IO.EndOfStream, IO.Error => {int _ -1; CONTINUE}]; newAction _ LIST[atom, NEW[INT _ int]]; } ELSE IF ISTYPE[action.rest.first, REF INT] THEN { -- TIP table call or SessionLog call newAction _ action; } ELSE ERROR; }; CheckForSelectedRope: PROC [atom: ATOM, action: LIST OF REF ANY] RETURNS [newAction: LIST OF REF ANY] = { IF action.rest = NIL THEN { -- interactive call newAction _ LIST[atom, ViewerTools.GetSelectionContents[]]; } ELSE IF ISTYPE[action.rest.first, REF TEXT] THEN { -- TIP table call newAction _ LIST[atom, Rope.FromRefText[NARROW[action.rest.first]]]; } ELSE newAction _ action; -- SessionLog call }; RegisteredEvent: TYPE = REF RegisteredEventObj; RegisteredEventObj: TYPE = RECORD [ eventProc: EventProc, argType: SVUserInput.ArgumentType ]; RegisterAction: PUBLIC PROC [atom: ATOM, eventProc: EventProc, argType: SVUserInput.ArgumentType] = { regEvent: RegisteredEvent _ NEW[RegisteredEventObj _ [eventProc, argType]]; notAlreadyRegistered: BOOL _ TRUE; notAlreadyRegistered _ RefTab.Insert[eventTable, atom, regEvent]; IF NOT notAlreadyRegistered THEN SIGNAL Problem[msg: IO.PutFR["Event %g was already registered in Solidviews's event table.", [rope[Atom.GetPName[atom]]] ]]; }; eventTable: RefTab.Ref; NoOp: EventProc = {}; RegisterSolidviewsActions: PROC = { <> eventTable _ RefTab.Create[300]; <> RegisterAction[$EndOfSessionLogMessage, SVSessionLog.EndOfSessionLogMessage, none]; <> RegisterAction[$Clear, SVEvent.Clear, none]; RegisterAction[$Restore, SVEvent.Restore, none]; RegisterAction[$Get, SVEvent.Get, rope]; RegisterAction[$Store, SVEvent.Store, rope]; RegisterAction[$Save, SVEvent.Save, none]; RegisterAction[$Split, SVEvent.Split, none]; <> RegisterAction[$ToIP, SVEvent.ToIP, rope]; RegisterAction[$StorePoly, SVEvent.StorePoly, none]; <> RegisterAction[$RayCast, SVEvent.RayCast, none]; RegisterAction[$StopRays, SVEvent.StopRays, none]; RegisterAction[$ARay, SVEvent.ARay, none]; <> RegisterAction[$DrawBoundBoxes, SVEvent.DrawBoundBoxes, none]; RegisterAction[$DrawBoundSpheres, SVEvent.DrawBoundSpheres, none]; RegisterAction[$DrawCoordSystems, SVEvent.DrawCoordSystems, none]; RegisterAction[$DrawPoint, SVEvent.DrawPt, none]; RegisterAction[$CrossHairs, SVEvent.CrossHairs, none]; RegisterAction[$TestGravity, SVEvent.TestGravity, refInt]; RegisterAction[$ResetStatistics, SVEvent.ResetStatistics, none]; RegisterAction[$PrintStatistics, SVEvent.PrintStatistics, none]; <> RegisterAction[$DrawSceneButton, SVEvent.DrawSceneButton, none]; RegisterAction[$DrawColor, SVEvent.DrawColor, none]; RegisterAction[$DrawBlackAndWhite, SVEvent.DrawBlackAndWhite, none]; RegisterAction[$ShowCoordsMode, SVEvent.ShowCoordsMode, none]; <