Package org.eclipse.ui.texteditor.templates

Source Code of org.eclipse.ui.texteditor.templates.ColumnLayout

/*******************************************************************************
* Copyright (c) 2005, 2010 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
*******************************************************************************/
package org.eclipse.ui.texteditor.templates;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
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.ScrollBar;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

import org.eclipse.core.runtime.Assert;

import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnWeightData;

/**
* Layout for tables, adapted from <code>TableLayoutComposite</code>.
* <p>
* XXX: Should switch to use {@link org.eclipse.jface.layout.TableColumnLayout}.
* </p>
*
* @since 3.2
*/
final class ColumnLayout extends Layout {

  private static final String RECALCULATE_LAYOUT= "recalculateKey"; //$NON-NLS-1$

  /**
   * 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.
   * <p>
   * XXX: Should either switch to use
   * {@link org.eclipse.jface.layout.TableColumnLayout} or get API from JFace
   * or SWT, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=218483
   * </p>
   *
   * @since 3.1
   */
  private static int COLUMN_TRIM;
  static {
    String platform= SWT.getPlatform();
    if ("win32".equals(platform)) //$NON-NLS-1$
      COLUMN_TRIM= 4;
    else if ("carbon".equals(platform)) //$NON-NLS-1$
      COLUMN_TRIM= 24;
    else
      COLUMN_TRIM= 3;
  }

  private List columns= new ArrayList();

  /**
   * Adds a new column of data to this table layout.
   *
   * @param data the column layout data
   */
  public void addColumnData(ColumnLayoutData data) {
    columns.add(data);
  }

  private Point computeTableSize(Table table, int wHint, int hHint) {
    Point result= table.computeSize(wHint, hHint);

    int width= 0;
    int size= columns.size();
    for (int i= 0; i < size; ++i) {
      ColumnLayoutData layoutData= (ColumnLayoutData) columns.get(i);
      if (layoutData instanceof ColumnPixelData) {
        ColumnPixelData col= (ColumnPixelData) layoutData;
        width += col.width;
        if (col.addTrim) {
          width += COLUMN_TRIM;
        }
      } 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 layoutTable(final Table table, final int width, final Rectangle area, final boolean increase) {
    final TableColumn[] tableColumns= table.getColumns();
    final int size= Math.min(columns.size(), tableColumns.length);
    final int[] widths= new int[size];

    final 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= (ColumnLayoutData) columns.get(i);
      if (col instanceof ColumnPixelData) {
        ColumnPixelData cpd= (ColumnPixelData) col;
        int pixels= cpd.width;
        if (cpd.addTrim) {
          pixels += COLUMN_TRIM;
        }
        widths[i]= pixels;
        fixedWidth += pixels;
      } else if (col instanceof ColumnWeightData) {
        ColumnWeightData cw= (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?
    final int restIncludingMinWidths= width - fixedWidth;
    final 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;
      final int[] wantedPixels= new int[numberOfWeightColumns];
      for (int i= 0; i < numberOfWeightColumns; i++) {
        ColumnWeightData cw= (ColumnWeightData) columns.get(weightIteration[i]);
        wantedPixels[i]= totalWeight == 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 == 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) {
      table.setSize(area.width, area.height);
    }
    for (int i= 0; i < size; i++) {
      tableColumns[i].setWidth(widths[i]);
    }
    if (!increase) {
      table.setSize(area.width, area.height);
    }
  }

  /*
   * @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite, int, int, boolean)
   */
  protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
    return computeTableSize(getTable(composite), wHint, hHint);
  }

  /*
   * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite, boolean)
   */
  protected void layout(Composite composite, boolean flushCache) {
        Rectangle area= composite.getClientArea();
        Table table= getTable(composite);
        int tableWidth= table.getSize().x;
        int trim= computeTrim(area, table, tableWidth);
        int width= Math.max(0, area.width - trim);

        if (width > 1)
          layoutTable(table, width, area, tableWidth < area.width);

        if( composite.getData(RECALCULATE_LAYOUT) == null ) {
          composite.setData(RECALCULATE_LAYOUT, Boolean.FALSE);
          composite.layout();
        }
  }

  private int computeTrim(Rectangle area, Table table, int tableWidth) {
    Point preferredSize= computeTableSize(table, area.width, area.height);
        int trim;
        if (tableWidth > 1) {
          trim= tableWidth - table.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 * table.getBorderWidth() + 1 ;
        }
        if (preferredSize.y > area.height) {
            // Subtract the scrollbar width from the total column width
            // if a vertical scrollbar will be required, but is not currently showing
          // (in which case it is already subtracted above)
            ScrollBar vBar= table.getVerticalBar();
            if (!vBar.isVisible()) {
              Point vBarSize= vBar.getSize();
              trim += vBarSize.x;
            }
        }
    return trim;
  }

  private Table getTable(Composite composite) {
    return (Table) composite.getChildren()[0];
  }

}
TOP

Related Classes of org.eclipse.ui.texteditor.templates.ColumnLayout

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.