/******************************************************************************* * Copyright (c) 2012, 2013 Original authors 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: * Original authors and others - initial API and implementation ******************************************************************************/ package org.eclipse.nebula.widgets.nattable.resize; import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry; import org.eclipse.nebula.widgets.nattable.grid.command.AutoResizeColumnCommandHandler; import org.eclipse.nebula.widgets.nattable.grid.command.AutoResizeRowCommandHandler; import org.eclipse.nebula.widgets.nattable.layer.ILayer; import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell; import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter; import org.eclipse.nebula.widgets.nattable.util.GCFactory; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Rectangle; /** * Does the calculations needed for auto resizing feature Helper class for * {@link AutoResizeColumnCommandHandler} and * {@link AutoResizeRowCommandHandler} */ public class MaxCellBoundsHelper { /** * @return Preferred widths for columns. Preferred width is the minimum * width required to horizontally fit all the contents of the column * (including header) */ public static int[] getPreferredColumnWidths( IConfigRegistry configRegistry, GCFactory gcFactory, ILayer layer, int[] columnPositions) { int[] columnWidths = new int[columnPositions.length]; GC gc = gcFactory.createGC(); for (int i = 0; i < columnPositions.length; i++) { columnWidths[i] = getPreferredColumnWidth(layer, columnPositions[i], configRegistry, gc); } gc.dispose(); return columnWidths; } /** * Calculates the minimum width (in pixels) required to display the complete * contents of the cells in a column. Takes into account the font settings * and display type conversion. */ private static int getPreferredColumnWidth(ILayer layer, int columnPosition, IConfigRegistry configRegistry, GC gc) { ICellPainter painter; int maxWidth = 0; ILayerCell cell; for (int rowPosition = 0; rowPosition < layer.getRowCount(); rowPosition++) { cell = layer.getCellByPosition(columnPosition, rowPosition); if (cell != null) { boolean atEndOfCellSpan = cell.getOriginColumnPosition() + cell.getColumnSpan() - 1 == columnPosition; if (atEndOfCellSpan) { painter = layer.getCellPainter(cell.getColumnPosition(), cell.getRowPosition(), cell, configRegistry); if (painter != null) { int preferredWidth = painter.getPreferredWidth(cell, gc, configRegistry); // Adjust width Rectangle bounds = cell.getBounds(); bounds.width = preferredWidth; Rectangle adjustedCellBounds = cell .getLayer() .getLayerPainter() .adjustCellBounds(columnPosition, rowPosition, bounds); preferredWidth += preferredWidth - adjustedCellBounds.width; if (cell.getColumnSpan() > 1) { int columnStartX = layer .getStartXOfColumnPosition(columnPosition); int cellStartX = layer .getStartXOfColumnPosition(cell .getOriginColumnPosition()); preferredWidth = Math.max(0, preferredWidth - (columnStartX - cellStartX)); } maxWidth = (preferredWidth > maxWidth) ? preferredWidth : maxWidth; } } } } return maxWidth; } public static int[] getPreferredRowHeights(IConfigRegistry configRegistry, GCFactory gcFactory, ILayer layer, int[] rows) { int[] rowHeights = new int[rows.length]; GC gc = gcFactory.createGC(); for (int i = 0; i < rows.length; i++) { rowHeights[i] = getPreferredRowHeight(layer, rows[i], configRegistry, gc); } gc.dispose(); return rowHeights; } private static int getPreferredRowHeight(ILayer layer, int rowPosition, IConfigRegistry configRegistry, GC gc) { int maxHeight = 0; ICellPainter painter; ILayerCell cell; for (int columnPosition = 0; columnPosition < layer.getColumnCount(); columnPosition++) { cell = layer.getCellByPosition(columnPosition, rowPosition); if (cell != null) { boolean atEndOfCellSpan = cell.getOriginRowPosition() + cell.getRowSpan() - 1 == rowPosition; if (atEndOfCellSpan) { painter = layer.getCellPainter(cell.getColumnPosition(), cell.getRowPosition(), cell, configRegistry); if (painter != null) { int preferredHeight = painter.getPreferredHeight(cell, gc, configRegistry); // Adjust height Rectangle bounds = cell.getBounds(); bounds.height = preferredHeight; Rectangle adjustedCellBounds = cell .getLayer() .getLayerPainter() .adjustCellBounds(columnPosition, rowPosition, bounds); preferredHeight += preferredHeight - adjustedCellBounds.height; if (cell.getColumnSpan() > 1) { int rowStartY = layer .getStartYOfRowPosition(rowPosition); int cellStartY = layer.getStartYOfRowPosition(cell .getOriginRowPosition()); preferredHeight = Math.max(0, preferredHeight - (rowStartY - cellStartY)); } maxHeight = (preferredHeight > maxHeight) ? preferredHeight : maxHeight; } } } } return maxHeight; } /** * Traverse the two arrays and return the greater element in each index * position. */ public static int[] greater(int[] array1, int[] array2) { int resultSize = (array1.length < array2.length) ? array1.length : array2.length; int[] result = new int[resultSize]; for (int i = 0; i < resultSize; i++) { result[i] = (array1[i] > array2[i]) ? array1[i] : array2[i]; } return result; } }