X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.browsing.ui.nattable%2Fsrc%2Forg%2Fsimantics%2Fbrowsing%2Fui%2Fnattable%2FNatTableColumnLayout.java;h=3bff312550d19a2ae40be7c3a0c4429669c2ca1e;hp=b0b6904ce10e14df86dd1c652ad679bb7daa7fda;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/NatTableColumnLayout.java b/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/NatTableColumnLayout.java index b0b6904ce..3bff31255 100644 --- a/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/NatTableColumnLayout.java +++ b/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/NatTableColumnLayout.java @@ -1,282 +1,282 @@ -package org.simantics.browsing.ui.nattable; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.jface.util.Util; -import org.eclipse.jface.viewers.ColumnLayoutData; -import org.eclipse.jface.viewers.ColumnPixelData; -import org.eclipse.jface.viewers.ColumnWeightData; -import org.eclipse.nebula.widgets.nattable.NatTable; -import org.eclipse.nebula.widgets.nattable.coordinate.Range; -import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer; -import org.eclipse.nebula.widgets.nattable.layer.ILayerListener; -import org.eclipse.nebula.widgets.nattable.layer.event.ColumnDeleteEvent; -import org.eclipse.nebula.widgets.nattable.layer.event.ColumnInsertEvent; -import org.eclipse.nebula.widgets.nattable.layer.event.ILayerEvent; -import org.eclipse.nebula.widgets.nattable.resize.event.ColumnResizeEvent; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Layout; -import org.eclipse.swt.widgets.Scrollable; - - -/** - * Modified org.eclipse.jface.layout.AbstractColumnLayout and TreeColumnLayout to NatTable compatible. - * - * @author Marko Luukkainen - * - */ -public class NatTableColumnLayout extends Layout implements ILayerListener{ - private static int COLUMN_TRIM; - static { - if (Util.isWindows()) { - COLUMN_TRIM = 4; - } else if (Util.isMac()) { - COLUMN_TRIM = 24; - } else { - COLUMN_TRIM = 3; - } - } - - NatTable natTable; - GEColumnHeaderDataProvider columnHeaderDataProvider; - DefaultRowHeaderDataLayer rowHeaderDataLayer; - Map layoutDatas = new HashMap<>(); - - private boolean inupdateMode = false; - - private boolean relayout = true; - - public NatTableColumnLayout(NatTable natTable, GEColumnHeaderDataProvider columnHeaderDataProvider) { - this.natTable = natTable; - this.columnHeaderDataProvider = columnHeaderDataProvider; - this.natTable.addLayerListener(this); - } - - public NatTableColumnLayout(NatTable natTable, GEColumnHeaderDataProvider columnHeaderDataProvider, DefaultRowHeaderDataLayer rowHeaderDataLayer) { - this.natTable = natTable; - this.columnHeaderDataProvider = columnHeaderDataProvider; - this.natTable.addLayerListener(this); - this.rowHeaderDataLayer = rowHeaderDataLayer; - } - - public void setColumnData(int column, ColumnLayoutData data) { - layoutDatas.put(column, data); - } - - protected void setColumnWidths(Scrollable tree, int[] widths) { - for (int i=0; i < widths.length; i++) { - columnHeaderDataProvider.getDataLayer().setColumnWidthByPosition(i, widths[i]); - } - } - - @Override - public void handleLayerEvent(ILayerEvent event) { - if (inupdateMode) - return; - if (event instanceof ColumnResizeEvent) { - ColumnResizeEvent evt = (ColumnResizeEvent)event; - for (Range r : evt.getColumnPositionRanges()) { - int colIndex = evt.getLayer().getColumnIndexByPosition(r.start); - int w = columnHeaderDataProvider.getDataLayer().getColumnWidthByPosition(colIndex); - setColumnData(colIndex, new ColumnPixelData(w)); - } - update(); - } else if (event instanceof ColumnInsertEvent || - event instanceof ColumnDeleteEvent) { - update(); - } - } - - boolean updateCalled = false; - - private void update() { - if (updateCalled) - return; - updateCalled = true; - natTable.getDisplay().asyncExec(new Runnable() { - - @Override - public void run() { - if (!natTable.isDisposed()) { - natTable.update(); - natTable.getParent().layout(); - } - updateCalled = false; - } - }); - } - - - @Override - protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { - return computeTableTreeSize(getControl(composite), wHint, hHint); - } - - Scrollable getControl(Composite composite) { - return natTable; - } - - - @Override - protected void layout(Composite composite, boolean flushCache) { - Rectangle area = composite.getClientArea(); - Scrollable table = getControl(composite); - int tableWidth = table.getSize().x; - int trim = computeTrim(area, table, tableWidth); - int width = Math.max(0, area.width - trim); - if (rowHeaderDataLayer != null) - width -= rowHeaderDataLayer.getWidth(); - - if (width > 1) - layoutTableTree(table, width, area, tableWidth < area.width); - - // For the first time we need to relayout because Scrollbars are not - // calculate appropriately - if (relayout) { - relayout = false; - composite.layout(); - } - - } - - protected ColumnLayoutData getLayoutData(Scrollable tableTree, - int columnIndex) { - return layoutDatas.get(columnIndex); - } - - protected int getColumnCount(Scrollable tableTree) { - return columnHeaderDataProvider.getColumnCount(); - } - - private Point computeTableTreeSize(Scrollable scrollable, int wHint, - int hHint) { - Point result = scrollable.computeSize(wHint, hHint); - - int width = 0; - int size = getColumnCount(scrollable); - if (rowHeaderDataLayer != null) - width += rowHeaderDataLayer.getWidth(); - for (int i = 0; i < size; ++i) { - ColumnLayoutData layoutData = getLayoutData(scrollable, i); - if (layoutData instanceof ColumnPixelData) { - ColumnPixelData col = (ColumnPixelData) layoutData; - width += col.width; - if (col.addTrim) { - width += getColumnTrim(); - } - } else if (layoutData instanceof ColumnWeightData) { - ColumnWeightData col = (ColumnWeightData) layoutData; - width += col.minimumWidth; - } else { - Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$ - } - } - if (width > result.x) - result.x = width; - - return result; - } - - private void layoutTableTree(final Scrollable scrollable, final int width, - final Rectangle area, final boolean increase) { - final int numberOfColumns = getColumnCount(scrollable); - final int[] widths = new int[numberOfColumns]; - - final int[] weightColumnIndices = new int[numberOfColumns]; - int numberOfWeightColumns = 0; - - int fixedWidth = 0; - int totalWeight = 0; - - // First calc space occupied by fixed columns - for (int i = 0; i < numberOfColumns; i++) { - ColumnLayoutData col = getLayoutData(scrollable, i); - if (col instanceof ColumnPixelData) { - ColumnPixelData cpd = (ColumnPixelData) col; - int pixels = cpd.width; - if (cpd.addTrim) { - pixels += getColumnTrim(); - } - widths[i] = pixels; - fixedWidth += pixels; - } else if (col instanceof ColumnWeightData) { - ColumnWeightData cw = (ColumnWeightData) col; - weightColumnIndices[numberOfWeightColumns] = i; - numberOfWeightColumns++; - totalWeight += cw.weight; - } else { - Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$ - } - } - - boolean recalculate; - do { - recalculate = false; - for (int i = 0; i < numberOfWeightColumns; i++) { - int colIndex = weightColumnIndices[i]; - ColumnWeightData cw = (ColumnWeightData) getLayoutData( - scrollable, colIndex); - final int minWidth = cw.minimumWidth; - final int allowedWidth = totalWeight == 0 ? 0 - : (width - fixedWidth) * cw.weight / totalWeight; - if (allowedWidth < minWidth) { - /* - * if the width assigned by weight is less than the minimum, - * then treat this column as fixed, remove it from weight - * calculations, and recalculate other weights. - */ - numberOfWeightColumns--; - totalWeight -= cw.weight; - fixedWidth += minWidth; - widths[colIndex] = minWidth; - System.arraycopy(weightColumnIndices, i + 1, - weightColumnIndices, i, numberOfWeightColumns - i); - recalculate = true; - break; - } - widths[colIndex] = allowedWidth; - } - } while (recalculate); - - if (increase) { - scrollable.setSize(area.width, area.height); - } - - inupdateMode = true; - setColumnWidths(scrollable, widths); - scrollable.update(); - inupdateMode = false; - - if (!increase) { - scrollable.setSize(area.width, area.height); - } - } - - private int computeTrim(Rectangle area, Scrollable scrollable, - int currentWidth) { - int trim; - - if (currentWidth > 1) { - trim = currentWidth - scrollable.getClientArea().width; - } else { - // initially, the table has no extend and no client area - use the - // border with - // plus some padding as educated guess - trim = 2 * scrollable.getBorderWidth() + 1; - } - - return trim; - } - - protected int getColumnTrim() { - return COLUMN_TRIM; - } - - - - -} +package org.simantics.browsing.ui.nattable; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.util.Util; +import org.eclipse.jface.viewers.ColumnLayoutData; +import org.eclipse.jface.viewers.ColumnPixelData; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.nebula.widgets.nattable.NatTable; +import org.eclipse.nebula.widgets.nattable.coordinate.Range; +import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer; +import org.eclipse.nebula.widgets.nattable.layer.ILayerListener; +import org.eclipse.nebula.widgets.nattable.layer.event.ColumnDeleteEvent; +import org.eclipse.nebula.widgets.nattable.layer.event.ColumnInsertEvent; +import org.eclipse.nebula.widgets.nattable.layer.event.ILayerEvent; +import org.eclipse.nebula.widgets.nattable.resize.event.ColumnResizeEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Scrollable; + + +/** + * Modified org.eclipse.jface.layout.AbstractColumnLayout and TreeColumnLayout to NatTable compatible. + * + * @author Marko Luukkainen + * + */ +public class NatTableColumnLayout extends Layout implements ILayerListener{ + private static int COLUMN_TRIM; + static { + if (Util.isWindows()) { + COLUMN_TRIM = 4; + } else if (Util.isMac()) { + COLUMN_TRIM = 24; + } else { + COLUMN_TRIM = 3; + } + } + + NatTable natTable; + GEColumnHeaderDataProvider columnHeaderDataProvider; + DefaultRowHeaderDataLayer rowHeaderDataLayer; + Map layoutDatas = new HashMap<>(); + + private boolean inupdateMode = false; + + private boolean relayout = true; + + public NatTableColumnLayout(NatTable natTable, GEColumnHeaderDataProvider columnHeaderDataProvider) { + this.natTable = natTable; + this.columnHeaderDataProvider = columnHeaderDataProvider; + this.natTable.addLayerListener(this); + } + + public NatTableColumnLayout(NatTable natTable, GEColumnHeaderDataProvider columnHeaderDataProvider, DefaultRowHeaderDataLayer rowHeaderDataLayer) { + this.natTable = natTable; + this.columnHeaderDataProvider = columnHeaderDataProvider; + this.natTable.addLayerListener(this); + this.rowHeaderDataLayer = rowHeaderDataLayer; + } + + public void setColumnData(int column, ColumnLayoutData data) { + layoutDatas.put(column, data); + } + + protected void setColumnWidths(Scrollable tree, int[] widths) { + for (int i=0; i < widths.length; i++) { + columnHeaderDataProvider.getDataLayer().setColumnWidthByPosition(i, widths[i]); + } + } + + @Override + public void handleLayerEvent(ILayerEvent event) { + if (inupdateMode) + return; + if (event instanceof ColumnResizeEvent) { + ColumnResizeEvent evt = (ColumnResizeEvent)event; + for (Range r : evt.getColumnPositionRanges()) { + int colIndex = evt.getLayer().getColumnIndexByPosition(r.start); + int w = columnHeaderDataProvider.getDataLayer().getColumnWidthByPosition(colIndex); + setColumnData(colIndex, new ColumnPixelData(w)); + } + update(); + } else if (event instanceof ColumnInsertEvent || + event instanceof ColumnDeleteEvent) { + update(); + } + } + + boolean updateCalled = false; + + private void update() { + if (updateCalled) + return; + updateCalled = true; + natTable.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if (!natTable.isDisposed()) { + natTable.update(); + natTable.getParent().layout(); + } + updateCalled = false; + } + }); + } + + + @Override + protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { + return computeTableTreeSize(getControl(composite), wHint, hHint); + } + + Scrollable getControl(Composite composite) { + return natTable; + } + + + @Override + protected void layout(Composite composite, boolean flushCache) { + Rectangle area = composite.getClientArea(); + Scrollable table = getControl(composite); + int tableWidth = table.getSize().x; + int trim = computeTrim(area, table, tableWidth); + int width = Math.max(0, area.width - trim); + if (rowHeaderDataLayer != null) + width -= rowHeaderDataLayer.getWidth(); + + if (width > 1) + layoutTableTree(table, width, area, tableWidth < area.width); + + // For the first time we need to relayout because Scrollbars are not + // calculate appropriately + if (relayout) { + relayout = false; + composite.layout(); + } + + } + + protected ColumnLayoutData getLayoutData(Scrollable tableTree, + int columnIndex) { + return layoutDatas.get(columnIndex); + } + + protected int getColumnCount(Scrollable tableTree) { + return columnHeaderDataProvider.getColumnCount(); + } + + private Point computeTableTreeSize(Scrollable scrollable, int wHint, + int hHint) { + Point result = scrollable.computeSize(wHint, hHint); + + int width = 0; + int size = getColumnCount(scrollable); + if (rowHeaderDataLayer != null) + width += rowHeaderDataLayer.getWidth(); + for (int i = 0; i < size; ++i) { + ColumnLayoutData layoutData = getLayoutData(scrollable, i); + if (layoutData instanceof ColumnPixelData) { + ColumnPixelData col = (ColumnPixelData) layoutData; + width += col.width; + if (col.addTrim) { + width += getColumnTrim(); + } + } else if (layoutData instanceof ColumnWeightData) { + ColumnWeightData col = (ColumnWeightData) layoutData; + width += col.minimumWidth; + } else { + Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$ + } + } + if (width > result.x) + result.x = width; + + return result; + } + + private void layoutTableTree(final Scrollable scrollable, final int width, + final Rectangle area, final boolean increase) { + final int numberOfColumns = getColumnCount(scrollable); + final int[] widths = new int[numberOfColumns]; + + final int[] weightColumnIndices = new int[numberOfColumns]; + int numberOfWeightColumns = 0; + + int fixedWidth = 0; + int totalWeight = 0; + + // First calc space occupied by fixed columns + for (int i = 0; i < numberOfColumns; i++) { + ColumnLayoutData col = getLayoutData(scrollable, i); + if (col instanceof ColumnPixelData) { + ColumnPixelData cpd = (ColumnPixelData) col; + int pixels = cpd.width; + if (cpd.addTrim) { + pixels += getColumnTrim(); + } + widths[i] = pixels; + fixedWidth += pixels; + } else if (col instanceof ColumnWeightData) { + ColumnWeightData cw = (ColumnWeightData) col; + weightColumnIndices[numberOfWeightColumns] = i; + numberOfWeightColumns++; + totalWeight += cw.weight; + } else { + Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$ + } + } + + boolean recalculate; + do { + recalculate = false; + for (int i = 0; i < numberOfWeightColumns; i++) { + int colIndex = weightColumnIndices[i]; + ColumnWeightData cw = (ColumnWeightData) getLayoutData( + scrollable, colIndex); + final int minWidth = cw.minimumWidth; + final int allowedWidth = totalWeight == 0 ? 0 + : (width - fixedWidth) * cw.weight / totalWeight; + if (allowedWidth < minWidth) { + /* + * if the width assigned by weight is less than the minimum, + * then treat this column as fixed, remove it from weight + * calculations, and recalculate other weights. + */ + numberOfWeightColumns--; + totalWeight -= cw.weight; + fixedWidth += minWidth; + widths[colIndex] = minWidth; + System.arraycopy(weightColumnIndices, i + 1, + weightColumnIndices, i, numberOfWeightColumns - i); + recalculate = true; + break; + } + widths[colIndex] = allowedWidth; + } + } while (recalculate); + + if (increase) { + scrollable.setSize(area.width, area.height); + } + + inupdateMode = true; + setColumnWidths(scrollable, widths); + scrollable.update(); + inupdateMode = false; + + if (!increase) { + scrollable.setSize(area.width, area.height); + } + } + + private int computeTrim(Rectangle area, Scrollable scrollable, + int currentWidth) { + int trim; + + if (currentWidth > 1) { + trim = currentWidth - scrollable.getClientArea().width; + } else { + // initially, the table has no extend and no client area - use the + // border with + // plus some padding as educated guess + trim = 2 * scrollable.getBorderWidth() + 1; + } + + return trim; + } + + protected int getColumnTrim() { + return COLUMN_TRIM; + } + + + + +}