-- TEditSelection2Impl.mesa Edited by Paxton on December 27, 1982 4:47 pm
DIRECTORY
Carets USING [StartCaret],
Graphics USING [Context],
TEditDocument USING [Selection, SelectionId],
TEditSelection USING [Copy, Create, ExtendSelection, FixupSelection, FixupCaret, MarkSelection, pSel, sSel, fSel],
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: BOOLFALSE;
CaretVisible: PUBLIC ENTRY PROC RETURNS [BOOL] = BEGIN
ENABLE UNWIND => NULL;
RETURN [caretVisible]; END;
IsDown: PUBLIC ENTRY PROC [id: SelectionId] RETURNS [BOOL] = BEGIN
ENABLE UNWIND => NULL;
state: SelState = SELECT id FROM
primary => pSelState, secondary => sSelState, feedback => fSelState, ENDCASE => ERROR;
RETURN [state=down]; END;
ForceDown: PUBLIC ENTRY PROC [id: SelectionId] = BEGIN
ENABLE UNWIND => NULL;
SELECT id FROM
primary => pSelState ← down;
secondary => sSelState ← down;
feedback => fSelState ← down;
ENDCASE => ERROR;
END;
ShowSelection: PUBLIC ENTRY PROC
[id: SelectionId, self: ViewerClasses.Viewer, context: Graphics.Context] = BEGIN
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];
END;
TakeDownForRedisplay: PUBLIC ENTRY PROC
[id: SelectionId, self: ViewerClasses.Viewer, context: Graphics.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: Graphics.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, ~sel.start.metricsValid, ~sel.end.metricsValid];
PutSelectionUpI[id, self, context];
IF caret AND sel.viewer=self THEN BEGIN
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];
END;
};
AdjustSelStates: PUBLIC ENTRY PROC [self: ViewerClasses.Viewer] = BEGIN
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;
END;
TakeSelectionDown: PUBLIC ENTRY PROC
[id: SelectionId, self: ViewerClasses.Viewer, context: Graphics.Context] = BEGIN
ENABLE UNWIND => NULL;
TakeSelectionDownI[id, self, context];
END;
TakeSelectionDownI: PROC
[id: SelectionId, self: ViewerClasses.Viewer, context: Graphics.Context] = BEGIN
sel: 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 sel.viewer # self OR state=down THEN RETURN;
IF sel.granularity#point AND state=up THEN MarkSelection[context, self, sel, id];
SELECT id FROM
primary => pSelState ← down;
secondary => sSelState ← down;
feedback => fSelState ← down;
ENDCASE => ERROR;
END;
PutSelectionUp: PUBLIC ENTRY PROC
[id: SelectionId, self: ViewerClasses.Viewer, context: Graphics.Context] = BEGIN
ENABLE UNWIND => NULL;
PutSelectionUpI[id, self, context];
END;
PutSelectionUpI: PROC [id: SelectionId, self: ViewerClasses.Viewer, context: Graphics.Context] = BEGIN
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 OR state=up THEN RETURN; -- something went wrong
Copy[source: sel, dest: selUp];
IF sel.granularity#point AND state=down THEN MarkSelection[context, self, selUp, id];
SELECT id FROM
primary => pSelState ← up;
secondary => sSelState ← up;
feedback => fSelState ← up;
ENDCASE => ERROR;
END;
END.