-- 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.