package org.eclipse.uml2.diagram.common.draw2d;
import org.eclipse.draw2d.AbstractHintLayout;
import org.eclipse.draw2d.BorderLayout;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gmf.runtime.draw2d.ui.figures.WrappingLabel;
public class NameAndStereotypeBlock extends RectangleFigure {
private StereotypeLabel2 myStereotypeLabel;
private WrappingLabel myNameLabel;
public NameAndStereotypeBlock() {
setLineWidthFloat(0f);
setOutline(false);
setFill(false);
setLayoutManager(new TopBottomLayout());
myStereotypeLabel = new StereotypeLabel2();
myNameLabel = new WrappingLabel();
myNameLabel.setAlignment(PositionConstants.CENTER);
myNameLabel.setBackgroundColor(ColorConstants.yellow);
this.add(myStereotypeLabel, BorderLayout.TOP);
this.add(myNameLabel, BorderLayout.BOTTOM);
}
public StereotypeLabel2 getStereotypeLabel() {
return myStereotypeLabel;
}
public WrappingLabel getNameLabel() {
return myNameLabel;
}
@Override
public String toString() {
boolean stereoVisible = getStereotypeLabel().isVisible();
return "Stereo:" + getStereotypeLabel().getText() + ", [" + stereoVisible + "], Name: " + getNameLabel().getText(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public void setNameTextWrap(boolean nameTextWrap) {
myNameLabel.setTextWrap(nameTextWrap);
}
/**
* Basically it is BorderLayout with
* a) only TOP/BOTTOM children and
* b) tweaked extraction of minimum size, which knows that stereotype label
* may never be hidden during inplace
*/
private static class TopBottomLayout extends AbstractHintLayout {
private IFigure top, bottom;
private int vGap = 5;
private int hGap = 0;
@Override
protected Dimension calculateMinimumSize(IFigure container, int wHint, int hHint) {
int minWHint = 0, minHHint = 0;
if (wHint < 0) {
minWHint = -1;
}
if (hHint < 0) {
minHHint = -1;
}
Insets border = container.getInsets();
wHint = Math.max(minWHint, wHint - border.getWidth());
hHint = Math.max(minHHint, hHint - border.getHeight());
Dimension minSize = new Dimension();
int middleRowWidth = 0, middleRowHeight = 0;
int rows = 0, columns = 0;
if (top != null && top.isVisible()) {
Dimension childSize = extractMinimumSize(top, wHint, hHint); //sic
hHint = Math.max(minHHint, hHint - (childSize.height + vGap));
minSize.setSize(childSize);
rows += 1;
}
if (bottom != null && bottom.isVisible()) {
Dimension childSize = extractMinimumSize(bottom, wHint, hHint); //sic
hHint = Math.max(minHHint, hHint - (childSize.height + vGap));
minSize.width = Math.max(minSize.width, childSize.width);
minSize.height += childSize.height;
rows += 1;
}
rows += columns > 0 ? 1 : 0;
// Add spacing, insets, and the size of the middle row
minSize.height += middleRowHeight + border.getHeight() + ((rows - 1) * vGap);
minSize.width = Math.max(minSize.width, middleRowWidth) + border.getWidth() + ((columns - 1) * hGap);
return minSize;
}
private Dimension extractMinimumSize(IFigure figure, int wHint, int hHint) {
if (figure instanceof StereotypeLabel2 && ((StereotypeLabel2) figure).isNeverHide()) {
return figure.getPreferredSize(wHint, hHint);
}
return figure.getMinimumSize(wHint, hHint);
}
@Override
protected Dimension calculatePreferredSize(IFigure container, int wHint, int hHint) {
int minWHint = 0, minHHint = 0;
if (wHint < 0)
minWHint = -1;
if (hHint < 0)
minHHint = -1;
Insets border = container.getInsets();
wHint = Math.max(minWHint, wHint - border.getWidth());
hHint = Math.max(minHHint, hHint - border.getHeight());
Dimension prefSize = new Dimension();
int middleRowWidth = 0, middleRowHeight = 0;
int rows = 0, columns = 0;
if (top != null && top.isVisible()) {
Dimension childSize = top.getPreferredSize(wHint, hHint);
hHint = Math.max(minHHint, hHint - (childSize.height + vGap));
prefSize.setSize(childSize);
rows += 1;
}
if (bottom != null && bottom.isVisible()) {
Dimension childSize = bottom.getPreferredSize(wHint, hHint);
hHint = Math.max(minHHint, hHint - (childSize.height + vGap));
prefSize.width = Math.max(prefSize.width, childSize.width);
prefSize.height += childSize.height;
rows += 1;
}
rows += columns > 0 ? 1 : 0;
// Add spacing, insets, and the size of the middle row
prefSize.height += middleRowHeight + border.getHeight() + ((rows - 1) * vGap);
prefSize.width = Math.max(prefSize.width, middleRowWidth) + border.getWidth() + ((columns - 1) * hGap);
return prefSize;
}
public void layout(IFigure container) {
Rectangle area = container.getClientArea();
Rectangle rect = new Rectangle();
Dimension childSize;
if (top != null && top.isVisible()) {
childSize = top.getPreferredSize(area.width, -1);
rect.setLocation(area.x, area.y);
rect.setSize(childSize);
rect.width = area.width;
top.setBounds(rect);
area.y += rect.height + vGap;
area.height -= rect.height + vGap;
}
if (bottom != null && bottom.isVisible()) {
childSize = bottom.getPreferredSize(Math.max(area.width, 0), -1);
rect.setSize(childSize);
rect.width = area.width;
rect.setLocation(area.x, area.y + area.height - rect.height);
bottom.setBounds(rect);
area.height -= rect.height + vGap;
}
}
@Override
public void remove(IFigure child) {
if (top == child) {
top = null;
} else if (bottom == child) {
bottom = null;
}
}
@Override
public void setConstraint(IFigure child, Object constraint) {
remove(child);
super.setConstraint(child, constraint);
if (constraint == null) {
return;
}
switch (((Integer) constraint).intValue()) {
case PositionConstants.TOP:
top = child;
break;
case PositionConstants.BOTTOM:
bottom = child;
break;
default:
break;
}
}
public void setHorizontalSpacing(int gap) {
hGap = gap;
}
public void setVerticalSpacing(int gap) {
vGap = gap;
}
}
}