DIRECTORY Cursors, Imager, ImagerTransformation, InputFocus, List, Pipal, PipalEdit, PipalMutate, PipalOps, PipalOverlayMutant, PipalPaint, PipalReal, Rope; PipalOverlayEditorImpl: CEDAR PROGRAM IMPORTS ImagerTransformation, InputFocus, List, Pipal, PipalEdit, PipalMutate, PipalOverlayMutant, PipalOps, PipalPaint, PipalReal, Rope = BEGIN OverlayMutant: TYPE = PipalOverlayMutant.OverlayMutant; overlayEditorClass: Pipal.Class _ Pipal.RegisterClass[name: "OverlayEditor", type: CODE [OverlayEditorRec]]; OverlayEditor: TYPE = REF OverlayEditorRec; OverlayEditorRec: TYPE = RECORD [ overlayMutant: OverlayMutant, mouseNow: PipalReal.Position _ PipalReal.zeroVector, -- mouse position now mouseDown: PipalReal.Position _ PipalReal.zeroVector, -- mouse position when a button went down previousTrackingArea: PipalPaint.Area _ Pipal.void, -- previous area modified by tracking; should be cleaned up at every paint if non nil! moving: BOOL _ FALSE ]; OverlayEditorSize: PipalReal.SizeProc ~ { oe: OverlayEditor = NARROW [object]; size _ PipalReal.ObjectSize[oe.overlayMutant]; }; OverlayEditorPaint: PipalPaint.PaintProc = { oe: OverlayEditor = NARROW [object]; PipalPaint.Paint[oe.overlayMutant, context]; }; EditOverlay: PipalEdit.EditProc = { om: OverlayMutant _ NARROW [mutant]; editor _ NEW [OverlayEditorRec _ [overlayMutant: om]]; PipalEdit.CreateBiscroller[editor, Rope.Cat[PipalOps.wDir, "PipalOverlayEditor.TIP"], Notify, TRUE]; }; Test: PROC [om: OverlayMutant] RETURNS [oe: OverlayEditor] = { oe _ NARROW [PipalEdit.Edit[om]]; }; TranslateArea: PROC [area: PipalPaint.Area, delta: PipalReal.Vector] RETURNS [new: PipalPaint.Area] = { new _ PipalReal.TransformObject[ImagerTransformation.Translate[delta], area]; }; Notify: PipalEdit.NotifyProc = { oe: OverlayEditor _ NARROW [editor]; om: OverlayMutant = oe.overlayMutant; atom: ATOM = NARROW [input.first]; result: REF; resultType: PipalMutate.ResultType; newMutant: Pipal.Object; newEditor _ oe; -- we return the same, i.e. we do not have immutability here! IF oe.previousTrackingArea#Pipal.void THEN { PipalPaint.Enqueue[queue, [type: clearAndPaint, area: oe.previousTrackingArea, data: oe.overlayMutant]]; oe.previousTrackingArea _ Pipal.void; }; SELECT atom FROM $MouseDown => { oe.mouseDown _ NARROW [input.rest.first, REF Imager.VEC]^; InputFocus.SetInputFocus[viewer]; }; $TrackSelected => { clipArea: PipalPaint.Area; outlines: Pipal.Object; IF NOT oe.moving THEN oe.mouseDown _ NARROW [input.rest.first, REF Imager.VEC]^; oe.mouseNow _ NARROW [input.rest.first, REF Imager.VEC]^; [resultType, result, newMutant] _ PipalMutate.ApplyCommand[om, $SelectedOutlines]; IF newMutant#om THEN ERROR; IF resultType#selectionArea THEN ERROR; outlines _ TranslateArea[result, PipalReal.Sub[oe.mouseNow, oe.mouseDown]]; clipArea _ PipalPaint.ChildArea[outlines, edgesChildren]; PipalPaint.Enqueue[queue, [type: clearAndPaint, area: clipArea, data: oe.overlayMutant]]; PipalPaint.Enqueue[queue, [type: paintArea, area: clipArea, data: PipalPaint.CreatePaintAreaOutline[outlines]]]; oe.previousTrackingArea _ clipArea; }; $Scrolling => PipalEdit.EnqueueSetCursor[queue, move]; $Scroll => { cc: PipalReal.Position _ NARROW [input.rest.first, REF Imager.VEC]^; delta: Imager.Transformation = ImagerTransformation.Translate[[cc.x-oe.mouseDown.x, cc.y-oe.mouseDown.y]]; PipalPaint.Enqueue[queue, [type: scale, data: delta]]; PipalEdit.EnqueueSetCursor[queue, textPointer]; }; ENDCASE => { arguments: LIST OF REF _ NIL; FOR list: LIST OF REF _ input.rest, list.rest WHILE list#NIL DO WITH list.first SELECT FROM cc: REF Imager.VEC => { oe.mouseNow _ cc^; arguments _ CONS [cc, arguments]; }; atom: ATOM => SELECT atom FROM $DownCoords => arguments _ CONS [NEW [PipalReal.Size _ oe.mouseDown], arguments]; ENDCASE => arguments _ CONS [atom, arguments]; ENDCASE => arguments _ CONS [atom, arguments]; ENDLOOP; [resultType, result, newMutant] _ PipalMutate.ApplyCommand[om, atom, List.Reverse[arguments]]; oe.overlayMutant _ NARROW [newMutant]; -- forgetting immutability ... SELECT resultType FROM none => PipalPaint.Enqueue[queue, [type: clearAndPaint, area: PipalPaint.fullArea, data: newMutant]]; changedArea => PipalPaint.Enqueue[queue, [type: clearAndPaint, area: result, data: newMutant]]; ENDCASE => ERROR; -- including object }; oe.moving _ atom=$TrackSelected; }; PushCommand: PipalMutate.CommandProc = { mutants: LIST OF Pipal.Object; [mutants, new] _ PipalOverlayMutant.Push[NARROW [mutant]]; WHILE mutants#NIL DO mutants _ mutants.rest; ENDLOOP; }; PopCommand: PipalMutate.CommandProc = { }; PassOverlayMutantCommand: PipalMutate.CommandProc ~ { oe: OverlayEditor = NARROW [mutant]; newOM: Pipal.Object; newOE: OverlayEditor; [resultType, result, newOM] _ PipalMutate.ApplyCommand[oe.overlayMutant, name, arguments, issuer]; newOE _ NEW [OverlayEditorRec _ oe^]; newOE.overlayMutant _ NARROW [newOM]; new _ newOE; }; PipalMutate.RegisterCommand[PipalOverlayMutant.overlayMutantClass, $Push, PushCommand]; PipalMutate.RegisterCommand[PipalOverlayMutant.overlayMutantClass, $Pop, PopCommand]; PipalMutate.RegisterCommand[overlayEditorClass, $Reset, PassOverlayMutantCommand]; PipalMutate.RegisterCommand[overlayEditorClass, $Undo, PassOverlayMutantCommand]; PipalMutate.RegisterCommand[overlayEditorClass, $Redo, PassOverlayMutantCommand]; PipalMutate.RegisterCommand[overlayEditorClass, $Flush, PassOverlayMutantCommand]; Pipal.PutClassMethod[overlayEditorClass, PipalReal.sizeMethod, NEW [PipalReal.SizeProc _ OverlayEditorSize]]; Pipal.PutClassMethod[overlayEditorClass, PipalPaint.paintMethod, NEW [PipalPaint.PaintProc _ OverlayEditorPaint]]; Pipal.PutClassMethod[PipalOverlayMutant.overlayMutantClass, PipalEdit.editMethod, NEW [PipalEdit.EditProc _ EditOverlay]]; END. ToBits: PROC [lines: ARRAY [0..16) OF Rope.ROPE] RETURNS [bits: Cursors.CursorArray] ~ { FOR line: NAT IN [0..16) DO bits[line] _ 0; FOR i: NAT IN [0..16) DO bits[line] _ 2*bits[line]; IF Rope.Equal[lines[line][i], "X"] THEN bits[line] _ bits[line]+1 ENDLOOP; ENDLOOP; }; HandCursor: PROC RETURNS [Cursors.CursorType] ~ { dots: ARRAY [0..16) Rope.ROPE; dots[0] = "................"; dots[1] = "................"; dots[2] = "................"; dots[3] = "................"; dots[4] = "................"; dots[5] = "................"; dots[6] = "................"; dots[7] = "................"; dots[8] = "................"; dots[9] = "................"; dots[10] = "................"; dots[11] = "................"; dots[12] = "................"; dots[13] = "................"; dots[14] = "................"; dots[15] = "................"; RETURN [Cursors.NewCursor[ToBits[dots]]]; }; †PipalOverlayEditorImpl.mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Louis Monier February 3, 1988 11:33:05 am PST Bertrand Serlet May 20, 1988 1:52:51 pm PDT BiScroller -- Paint the data structure Push / Pop Hacks [] _ Test[mutants.first, Rope.Cat[PipalOps.wDir, "PipalOverlayEditor.TIP"]]; -- AAAARRRGH viewer: ViewerClasses.Viewer = NARROW [issuer]; TRUSTED {Process.Detach[FORK PipalMutate.DestroyMutant[mutant]]}; -- believe it or not if you don't fork, you lock the viewers! (because of TerminalIO!) ViewerOps.CloseViewer[viewer]; -- this one does very very strange things ... Undo/Redo Commands Initialization Κ– "cedar" style˜codešœ™Kšœ<™Jšœœ˜!K˜K˜—šž œœ2œ˜gKšœM˜MK˜K˜—šžœ˜ Kšœœ ˜$Kšœ%˜%Kšœœœ˜"Kšœœ˜ Kšœ#˜#Kšœ˜KšœŸ=˜Mšœ$œ˜,Kšœh˜hKšœ%˜%K˜—šœ˜šœ˜Kšœœœœ˜:Kšœ!˜!K˜—šœ˜Kšœ˜Kšœ˜Kš œœ œœœœ˜PKšœœœœ˜9KšœR˜RKšœœœ˜Kšœœœ˜'KšœK˜KKšœ9˜9KšŸ™KšœY˜YKšœp˜pKšœ#˜#K˜—Kšœ6˜6˜ Kšœœœœ˜DK– [t: VEC]šœj˜jKšœ6˜6Kšœ/˜/K˜—šœ˜ Kš œ œœœœ˜š œœœœœœ˜?šœ œ˜šœœœ˜Kšœ˜Kšœ œ˜!K˜—šœœœ˜Kšœœœ-˜QKšœœ˜.—Kšœœ˜/—Kšœ˜—Kšœ^˜^KšœœŸ˜Ešœ ˜Kšœe˜eKšœ_˜_KšœœŸ˜&—K˜——Kšœ ˜ K˜——™šž œ˜(Kšœ œœ˜Kšœ)œ ˜:šœ œ˜KšœMŸ ™YKšœ˜Kšœ˜—K˜K˜—šž œ˜'KšΟbΠbk  ™/Kš‘ ‘ &ΠbcV™˜Kš ’-™LK˜K˜——™šžœ˜5Kšœœ ˜$K˜Kšœ˜Kšœb˜bKšœœ˜%Kšœœ ˜%K˜ K˜——™KšœW˜WKšœU˜UK˜KšœR˜RKšœQ˜QKšœQ˜QKšœR˜RK˜Kšœ?œ+˜mKšœAœ.˜rK˜šœRœ%˜zK˜——K˜Kšœ˜K˜K˜K˜K˜š žœœ œ œœœ ˜Xšœœœ ˜Kšœ˜šœœœ ˜Kšœ˜Kšœ!œ˜AKšœ˜—Kšœ˜—K˜—šž œœœ˜1Kšœœœ˜Kšœ Οfœ˜Kšœ £œ˜Kšœ £œ˜Kšœ £œ˜Kšœ £œ˜Kšœ £œ˜Kšœ £œ˜Kšœ £œ˜Kšœ £œ˜Kšœ £œ˜Kšœ £œ˜Kšœ £œ˜Kšœ £œ˜Kšœ £œ˜Kšœ £œ˜Kšœ £œ˜Kšœ#˜)K˜K˜—K˜—…—#