Mercurial > projects > dwt-addons
view dwtx/jface/layout/AbstractColumnLayout.d @ 43:ea8ff534f622
Fix override and super aliases
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 11 Apr 2008 01:24:25 +0200 |
parents | b6c35faf97c8 |
children | 46a6e0e6ccd4 |
line wrap: on
line source
/******************************************************************************* * Copyright (c) 2006, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation (original file dwtx.ui.texteditor.templates.ColumnLayout) * Tom Schindl <tom.schindl@bestsolution.at> - refactored to be widget independent (bug 171824) * - fix for bug 178280, 184342, 184045 * Port to the D programming language: * Frank Benoit <benoit@tionex.de> *******************************************************************************/ module dwtx.jface.layout.AbstractColumnLayout; import dwt.DWT; import dwt.graphics.Point; import dwt.graphics.Rectangle; import dwt.widgets.Composite; import dwt.widgets.Event; import dwt.widgets.Layout; import dwt.widgets.Listener; import dwt.widgets.Scrollable; import dwt.widgets.Widget; import dwtx.core.runtime.Assert; import dwtx.jface.util.Policy; import dwtx.jface.viewers.ColumnLayoutData; import dwtx.jface.viewers.ColumnPixelData; import dwtx.jface.viewers.ColumnWeightData; import dwtx.jface.viewers.TableLayout; import dwt.dwthelper.utils; /** * The AbstractColumnLayout is a {@link Layout} used to set the size of a table * in a consistent way even during a resize unlike a {@link TableLayout} which * only sets initial sizes. * * <p><b>You can only add the layout to a container whose * only child is the table/tree control you want the layouts applied to.</b> * </p> * * @since 3.3 */ abstract class AbstractColumnLayout : Layout { /** * The number of extra pixels taken as horizontal trim by the table column. * To ensure there are N pixels available for the content of the column, * assign N+COLUMN_TRIM for the column width. * * @since 3.1 */ private static int COLUMN_TRIM; static const bool IS_GTK; static const String LAYOUT_DATA; static this(){ COLUMN_TRIM = "carbon".equals(DWT.getPlatform()) ? 24 : 3; //$NON-NLS-1$ IS_GTK = "gtk".equals(DWT.getPlatform());//$NON-NLS-1$ LAYOUT_DATA = Policy.JFACE ~ ".LAYOUT_DATA"; //$NON-NLS-1$ } private bool inupdateMode = false; private bool relayout = true; private Listener resizeListener; private void init_resizeListener(){ resizeListener = new class Listener { public void handleEvent(Event event) { if( ! inupdateMode ) { updateColumnData(event.widget); } } }; } public this(){ init_resizeListener(); } /** * Adds a new column of data to this table layout. * * @param column * the column * * @param data * the column layout data */ public void setColumnData(Widget column, ColumnLayoutData data) { if( column.getData(LAYOUT_DATA) is null ) { column.addListener(DWT.Resize, resizeListener); } column.setData(LAYOUT_DATA, data); } /** * Compute the size of the table or tree based on the ColumnLayoutData and * the width and height hint. * * @param scrollable * the widget to compute * @param wHint * the width hint * @param hHint * the height hint * @return Point where x is the width and y is the height */ private Point computeTableTreeSize(Scrollable scrollable, int wHint, int hHint) { Point result = scrollable.computeSize(wHint, hHint); int width = 0; int size = getColumnCount(scrollable); for (int i = 0; i < size; ++i) { ColumnLayoutData layoutData = getLayoutData(scrollable,i); if ( auto col = cast(ColumnPixelData)layoutData) { width += col.width; if (col.addTrim) { width += COLUMN_TRIM; } } else if ( auto col = cast(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; } /** * Layout the scrollable based on the supplied width and area. Only increase * the size of the scrollable if increase is <code>true</code>. * * @param scrollable * @param width * @param area * @param increase */ private void layoutTableTree(Scrollable scrollable, int width, Rectangle area, bool increase) { int size = getColumnCount(scrollable); int[] widths = new int[size]; int[] weightIteration = new int[size]; int numberOfWeightColumns = 0; int fixedWidth = 0; int minWeightWidth = 0; int totalWeight = 0; // First calc space occupied by fixed columns for (int i = 0; i < size; i++) { ColumnLayoutData col = getLayoutData(scrollable,i); if ( auto cpd = cast(ColumnPixelData)col ) { int pixels = cpd.width; if (cpd.addTrim) { pixels += COLUMN_TRIM; } widths[i] = pixels; fixedWidth += pixels; } else if ( auto cw = cast(ColumnWeightData) col ) { weightIteration[numberOfWeightColumns] = i; numberOfWeightColumns++; totalWeight += cw.weight; minWeightWidth += cw.minimumWidth; widths[i] = cw.minimumWidth; } else { Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$ } } // Do we have columns that have a weight? int restIncludingMinWidths = width - fixedWidth; int rest = restIncludingMinWidths - minWeightWidth; if (numberOfWeightColumns > 0 && rest > 0) { // Modify the weights to reflect what each column already // has due to its minimum. Otherwise, columns with low // minimums get discriminated. int totalWantedPixels = 0; int[] wantedPixels = new int[numberOfWeightColumns]; for (int i = 0; i < numberOfWeightColumns; i++) { ColumnWeightData cw = cast(ColumnWeightData) getLayoutData(scrollable,weightIteration[i]); wantedPixels[i] = totalWeight is 0 ? 0 : cw.weight * restIncludingMinWidths / totalWeight; totalWantedPixels += wantedPixels[i]; } // Now distribute the rest to the columns with weight. int totalDistributed = 0; for (int i = 0; i < numberOfWeightColumns; ++i) { int pixels = totalWantedPixels is 0 ? 0 : wantedPixels[i] * rest / totalWantedPixels; totalDistributed += pixels; widths[weightIteration[i]] += pixels; } // Distribute any remaining pixels to columns with weight. int diff = rest - totalDistributed; for (int i = 0; diff > 0; i = ((i + 1) % numberOfWeightColumns)) { ++widths[weightIteration[i]]; --diff; } } 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); } } /* * (non-Javadoc) * * @see dwt.widgets.Layout#computeSize(dwt.widgets.Composite, * int, int, bool) */ protected override Point computeSize(Composite composite, int wHint, int hHint, bool flushCache) { return computeTableTreeSize(getControl(composite), wHint, hHint); } /* * (non-Javadoc) * * @see dwt.widgets.Layout#layout(dwt.widgets.Composite, * bool) */ protected override void layout(Composite composite, bool 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 (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(); } } /** * Compute the area required for trim. * * @param area * @param scrollable * @param currentWidth * @return int */ 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; } /** * Get the control being laid out. * * @param composite * the composite with the layout * @return {@link Scrollable} */ Scrollable getControl(Composite composite) { return cast(Scrollable) composite.getChildren()[0]; } /** * Get the number of columns for the receiver. * * @return the number of columns */ abstract int getColumnCount(Scrollable tableTree); /** * Set the widths of the columns. * * @param widths */ abstract void setColumnWidths(Scrollable tableTree, int[] widths); abstract ColumnLayoutData getLayoutData(Scrollable tableTree, int columnIndex); abstract void updateColumnData(Widget column); }