blob: eecffd4d40a0daf0059b9477d46df5fee8432287 [file] [log] [blame]
/*******************************************************************************
* Copyright 2005, CHISEL Group, University of Victoria, Victoria, BC, Canada.
* 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: The Chisel Group, University of Victoria
******************************************************************************/
package org.eclipse.zest.core.widgets.internal;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.FigureUtilities;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.ScaledGraphics;
import org.eclipse.draw2d.StackLayout;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
/**
* Overrides the Draw2D Label Figure class to ensure that the text is never
* truncated. Also draws a rounded rectangle border.
*
* @author Chris Callendar
*/
public class GraphLabel extends CachedLabel {
private Color borderColor;
private int borderWidth;
private int arcWidth;
private boolean painting = false;
/**
* Creates a GraphLabel
*
* @param cacheLabel
* Determine if the text should be cached. This will make it
* faster, but the text is not as clear
*/
public GraphLabel(boolean cacheLabel) {
this("", cacheLabel);
}
/**
* Creates a graph label with text
*
* @param text
* The text
* @param cacheLabel
* Determine if the text should be cached. This will make it
* faster, but the
*/
public GraphLabel(String text, boolean cacheLabel) {
this("", null, cacheLabel);
}
/**
* Creates the graph label with an image
*
* @param i
* The Image
* @param cacheLabel
* Determine if the text should be cached. This will make it
* faster, but the
*/
public GraphLabel(Image i, boolean cacheLabel) {
this("", i, cacheLabel);
}
/**
* Creates a graph label with an image and text
*
* @param text
* The text
* @param i
* The Image
* @param cacheLabel
* Determine if the text should be cached. This will make it
* faster, but the
*/
public GraphLabel(String text, Image i, boolean cacheLabel) {
super(cacheLabel);
initLabel();
setText(text);
setIcon(i);
adjustBoundsToFit();
}
/**
* Initialises the border colour, border width, and sets the layout manager.
* Also sets the font to be the default system font.
*/
protected void initLabel() {
super.setFont(Display.getDefault().getSystemFont());
this.borderColor = ColorConstants.black;
this.borderWidth = 0;
this.arcWidth = 8;
this.setLayoutManager(new StackLayout());
this.setBorder(new MarginBorder(1));
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.Figure#setFont(org.eclipse.swt.graphics.Font)
*/
public void setFont(Font f) {
super.setFont(f);
adjustBoundsToFit();
}
/**
* Adjust the bounds to make the text fit without truncation.
*/
protected void adjustBoundsToFit() {
String text = getText();
int safeBorderWidth = borderWidth > 0 ? borderWidth : 1;
if ((text != null)) {
Font font = getFont();
if (font != null) {
Dimension minSize = FigureUtilities.getTextExtents(text, font);
if (getIcon() != null) {
org.eclipse.swt.graphics.Rectangle imageRect = getIcon().getBounds();
int expandHeight = Math.max(imageRect.height - minSize.height, 0);
minSize.expand(imageRect.width + 4, expandHeight);
}
minSize.expand(10 + (2 * safeBorderWidth), 4 + (2 * safeBorderWidth));
setBounds(new Rectangle(getLocation(), minSize));
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.Label#paintFigure(org.eclipse.draw2d.Graphics)
*/
public void paint(Graphics graphics) {
int blue = getBackgroundColor().getBlue();
blue = (int) (blue - (blue * 0.20));
blue = blue > 0 ? blue : 0;
int red = getBackgroundColor().getRed();
red = (int) (red - (red * 0.20));
red = red > 0 ? red : 0;
int green = getBackgroundColor().getGreen();
green = (int) (green - (green * 0.20));
green = green > 0 ? green : 0;
Color lightenColor = new Color(Display.getCurrent(), new RGB(red, green, blue));
graphics.setForegroundColor(lightenColor);
graphics.setBackgroundColor(getBackgroundColor());
int safeBorderWidth = borderWidth > 0 ? borderWidth : 1;
graphics.pushState();
double scale = 1;
if (graphics instanceof ScaledGraphics) {
scale = ((ScaledGraphics) graphics).getAbsoluteScale();
}
// Top part inside the border (as fillGradient does not allow to fill a rectangle with round corners).
Rectangle rect = getBounds().getCopy();
rect.height /= 2;
graphics.setForegroundColor(getBackgroundColor());
graphics.setBackgroundColor(getBackgroundColor());
graphics.fillRoundRectangle(rect, arcWidth * safeBorderWidth, arcWidth * 2 * safeBorderWidth);
// Bottom part inside the border.
rect.y = rect.y + rect.height;
rect.height += 1; // Not sure why it is needed, but it is needed ;-)
graphics.setForegroundColor(lightenColor);
graphics.setBackgroundColor(lightenColor);
graphics.fillRoundRectangle(rect, arcWidth * safeBorderWidth, arcWidth * 2 * safeBorderWidth);
// Now fill the middle part of top and bottom part with a gradient.
rect = bounds.getCopy();
rect.height -= 2;
rect.y += (safeBorderWidth) / 2;
rect.y += (arcWidth / 2);
rect.height -= arcWidth / 2;
rect.height -= safeBorderWidth;
graphics.setBackgroundColor(lightenColor);
graphics.setForegroundColor(getBackgroundColor());
graphics.fillGradient(rect, true);
// Paint the border
if (borderWidth > 0) {
rect = getBounds().getCopy();
rect.x += safeBorderWidth / 2;
rect.y += safeBorderWidth / 2;
rect.width -= safeBorderWidth;
rect.height -= safeBorderWidth;
graphics.setForegroundColor(borderColor);
graphics.setBackgroundColor(borderColor);
graphics.setLineWidth((int) (safeBorderWidth * scale));
graphics.drawRoundRectangle(rect, arcWidth, arcWidth);
}
super.paint(graphics);
graphics.popState();
lightenColor.dispose();
}
protected Color getBackgroundTextColor() {
return getBackgroundColor();
}
/**
* This method is overridden to ensure that it doesn't get called while the
* super.paintFigure() is being called. Otherwise NullPointerExceptions can
* occur because the icon or text locations are cleared *after* they were
* calculated.
*
* @see org.eclipse.draw2d.Label#invalidate()
*/
public void invalidate() {
if (!painting) {
super.invalidate();
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.Label#setText(java.lang.String)
*/
public void setText(String s) {
if (!s.equals("")) {
super.setText(s);
} else {
super.setText("");
}
adjustBoundsToFit();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.Label#setIcon(org.eclipse.swt.graphics.Image)
*/
public void setIcon(Image image) {
super.setIcon(image);
//adjustBoundsToFit();
}
public Color getBorderColor() {
return borderColor;
}
public void setBorderColor(Color c) {
this.borderColor = c;
}
public int getBorderWidth() {
return borderWidth;
}
public void setBorderWidth(int width) {
this.borderWidth = width;
}
public int getArcWidth() {
return arcWidth;
}
public void setArcWidth(int arcWidth) {
this.arcWidth = arcWidth;
}
public void setBounds(Rectangle rect) {
// TODO Auto-generated method stub
super.setBounds(rect);
}
}