Skip to main content
summaryrefslogblamecommitdiffstats
blob: 37839ae3d790b055166077a64b8dfc248d17144f (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12


                                

                                       






                                   



                                        










































                                                                                                


                                        





















                                                                     

























































                                                                                            















































































































                                                                                                  












                                                         
                           
                                                     
                                             
                                         

                                               









                                                           
                                               
















                                                      



                                                                           
                                                                                               























                                                                                                                  


                                                           
                                   


                                                   
 





                                                                             


                                                                            










































                                                                                                                
                                                                 
                              
                                                                                
                                                               





                                                                     
                                                            
                                                                    
                                                                       

                                                                    
                                                                       
                          



                                                  








                                                                                                      

                                                  




                                                                                    
                          
                                          
                  

                                        
          

                                  

                                         






                                                                                          
          






                                                 



































                                                                           
                                    



















                                                
package org.eclipse.swt.custom;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved
 */

import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.events.*;

/* Start ACCESSIBILITY */
import org.eclipse.swt.accessibility.*;
/* End ACCESSIBILITY */

/**
 * A Label which supports aligned text and/or an image and different border styles.
 * <p>
 * If there is not enough space a SmartLabel uses the following strategy to fit the 
 * information into the available space:
 * <pre>
 * 		ignores the indent in left align mode
 * 		ignores the image and the gap
 * 		shortens the text by replacing the center portion of the label with an ellipsis
 * 		shortens the text by removing the center portion of the label
 * </pre>
 * <p>
 * <dl>
 * <dt><b>Styles:</b>
 * <dd>SHADOW_IN, SHADOW_OUT, SHADOW_NONE</dd>
 * <dt><b>Events:</b>
 * <dd></dd>
 * </dl>
 */
public class CLabel extends Canvas {

	/** Gap between icon and text */
	private static final int GAP = 5;
	/** Left and right margins */
	private static final int INDENT = 3;
	/** a string inserted in the middle of text that has been shortened */
	private static final String ellipsis = "...";
	/** the alignment. Either CENTER, RIGHT, LEFT. Default is LEFT*/
	private int align = SWT.LEFT;
	private int hIndent = INDENT;
	private int vIndent = INDENT;
	/** the current text */
	private String text;
	/** the current icon */
	private Image image;
	// The tooltip is used for two purposes - the application can set
	// a tooltip or the tooltip can be used to display the full text when the
	// the text has been truncated due to the label being too short.
	// The appToolTip stores the tooltip set by the application.  Control.tooltiptext 
	// contains whatever tooltip is currently being displayed.
	private String appToolTipText;
	
	private Image backgroundImage;
	private Color[] gradientColors;
	private int[] gradientPercents;

/**
 * Create a CLabel with the given border style as a child of parent.
 */
public CLabel(Composite parent, int style) {
	super(parent, checkStyle(style));
	
	if ((style & SWT.CENTER) != 0) align = SWT.CENTER;
	if ((style & SWT.RIGHT) != 0)  align = SWT.RIGHT;
	if ((style & SWT.LEFT) != 0)   align = SWT.LEFT;
	
	addPaintListener(new PaintListener(){
		public void paintControl(PaintEvent event) {
			onPaint(event);
		}
	});
	
	addDisposeListener(new DisposeListener(){
		public void widgetDisposed(DisposeEvent event) {
			onDispose(event);
		}
	});

/* Start ACCESSIBILITY */
	getAccessibleObject().addAccessibleListener(new AccessibleAdapter() {
		public void getName(AccessibleEvent e) {
			if (e.childID == ACC.CHILDID_SELF) {
				e.result = getText();
			}
		}
		
		public void getHelp(AccessibleEvent e) {
			if (e.childID == ACC.CHILDID_SELF) {
				e.result = getToolTipText();
			}
		}
		
		public void getDescription(AccessibleEvent e) {
			if (e.childID == ACC.CHILDID_SELF) {
				e.result = "This is a CLabel";
			}
		}
	});
		
	getAccessibleObject().addAccessibleControlListener(new AccessibleControlAdapter() {
		public void accHitTest(AccessibleControlEvent e) {
			Point testPoint = toControl(new Point(e.x, e.y));
			if (getBounds().contains(testPoint)) {
				e.childID = ACC.CHILDID_SELF;
			}
		}
		
		public void accLocation(AccessibleControlEvent e) {
			if (e.childID == ACC.CHILDID_SELF) {
				Rectangle location = getBounds();
				Point pt = toDisplay(new Point(location.x, location.y));
				e.x = pt.x;
				e.y = pt.y;
				e.width = location.width;
				e.height = location.height;
			}
		}
		
		public void getChildCount(AccessibleControlEvent e) {
			e.code = 0;
		}
		
		public void getRole(AccessibleControlEvent e) {
			if (e.childID == ACC.CHILDID_SELF) {
				e.code = ACC.ROLE_SYSTEM_STATICTEXT;
			}
		}
		
		public void getState(AccessibleControlEvent e) {
			if (e.childID == ACC.CHILDID_SELF) {
				e.code = ACC.STATE_SYSTEM_NORMAL;
			}
		}
	});
/* End ACCESSIBILITY */

}
/**
 * Check the style bits to ensure that no invalid styles are applied.
 */
private static int checkStyle (int style) {
	int mask = SWT.SHADOW_IN | SWT.SHADOW_OUT | SWT.SHADOW_NONE;
	style = style & mask;
	style |= SWT.NO_FOCUS | SWT.NO_BACKGROUND;
	return style;
}
public Point computeSize(int wHint, int hHint, boolean changed) {
	Point e = getTotalSize(image, text);
	if (wHint == SWT.DEFAULT){
		e.x += 2*hIndent;
	} else {
		e.x = wHint;
	}
	if (hHint == SWT.DEFAULT) {
		e.y += 2*vIndent;
	} else {
		e.y = hHint;
	}
	return e;
}
/**
 * Draw a rectangle in the given colors.
 */
private void drawBevelRect(GC gc, int x, int y, int w, int h, Color topleft, Color bottomright) {
	gc.setForeground(bottomright);
	gc.drawLine(x+w, y,   x+w, y+h);
	gc.drawLine(x,   y+h, x+w, y+h);
	
	gc.setForeground(topleft);
	gc.drawLine(x, y, x+w-1, y);
	gc.drawLine(x, y, x,     y+h-1);
}
/**
 * Returns the alignment.
 * The alignment style (LEFT, CENTER or RIGHT) is returned.
 */
public int getAlignment() {
	return align;
}
/**
 * Return the CLabel's image or <code>null</code>.
 */
public Image getImage() {
	return image;
}
/**
 * Compute the minimum size.
 */
private Point getTotalSize(Image image, String text) {
	Point size = new Point(0, 0);
	
	if (image != null) {
		Rectangle r = image.getBounds();
		size.x += r.width;
		size.y += r.height;
	}
		
	GC gc = new GC(this);
	if (text != null && text.length() > 0) {
		Point e = gc.textExtent(text);
		size.x += e.x;
		size.y = Math.max(size.y, e.y);
		if (image != null) size.x += GAP;
	} else {
		size.y = Math.max(size.y, gc.getFontMetrics().getHeight());
	}
	gc.dispose();
	
	return size;
}
public void setToolTipText (String string) {
	super.setToolTipText (string);
	appToolTipText = super.getToolTipText();
}	
/**
 * Return the Label's text.
 */
public String getText() {
	return text;
}
public String getToolTipText () {
	return appToolTipText;
}
/**
 * Paint the Label's border.
 */
private void paintBorder(GC gc, Rectangle r) {
	Display disp= getDisplay();

	Color c1 = null;
	Color c2 = null;
	
	int style = getStyle();
	if ((style & SWT.SHADOW_IN) != 0) {
		c1 = disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
		c2 = disp.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
	}
	if ((style & SWT.SHADOW_OUT) != 0) {		
		c1 = disp.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW);
		c2 = disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
	}
		
	if (c1 != null && c2 != null) {
		gc.setLineWidth(1);
		drawBevelRect(gc, r.x, r.y, r.width-1, r.height-1, c1, c2);
	}
}
private void onDispose(DisposeEvent event) {
	gradientColors = null;
	gradientPercents = null;
	backgroundImage = null;
}
/* 
 * Process the paint event
 */
private void onPaint(PaintEvent event) {
	Rectangle rect = getClientArea();
	if (rect.width == 0 || rect.height == 0) return;
	
	boolean shortenText = false;
	String t = text;
	Image img = image;
	int availableWidth = rect.width - 2*hIndent;
	Point extent = getTotalSize(img, t);
	if (extent.x > availableWidth) {
		img = null;
		extent = getTotalSize(img, t);
		if (extent.x > availableWidth) {
			shortenText = true;
		}
	}
	
	GC gc = event.gc;
		
	// shorten the text
	if (shortenText) {
		t = shortenText(gc, text, availableWidth);
		extent = getTotalSize(img, t);
		if (appToolTipText == null) {
			super.setToolTipText(text);
		}
	} else {
		super.setToolTipText(appToolTipText);
	}
		
	// determine horizontal position
	int x = rect.x + hIndent;
	if (align == SWT.CENTER) {
		x = (rect.width-extent.x)/2;
	}
	if (align == SWT.RIGHT) {
		x = rect.width-extent.x - hIndent;
	}
	
	// draw a background image behind the text
	try {
		if (backgroundImage != null) {
			// draw a background image behind the text
			Rectangle imageRect = backgroundImage.getBounds();
			gc.drawImage(backgroundImage, 0, 0, imageRect.width, imageRect.height,
				0, 0, rect.width, rect.height);
		} else if (gradientColors != null) {
			// draw a gradient behind the text
			final Color oldBackground = gc.getBackground();
			if (gradientColors.length == 1) {
				if (gradientColors[0] != null) gc.setBackground(gradientColors[0]);
				gc.fillRectangle(0, 0, rect.width, rect.height);
			} else {
				final Color oldForeground = gc.getForeground();
				Color lastColor = gradientColors[0];
				if (lastColor == null) lastColor = oldBackground;
				for (int i = 0, pos = 0; i < gradientPercents.length; ++i) {
					gc.setForeground(lastColor);
					lastColor = gradientColors[i + 1];
					if (lastColor == null) lastColor = oldBackground;
					gc.setBackground(lastColor);
					final int gradientWidth = (gradientPercents[i] * rect.width / 100) - pos;
					gc.fillGradientRectangle(pos, 0, gradientWidth, rect.height, false);
					pos += gradientWidth;
				}
				gc.setForeground(oldForeground);
			}
			gc.setBackground(oldBackground);
		} else {
			gc.setBackground(getBackground());
			gc.fillRectangle(rect);
		}
	} catch (SWTException e) {
		gc.setBackground(getBackground());
		gc.fillRectangle(rect);
	}

	// draw border
	int style = getStyle();
	if ((style & SWT.SHADOW_IN) != 0 || (style & SWT.SHADOW_OUT) != 0) {
		paintBorder(gc, rect);
	}
	// draw the image		
	if (img != null) {
		Rectangle imageRect = img.getBounds();
		gc.drawImage(img, 0, 0, imageRect.width, imageRect.height, 
		                x, (rect.height-imageRect.height)/2, imageRect.width, imageRect.height);
		x += imageRect.width + GAP;
	}
	// draw the text
	if (t != null) {
		int textHeight = gc.getFontMetrics().getHeight();
		gc.setForeground(getForeground());
		gc.drawText(t, x, rect.y + (rect.height-textHeight)/2, true);
	}
}
/**
 * Set the alignment of the CLabel.
 * Use the values LEFT, CENTER and RIGHT to align image and text within the available space.
 */
public void setAlignment(int align) {
	if (align != SWT.LEFT && align != SWT.RIGHT && align != SWT.CENTER) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (this.align != align) {
		this.align = align;
		redraw();
	}
}
/**
 * Specify a gradiant of colours to be draw in the background of the CLabel.
 * For example to draw a gradiant that varies from dark blue to blue and then to
 * white, use the following call to setBackground:
 * <pre>
 *	clabel.setBackground(new Color[]{display.getSystemColor(SWT.COLOR_DARK_BLUE), 
 *		                           display.getSystemColor(SWT.COLOR_BLUE),
 *		                           display.getSystemColor(SWT.COLOR_WHITE), 
 *		                           display.getSystemColor(SWT.COLOR_WHITE)},
 *		               new int[] {25, 50, 100});
 * </pre>
 *
 * @param colors an array of Color that specifies the colors to appear in the gradiant 
 *               in order of appearance left to right.  The value <code>null</code> clears the
 *               background gradiant. The value <code>null</code> can be used inside the array of 
 *               Color to specify the background color.
 * @param percents an array of integers between 0 and 100 specifying the percent of the width 
 *                 of the widget at which the color should change.  The size of the percents array must be one 
 *                 less than the size of the colors array.
 */
public void setBackground(Color[] colors, int[] percents) {	
	if (colors != null) {
		if (percents == null || percents.length != colors.length - 1) {
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
		if (getDisplay().getDepth() < 15) {
			// Don't use gradients on low color displays
			colors = new Color[] { colors[0] };
			percents = new int[] { };
		}
		for (int i = 0; i < percents.length; i++) {
			if (percents[i] < 0 || percents[i] > 100) {
				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
			}
			if (i > 0 && percents[i] < percents[i-1]) {
				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
			}
		}
	}
	
	// Are these settings the same as before?
	final Color background = getBackground();
	if (backgroundImage == null) {
		if ((gradientColors != null) && (colors != null) && 
			(gradientColors.length == colors.length)) {
			boolean same = false;
			for (int i = 0; i < gradientColors.length; i++) {
				same = (gradientColors[i] == colors[i]) ||
					((gradientColors[i] == null) && (colors[i] == background)) ||
					((gradientColors[i] == background) && (colors[i] == null));
				if (!same) break;
			}
			if (same) {
				for (int i = 0; i < gradientPercents.length; i++) {
					same = gradientPercents[i] == percents[i];
					if (!same) break;
				}
			}
			if (same) return;
		}
	} else {
		backgroundImage = null;
	}
	// Store the new settings
	if (colors == null) {
		gradientColors = null;
		gradientPercents = null;
	} else {
		gradientColors = new Color[colors.length];
		for (int i = 0; i < colors.length; ++i)
			gradientColors[i] = (colors[i] != null) ? colors[i] : background;
		gradientPercents = new int[percents.length];
		for (int i = 0; i < percents.length; ++i)
			gradientPercents[i] = percents[i];
	}
	// Refresh with the new settings
	redraw();
}
public void setBackground(Image image) {
	if (image == backgroundImage) return;	
	gradientColors = null;
	gradientPercents = null;
	backgroundImage = image;
	redraw();
	
}
public void setFont(Font font) {
	super.setFont(font);
	redraw();
}
/**
 * Set the label's Image.
 * The value <code>null</code> clears it.
 */
public void setImage(Image image) {
	if (image != this.image) {
		this.image = image;
		redraw();
	}
}
/**
 * Set the label's text.
 * The value <code>null</code> clears it.
 */
public void setText(String text) {
	if (text == null) text = "";
	if (! text.equals(this.text)) {
		this.text = text;
		redraw();
	}
}
/**
 * Shorten the given text <code>t</code> so that its length doesn't exceed
 * the given width. The default implementation replaces characters in the
 * center of the original string with an ellipsis ("...").
 * Override if you need a different strategy.
 */
protected String shortenText(GC gc, String t, int width) {
	if (t == null) return null;
	int w = gc.textExtent(ellipsis).x;
	int l = t.length();
	int pivot = l/2;
	int s = pivot;
	int e = pivot+1;
	while (s >= 0 && e < l) {
		String s1 = t.substring(0, s);
		String s2 = t.substring(e, l);
		int l1 = gc.textExtent(s1).x;
		int l2 = gc.textExtent(s2).x;
		if (l1+w+l2 < width) {
			t = s1 + ellipsis + s2;
			break;
		}
		s--;
		e++;
	}
	return t;
}
}

Back to the top