-- ButtonCellsImpl.mesa
-- last edit July 10, 1984 4:45:08 pm PDT Sturgis
DIRECTORY
ButtonCells USING[],
Buttons USING[ButtonProc, Create, ReLabel],
GCell USING[NoteItemSelection],
IO USING[STREAM],
NewCalcGlobal USING[Displayer, Document],
Rope USING[Equal, ROPE],
StructureNodes USING[Action, DACell, DisplayArray, GetContextDACell, MarkElementDirty, PrePaintPass, StructureNode, StructureNodeBody, StructureNodeProcs],
VFonts USING[FontHeight, StringWidth],
ViewerClasses USING[Viewer],
ViewerOps USING[AddProp, DestroyViewer, PaintViewer],
ViewerTools USING[GetSelectedViewer, InhibitUserEdits, MakeNewTextViewer, SetContents, SetSelection];
ButtonCellsImpl: MONITOR IMPORTS Buttons, GCell, Rope, StructureNodes, VFonts, ViewerOps, ViewerTools EXPORTS ButtonCells =
BEGIN OPEN IO, NewCalcGlobal, ViewerClasses;
BCell: TYPE = REF BCellBody;
BCellBody: TYPE = RECORD[
document: NewCalcGlobal.Document,
displayer: Displayer,
dac: StructureNodes.DACell,
da: StructureNodes.DisplayArray,
sn: StructureNodes.StructureNode, -- of the button, someday maybe I can get rid of this
vParent: Viewer,
newLabel, oldLabel: Rope.ROPE,
lastPrePaintY, lastPrePaintX, lastPrePaintW: INTEGER,
dirty: BOOLEAN,
viewer: Viewer,
mode: BCellMode,
proc: PROCEDURE[REF ANY],
procArg: REF ANY,
setSelection: BOOLEAN
];
BCellMode: TYPE = {button, textBox, nil};
CreateBCell: PUBLIC PROCEDURE[document: NewCalcGlobal.Document, displayer: Displayer, vParent: Viewer, label, forSize: Rope.ROPE, proc: PROCEDURE[REF ANY], procArg: REF ANY, setSelection: BOOLEAN ← FALSE] RETURNS[StructureNodes.StructureNode] =
BEGIN
bc: BCell ← NEW[BCellBody ← [
document: document,
displayer: displayer,
dac: NIL,
sn: NIL,
vParent: vParent,
newLabel: label,
oldLabel: NIL,
lastPrePaintY: 0, lastPrePaintX: 0, lastPrePaintW: 0,
dirty: FALSE,
viewer: NIL,
mode: nil,
proc: proc,
procArg: procArg,
setSelection: setSelection]];
bc.sn ← NEW[StructureNodes.StructureNodeBody ← [bc, BCellSNProcs]];
RETURN[bc.sn];
END;
ReLabelBCell: PUBLIC PROCEDURE[bCell: StructureNodes.StructureNode, newLabel: Rope.ROPE] =
BEGIN
bCellX: BCell ← NARROW[bCell.ref];
IF NOT Rope.Equal[bCellX.newLabel, newLabel] AND bCellX.viewer # NIL THEN
IF bCellX.mode = button THEN Buttons.ReLabel[bCellX.viewer, newLabel, TRUE]
ELSE
BEGIN
ViewerTools.SetContents[bCellX.viewer, newLabel, TRUE];
StructureNodes.MarkElementDirty[bCellX.da, 0, 0];
END;
bCellX.newLabel ← newLabel;
END;
BCellSNProcs: REF StructureNodes.StructureNodeProcs ← NEW[StructureNodes.StructureNodeProcs ← [
CheckBCellForDirtyData,
PreShowBCell,
ShowBCellLine,
PrePrePaintBCell,
PrePaintBCell,
PaintBCell,
UnPaintBCell,
NoteEnclosingCellBCell,
NoteCoordinatesBCell,
SaveBCell,
ActBCell,
SubstituteInBCell,
AbandonBCell,
VerifyBCell]];
-- BCell Logical node interface procedures
SaveBCell: PROCEDURE[node: StructureNodes.StructureNode, to: STREAM] =
{ERROR};
ActBCell: PROCEDURE[info: StructureNodes.StructureNode, I, J: CARDINAL, action: StructureNodes.Action, p1, p2: REF ANY] RETURNS[StructureNodes.StructureNode, CARDINAL, CARDINAL] =
BEGIN
bc: BCell ← NARROW[info.ref];
sn: StructureNodes.StructureNode; cI, cJ: CARDINAL;
[sn, cI, cJ] ← StructureNodes.GetContextDACell[bc.dac];
RETURN[sn, cI, cJ];
END;
SubstituteInBCell: PROCEDURE[info: StructureNodes.StructureNode, newText, oldText: Rope.ROPE] =
{ERROR};
AbandonBCell: PROCEDURE[node: StructureNodes.StructureNode] =
BEGIN
bc: BCell ← NARROW[node.ref];
ClearBCellViewer[bc];
bc.sn ← NIL;
END;
VerifyBCell: PROCEDURE[node: StructureNodes.StructureNode] =
BEGIN
bc: BCell ← NARROW[node.ref];
END;
-- display node interface procedures
CheckBCellForDirtyData: PROCEDURE[node: StructureNodes.StructureNode] =
BEGIN
bc: BCell ← NARROW[node.ref];
END;
PreShowBCell: PROCEDURE[node: StructureNodes.StructureNode] RETURNS[lead, height: INTEGER, space, L, A, B, R, W: INTEGER] =
{ERROR};
ShowBCellLine: PROCEDURE[node: StructureNodes.StructureNode, L, R, W: INTEGER, lineX: INTEGER, to: STREAM] =
{ERROR};
PrePrePaintBCell: PROCEDURE[node: StructureNodes.StructureNode] RETURNS[lead, height: INTEGER, space, L, A, B, R, W: INTEGER] =
BEGIN
bc: BCell ← NARROW[node.ref];
RETURN[
lead: 0,
height: VFonts.FontHeight[] + 5,
space: 0,
L: 0, A: 0, B: 0, R: 0,
W: VFonts.StringWidth[bc.newLabel] + 20
];
END;
PrePaintBCell: PROCEDURE[node: StructureNodes.StructureNode, y, x, L, R, W: INTEGER, pass: StructureNodes.PrePaintPass] =
BEGIN
bc: BCell ← NARROW[node.ref];
paramChanges: BOOLEAN ← bc.lastPrePaintY # y OR bc.lastPrePaintX # x OR bc.lastPrePaintW # W;
IF paramChanges OR bc.viewer = NIL OR bc.oldLabel # bc.newLabel THEN
BEGIN
button: Viewer;
IF ViewerTools.GetSelectedViewer[] = bc.viewer THEN
ForceButtonSelection[bc, y, x, L, R, W]
ELSE
BEGIN
ClearBCellViewer[bc];
bc.oldLabel ← bc.newLabel;
button ← Buttons.Create[
info: [
name: bc.newLabel,
wx: x,
ww: W,
wy: y,
wh: VFonts.FontHeight[]+5,
parent: bc.vParent,
border: FALSE,
scrollable: FALSE],
proc: NominalBCellProc,
clientData: bc,
paint: FALSE,
fork: TRUE];
bc.viewer ← button;
bc.mode ← button;
END;
bc.dirty ← TRUE;
END;
bc.lastPrePaintX ← x;
bc.lastPrePaintY ← y;
bc.lastPrePaintW ← W
END;
PaintBCell: PROCEDURE[node: StructureNodes.StructureNode, dirtyOnly: BOOLEAN] =
BEGIN
bc: BCell ← NARROW[node.ref];
IF NOT dirtyOnly OR bc.dirty THEN
BEGIN
ViewerOps.PaintViewer[bc.viewer, all];
bc.dirty ← FALSE;
END;
END;
UnPaintBCell: PROCEDURE[node: StructureNodes.StructureNode] =
BEGIN
END;
NoteEnclosingCellBCell: PROCEDURE[node: StructureNodes.StructureNode, dac: StructureNodes.DACell] =
BEGIN
bc: BCell ← NARROW[node.ref];
bc.dac ← dac;
END;
NoteCoordinatesBCell: PROCEDURE[node: StructureNodes.StructureNode, da: StructureNodes.DisplayArray, I, J: CARDINAL] =
BEGIN
bc: BCell ← NARROW[node.ref];
bc.da ← da;
END;
-- BCell support code
ClearBCellViewer: PROCEDURE[bc: BCell] =
BEGIN
IF bc.viewer # NIL THEN
BEGIN
Buttons.ReLabel[bc.viewer, "", TRUE];
ViewerOps.DestroyViewer[bc.viewer, FALSE];
bc.viewer ← NIL;
bc.mode ← nil;
END;
END;
NominalBCellProc: Buttons.ButtonProc = TRUSTED
BEGIN
bc: BCell ← NARROW[clientData];
NBCPInternal: PROCEDURE =
BEGIN
bc.proc[bc.procArg];
IF bc.setSelection THEN ForceButtonSelection[bc, bc.lastPrePaintY, bc.lastPrePaintX, 0, 0, bc.lastPrePaintW];
IF bc.da # NIL THEN StructureNodes.MarkElementDirty[bc.da, 0, 0];
END;
bc.document.procs.executeInMonitor[bc.document, NBCPInternal];
END;
ForceButtonSelection: PROCEDURE[bc: BCell, y, x, L, R, W: INTEGER] =
BEGIN
textBox: ViewerClasses.Viewer;
GCell.NoteItemSelection[bc.displayer, bc.sn, 0];
ClearBCellViewer[bc];
textBox ← ViewerTools.MakeNewTextViewer[
info: [
parent: bc.vParent,
wx: x,
wy: y,
ww: W,
wh: VFonts.FontHeight[]+5,
border: FALSE,
scrollable: FALSE],
paint: FALSE];
ViewerTools.InhibitUserEdits[textBox];
ViewerTools.SetContents[textBox, bc.newLabel];
ViewerOps.AddProp[textBox, $BCell, bc];
ViewerTools.SetSelection[textBox, NIL];
bc.viewer ← textBox;
bc.mode ← textBox;
bc.lastPrePaintX ← x;
bc.lastPrePaintY ← y;
bc.lastPrePaintW ← W;
StructureNodes.MarkElementDirty[bc.da, 0, 0];
END;
ForceNoteBCellSelection: PUBLIC PROCEDURE[bcRef: REF ANY] =
BEGIN
bc: BCell ← NARROW[bcRef];
GCell.NoteItemSelection[bc.displayer, bc.sn, 0];
END;
END..
-- November 5, 1982 12:43 pm: Sturgis, ButtonCellsImpl. Moved from NewCalcImpl
-- November 14, 1982 2:02 pm: convert to new selection logic.
-- February 27, 1983 4:04 pm: replace LogicalNode, DisplayNode, and BCell etc with StructureNode. Took about 10 minutes.
-- RTE: February 28, 1983 11:25 am: bc.sn was found to be nil, not sure what the problem is, so replaced "RETURN[bc.sn ← NEW[]]" with "bc.sn ← NEW[]; RETURN[bc.sn]". February 28, 1983 11:27 am: nope, wasn't the problem.
-- RTE: February 28, 1983 11:36 am: ClearBCellViewer was setting bCell.sn to Nil, and shouldnt have, that should have been done by abandon..
-- February 28, 1983 2:22 pm: add dummy noteCoordinates
-- March 8, 1983 11:44 am: add UnPaint Stub.
-- March 8, 1983 12:04 pm: add appropriate code to inform containing display array that button is dirty.
-- RTE: July 10, 1984 4:45:04 pm PDT: some confusion about new locations when the viewer is being forcebly selected. So, modified ForceButtonSelection to use new coordinates, and to record the new coordinates as lastPrePaint coordinates.