<> <> <> <> DIRECTORY GriffinDefs: FROM "GriffinDefs", MenuDefs: FROM "MenuDefs", ObjectDefs: FROM "ObjectDefs", GriffinText USING [GetCaption, GetBoundingBox], RefreshDefs: FROM "RefreshDefs", StyleDefs USING [StyleHandle], GriffinStyle USING [SetCurrentStyle, CopyCurrentStyle], PointDefs: FROM "PointDefs", GriffinMemoryDefs USING [CZone], CubicSplines USING [SplineType], Rope USING [ROPE, Equal], GriffinEncoding USING [Link, EncodeArea], GriffinMenusInterface, ControllerMenuDefs; DrawOps: CEDAR PROGRAM IMPORTS GriffinDefs, MenuDefs, ObjectDefs, ControllerMenuDefs, GriffinMemoryDefs, PointDefs, RefreshDefs, Rope, GriffinStyle, GriffinText, GriffinEncoding EXPORTS GriffinDefs, GriffinMenusInterface = BEGIN OPEN ObjectDefs,PointDefs,GriffinMemoryDefs; newObj: REF shape Object _ NIL; spline: CubicSplines.SplineType _ naturalAL; Fitting: TYPE = {lines,curve}; fitting: Fitting; ROPE: TYPE = Rope.ROPE; BugItemByString: PROCEDURE[menu: MenuDefs.MenuHandle, string: ROPE]= BEGIN OPEN MenuDefs; menuItem: MenuItemHandle _ NARROW[menu.head]; IsThisItem: MenuProc = { IF Rope.Equal[MenuString[item], string, FALSE] THEN menuItem _ item}; ForAllMenuItems[menu, IsThisItem]; BugItem[menuItem] END; ExpandShape: PUBLIC MenuDefs.MenuProc = BEGIN OPEN ControllerMenuDefs; IF MenuDefs.IsSelected[item] THEN ControllerMenuDefs.UnDisplayShapeMenu[] ELSE ControllerMenuDefs.DisplayShapeMenu[]; IF MenuDefs.IsSelected[item] THEN MenuDefs.Deselect[item] ELSE MenuDefs.Select[item]; RefreshDefs.RestoreScreen; END; ExpandColor: PUBLIC MenuDefs.MenuProc = BEGIN OPEN ControllerMenuDefs; IF MenuDefs.IsSelected[item] THEN ControllerMenuDefs.UnDisplayColorMenu[] ELSE ControllerMenuDefs.DisplayColorMenu[]; IF MenuDefs.IsSelected[item] THEN MenuDefs.Deselect[item] ELSE MenuDefs.Select[item]; RefreshDefs.RestoreScreen; END; ExpandText: PUBLIC MenuDefs.MenuProc = BEGIN OPEN ControllerMenuDefs; IF MenuDefs.IsSelected[item] THEN ControllerMenuDefs.UnDisplayCaptionMenu[] ELSE ControllerMenuDefs.DisplayCaptionMenu[]; IF MenuDefs.IsSelected[item] THEN MenuDefs.Deselect[item] ELSE MenuDefs.Select[item]; RefreshDefs.RestoreScreen; END; ApplyStyle: PUBLIC MenuDefs.MenuProc = BEGIN OPEN ControllerMenuDefs; <> new: StyleDefs.StyleHandle _ GriffinStyle.CopyCurrentStyle[]; ChangeObj: ObjectProc=BEGIN oldTL: ScrPt _ obj.tl; oldBR: ScrPt _ obj.br; tl, br: ScrPt; obj.style _ new; AdjustBoxForStyle[obj]; tl[X] _ MIN[oldTL[X], obj.tl[X]]; br[X] _ MAX[oldBR[X], obj.br[X]]; tl[Y] _ MAX[oldTL[Y], obj.tl[Y]]; br[Y] _ MIN[oldBR[Y], obj.br[Y]]; RefreshDefs.EraseAndSaveBox[tl, br] END; ForAllSelectedDo[ChangeObj]; RefreshDefs.RestoreScreen[]; END; IndicateStyle: PUBLIC MenuDefs.MenuProc = BEGIN style: StyleDefs.StyleHandle _ NIL; SetSelectedStyle: ObjectProc = BEGIN style _ obj.style END; ObjectDefs.ForAllSelectedDo [SetSelectedStyle]; IF style#NIL THEN { ControllerMenuDefs.SetStyleMenus[style]; GriffinStyle.SetCurrentStyle[style]; }; END; FittingType: PUBLIC MenuDefs.MenuProc = BEGIN string: ROPE _ MenuDefs.MenuString[item]; fitting _ SELECT TRUE FROM Rope.Equal[string,"Straight",FALSE] => lines, Rope.Equal[string,"Curved",FALSE] => curve, ENDCASE => ERROR; MenuDefs.SelectOnly[item]; END; ExpandSplines: PUBLIC MenuDefs.MenuProc = BEGIN IF MenuDefs.IsSelected[item] THEN MenuDefs.HideMenu[splineMenu] ELSE MenuDefs.ShowMenu[splineMenu]; IF MenuDefs.IsSelected[item] THEN MenuDefs.Deselect[item] ELSE MenuDefs.Select[item]; RefreshDefs.RestoreScreen; END; SplineType: PUBLIC MenuDefs.MenuProc = BEGIN string: ROPE _ MenuDefs.MenuString[item]; IF newObj#NIL THEN GriffinDefs.UserMessage["Only one spline type per object"]; spline _ SELECT TRUE FROM Rope.Equal[string,"Natural: Arc Length",FALSE] => naturalAL, Rope.Equal[string,"Natural: Unit Length",FALSE] => naturalUM, Rope.Equal[string,"Bezier Curve",FALSE] => bezier, Rope.Equal[string,"B-Spline",FALSE] => bspline, Rope.Equal[string,"Catmull-Rom Curve",FALSE] => crspline, ENDCASE => ERROR; MenuDefs.SelectOnly[item]; END; SetSplineType: PROCEDURE[splinetype: CubicSplines.SplineType] = BEGIN string: ROPE _ SELECT splinetype FROM naturalAL => "Natural: Arc Length", naturalUM => "Natural: Unit Length", bezier => "Bezier Curve", bspline => "B-Spline", crspline => "Catmull-Rom Curve", ENDCASE => ERROR; BugItemByString[splineMenu, string]; END; NewLink: PUBLIC MenuDefs.MenuProc = BEGIN tempLink: REF Link _ NIL; lastPt: PointDefs.ScrPt; cps: PointDefs.ObjPtSequence; encoding: GriffinEncoding.Link; IF spline=bspline OR spline=crspline THEN GriffinDefs.UserMessage["B-Splines and Catmull-Rom Curves cannot be used in linked objects"]; cps _ ReadCPs[]; IF cps=NIL OR cps.length <=1 THEN RETURN; lastPt _ PointDefs.ObjToScr[cps[cps.length-1]]; tempLink _ MakeLink[fitting=lines,cps]; IF newObj=NIL THEN newObj _ StartShapeObject[closed: FALSE, linked: TRUE]; encoding _ ObjectDefs.AppendLink[newObj,tempLink]; RefreshDefs.EraseAndSaveAllCPs[]; DeleteAllCPs[]; PlotLink[encoding, NIL]; AddToken[lastPt,open]; RefreshDefs.RestoreScreen[]; END; MakeLink: PROCEDURE[isLines: BOOLEAN,cps: PointDefs.ObjPtSequence]RETURNS[newLink: REF Link] = BEGIN newLink _ CZone.NEW[Link]; newLink^ _ [NIL, (IF isLines THEN D1 ELSE D3), cps]; END; BackLink: PUBLIC MenuDefs.MenuProc = BEGIN lastLink: REF Link _ GetNewObjectLinks[]; RefreshDefs.EraseAndSaveAllCPs[]; DeleteAllCPs[]; <> IF lastLink = NIL THEN BEGIN [] _ DeleteObject[newObj]; newObj _ NIL; RefreshDefs.RestoreScreen[]; RETURN; END; <> IF lastLink.link = NIL THEN BEGIN ShowKnots[lastLink.knots,FALSE]; RefreshDefs.EraseAndSave[newObj]; [] _ DeleteObject[newObj]; newObj _ NIL; RefreshDefs.RestoreScreen[]; RETURN; END; UNTIL lastLink.link=NIL DO lastLink _ lastLink.link; ENDLOOP; ShowLinkKnots[lastLink.knots,FALSE]; EraseLink[RemoveLastLink[newObj]]; RefreshDefs.RestoreScreen[]; END; ShowLinkKnots: PROCEDURE[knots: PointDefs.ObjPtSequence, exceptLast: BOOLEAN] = BEGIN i: CARDINAL; lastknot: CARDINAL _ knots.length-1; cps: PointDefs.ObjPtSequence _ ReadCPs[]; DeleteAllCPs[]; IF exceptLast THEN lastknot _ lastknot-1; AddToken[ObjToScr[knots[0]], open]; FOR i IN [1..lastknot] DO AddToken[ObjToScr[knots[i]], CP]; ENDLOOP; IF cps#NIL THEN BEGIN FOR i IN [0..cps.length) DO AddToken[ObjToScr[cps[i]], CP]; ENDLOOP; END; END; GetNewObjectLinks: PROCEDURE RETURNS [link: REF Link]= TRUSTED BEGIN IF newObj=NIL THEN RETURN[NIL]; WITH traj: newObj.trajectory SELECT FROM linked => link _ traj.links; ENDCASE => ERROR; RETURN; END; Draw: PUBLIC MenuDefs.MenuProc = BEGIN DrawObject[newObj,FALSE]; END; Close: PUBLIC MenuDefs.MenuProc = BEGIN DrawObject[newObj,TRUE]; END; Box: PUBLIC MenuDefs.MenuProc = BEGIN cps: PointDefs.ObjPtSequence; pt: ObjPt; cps _ ReadCPs[]; IF cps=NIL OR cps.length #2 THEN SIGNAL GriffinDefs.UserMessage["Exactly 2 points for a box"]; DeleteAllCPs[]; AddToken[ObjToScr[cps[0]],CP]; pt _ [cps[0][X],cps[1][Y]]; AddToken[ObjToScr[pt],CP]; AddToken[ObjToScr[cps[1]],CP]; pt _ [cps[1][X],cps[0][Y]]; AddToken[ObjToScr[pt],CP]; BugItemByString[shapeMenu,"Straight"]; DrawObject[newObj,TRUE]; END; Caption: PUBLIC MenuDefs.MenuProc = { cps: PointDefs.ObjPtSequence _ ObjectDefs.ReadCPs[]; text: ROPE _ GriffinText.GetCaption[]; IF cps=NIL OR cps.length # 1 THEN SIGNAL GriffinDefs.UserMessage["Place exactly one control point for caption."]; IF text=NIL THEN SIGNAL GriffinDefs.UserMessage["Please select the text for the caption in a Tioga viewer."] ELSE BEGIN caption: REF Object[caption] _ NARROW[ObjectDefs.StartObject[caption]]; caption.text _ text; caption.style _ GriffinStyle.CopyCurrentStyle[]; caption.p0 _ cps[0]; [caption.tl, caption.br] _ GriffinText.GetBoundingBox[text, caption.style, caption.p0]; caption.validEncoding _ TRUE; caption.cluster _ 0; [] _ ObjectDefs.SelectObject[caption]; RefreshDefs.EraseAndSaveAllCPs; ObjectDefs.DeleteAllCPs[]; RefreshDefs.MarkObject[caption]; RefreshDefs.RestoreScreen[]; END; }; Modify: PUBLIC MenuDefs.MenuProc = BEGIN selected: ObjectHandle _ NIL; FindLastSelected: ObjectProc=BEGIN selected _ obj; END; IF newObj#NIL THEN RETURN; --don't modify while drawing or modifying ForAllSelectedDo[FindLastSelected]; IF selected=NIL THEN RETURN; WITH selected SELECT FROM obj: REF Object[shape] => BEGIN GriffinStyle.SetCurrentStyle[selected.style]; SetSplineType[obj.trajectory.splineType]; EraseObject[selected]; DeSelectObject[selected]; --will get selected again when finished OpenObject[obj]; --remove link, show cps, plot remaining object END; obj: REF Object[caption] => BEGIN <> <> <> <> GriffinDefs.UserMessage["You must delete the caption and start over"]; END; ENDCASE => RETURN; END; OpenObject: PROCEDURE[obj: REF Object[shape]] = TRUSTED BEGIN WITH traj: obj.trajectory SELECT FROM linked => BEGIN link: REF Link _ traj.links; IF link = NIL THEN ERROR; <> IF link.link=NIL THEN BEGIN ShowKnots[link.knots,obj.closed]; IF link.degree=D1 THEN BugItemByString[shapeMenu,"Straight"] ELSE BugItemByString[shapeMenu,"Curved"]; [] _ DeleteObject[obj]; END <> ELSE BEGIN closed: BOOLEAN _ obj.closed; newObj _ obj; newObj.closed _ FALSE; newObj.cluster _ OpenCluster; <> FOR link _ traj.links , link.link UNTIL link.link=NIL DO ENDLOOP; <> ShowLinkKnots[link.knots,closed]; IF link.degree=D1 THEN BugItemByString[shapeMenu,"Straight"] ELSE BugItemByString[shapeMenu,"Curved"]; [] _ ObjectDefs.RemoveLastLink[obj]; <> PlotOneObject[newObj]; END; END; cyclic => BEGIN ShowKnots[traj.knots, FALSE]; BugItemByString[shapeMenu,"Curved"]; [] _ DeleteObject[obj]; END; ENDCASE; END; ShowKnots: PROCEDURE[knots: PointDefs.ObjPtSequence, exceptLast: BOOLEAN] = BEGIN i: CARDINAL; lastknot: CARDINAL _ knots.length-1; IF exceptLast THEN lastknot _ lastknot-1; FOR i IN [0..lastknot] DO AddToken[ObjToScr[knots[i]], CP]; ENDLOOP; END; StartShapeObject: PROC [closed: BOOLEAN, linked: BOOLEAN] RETURNS [REF Object[shape]] ~ { shape: REF Object[shape] _ NARROW[StartObject[shape]]; shape.closed _ closed; shape.edgeEncoding _ NIL; shape.areaEncoding _ NIL; shape.style _ GriffinStyle.CopyCurrentStyle[]; shape.cluster _ OpenCluster; IF linked THEN shape.trajectory _ CZone.NEW[Trajectory[linked] _ [spline,linked[NIL]]] ELSE shape.trajectory _ CZone.NEW[Trajectory[cyclic] _ [spline,cyclic[NIL]]]; RETURN[shape]; }; DrawObject: PROCEDURE[shapeObj: REF shape Object, closed: BOOLEAN] = TRUSTED BEGIN cps: PointDefs.ObjPtSequence _ ReadCPs[]; IF shapeObj=NIL AND (cps=NIL OR cps.length<1) THEN RETURN; IF shapeObj = NIL THEN shapeObj _ StartShapeObject[closed: closed, linked: NOT (closed AND fitting=curve)]; shapeObj.closed _ closed; IF shapeObj.closed THEN { WITH traj: shapeObj.trajectory SELECT FROM cyclic => AddToken[ObjToScr[cps[0]],CP]; linked => IF traj.links=NIL THEN AddToken[ObjToScr[cps[0]],CP] ELSE AddToken[ObjToScr[traj.links.knots[0]],CP]; ENDCASE => ERROR; cps _ ReadCPs[]; --reread them with new cp }; WITH traj: shapeObj.trajectory SELECT FROM cyclic => { traj.splineType _ SELECT traj.splineType FROM naturalUM => cyclicUM, naturalAL => cyclicAL, ENDCASE => traj.splineType; traj.knots _ cps; EncodeObject[shapeObj]; --makes edge and area encoding }; linked => { link: REF Link; link _ MakeLink[fitting=lines,cps]; PlotLink[AppendLink[shapeObj,link], shapeObj.style]; <> <> IF shapeObj.closed THEN shapeObj.areaEncoding _ GriffinEncoding.EncodeArea[shapeObj.edgeEncoding]; }; ENDCASE; shapeObj.cluster _ 0; [] _ ObjectDefs.SelectObject[shapeObj]; AdjustBoxForStyle[shapeObj]; RefreshDefs.EraseAndSaveAllCPs[]; DeleteAllCPs[]; RefreshDefs.MarkObject[shapeObj]; RefreshDefs.RestoreScreen[]; newObj _ NIL; END; editMenu: MenuDefs.MenuHandle_NIL; styleMenu: MenuDefs.MenuHandle_NIL; shapeMenu: MenuDefs.MenuHandle_NIL; splineMenu: MenuDefs.MenuHandle_NIL; default: MenuDefs.MenuItemHandle_NIL; showstyle: MenuDefs.MenuItemHandle_NIL; newLink: MenuDefs.MenuItemHandle_NIL; ToggleEditMenus: PUBLIC PROC = { --edit and spline menus IF editMenu.visible THEN { IF splineMenu.visible THEN MenuDefs.HideMenu[splineMenu]; MenuDefs.HideMenu[shapeMenu]; MenuDefs.HideMenu[editMenu]; } ELSE { item: MenuDefs.MenuItemHandle; MenuDefs.ShowMenu[editMenu]; MenuDefs.ShowMenu[shapeMenu]; item _ FindItemByString[editMenu,"Spline Type"]; IF MenuDefs.IsSelected[item] THEN MenuDefs.BugItem[item]; --show spline menu }; RefreshDefs.RestoreScreen[]; }; ToggleStyleMenu: PUBLIC PROC = { -- the top level style menu IF styleMenu.visible THEN { <> ControllerMenuDefs.UnDisplayColorMenu[]; ControllerMenuDefs.UnDisplayCaptionMenu[]; ControllerMenuDefs.UnDisplayShapeMenu[]; MenuDefs.HideMenu[styleMenu]; } ELSE { item: MenuDefs.MenuItemHandle; MenuDefs.ShowMenu[styleMenu]; item _ FindItemByString[styleMenu,"Text Style"]; IF MenuDefs.IsSelected[item] THEN MenuDefs.BugItem[item]; item _ FindItemByString[styleMenu,"Color Style"]; IF MenuDefs.IsSelected[item] THEN MenuDefs.BugItem[item]; item _ FindItemByString[styleMenu,"Shape Style"]; IF MenuDefs.IsSelected[item] THEN MenuDefs.BugItem[item]; }; RefreshDefs.RestoreScreen[]; }; FindItemByString: PROCEDURE[menu: MenuDefs.MenuHandle,string: ROPE] RETURNS [mitem: MenuDefs.MenuItemHandle]= BEGIN OPEN MenuDefs; IsItem: MenuDefs.MenuProc = BEGIN IF Rope.Equal[MenuDefs.MenuString[item],string] THEN mitem _ item; END; MenuDefs.ForAllMenuItems[menu,IsItem]; END; StartDrawMenus: PUBLIC PROC = { editMenu _ MenuDefs.CreateMenu[horizontal, [100,500], NIL]; []_MenuDefs.AddMenuItem[editMenu,"Draw",Draw]; []_MenuDefs.AddMenuItem[editMenu,"Close",Close]; []_MenuDefs.AddMenuItem[editMenu,"Draw link",NewLink]; []_MenuDefs.AddMenuItem[editMenu,"Modify",Modify]; []_MenuDefs.AddMenuItem[editMenu,"Back link",BackLink]; []_MenuDefs.AddMenuItem[editMenu,"Box",Box]; []_MenuDefs.AddMenuItem[editMenu,"Caption",Caption]; []_MenuDefs.AddMenuItem[editMenu,"Spline Type",ExpandSplines]; shapeMenu _ MenuDefs.CreateMenu[vertical, [100,550], NIL]; default _MenuDefs.AddMenuItem[shapeMenu,"Straight",FittingType]; []_MenuDefs.AddMenuItem[shapeMenu,"Curved",FittingType]; MenuDefs.BugItem[default]; splineMenu _ MenuDefs.CreateMenu[vertical, [200,550], NIL]; default _MenuDefs.AddMenuItem[splineMenu,"Natural: Arc Length",SplineType]; []_MenuDefs.AddMenuItem[splineMenu,"Natural: Unit Length",SplineType]; []_MenuDefs.AddMenuItem[splineMenu,"Bezier Curve",SplineType]; []_MenuDefs.AddMenuItem[splineMenu,"B-Spline",SplineType]; []_MenuDefs.AddMenuItem[splineMenu,"Catmull-Rom Curve",SplineType]; MenuDefs.BugItem[default]; styleMenu _ MenuDefs.CreateMenu[vertical, [400,200], NIL]; []_MenuDefs.AddMenuItem [styleMenu, "Indicate", IndicateStyle]; []_MenuDefs.AddMenuItem [styleMenu, "Apply", ApplyStyle]; []_MenuDefs.AddMenuItem [styleMenu, "Shape Style", ExpandShape]; []_MenuDefs.AddMenuItem [styleMenu, "Color Style", ExpandColor]; []_MenuDefs.AddMenuItem [styleMenu, "Text Style", ExpandText]; }; END.