/**
* Copyright (c) 2009 Borland Software Corp.
*
* 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:
* Alexander Shatalin (Borland) - initial API and implementation
*/
package org.eclipse.gmf.graphdef.editor.edit.policies;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.GridLayout;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Shape;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.graphics.Color;
public class GridFigure extends Shape {
private static final Rectangle INNER_FIGURE_BOUNDS = new Rectangle();
private int[] myHeights;
private int[] myWidths;
private IFigure[][] myGrid;
private Color myInnerFigureColor;
private GridLayout myGridLayout;
public GridFigure(int[] heights, int[] widths) {
myHeights = new int[heights.length - 1];
System.arraycopy(heights, 0, myHeights, 0, myHeights.length);
myWidths = widths;
}
public GridFigure(IFigure[][] grid, int[] heights, int[] widths, GridLayout gridLayout) {
this(heights, widths);
myGrid = grid;
myGridLayout = gridLayout;
}
public void setInnerFigureBoundsColor(Color color) {
myInnerFigureColor = color;
}
@Override
protected void fillShape(Graphics graphics) {
}
@Override
protected void outlineShape(Graphics graphics) {
float lineInset = Math.max(1.0f, getLineWidthFloat()) / 2.0f;
int inset1 = (int) Math.floor(lineInset);
int inset2 = (int) Math.ceil(lineInset);
Rectangle r = Rectangle.SINGLETON;
r.x = getBounds().x + inset1 + myGridLayout.marginWidth;
r.y = getBounds().y + inset1 + myGridLayout.marginHeight;
int acc = 0;
for (int i = 0; i < myWidths.length; i++) {
acc += myWidths[i] + myGridLayout.horizontalSpacing;
}
r.width = Math.min(acc, getBounds().width - inset1 - inset2);
acc = 0;
for (int i = 0; i < myHeights.length; i++) {
acc += myHeights[i] + myGridLayout.verticalSpacing;
}
r.height = Math.min(acc, getBounds().height - inset1 - inset2);
graphics.drawRectangle(r);
acc = r.y - myGridLayout.verticalSpacing/2;
for (int i = 0; i < myHeights.length - 1; i++) {
acc += myHeights[i] + myGridLayout.verticalSpacing;
graphics.drawLine(r.x, acc, r.right(), acc);
}
acc = r.x - myGridLayout.horizontalSpacing/2;
for (int i = 0; i < myWidths.length - 1; i++) {
acc += myWidths[i] + myGridLayout.horizontalSpacing;
graphics.drawLine(acc, r.y, acc, r.bottom());
}
for (int i = 0; i < myHeights.length; i++) {
for (int j = 0; j < myWidths.length; ) {
if (myGrid[i][j] == null || i > 0 && myGrid[i - 1][j] == myGrid[i][j]) {
j++;
continue;
}
int width = 1;
while (j + width < myWidths.length && myGrid[i][j] == myGrid[i][j + width]) {
width++;
}
int height = 1;
while (j + height < myHeights.length && myGrid[i][j] == myGrid[i + height][j]) {
height++;
}
drawInnerFigureBounds(graphics, r, i, j, width, height);
j += width;
}
}
}
private void drawInnerFigureBounds(Graphics graphics, Rectangle figureBounds, int row, int column, int width, int height) {
graphics.pushState();
if (myInnerFigureColor != null) {
graphics.setForegroundColor(myInnerFigureColor);
}
INNER_FIGURE_BOUNDS.x = figureBounds.x - myGridLayout.horizontalSpacing/2;
for (int k = 0; k < column; k++) {
INNER_FIGURE_BOUNDS.x += myWidths[k] + myGridLayout.horizontalSpacing;
}
INNER_FIGURE_BOUNDS.width = 0;
for (int k = column; k < column + width; k++) {
INNER_FIGURE_BOUNDS.width += myWidths[k] + myGridLayout.horizontalSpacing;
}
INNER_FIGURE_BOUNDS.y = figureBounds.y - myGridLayout.verticalSpacing/2;
for (int k = 0; k < row; k++) {
INNER_FIGURE_BOUNDS.y += myHeights[k] + myGridLayout.verticalSpacing;
}
INNER_FIGURE_BOUNDS.height = 0;
for (int k = row; k < row + height; k++) {
INNER_FIGURE_BOUNDS.height += myHeights[k] + myGridLayout.verticalSpacing;
}
graphics.drawRoundRectangle(INNER_FIGURE_BOUNDS, 10, 10);
graphics.popState();
}
}