-- EasyToolImpl.mesa -- last edit June 22, 1984 9:27:11 am PDT Sturgis -- Swinehart, July 19, 1985 10:15:29 am PDT DIRECTORY Basics USING[LongNumber], Buttons USING[Button, ButtonProc, Create, ReLabel], Containers USING[Create], Convert USING[CardFromRope, IntFromRope, RopeFromCard, RopeFromInt], EasyTool USING[DefineItemsProc], Labels USING[Create], Rope USING[Cat, ROPE], VFonts USING[FontHeight, StringWidth], ViewerClasses USING[Viewer], ViewerOps USING[DestroyViewer], ViewerTools USING[GetContents, MakeNewTextViewer, SetContents]; EasyToolImpl: PROGRAM IMPORTS Buttons, Containers, Convert, Labels, Rope, VFonts, ViewerOps, ViewerTools EXPORTS EasyTool = BEGIN OPEN EasyTool, ViewerClasses; -- public types ToolHandle: TYPE = REF ToolBody; ToolBody: PUBLIC TYPE = RECORD[ container: ViewerClasses.Viewer, currentY: INTEGER, nextX: INTEGER, nextY: INTEGER, items: REF ANY ]; ItemHandle: TYPE = REF ItemBody; ItemBody: PUBLIC TYPE = RECORD[ w1, w2, w3: CARDINAL, -- min field widths height: CARDINAL, data: REF ANY, next: ItemHandle -- next is used in row chain in matrices ]; -- Public Procedures DefineTool: PUBLIC PROCEDURE[toolName: Rope.ROPE, toolData: REF ANY, obtainItems: DefineItemsProc] RETURNS[ToolHandle] = BEGIN tool: ToolHandle _ NEW[ToolBody _ [container: Containers.Create[[name: toolName]], currentY: 10, nextX: 0, nextY: 10 + VFonts.FontHeight[] + 2]]; defineButton: PROCEDURE[buttonName: Rope.ROPE, buttonProc: PROCEDURE[REF ANY], data: REF ANY] RETURNS[ItemHandle] = {RETURN[AddButtonItemToTool[tool, buttonName, NIL, buttonProc, IF data # NIL THEN data ELSE toolData, TRUE]]}; defineItem: PROCEDURE[ prefix, label, suffix: Rope.ROPE _ NIL, ref: REF ANY, forSize: Rope.ROPE _ NIL, editable: BOOLEAN _ FALSE] RETURNS[ItemHandle] = {RETURN[AddLabeledItemToTool[tool, Rope.Cat[prefix, label, suffix], label, ref, forSize, editable]]}; defineFiller: PROCEDURE[width, height: CARDINAL] RETURNS[ItemHandle]= {RETURN[AddFillerItemToTool[tool, width, height]]}; defineMatrix: PROCEDURE[items: LIST OF LIST OF ItemHandle, rowLead, colSpacing: INTEGER] RETURNS[ItemHandle] = {RETURN[AddMatrixToTool[items, rowLead, colSpacing]]}; defineRow: PROCEDURE[items: LIST OF ItemHandle, spacing: INTEGER] RETURNS[ItemHandle] = {RETURN[AddRowToTool[items, spacing]]}; defineColumn: PROCEDURE[items: LIST OF ItemHandle, lead: INTEGER] RETURNS[ItemHandle] = {RETURN[AddColumnToTool[items, lead]]}; context: ItemHandle _ obtainItems[defineButton, defineItem, defineFiller, defineMatrix, defineRow, defineColumn]; PositionItem[context, 0, context.w1, context.w1, context.w2, context.w1+context.w2, context.w3, 0]; RETURN[tool]; END; UpdateScreen: PUBLIC PROCEDURE[tool: ToolHandle] = BEGIN item: REF ANY _ tool.items; WHILE item # NIL DO SELECT TRUE FROM ISTYPE[item, TextItemHandle] => item _ UpdateScreenText[NARROW[item]]; ISTYPE[item, UnsignedItemHandle] => item _ UpdateScreenUnsigned[NARROW[item]]; ISTYPE[item, CardinalItemHandle] => item _ UpdateScreenCardinal[NARROW[item]]; ISTYPE[item, SignedItemHandle] => item _ UpdateScreenSigned[NARROW[item]]; ISTYPE[item, BooleanItemHandle] => item _ UpdateScreenBoolean[NARROW[item]]; ENDCASE => ERROR; ENDLOOP; END; -- Public Errors UnimplimentedType: PUBLIC ERROR = CODE; -- local types ButtonItemHandle: TYPE = REF ButtonItemBody; ButtonItemBody: TYPE = RECORD[ tool: ToolHandle, proc: PROCEDURE[REF ANY], forSize: Rope.ROPE, name: Rope.ROPE, border: BOOLEAN, button: Buttons.Button, data: REF ANY ]; LabelItemHandle: TYPE = REF LabelItemBody; LabelItemBody: TYPE = RECORD[ tool: ToolHandle, name: Rope.ROPE, w, h: INTEGER, viewer: Viewer ]; SubTextItemHandle: TYPE = REF SubTextItemBody; SubTextItemBody: TYPE = RECORD[ parent: ViewerClasses.Viewer, v: Viewer, mode: SubTextItemMode, editable: BOOLEAN, textRef: REF Rope.ROPE, contents: Rope.ROPE, x, y, w, h: INTEGER, correspondingItem: REF ANY ]; SubTextItemMode: TYPE = {nil, button, textBox}; FillerItemHandle: TYPE = REF FillerItemBody; FillerItemBody: TYPE = RECORD[ justToBeNonEmpty: CARDINAL ]; TextItemHandle: TYPE = REF TextItemBody; TextItemBody: TYPE = RECORD[ forValSize: Rope.ROPE, label: LabelItemHandle, ref: REF Rope.ROPE, val: Rope.ROPE, text: REF Rope.ROPE, subTextItem: SubTextItemHandle, nextItem: REF ANY -- used in chain for update screen and value ]; UnsignedItemHandle: TYPE = REF UnsignedItemBody; UnsignedItemBody: TYPE = RECORD[ forValSize: Rope.ROPE, label: LabelItemHandle, ref: REF LONG CARDINAL, val: LONG CARDINAL, text: REF Rope.ROPE, subTextItem: SubTextItemHandle, nextItem: REF ANY -- used in chain for update screen and value ]; CardinalItemHandle: TYPE = REF CardinalItemBody; CardinalItemBody: TYPE = RECORD[ forValSize: Rope.ROPE, label: LabelItemHandle, ref: REF CARDINAL, val: CARDINAL, text: REF Rope.ROPE, subTextItem: SubTextItemHandle, nextItem: REF ANY -- used in chain for update screen and value ]; SignedItemHandle: TYPE = REF SignedItemBody; SignedItemBody: TYPE = RECORD[ forValSize: Rope.ROPE, label: LabelItemHandle, ref: REF INT, val: INT, text: REF Rope.ROPE, subTextItem: SubTextItemHandle, nextItem: REF ANY -- used in chain for update screen and value ]; BooleanItemHandle: TYPE = REF BooleanItemBody; BooleanItemBody: TYPE = RECORD[ tool: ToolHandle, label: LabelItemHandle, ref: REF BOOLEAN, val: BOOLEAN, button: Buttons.Button, editable: BOOLEAN, changed: BOOLEAN, x, y, w, h: INTEGER, nextItem: REF ANY -- used in chain for update screen and value ]; MatrixHandle: TYPE = REF MatrixBody; MatrixBody: TYPE = RECORD[ rowLead: INTEGER, colSpacing: INTEGER, columns: MatrixColumnHandle, rows: MatrixRowHandle]; -- following are used in matrices MatrixColumnHandle: TYPE = REF MatrixColumnBody; MatrixColumnBody: TYPE = RECORD[ w1, w2, w3: CARDINAL, -- sub column widths next: MatrixColumnHandle]; MatrixRowHandle: TYPE = REF MatrixRowBody; MatrixRowBody: TYPE = RECORD[ h: CARDINAL, -- row height items: ItemHandle, next: MatrixRowHandle]; -- localProcedures AddLabelToTool: PROCEDURE[tool: ToolHandle, label: Rope.ROPE] RETURNS[LabelItemHandle] = BEGIN labelItem: LabelItemHandle _ NEW[LabelItemBody _ [tool, label, 0, 0, NIL]]; labelItem.w _ VFonts.StringWidth[label] + 10; labelItem.h _ VFonts.FontHeight[] + 5; RETURN[labelItem]; END; AddSubTextItemToTool: PROCEDURE[tool: ToolHandle, textRef: REF Rope.ROPE, forSize: Rope.ROPE, editable: BOOLEAN, correspondingItem: REF ANY] RETURNS[SubTextItemHandle] = BEGIN w: INTEGER _ VFonts.StringWidth[IF forSize # NIL THEN forSize ELSE textRef^] + 10; h: INTEGER _ VFonts.FontHeight[] + 5; item: SubTextItemHandle _ NEW[SubTextItemBody _ [tool.container, NIL, nil, editable, textRef, textRef^, 0, 0, w, h, correspondingItem]]; RETURN[item]; END; AddFillerItemToTool: PROCEDURE[tool: ToolHandle, width, height: CARDINAL] RETURNS[ItemHandle] = BEGIN fItem: FillerItemHandle _ NEW[FillerItemBody _ [0]]; RETURN[NEW[ItemBody _ [width, 0, 0, height, fItem, NIL]]]; END; AddLabeledItemToTool: PROCEDURE[tool: ToolHandle, fullName: Rope.ROPE, label: Rope.ROPE, ref: REF ANY, forSize: Rope.ROPE, editable: BOOLEAN] RETURNS[ItemHandle] = BEGIN SELECT TRUE FROM ISTYPE[ref, REF Rope.ROPE] => BEGIN textRef: REF Rope.ROPE _ NARROW[ref]; RETURN[AddTextItemToTool[tool, label, textRef, forSize, editable, NIL]]; END; ISTYPE[ref, REF LONG CARDINAL] => BEGIN lcRef: REF LONG CARDINAL _ NARROW[ref]; RETURN[AddUnsignedItemToTool[tool, label, lcRef, forSize, editable]]; END; ISTYPE[ref, REF CARDINAL] => BEGIN cRef: REF CARDINAL _ NARROW[ref]; RETURN[AddCardinalItemToTool[tool, label, cRef, forSize, editable]]; END; ISTYPE[ref, REF INT] => BEGIN intRef: REF INT _ NARROW[ref]; RETURN[AddSignedItemToTool[tool, label, intRef, forSize, editable]]; END; ISTYPE[ref, REF BOOLEAN] => BEGIN boolRef: REF BOOLEAN _ NARROW[ref]; RETURN[AddBooleanItemToTool[tool, label, boolRef, editable]]; END; ENDCASE => ERROR UnimplimentedType; END; AddUnsignedItemToTool: PROCEDURE[tool: ToolHandle, labelName: Rope.ROPE, ref: REF LONG CARDINAL, forSize: Rope.ROPE, editable: BOOLEAN] RETURNS[ItemHandle] = BEGIN initialText: Rope.ROPE _ Convert.RopeFromCard[ref^]; uItem: UnsignedItemHandle _ NEW[UnsignedItemBody _ [forSize, NIL, ref, ref^, NEW[Rope.ROPE _ initialText], NIL, NIL]]; subTextItem: SubTextItemHandle _ AddSubTextItemToTool[tool, uItem.text, forSize, editable, uItem]; labelItem: LabelItemHandle _ AddLabelToTool[tool, Rope.Cat[labelName, ":"]]; uItem.subTextItem _ subTextItem; uItem.nextItem _ tool.items; tool.items _ uItem; uItem.label _ labelItem; RETURN[NEW[ItemBody _ [labelItem.w , subTextItem.w, 0, MAX[labelItem.h, subTextItem.h], uItem, NIL]]]; END; AddCardinalItemToTool: PROCEDURE[tool: ToolHandle, labelName: Rope.ROPE, ref: REF CARDINAL, forSize: Rope.ROPE, editable: BOOLEAN] RETURNS[ItemHandle] = BEGIN initialText: Rope.ROPE _ Convert.RopeFromCard[ref^]; cItem: CardinalItemHandle _ NEW[CardinalItemBody _ [forSize, NIL, ref, ref^, NEW[Rope.ROPE _ initialText], NIL, NIL]]; subTextItem: SubTextItemHandle _ AddSubTextItemToTool[tool, cItem.text, forSize, editable, cItem]; labelItem: LabelItemHandle _ AddLabelToTool[tool, Rope.Cat[labelName, ":"]]; cItem.subTextItem _ subTextItem; cItem.nextItem _ tool.items; tool.items _ cItem; cItem.label _ labelItem; RETURN[NEW[ItemBody _ [labelItem.w , subTextItem.w, 0, MAX[labelItem.h, subTextItem.h], cItem, NIL]]]; END; AddSignedItemToTool: PROCEDURE[tool: ToolHandle, labelName: Rope.ROPE, ref: REF INT, forSize: Rope.ROPE, editable: BOOLEAN] RETURNS[ItemHandle] = BEGIN initialText: Rope.ROPE _ Convert.RopeFromInt[ref^]; sItem: SignedItemHandle _ NEW[SignedItemBody _ [forSize, NIL, ref, ref^, NEW[Rope.ROPE _ initialText], NIL, NIL]]; subTextItem: SubTextItemHandle _ AddSubTextItemToTool[tool, sItem.text, forSize, editable, sItem]; labelItem: LabelItemHandle _ AddLabelToTool[tool, Rope.Cat[labelName, ":"]]; sItem.subTextItem _ subTextItem; sItem.nextItem _ tool.items; tool.items _ sItem; sItem.label _ labelItem; RETURN[NEW[ItemBody _ [labelItem.w , subTextItem.w, 0, MAX[labelItem.h, subTextItem.h], sItem, NIL]]]; END; AddTextItemToTool: PROCEDURE[tool: ToolHandle, labelName: Rope.ROPE, ref: REF Rope.ROPE, forSize: Rope.ROPE, editable: BOOLEAN, correspondingItem: REF ANY] RETURNS[ItemHandle] = BEGIN w: INTEGER _ VFonts.StringWidth[IF forSize # NIL THEN forSize ELSE ref^] + 10; h: INTEGER _ VFonts.FontHeight[] + 5; tItem: TextItemHandle _ NEW[TextItemBody _ [forSize, NIL, ref, ref^, NEW[Rope.ROPE _ ref^], NIL, NIL]]; subTextItem: SubTextItemHandle _ AddSubTextItemToTool[tool, tItem.text, forSize, editable, tItem]; labelItem: LabelItemHandle _ AddLabelToTool[tool, Rope.Cat[labelName, ":"]]; tItem.subTextItem _ subTextItem; tItem.nextItem _ tool.items; tool.items _ tItem; tItem.label _ labelItem; RETURN[NEW[ItemBody _ [labelItem.w , subTextItem.w, 0, MAX[labelItem.h, subTextItem.h], tItem, NIL]]]; END; AddBooleanItemToTool: PROCEDURE[tool: ToolHandle, labelName: Rope.ROPE, ref: REF BOOLEAN, editable: BOOLEAN] RETURNS[ItemHandle] = BEGIN bItem: BooleanItemHandle _ NEW[BooleanItemBody _ [tool, NIL, ref, ref^, NIL, editable, FALSE, 0, 0, 0, 0, NIL]]; labelItem: LabelItemHandle _ AddLabelToTool[tool, Rope.Cat[labelName, ":"]]; bItem.nextItem _ tool.items; tool.items _ bItem; bItem.label _ labelItem; bItem.w _ VFonts.StringWidth["FALSE"] + 10; bItem.h _ VFonts.FontHeight[] + 5; RETURN[NEW[ItemBody _ [labelItem.w, bItem.w, 0, MAX[labelItem.h,bItem.h], bItem, NIL]]]; END; AddButtonItemToTool: PROCEDURE[tool: ToolHandle, buttonName, forSize: Rope.ROPE, buttonProc: PROCEDURE[REF ANY], toolData: REF ANY, border: BOOLEAN _ FALSE] RETURNS[ItemHandle] = BEGIN buttonItem: ButtonItemHandle _ NEW[ButtonItemBody _ [tool, buttonProc, forSize, buttonName, border, NIL, toolData]]; RETURN[NEW[ItemBody _ [VFonts.StringWidth[IF forSize # NIL THEN forSize ELSE buttonName], 0, 0, VFonts.FontHeight[] + 2, buttonItem, NIL]]]; END; NominalButtonProc: Buttons.ButtonProc = TRUSTED BEGIN buttonItem: ButtonItemHandle _ NARROW[clientData]; UpdateValuesFromScreen[buttonItem.tool]; buttonItem.proc[buttonItem.data]; UpdateScreen[buttonItem.tool]; END; BooleanButtonProc: Buttons.ButtonProc = TRUSTED BEGIN item: BooleanItemHandle _ NARROW[clientData]; IF item.editable THEN BEGIN item.changed _ TRUE; item.val _ NOT item.val; Buttons.ReLabel[item.button, IF item.val THEN "TRUE" ELSE "FALSE"] END; END; MakeSubTextItemAsButton: PROCEDURE[item: SubTextItemHandle] = BEGIN contentsWidth: INTEGER _ VFonts.StringWidth[item.contents]; button: Viewer; ClearSubTextItem[item]; button _ Buttons.Create[ info: [ name: item.contents, wx: item.x+item.w-contentsWidth-10, wy: item.y, ww: contentsWidth+10, wh: VFonts.FontHeight[]+5, parent: item.parent, border: FALSE, scrollable: FALSE], proc: MakeSubTextItemAsTextBox, clientData: item, paint: TRUE]; item.mode _ button; item.v _ button; END; MakeSubTextItemAsTextBox: Buttons.ButtonProc = TRUSTED BEGIN item: SubTextItemHandle _ NARROW[clientData]; textBox: ViewerClasses.Viewer; IF NOT item.editable THEN RETURN; IF item.v # NARROW[parent, ViewerClasses.Viewer] THEN ERROR; ClearSubTextItem[item]; textBox _ ViewerTools.MakeNewTextViewer[ info: [ parent: item.parent, wx: item.x, wy: item.y, ww: item.w, wh: item.h, border: FALSE, scrollable: FALSE], paint: FALSE]; ViewerTools.SetContents[textBox, item.contents]; item.v _ textBox; item.mode _ textBox; END; ClearSubTextItem: PROCEDURE[item: SubTextItemHandle] = BEGIN IF item.mode = button THEN BEGIN Buttons.ReLabel[item.v, "", TRUE]; END; IF item.mode = textBox THEN BEGIN ViewerTools.SetContents[item.v, "", TRUE]; END; IF item.mode # nil THEN ViewerOps.DestroyViewer[item.v, FALSE]; item.mode _ nil; item.v _ NIL; END; BooleanItemProc: PROCEDURE[clientData: REF ANY] = BEGIN item: BooleanItemHandle _ NARROW[clientData]; IF NOT item.editable THEN RETURN; item.val _ NOT item.val; item.changed _ TRUE; Buttons.ReLabel[item.button, IF item.val THEN "TRUE" ELSE "FALSE"]; END; UpdateScreenSubText: PROCEDURE[item: SubTextItemHandle] = BEGIN -- this code has been simplified to look for a bug, later it should avoid converting unchnged buttons to buttons. IF item.textRef^ # item.contents THEN BEGIN item.contents _ item.textRef^ END; MakeSubTextItemAsButton[item]; END; UpdateScreenText: PROCEDURE[item: TextItemHandle] RETURNS[nextItem: REF ANY] = BEGIN IF item.ref^ # item.val THEN BEGIN item.val _ item.ref^; item.text^ _ item.val; UpdateScreenSubText[item.subTextItem]; END; RETURN[item.nextItem]; END; UpdateScreenUnsigned: PROCEDURE[item: UnsignedItemHandle] RETURNS[nextItem: REF ANY] = BEGIN IF item.ref^ # item.val THEN BEGIN item.val _ item.ref^; item.text^ _ Convert.RopeFromCard[item.val]; UpdateScreenSubText[item.subTextItem]; END; RETURN[item.nextItem]; END; UpdateScreenCardinal: PROCEDURE[item: CardinalItemHandle] RETURNS[nextItem: REF ANY] = BEGIN IF item.ref^ # item.val THEN BEGIN item.val _ item.ref^; item.text^ _ Convert.RopeFromCard[item.val]; UpdateScreenSubText[item.subTextItem]; END; RETURN[item.nextItem]; END; UpdateScreenSigned: PROCEDURE[item: SignedItemHandle] RETURNS[nextItem: REF ANY] = BEGIN IF item.ref^ # item.val THEN BEGIN item.val _ item.ref^; item.text^ _ Convert.RopeFromInt[item.val]; UpdateScreenSubText[item.subTextItem]; END; RETURN[item.nextItem]; END; UpdateScreenBoolean: PROCEDURE[item: BooleanItemHandle] RETURNS[nextItem: REF ANY] = BEGIN IF item.ref^ # item.val THEN BEGIN item.val _ item.ref^; Buttons.ReLabel[item.button, IF item.ref^ THEN "TRUE" ELSE "FALSE"]; END; RETURN[item.nextItem]; END; UpdateValuesFromScreen: PROCEDURE[tool: ToolHandle] = BEGIN item: REF ANY _ tool.items; WHILE item # NIL DO item _ UpdateOneItemValueFromScreen[item]; ENDLOOP; END; UpdateOneItemValueFromScreen: PROCEDURE[item: REF ANY] RETURNS[nextItem: REF ANY] = BEGIN SELECT TRUE FROM ISTYPE[item, TextItemHandle] => nextItem _ UpdateTextValue[NARROW[item]]; ISTYPE[item, UnsignedItemHandle] => nextItem _ UpdateUnsignedValue[NARROW[item]]; ISTYPE[item, CardinalItemHandle] => nextItem _ UpdateCardinalValue[NARROW[item]]; ISTYPE[item, SignedItemHandle] => nextItem _ UpdateSignedValue[NARROW[item]]; ISTYPE[item, BooleanItemHandle] => nextItem _ UpdateBooleanValue[NARROW[item]]; ENDCASE => ERROR; END; UpdateSubTextValue: PROCEDURE[item: SubTextItemHandle] = BEGIN changed: BOOLEAN _ item.mode = textBox; IF changed THEN BEGIN item.contents _ ViewerTools.GetContents[item.v]; MakeSubTextItemAsButton[item]; END; item.textRef^ _ item.contents; END; UpdateTextValue: PROCEDURE[item: TextItemHandle] RETURNS[nextItem: REF ANY] = BEGIN UpdateSubTextValue[item.subTextItem]; item.ref^ _ item.val _ item.text^; RETURN[item.nextItem]; END; UpdateUnsignedValue: PROCEDURE[item: UnsignedItemHandle] RETURNS[nextItem: REF ANY] = BEGIN UpdateSubTextValue[item.subTextItem]; item.val _ Convert.CardFromRope[item.text^]; item.ref^ _ item.val; RETURN[item.nextItem]; END; UpdateCardinalValue: PROCEDURE[item: CardinalItemHandle] RETURNS[nextItem: REF ANY] = BEGIN ln: Basics.LongNumber; UpdateSubTextValue[item.subTextItem]; ln.lc _ Convert.CardFromRope[item.text^]; item.val _ ln.lowbits; item.ref^ _ item.val; RETURN[item.nextItem]; END; UpdateSignedValue: PROCEDURE[item: SignedItemHandle] RETURNS[nextItem: REF ANY] = BEGIN UpdateSubTextValue[item.subTextItem]; item.val _ Convert.IntFromRope[item.text^]; item.ref^ _ item.val; RETURN[item.nextItem]; END; UpdateBooleanValue: PROCEDURE[item: BooleanItemHandle] RETURNS[nextItem: REF ANY] = BEGIN item.ref^ _ item.val; item.changed _ FALSE; RETURN[item.nextItem]; END; -- structure routines AddRowToTool: PROCEDURE[items: LIST OF ItemHandle, spacing: INTEGER] RETURNS[ItemHandle] = BEGIN RETURN[AddMatrixToTool[LIST[items], 0, spacing]] END; AddColumnToTool: PROCEDURE[items: LIST OF ItemHandle, lead: INTEGER] RETURNS[ItemHandle] = BEGIN firstRowCell: LIST OF LIST OF ItemHandle _ NIL; lastRowCell: LIST OF LIST OF ItemHandle; FOR itemCell: LIST OF ItemHandle _ items, itemCell.rest WHILE itemCell # NIL DO rowCell: LIST OF LIST OF ItemHandle _ LIST[LIST[itemCell.first]]; IF firstRowCell = NIL THEN firstRowCell _ rowCell ELSE lastRowCell.rest _ rowCell; lastRowCell _ rowCell; ENDLOOP; RETURN[AddMatrixToTool[firstRowCell, lead, 0]]; END; AddMatrixToTool: PROCEDURE[items: LIST OF LIST OF ItemHandle, rowLead, colSpacing: INTEGER] RETURNS[ItemHandle] = BEGIN firstRow: MatrixRowHandle _ NIL; lastRow: MatrixRowHandle _ NIL; firstColumn: MatrixColumnHandle _ NIL; lastColumn: MatrixColumnHandle _ NIL; matrix: MatrixHandle _ NEW[MatrixBody _ [rowLead, colSpacing, NIL, NIL]]; matrixItem: ItemHandle _ NEW[ItemBody _ [0, 0, 0, 0, NIL, NIL]]; FOR rowCell: LIST OF LIST OF ItemHandle _ items, rowCell.rest WHILE rowCell # NIL DO row: MatrixRowHandle _ NEW[MatrixRowBody _ [0, NIL, NIL]]; column: MatrixColumnHandle; lastItem: ItemHandle _ NIL; IF firstRow = NIL THEN firstRow _ row ELSE lastRow.next _ row; lastRow _ row; IF firstRow = lastRow THEN -- this is first row, build up the columns FOR itemCell: LIST OF ItemHandle _ rowCell.first, itemCell.rest WHILE itemCell # NIL DO column _ NEW[MatrixColumnBody _ [0, 0, 0, NIL]]; IF firstColumn = NIL THEN firstColumn _ column ELSE lastColumn.next _ column; lastColumn _ column; ENDLOOP; column _ firstColumn; FOR itemCell: LIST OF ItemHandle _ rowCell.first, itemCell.rest WHILE itemCell # NIL DO item: ItemHandle _ itemCell.first; IF item.w1 > column.w1 THEN column.w1 _ item.w1; IF item.w2 > column.w2 THEN column.w2 _ item.w2; IF item.w3 > column.w3 THEN column.w3 _ item.w3; IF item.height > row.h THEN row.h _ item.height; IF row.items = NIL THEN row.items _ item ELSE lastItem.next _ item; lastItem _ item; column _ column.next; ENDLOOP; ENDLOOP; FOR c: MatrixColumnHandle _ firstColumn, c.next WHILE c # NIL DO matrixItem.w1 _ matrixItem.w1 + c.w1 + c.w2 + c.w3 + matrix.colSpacing; ENDLOOP; matrixItem.w1 _ matrixItem.w1-matrix.colSpacing; -- correct for last column FOR r: MatrixRowHandle _ firstRow, r.next WHILE r # NIL DO matrixItem.height _ matrixItem.height+r.h+matrix.rowLead; ENDLOOP; matrixItem.height _ matrixItem.height-matrix.rowLead; -- correct for last row matrix.rows _ firstRow; matrix.columns _ firstColumn; matrixItem.data _ matrix; RETURN[matrixItem]; END; PositionItem: PROCEDURE[item: ItemHandle, x1, w1, x2, w2, x3, w3: INTEGER, y: INTEGER] = BEGIN SELECT TRUE FROM ISTYPE[item.data, ButtonItemHandle] => PositionButtonItem[NARROW[item.data], x1, w1, x2, w2, x3, w3, y]; ISTYPE[item.data, MatrixHandle] => PositionMatrix[NARROW[item.data], x1, w1, x2, w2, x3, w3, y]; ISTYPE[item.data, FillerItemHandle] => NULL; ISTYPE[item.data, TextItemHandle] => PositionTextItem[NARROW[item.data], x1, w1, x2, w2, x3, w3, y]; ISTYPE[item.data, UnsignedItemHandle] => PositionUnsignedItem[NARROW[item.data], x1, w1, x2, w2, x3, w3, y]; ISTYPE[item.data, CardinalItemHandle] => PositionCardinalItem[NARROW[item.data], x1, w1, x2, w2, x3, w3, y]; ISTYPE[item.data, SignedItemHandle] => PositionSignedItem[NARROW[item.data], x1, w1, x2, w2, x3, w3, y]; ISTYPE[item.data, BooleanItemHandle] => PositionBooleanItem[NARROW[item.data], x1, w1, x2, w2, x3, w3, y]; ENDCASE => ERROR; END; PositionButtonItem: PROCEDURE[item: ButtonItemHandle, x1, w1, x2, w2, x3, w3: INTEGER, y: INTEGER] = BEGIN item.button _ Buttons.Create[info: [name: IF item.forSize # NIL THEN item.forSize ELSE item.name, wx: x1, wy: y, parent: item.tool.container, border: item.border], proc: NominalButtonProc, clientData: item, fork: TRUE]; IF item.forSize # NIL THEN Buttons.ReLabel[item.button, item.name]; END; PositionMatrix: PROCEDURE[item: MatrixHandle, x1, w1, x2, w2, x3, w3: INTEGER, y: INTEGER] = BEGIN FOR row: MatrixRowHandle _ item.rows, row.next WHILE row # NIL DO col: MatrixColumnHandle _ item.columns; x: INTEGER _ x1; FOR subItem: ItemHandle _ row.items, subItem.next WHILE subItem # NIL DO PositionItem[subItem, x, col.w1, x+col.w1, col.w2, x+col.w1+col.w2, col.w3, y]; x _ x + col.w1 + col.w2 + col.w3 + item.colSpacing; col _ col.next; ENDLOOP; y _ y + row.h + item.rowLead; ENDLOOP; END; PositionSubTextItem: PROCEDURE[item: SubTextItemHandle, x1, w1, x2, w2, x3, w3: INTEGER, y: INTEGER] = BEGIN item.x _ x2; item.w _ w2; item.y _ y; MakeSubTextItemAsButton[item]; END; PositionTextItem: PROCEDURE[item: TextItemHandle, x1, w1, x2, w2, x3, w3: INTEGER, y: INTEGER] = BEGIN PositionLabel[item.label, x1, w1, x2, w2, x3, w3, y]; PositionSubTextItem[item.subTextItem, x1, w1, x2, w2, x3, w3, y] END; PositionUnsignedItem: PROCEDURE[item: UnsignedItemHandle, x1, w1, x2, w2, x3, w3: INTEGER, y: INTEGER] = BEGIN PositionLabel[item.label, x1, w1, x2, w2, x3, w3, y]; PositionSubTextItem[item.subTextItem, x1, w1, x2, w2, x3, w3, y] END; PositionCardinalItem: PROCEDURE[item: CardinalItemHandle, x1, w1, x2, w2, x3, w3: INTEGER, y: INTEGER] = BEGIN PositionLabel[item.label, x1, w1, x2, w2, x3, w3, y]; PositionSubTextItem[item.subTextItem, x1, w1, x2, w2, x3, w3, y] END; PositionSignedItem: PROCEDURE[item: SignedItemHandle, x1, w1, x2, w2, x3, w3: INTEGER, y: INTEGER] = BEGIN PositionLabel[item.label, x1, w1, x2, w2, x3, w3, y]; PositionSubTextItem[item.subTextItem, x1, w1, x2, w2, x3, w3, y] END; PositionBooleanItem: PROCEDURE[item: BooleanItemHandle, x1, w1, x2, w2, x3, w3: INTEGER, y: INTEGER] = BEGIN PositionLabel[item.label, x1, w1, x2, w2, x3, w3, y]; item.button _ Buttons.Create[info: [name: "FALSE", wx: x2, wy: y+2, parent: item.tool.container, border: FALSE], proc: BooleanButtonProc, clientData: item, fork: TRUE]; IF item.val THEN Buttons.ReLabel[item.button, "TRUE"]; END; PositionLabel: PROCEDURE[item: LabelItemHandle, x1, w1, x2, w2, x3, w3: INTEGER, y: INTEGER] = BEGIN item.viewer _ Labels.Create[[parent: item.tool.container, wx: x1, wy: y, ww: item.w, wh: item.h, name: item.name, border: FALSE]]; END; --UserExec.RegisterCommand[name: "EasyTool", proc: BuildTool, briefDoc: ""]; --[] _ EasyTool[UserExec.GetExecHandle[]]; END.. -- approx Sept 5, 82: Sturgis, started EasyToolImpl.mesa, by edit of NewCalc.mesa -- September 6, 1982 7:50 pm: Sturgis: spent today re-implementing to conform to the new easy interface. now works. Several RTEs involving not getting screen or values updated at appropriate times. Tested unsigned, boolean, and buttons. Have not implemented save or restore. -- September 6, 1982 7:52 pm: position buttons down 2 units to try for better allignment. -- RTE: approx September 6, 1982 8:11 pm: found that when text became editable, it overlaid line directly above it. so, made some changes to calculation of next y etc. In particular, replaced currentH by currentY. -- RTE: September 6, 1982 8:11 pm: now have a stair case for each line, clearly currentY is getting advanced when it should not. -- RTE: September 6, 1982 8:18 pm: more staircase. -- September 6, 1982 8:25 pm: add skipOver to obtainItems -- RTE: September 6, 1982 8:38 pm: overlay test in tabTo was inverted. -- Sept 17: begin conversion to Matrices, Rows, and Columns. -- RTE: September 18, 1982 12:31 pm: forgot to position items. -- RTE: September 18, 1982 12:41 pm: matrix advanced x incorrectly. -- RTE: September 18, 1982 1:03 pm: add column to tool incorrectly constructed the LIST of LIST of with which to call add matrix to tool. -- RTE: September 18, 1982 1:30 pm: matrix items should have only a w1, which should be sum of w1, w2 and w3 for each column. Incorrect code computed a w1 and a w2 and a w3. but these created troble outside? -- RTE: September 18, 1982 1:43 pm: forgot to attach labels to items. during position item code. -- RTE: September 18, 1982 1:50 pm: always used "forSize" in computing width of buttons. -- RET: September 18, 1982 2:01 pm: update one item from screen still had "secondLook" logic for calls from TextItems. THus text type items were never updated from screen. -- RTE: September 18, 1982 2:26 pm: positionItem code needed to have a (null) case for FIllerItem. -- change: September 18, 1982 2:40 pm: right adjust sub text when as buttons. -- RTE: September 18, 1982 2:47 pm: can't see the text, adjust a few fiddle factors. -- change: September 18, 1982 3:05 pm: (above not fixed, but) add automatic row lead and col spacing. -- change: September 18, 1982 3:38 pm: work on previous problem, and also try to get right justification to work. -- ugh: September 18, 1982 4:32 pm: replace viewer seems to be putting the new viewer in the same position as the old viewer. -- RTE: September 18, 1982 5:27 pm: remarks on preceeding period: to change local position, and contents of a viewer without repainting whole container: set contents to empty (different routine for textbos and button), with paint=true. destroy viewer. create new one, with paint=true?. Don't know if this will work with borders. Also, text items did not work because I passed the wrong ref rope to the subtextitem. -- change: October 6, 1982 3:19 pm: defineButton now takes an obtional data param specific to the button. -- change: October 10, 1982 12:04 pm: Change to 3.4: in a button proc, viewer becomes NARROW[parent, Viewer]. -- change: May 31, 1983 11:33 am: change " = BEGIN " to "= TRUSTED BEGIN " for NominalButtonProc, BooleanButtonProc, and MakeSubTextItemAsTextBox. -- Change: June 22, 1984 9:27:29 am PDT: conversion to Cedar 5.2