<<>> <> <> <> <> <> DIRECTORY Carets USING [StartCaret], Imager USING [Context], TEditDocument USING [Selection, SelectionId], TEditSelection USING [CannotFindIt, Copy, Create, ExtendSelection, FixupSelection, FixupCaret, MarkSelection, pSel, sSel, fSel, nilSel], ViewerClasses USING [Viewer]; TEditSelection2Impl: CEDAR MONITOR IMPORTS Carets, TEditSelection EXPORTS TEditSelection = BEGIN OPEN TEditDocument, TEditSelection; SelState: TYPE = {up, down}; pSelState, sSelState, fSelState: SelState ¬ down; pSelUp: Selection ¬ Create[]; -- copy of pSel from when put it up sSelUp: Selection ¬ Create[]; -- copy of sSel from when put it up fSelUp: Selection ¬ Create[]; -- copy of fSel from when put it up caretVisible: BOOL ¬ FALSE; CaretVisible: PUBLIC ENTRY PROC RETURNS [BOOL] = { ENABLE UNWIND => NULL; RETURN [caretVisible]; }; IsDown: PUBLIC ENTRY PROC [id: SelectionId] RETURNS [BOOL] = { ENABLE UNWIND => NULL; state: SelState = SELECT id FROM primary => pSelState, secondary => sSelState, feedback => fSelState, ENDCASE => ERROR; RETURN [state=down]; }; ForceDown: PUBLIC ENTRY PROC [id: SelectionId] = { ENABLE UNWIND => NULL; SELECT id FROM primary => pSelState ¬ down; secondary => sSelState ¬ down; feedback => fSelState ¬ down; ENDCASE => ERROR; }; ShowSelection: PUBLIC ENTRY PROC [id: SelectionId, self: ViewerClasses.Viewer, context: Imager.Context] = { ENABLE UNWIND => NULL; sel: Selection = SELECT id FROM primary => pSel, secondary => sSel, feedback => fSel, ENDCASE => ERROR; selUp: Selection = SELECT id FROM primary => pSelUp, secondary => sSelUp, feedback => fSelUp, ENDCASE => ERROR; IF sel.viewer # self THEN RETURN; IF sel.start.metricsValid = sel.end.metricsValid THEN TakeSelectionDownI[id, self, context] ELSE IF selUp.viewer=self THEN ExtendSelection[context, self, selUp, sel, id, sel.start.metricsValid] ELSE TakeSelectionDownI[id, self, context]; }; TakeDownForRedisplay: PUBLIC ENTRY PROC [id: SelectionId, self: ViewerClasses.Viewer, context: Imager.Context] = { ENABLE UNWIND => NULL; sel, selUp: Selection; state: SelState; SELECT id FROM primary => { sel ¬ pSel; state ¬ pSelState; selUp ¬ pSelUp }; secondary => { sel ¬ sSel; state ¬ sSelState; selUp ¬ sSelUp }; feedback => { sel ¬ fSel; state ¬ fSelState; selUp ¬ fSelUp }; ENDCASE => ERROR; IF selUp.viewer # self THEN RETURN; IF state=up THEN TakeSelectionDownI[id, self, context]; sel.start.metricsValid ¬ sel.end.metricsValid ¬ FALSE; }; FixUpAfterDisplay: PUBLIC ENTRY PROC [id: SelectionId, self: ViewerClasses.Viewer, context: Imager.Context, caret: BOOL] = { ENABLE UNWIND => NULL; sel, selUp: Selection; state: SelState; SELECT id FROM primary => { sel ¬ pSel; state ¬ pSelState; selUp ¬ pSelUp }; secondary => { sel ¬ sSel; state ¬ sSelState; selUp ¬ sSelUp }; feedback => { sel ¬ fSel; state ¬ fSelState; selUp ¬ fSelUp }; ENDCASE => ERROR; IF sel.viewer # self THEN RETURN; FixupSelection[sel, self, NOT sel.start.metricsValid, NOT sel.end.metricsValid ! TEditSelection.CannotFindIt => { Copy[source: nilSel, dest: sel]; CONTINUE; } ]; PutSelectionUpI[id, self, context]; IF caret AND sel.viewer=self THEN { FixupCaret[sel]; IF id=primary THEN caretVisible ¬ (sel.caretY # LAST[INTEGER]); -- remember if visible Carets.StartCaret[self, sel.caretX, sel.caretY, IF id=primary THEN primary ELSE secondary]; }; }; AdjustSelStates: PUBLIC ENTRY PROC [self: ViewerClasses.Viewer] = { ENABLE UNWIND => NULL; IF pSelState=up AND pSelUp.viewer=self THEN pSelState ¬ down; IF sSelState=up AND sSelUp.viewer=self THEN sSelState ¬ down; IF fSelState=up AND fSelUp.viewer=self THEN fSelState ¬ down; }; TakeSelectionDown: PUBLIC ENTRY PROC [id: SelectionId, self: ViewerClasses.Viewer, context: Imager.Context] = { ENABLE UNWIND => NULL; TakeSelectionDownI[id, self, context]; }; TakeSelectionDownI: INTERNAL PROC [id: SelectionId, self: ViewerClasses.Viewer, context: Imager.Context] = { selUp: Selection = SELECT id FROM primary => pSelUp, secondary => sSelUp, feedback => fSelUp, ENDCASE => ERROR; state: SelState = SELECT id FROM primary => pSelState, secondary => sSelState, feedback => fSelState, ENDCASE => ERROR; IF state#down THEN { IF selUp.viewer # self THEN RETURN; -- something went wrong IF selUp.granularity#point THEN MarkSelection[context, self, selUp, id]; SELECT id FROM primary => pSelState ¬ down; secondary => sSelState ¬ down; feedback => fSelState ¬ down; ENDCASE => ERROR; }; }; PutSelectionUp: PUBLIC ENTRY PROC [id: SelectionId, self: ViewerClasses.Viewer, context: Imager.Context] = { ENABLE UNWIND => NULL; PutSelectionUpI[id, self, context]; }; PutSelectionUpI: INTERNAL PROC [id: SelectionId, self: ViewerClasses.Viewer, context: Imager.Context] = { sel, selUp: Selection; state: SelState; SELECT id FROM primary => { sel ¬ pSel; state ¬ pSelState; selUp ¬ pSelUp }; secondary => { sel ¬ sSel; state ¬ sSelState; selUp ¬ sSelUp }; feedback => { sel ¬ fSel; state ¬ fSelState; selUp ¬ fSelUp }; ENDCASE => ERROR; IF state#up THEN { Copy[source: sel, dest: selUp]; IF selUp.viewer # self THEN RETURN; -- something went wrong IF selUp.granularity#point THEN MarkSelection[context, self, selUp, id]; SELECT id FROM primary => pSelState ¬ up; secondary => sSelState ¬ up; feedback => fSelState ¬ up; ENDCASE => ERROR; }; }; END.