DIRECTORY CornerStitching, TableBase, TableSelection, TSOutput, TSTypes; TableSelectionImpl: CEDAR PROGRAM IMPORTS CornerStitching, TableBase EXPORTS TableSelection = { OPEN TableBase, TableSelection; NewSelection: PUBLIC PROCEDURE [table: TableBase.RefTable] RETURNS [sel: Selection] = { sel _ NEW[SelectionRec _ [table]]; }; AnEmptySelection: PUBLIC PROCEDURE [sel: Selection] RETURNS [BOOLEAN] = { RETURN [sel = NIL OR sel.list = NIL]; }; ASingleSelection: PUBLIC PROCEDURE [sel: Selection] RETURNS [BOOLEAN] = { RETURN [NOT AnEmptySelection[sel] AND sel.list.rest = NIL]; }; ResolveToBox: PUBLIC PROCEDURE [table: RefTable, x, y: TSTypes.Dimn] RETURNS [box: RefTableBox] = { left: GridNumber; top: GridNumber; rect: CornerStitching.Rect; tile: CornerStitching.TilePtr; IF x.texPts < table.colGridPositions[0].texPts OR x.texPts > table.colGridPositions[table.columnGrids].texPts OR table.rowGridPositions[0].texPts < y.texPts OR table.rowGridPositions[table.rowGrids].texPts > y.texPts THEN RETURN [NIL]; FOR left IN [0..table.columnGrids) DO IF table.colGridPositions[left].texPts <= x.texPts AND x.texPts <= table.colGridPositions[left+1].texPts THEN EXIT; ENDLOOP; FOR top IN [0..table.rowGrids) DO IF y.texPts <= table.rowGridPositions[top].texPts AND table.rowGridPositions[top+1].texPts <= y.texPts THEN EXIT; ENDLOOP; rect _ InsideGridToRect[left, top, left+1, top+1]; tile _ table.tableGrid.TileAt[pos: [rect.x1, rect.y1]]; box _ BoxFromTile[tile]; }; SelectBox: PUBLIC PROCEDURE [table: RefTable, box: RefTableBox, kind: KindOfSelection] RETURNS [sel: Selection] = { }; GrowSelection: PUBLIC PROCEDURE [sel: Selection, which: RowOrColumn] = { IF AnEmptySelection[sel] THEN RETURN; IF sel.kind = table THEN RETURN; SELECT sel.kind FROM box => { FOR list: LIST OF SelectedThing _ sel.list, list.rest WHILE list # NIL DO box: RefTableBox ~ list.first.box; SELECT which FROM row => list.first _ NEW[SelectedThingRec _ [grid1~box.top, grid2~box.bottom]]; column => list.first _ NEW[SelectedThingRec _ [grid1~box.left, grid2~box.right]]; ENDCASE => ERROR; ENDLOOP; sel.kind _ SELECT which FROM row => row, column => column, ENDCASE => row; }; row => { IF which # row THEN ERROR; FOR list: LIST OF SelectedThing _ sel.list, list.rest WHILE list # NIL DO top: GridNumber ~ list.first.grid1; bottom: GridNumber ~ list.first.grid2; newTop: GridNumber _ top; newBottom: GridNumber _ bottom; currentExpansion: GridNumber _ 0; ExpandGridLines: EnumeratedEntryProc ~ { expansion: GridNumber _ (entry.top - top) + (entry.bottom - bottom); IF top >= entry.top AND entry.bottom >= bottom THEN RETURN; IF expansion > 0 AND expansion < currentExpansion THEN { newTop _ entry.top; newBottom _ entry.bottom; currentExpansion _ expansion; }; }; EnumerateTable[table~sel.table, entryProc~ExpandGridLines, top~top, bottom~bottom]; list.first _ NEW[SelectedThingRec _ [grid1~newTop, grid2~newBottom]]; ENDLOOP; }; table => NULL; ENDCASE => ERROR; }; }. lTableSelectionImpl.Mesa Created by Rick Beach, October 26, 1984 2:49:19 pm PDT (x,y) are coordinates relative to the origin of table, that is, (0,0) is the bottom-left corner. Returns the box that contains (x,y) or NIL if they are not within the table at all. check if (x,y) is within the table at all? find col grids that bracket x find row grids that bracket y convert grid numbers to a rectangle using TableBase.InsideGridToRect ?? what about selecting rules? find tile at that rectangle find box from that tile search for the minimum expansion of these grid lines by enumerating the row column => Statement; Κ`˜™J™6—unitšΟk ˜ J˜J˜ Jšœ˜J˜ Jšœ˜—šœœ˜!Jšœ˜"Jšœ˜Jšœ˜J˜—šΟn œœœ˜WJšœœ˜"Jšœ˜—šžœœœœ˜IJšœœœ œ˜%J˜—šžœœœœ˜IJšœœœœ˜;J˜—šž œœ'œ˜cJ™`J™SJ˜J˜Jšœ˜Jšœ˜J™*Jšœ-œ=œ-œ:œœœ˜λJ™šœœ˜%Jšœ1œ3œœ˜sJš˜—J™šœœ˜!Jšœ0œ2œœ˜qJš˜—J™DJ™J˜2J™J˜7J™J˜Jšœ˜—šž œœ<œ˜sJšœ˜—šž œœ)˜HJšœœœ˜%Jšœœœ˜ šœ ˜šœ˜š œœœ%œœ˜IJ˜"šœ˜Jšœœ7˜NJšœœ7˜QJšœœ˜—Jšœ˜—Jšœ œœœ˜JJšœ˜—šœ˜Jšœ œœ˜š œœœ%œœ˜IJ˜#J˜&J˜J˜J˜!J™Kšžœ˜(J˜DJšœœœœ˜;šœœœ˜8Jšœ˜J˜J˜Jšœ˜—J˜—J˜SJšœ œ5˜EJšœ˜—Jšœ˜—J™Jšœ œ˜Jšœœ˜—Jšœ˜—J˜—…— €L