-- TiogaSelection2Impl.mesa Edited by Paxton on December 27, 1982 4:47 pm
DIRECTORY
Carets USING [StartCaret],
Graphics USING [Context],
TiogaDocument USING [Selection, SelectionId],
TiogaSelection USING [Copy, Create, ExtendSelection, FixupSelection, FixupCaret, MarkSelection, pSel, sSel, fSel],
ViewerClasses USING [Viewer];
TiogaSelection2Impl: CEDAR MONITOR
IMPORTS Carets, TiogaSelection
EXPORTS TiogaSelection = BEGIN
OPEN TiogaDocument, TiogaSelection;
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] =
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.