comparison dwtx/ui/forms/widgets/TableWrapLayout.d @ 104:04b47443bb01

Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections. These new wrappers now use the tango.util.containers instead of the tango.util.collections.
author Frank Benoit <benoit@tionex.de>
date Thu, 07 Aug 2008 15:01:33 +0200
parents 56fea7e5f0f9
children 8df1d4193877
comparison
equal deleted inserted replaced
103:2d6540440fe6 104:04b47443bb01
23 import dwt.widgets.Composite; 23 import dwt.widgets.Composite;
24 import dwt.widgets.Control; 24 import dwt.widgets.Control;
25 import dwt.widgets.Layout; 25 import dwt.widgets.Layout;
26 26
27 import dwt.dwthelper.utils; 27 import dwt.dwthelper.utils;
28 import tango.util.collection.ArraySeq; 28 import dwtx.dwtxhelper.Collection;
29 import tango.util.collection.HashMap;
30 29
31 /** 30 /**
32 * This implementation of the layout algorithm attempts to position controls in 31 * This implementation of the layout algorithm attempts to position controls in
33 * the composite using a two-pass autolayout HTML table altorithm recommeded by 32 * the composite using a two-pass autolayout HTML table altorithm recommeded by
34 * HTML 4.01 W3C specification (see 33 * HTML 4.01 W3C specification (see
99 */ 98 */
100 public bool makeColumnsEqualWidth = false; 99 public bool makeColumnsEqualWidth = false;
101 100
102 private bool initialLayout = true; 101 private bool initialLayout = true;
103 102
104 private ArraySeq!(Object) grid = null; 103 private Vector grid = null;
105 104
106 private HashMap!(Object,Object) rowspans; 105 private Hashtable rowspans;
107 106
108 private int[] minColumnWidths, maxColumnWidths; 107 private int[] minColumnWidths, maxColumnWidths;
109 108
110 private int widestColumnWidth; 109 private int widestColumnWidth;
111 110
177 changed = true; 176 changed = true;
178 initialLayout = false; 177 initialLayout = false;
179 } 178 }
180 if (grid is null || changed) { 179 if (grid is null || changed) {
181 changed = true; 180 changed = true;
182 grid = new ArraySeq!(Object); 181 grid = new Vector();
183 createGrid(parent); 182 createGrid(parent);
184 } 183 }
185 if (minColumnWidths is null) 184 if (minColumnWidths is null)
186 minColumnWidths = new int[numColumns]; 185 minColumnWidths = new int[numColumns];
187 for (int i = 0; i < numColumns; i++) { 186 for (int i = 0; i < numColumns; i++) {
209 changed = true; 208 changed = true;
210 initialLayout = false; 209 initialLayout = false;
211 } 210 }
212 if (grid is null || changed) { 211 if (grid is null || changed) {
213 changed = true; 212 changed = true;
214 grid = new ArraySeq!(Object); 213 grid = new Vector();
215 createGrid(parent); 214 createGrid(parent);
216 } 215 }
217 if (maxColumnWidths is null) 216 if (maxColumnWidths is null)
218 maxColumnWidths = new int[numColumns]; 217 maxColumnWidths = new int[numColumns];
219 for (int i = 0; i < numColumns; i++) { 218 for (int i = 0; i < numColumns; i++) {
245 changed = true; 244 changed = true;
246 initialLayout = false; 245 initialLayout = false;
247 } 246 }
248 if (grid is null || changed) { 247 if (grid is null || changed) {
249 changed = true; 248 changed = true;
250 grid = new ArraySeq!(Object); 249 grid = new Vector();
251 createGrid(parent); 250 createGrid(parent);
252 } 251 }
253 resetColumnWidths(); 252 resetColumnWidths();
254 int minWidth = internalGetMinimumWidth(parent, changed); 253 int minWidth = internalGetMinimumWidth(parent, changed);
255 int maxWidth = internalGetMaximumWidth(parent, changed); 254 int maxWidth = internalGetMaximumWidth(parent, changed);
297 int y = topMargin+clientArea.y; 296 int y = topMargin+clientArea.y;
298 int[] rowHeights = computeRowHeights(children, columnWidths, changed); 297 int[] rowHeights = computeRowHeights(children, columnWidths, changed);
299 for (int i = 0; i < grid.size(); i++) { 298 for (int i = 0; i < grid.size(); i++) {
300 int rowHeight = rowHeights[i]; 299 int rowHeight = rowHeights[i];
301 int x = leftMargin+clientArea.x; 300 int x = leftMargin+clientArea.x;
302 TableWrapData[] row = (cast(ArrayWrapperT!(TableWrapData)) grid.get(i)).array; 301 TableWrapData[] row = arrayFromObject!(TableWrapData)( grid.elementAt(i));
303 for (int j = 0; j < numColumns; j++) { 302 for (int j = 0; j < numColumns; j++) {
304 TableWrapData td = row[j]; 303 TableWrapData td = row[j];
305 if (td.isItemData) { 304 if (td.isItemData) {
306 Control child = children[td.childIndex]; 305 Control child = children[td.childIndex];
307 placeControl(child, td, x, y, rowHeights, i); 306 placeControl(child, td, x, y, rowHeights, i);
316 315
317 int[] computeRowHeights(Control[] children, int[] columnWidths, 316 int[] computeRowHeights(Control[] children, int[] columnWidths,
318 bool changed) { 317 bool changed) {
319 int[] rowHeights = new int[grid.size()]; 318 int[] rowHeights = new int[grid.size()];
320 for (int i = 0; i < grid.size(); i++) { 319 for (int i = 0; i < grid.size(); i++) {
321 TableWrapData[] row = (cast(ArrayWrapperT!(TableWrapData)) grid.get(i)).array; 320 TableWrapData[] row = arrayFromObject!(TableWrapData)( grid.elementAt(i));
322 rowHeights[i] = 0; 321 rowHeights[i] = 0;
323 for (int j = 0; j < numColumns; j++) { 322 for (int j = 0; j < numColumns; j++) {
324 TableWrapData td = row[j]; 323 TableWrapData td = row[j];
325 if (td.isItemData is false) { 324 if (td.isItemData is false) {
326 continue; 325 continue;
337 td.compWidth = cwidth; 336 td.compWidth = cwidth;
338 if (td.heightHint !is DWT.DEFAULT) { 337 if (td.heightHint !is DWT.DEFAULT) {
339 size = new Point(size.x, td.heightHint); 338 size = new Point(size.x, td.heightHint);
340 } 339 }
341 td.compSize = size; 340 td.compSize = size;
342 RowSpan rowspan = rowspans.containsKey(child) ? cast(RowSpan) rowspans.get(child) : null; 341 RowSpan rowspan = cast(RowSpan) rowspans.get(child);
343 if (rowspan is null) { 342 if (rowspan is null) {
344 rowHeights[i] = Math.max(rowHeights[i], size.y); 343 rowHeights[i] = Math.max(rowHeights[i], size.y);
345 } else 344 } else
346 rowspan.height = size.y; 345 rowspan.height = size.y;
347 } 346 }
348 updateRowSpans(i, rowHeights[i]); 347 updateRowSpans(i, rowHeights[i]);
349 } 348 }
350 foreach( k, v; rowspans ){ 349 for (Enumeration enm = rowspans.elements(); enm.hasMoreElements();) {
351 RowSpan rowspan = cast(RowSpan) v; 350 RowSpan rowspan = cast(RowSpan) enm.nextElement();
352 int increase = rowspan.getRequiredHeightIncrease(); 351 int increase = rowspan.getRequiredHeightIncrease();
353 if (increase is 0) 352 if (increase is 0)
354 continue; 353 continue;
355 TableWrapData td = cast(TableWrapData) rowspan.child.getLayoutData(); 354 TableWrapData td = cast(TableWrapData) rowspan.child.getLayoutData();
356 int ngrowing = 0; 355 int ngrowing = 0;
429 int height = td.compSize.y; 428 int height = td.compSize.y;
430 int colWidth = td.compWidth - td.indent; 429 int colWidth = td.compWidth - td.indent;
431 int width = td.compSize.x-td.indent; 430 int width = td.compSize.x-td.indent;
432 width = Math.min(width, colWidth); 431 width = Math.min(width, colWidth);
433 int slotHeight = rowHeights[row]; 432 int slotHeight = rowHeights[row];
434 RowSpan rowspan = rowspans.containsKey(control) ? cast(RowSpan) rowspans.get(control) : null; 433 RowSpan rowspan = cast(RowSpan) rowspans.get(control);
435 if (rowspan !is null) { 434 if (rowspan !is null) {
436 slotHeight = 0; 435 slotHeight = 0;
437 for (int i = row; i < row + td.rowspan; i++) { 436 for (int i = row; i < row + td.rowspan; i++) {
438 if (i > row) 437 if (i > row)
439 slotHeight += verticalSpacing; 438 slotHeight += verticalSpacing;
461 460
462 void createGrid(Composite composite) { 461 void createGrid(Composite composite) {
463 int row, column, rowFill, columnFill; 462 int row, column, rowFill, columnFill;
464 Control[] children; 463 Control[] children;
465 TableWrapData spacerSpec; 464 TableWrapData spacerSpec;
466 ArraySeq!(Object) growingCols = new ArraySeq!(Object); 465 Vector growingCols = new Vector();
467 ArraySeq!(Object) growingRows = new ArraySeq!(Object); 466 Vector growingRows = new Vector();
468 rowspans = new HashMap!(Object,Object); 467 rowspans = new Hashtable();
469 // 468 //
470 children = composite.getChildren(); 469 children = composite.getChildren();
471 if (children.length is 0) 470 if (children.length is 0)
472 return; 471 return;
473 // 472 //
474 grid.append( new ArrayWrapperT!(TableWrapData)(createEmptyRow())); 473 grid.addElement( new ArrayWrapperObject(createEmptyRow()));
475 row = 0; 474 row = 0;
476 column = 0; 475 column = 0;
477 // Loop through the children and place their associated layout specs in 476 // Loop through the children and place their associated layout specs in
478 // the 477 // the
479 // grid. Placement occurs left to right, top to bottom (i.e., by row). 478 // grid. Placement occurs left to right, top to bottom (i.e., by row).
480 for (int i = 0; i < children.length; i++) { 479 for (int i = 0; i < children.length; i++) {
481 // Find the first available spot in the grid. 480 // Find the first available spot in the grid.
482 Control child = children[i]; 481 Control child = children[i];
483 TableWrapData spec = cast(TableWrapData) child.getLayoutData(); 482 TableWrapData spec = cast(TableWrapData) child.getLayoutData();
484 while ((cast(ArrayWrapperT!(TableWrapData)) grid.get(row)).array[column] !is null) { 483 while (arrayFromObject!(TableWrapData)( grid.elementAt(row))[column] !is null) {
485 column = column + 1; 484 column = column + 1;
486 if (column >= numColumns) { 485 if (column >= numColumns) {
487 row = row + 1; 486 row = row + 1;
488 column = 0; 487 column = 0;
489 if (row >= grid.size()) { 488 if (row >= grid.size()) {
490 grid.append(new ArrayWrapperT!(TableWrapData)(createEmptyRow())); 489 grid.addElement(new ArrayWrapperObject(createEmptyRow()));
491 } 490 }
492 } 491 }
493 } 492 }
494 // See if the place will support the widget's horizontal span. If 493 // See if the place will support the widget's horizontal span. If
495 // not, go to the 494 // not, go to the
496 // next row. 495 // next row.
497 if (column + spec.colspan - 1 >= numColumns) { 496 if (column + spec.colspan - 1 >= numColumns) {
498 grid.append(new ArrayWrapperT!(TableWrapData)(createEmptyRow())); 497 grid.addElement(new ArrayWrapperObject(createEmptyRow()));
499 row = row + 1; 498 row = row + 1;
500 column = 0; 499 column = 0;
501 } 500 }
502 // The vertical span for the item will be at least 1. If it is > 1, 501 // The vertical span for the item will be at least 1. If it is > 1,
503 // add other rows to the grid. 502 // add other rows to the grid.
504 if (spec.rowspan > 1) { 503 if (spec.rowspan > 1) {
505 rowspans.add(child, new RowSpan(child, column, row)); 504 rowspans.put(child, new RowSpan(child, column, row));
506 } 505 }
507 for (int j = 2; j <= spec.rowspan; j++) { 506 for (int j = 2; j <= spec.rowspan; j++) {
508 if (row + j > grid.size()) { 507 if (row + j > grid.size()) {
509 grid.append(new ArrayWrapperT!(TableWrapData)(createEmptyRow())); 508 grid.addElement(new ArrayWrapperObject(createEmptyRow()));
510 } 509 }
511 } 510 }
512 // Store the layout spec. Also cache the childIndex. NOTE: That we 511 // Store the layout spec. Also cache the childIndex. NOTE: That we
513 // assume the children of a 512 // assume the children of a
514 // composite are maintained in the order in which they are created 513 // composite are maintained in the order in which they are created
515 // and added to the composite. 514 // and added to the composite.
516 (cast(ArrayWrapperT!(TableWrapData)) grid.get(row)).array[column] = spec; 515 arrayFromObject!(TableWrapData)( grid.elementAt(row))[column] = spec;
517 spec.childIndex = i; 516 spec.childIndex = i;
518 if (spec.grabHorizontal) { 517 if (spec.grabHorizontal) {
519 updateGrowingColumns(growingCols, spec, column); 518 updateGrowingColumns(growingCols, spec, column);
520 } 519 }
521 if (spec.grabVertical) { 520 if (spec.grabVertical) {
528 columnFill = spec.colspan - 1; 527 columnFill = spec.colspan - 1;
529 for (int r = 1; r <= rowFill; r++) { 528 for (int r = 1; r <= rowFill; r++) {
530 for (int c = 0; c < spec.colspan; c++) { 529 for (int c = 0; c < spec.colspan; c++) {
531 spacerSpec = new TableWrapData(); 530 spacerSpec = new TableWrapData();
532 spacerSpec.isItemData = false; 531 spacerSpec.isItemData = false;
533 (cast(ArrayWrapperT!(TableWrapData)) grid.get(row + r)).array[column + c] = spacerSpec; 532 arrayFromObject!(TableWrapData)( grid.elementAt(row + r))[column + c] = spacerSpec;
534 } 533 }
535 } 534 }
536 for (int c = 1; c <= columnFill; c++) { 535 for (int c = 1; c <= columnFill; c++) {
537 for (int r = 0; r < spec.rowspan; r++) { 536 for (int r = 0; r < spec.rowspan; r++) {
538 spacerSpec = new TableWrapData(); 537 spacerSpec = new TableWrapData();
539 spacerSpec.isItemData = false; 538 spacerSpec.isItemData = false;
540 (cast(ArrayWrapperT!(TableWrapData)) grid.get(row + r)).array[column + c] = spacerSpec; 539 arrayFromObject!(TableWrapData)( grid.elementAt(row + r))[column + c] = spacerSpec;
541 } 540 }
542 } 541 }
543 column = column + spec.colspan - 1; 542 column = column + spec.colspan - 1;
544 } 543 }
545 // Fill out empty grid cells with spacers. 544 // Fill out empty grid cells with spacers.
546 for (int k = column + 1; k < numColumns; k++) { 545 for (int k = column + 1; k < numColumns; k++) {
547 spacerSpec = new TableWrapData(); 546 spacerSpec = new TableWrapData();
548 spacerSpec.isItemData = false; 547 spacerSpec.isItemData = false;
549 (cast(ArrayWrapperT!(TableWrapData)) grid.get(row)).array[k] = spacerSpec; 548 arrayFromObject!(TableWrapData)( grid.elementAt(row))[k] = spacerSpec;
550 } 549 }
551 for (int k = row + 1; k < grid.size(); k++) { 550 for (int k = row + 1; k < grid.size(); k++) {
552 spacerSpec = new TableWrapData(); 551 spacerSpec = new TableWrapData();
553 spacerSpec.isItemData = false; 552 spacerSpec.isItemData = false;
554 (cast(ArrayWrapperT!(TableWrapData)) grid.get(k)).array[column] = spacerSpec; 553 arrayFromObject!(TableWrapData)( grid.elementAt(k))[column] = spacerSpec;
555 } 554 }
556 growingColumns = new int[growingCols.size()]; 555 growingColumns = new int[growingCols.size()];
557 for (int i = 0; i < growingCols.size(); i++) { 556 for (int i = 0; i < growingCols.size(); i++) {
558 growingColumns[i] = (cast(Integer) growingCols.get(i)).intValue(); 557 growingColumns[i] = (cast(Integer) growingCols.get(i)).intValue();
559 } 558 }
561 for (int i = 0; i < growingRows.size(); i++) { 560 for (int i = 0; i < growingRows.size(); i++) {
562 this.growingRows[i] = (cast(Integer) growingRows.get(i)).intValue(); 561 this.growingRows[i] = (cast(Integer) growingRows.get(i)).intValue();
563 } 562 }
564 } 563 }
565 564
566 private void updateGrowingColumns(ArraySeq!(Object) growingColumns, 565 private void updateGrowingColumns(Vector growingColumns,
567 TableWrapData spec, int column) { 566 TableWrapData spec, int column) {
568 int affectedColumn = column + spec.colspan - 1; 567 int affectedColumn = column + spec.colspan - 1;
569 for (int i = 0; i < growingColumns.size(); i++) { 568 for (int i = 0; i < growingColumns.size(); i++) {
570 Integer col = cast(Integer) growingColumns.get(i); 569 Integer col = cast(Integer) growingColumns.get(i);
571 if (col.intValue() is affectedColumn) 570 if (col.intValue() is affectedColumn)
572 return; 571 return;
573 } 572 }
574 growingColumns.append(new Integer(affectedColumn)); 573 growingColumns.add(new Integer(affectedColumn));
575 } 574 }
576 575
577 private void updateGrowingRows(ArraySeq!(Object) growingRows, TableWrapData spec, 576 private void updateGrowingRows(Vector growingRows, TableWrapData spec,
578 int row) { 577 int row) {
579 int affectedRow = row + spec.rowspan - 1; 578 int affectedRow = row + spec.rowspan - 1;
580 for (int i = 0; i < growingRows.size(); i++) { 579 for (int i = 0; i < growingRows.size(); i++) {
581 Integer irow = cast(Integer) growingRows.get(i); 580 Integer irow = cast(Integer) growingRows.get(i);
582 if (irow.intValue() is affectedRow) 581 if (irow.intValue() is affectedRow)
583 return; 582 return;
584 } 583 }
585 growingRows.append(new Integer(affectedRow)); 584 growingRows.add(new Integer(affectedRow));
586 } 585 }
587 586
588 private TableWrapData[] createEmptyRow() { 587 private TableWrapData[] createEmptyRow() {
589 TableWrapData[] row = new TableWrapData[numColumns]; 588 TableWrapData[] row = new TableWrapData[numColumns];
590 for (int i = 0; i < numColumns; i++) 589 for (int i = 0; i < numColumns; i++)
613 changed = true; 612 changed = true;
614 initialLayout = false; 613 initialLayout = false;
615 } 614 }
616 if (grid is null || changed) { 615 if (grid is null || changed) {
617 changed = true; 616 changed = true;
618 grid = new ArraySeq!(Object); 617 grid = new Vector();
619 createGrid(parent); 618 createGrid(parent);
620 } 619 }
621 resetColumnWidths(); 620 resetColumnWidths();
622 int minWidth = internalGetMinimumWidth(parent, changed); 621 int minWidth = internalGetMinimumWidth(parent, changed);
623 int maxWidth = internalGetMaximumWidth(parent, changed); 622 int maxWidth = internalGetMaximumWidth(parent, changed);
664 } 663 }
665 int totalHeight = 0; 664 int totalHeight = 0;
666 int innerHeight = 0; 665 int innerHeight = 0;
667 // compute widths 666 // compute widths
668 for (int i = 0; i < grid.size(); i++) { 667 for (int i = 0; i < grid.size(); i++) {
669 TableWrapData[] row = (cast(ArrayWrapperT!(TableWrapData)) grid.get(i)).array; 668 TableWrapData[] row = arrayFromObject!(TableWrapData)( grid.elementAt(i));
670 // assign widths, calculate heights 669 // assign widths, calculate heights
671 int rowHeight = 0; 670 int rowHeight = 0;
672 for (int j = 0; j < numColumns; j++) { 671 for (int j = 0; j < numColumns; j++) {
673 TableWrapData td = row[j]; 672 TableWrapData td = row[j];
674 if (td.isItemData is false) { 673 if (td.isItemData is false) {
685 int cy = td.heightHint; 684 int cy = td.heightHint;
686 if (cy is DWT.DEFAULT) { 685 if (cy is DWT.DEFAULT) {
687 Point size = computeSize(td.childIndex, cwidth, td.indent, td.maxWidth, td.maxHeight); 686 Point size = computeSize(td.childIndex, cwidth, td.indent, td.maxWidth, td.maxHeight);
688 cy = size.y; 687 cy = size.y;
689 } 688 }
690 RowSpan rowspan = rowspans.containsKey(child) ? cast(RowSpan) rowspans.get(child) : null; 689 RowSpan rowspan = cast(RowSpan) rowspans.get(child);
691 if (rowspan !is null) { 690 if (rowspan !is null) {
692 // don't take the height of this child into acount 691 // don't take the height of this child into acount
693 // because it spans multiple rows 692 // because it spans multiple rows
694 rowspan.height = cy; 693 rowspan.height = cy;
695 } else { 694 } else {
699 updateRowSpans(i, rowHeight); 698 updateRowSpans(i, rowHeight);
700 if (i > 0) 699 if (i > 0)
701 innerHeight += verticalSpacing; 700 innerHeight += verticalSpacing;
702 innerHeight += rowHeight; 701 innerHeight += rowHeight;
703 } 702 }
704 if (!rowspans.drained()) 703 if (!rowspans.isEmpty())
705 innerHeight = compensateForRowSpans(innerHeight); 704 innerHeight = compensateForRowSpans(innerHeight);
706 totalHeight = topMargin + innerHeight + bottomMargin; 705 totalHeight = topMargin + innerHeight + bottomMargin;
707 return new Point(tableWidth, totalHeight); 706 return new Point(tableWidth, totalHeight);
708 } 707 }
709 708
710 private void updateRowSpans(int row, int rowHeight) { 709 private void updateRowSpans(int row, int rowHeight) {
711 if (rowspans is null || rowspans.size() is 0) 710 if (rowspans is null || rowspans.size() is 0)
712 return; 711 return;
713 foreach( k, v; rowspans ){ 712 for (Enumeration enm = rowspans.elements(); enm.hasMoreElements();) {
714 RowSpan rowspan = cast(RowSpan) v; 713 RowSpan rowspan = cast(RowSpan) enm.nextElement();
715 rowspan.update(row, rowHeight); 714 rowspan.update(row, rowHeight);
716 } 715 }
717 } 716 }
718 717
719 private int compensateForRowSpans(int totalHeight) { 718 private int compensateForRowSpans(int totalHeight) {
720 foreach( k, v; rowspans ){ 719 for (Enumeration enm = rowspans.elements(); enm.hasMoreElements();) {
721 RowSpan rowspan = cast(RowSpan) v; 720 RowSpan rowspan = cast(RowSpan) enm.nextElement();
722 totalHeight += rowspan.getRequiredHeightIncrease(); 721 totalHeight += rowspan.getRequiredHeightIncrease();
723 } 722 }
724 return totalHeight; 723 return totalHeight;
725 } 724 }
726 725
778 } 777 }
779 778
780 void calculateColumnWidths(Composite parent, int [] columnWidths, bool max, bool changed) { 779 void calculateColumnWidths(Composite parent, int [] columnWidths, bool max, bool changed) {
781 bool secondPassNeeded=false; 780 bool secondPassNeeded=false;
782 for (int i = 0; i < grid.size(); i++) { 781 for (int i = 0; i < grid.size(); i++) {
783 TableWrapData[] row = (cast(ArrayWrapperT!(TableWrapData)) grid.get(i)).array; 782 TableWrapData[] row = arrayFromObject!(TableWrapData)( grid.elementAt(i));
784 for (int j = 0; j < numColumns; j++) { 783 for (int j = 0; j < numColumns; j++) {
785 TableWrapData td = row[j]; 784 TableWrapData td = row[j];
786 if (td.isItemData is false) 785 if (td.isItemData is false)
787 continue; 786 continue;
788 787
806 } 805 }
807 if (!secondPassNeeded) return; 806 if (!secondPassNeeded) return;
808 807
809 // Second pass for controls with multi-column horizontal span 808 // Second pass for controls with multi-column horizontal span
810 for (int i = 0; i < grid.size(); i++) { 809 for (int i = 0; i < grid.size(); i++) {
811 TableWrapData[] row = (cast(ArrayWrapperT!(TableWrapData)) grid.get(i)).array; 810 TableWrapData[] row = arrayFromObject!(TableWrapData)( grid.elementAt(i));
812 for (int j = 0; j < numColumns; j++) { 811 for (int j = 0; j < numColumns; j++) {
813 TableWrapData td = row[j]; 812 TableWrapData td = row[j];
814 if (td.isItemData is false || td.colspan is 1) 813 if (td.isItemData is false || td.colspan is 1)
815 continue; 814 continue;
816 815