| /******************************************************************************* |
| * Copyright (c) 2000, 2008 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.swt.widgets; |
| |
| |
| import org.eclipse.swt.*; |
| import org.eclipse.swt.events.*; |
| import org.eclipse.swt.graphics.*; |
| |
| /** |
| * Instances of this class are selectable user interface |
| * objects that represent the dynamically positionable |
| * areas of a <code>CoolBar</code>. |
| * <dl> |
| * <dt><b>Styles:</b></dt> |
| * <dd>DROP_DOWN</dd> |
| * <dt><b>Events:</b></dt> |
| * <dd>Selection</dd> |
| * </dl> |
| * <p> |
| * IMPORTANT: This class is <em>not</em> intended to be subclassed. |
| * </p> |
| * |
| * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public class CoolItem extends Item { |
| Control control; |
| CoolBar parent; |
| boolean ideal; |
| int preferredWidth, preferredHeight, minimumWidth, minimumHeight, requestedWidth; |
| Rectangle itemBounds = new Rectangle(0, 0, 0, 0); |
| |
| static final int MARGIN_WIDTH = 4; |
| static final int GRABBER_WIDTH = 2; |
| static final int MINIMUM_WIDTH = (2 * MARGIN_WIDTH) + GRABBER_WIDTH; |
| |
| private int CHEVRON_HORIZONTAL_TRIM = -1; //platform dependent values |
| private int CHEVRON_VERTICAL_TRIM = -1; |
| private static final int CHEVRON_LEFT_MARGIN = 2; |
| private static final int CHEVRON_IMAGE_WIDTH = 8; //Width to draw the double arrow |
| |
| ToolBar chevron; |
| boolean wrap; |
| Image arrowImage = null; |
| |
| /** |
| * Constructs a new instance of this class given its parent |
| * (which must be a <code>CoolBar</code>) and a style value |
| * describing its behavior and appearance. The item is added |
| * to the end of the items maintained by its parent. |
| * <p> |
| * The style value is either one of the style constants defined in |
| * class <code>SWT</code> which is applicable to instances of this |
| * class, or must be built by <em>bitwise OR</em>'ing together |
| * (that is, using the <code>int</code> "|" operator) two or more |
| * of those <code>SWT</code> style constants. The class description |
| * lists the style constants that are applicable to the class. |
| * Style bits are also inherited from superclasses. |
| * </p> |
| * |
| * @param parent a composite control which will be the parent of the new instance (cannot be null) |
| * @param style the style of control to construct |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> |
| * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> |
| * </ul> |
| * |
| * @see SWT#DROP_DOWN |
| * @see Widget#checkSubclass |
| * @see Widget#getStyle |
| */ |
| public CoolItem (CoolBar parent, int style) { |
| super(parent, style); |
| this.parent = parent; |
| parent.createItem (this, parent.getItemCount()); |
| calculateChevronTrim (); |
| } |
| /** |
| * Constructs a new instance of this class given its parent |
| * (which must be a <code>CoolBar</code>), a style value |
| * describing its behavior and appearance, and the index |
| * at which to place it in the items maintained by its parent. |
| * <p> |
| * The style value is either one of the style constants defined in |
| * class <code>SWT</code> which is applicable to instances of this |
| * class, or must be built by <em>bitwise OR</em>'ing together |
| * (that is, using the <code>int</code> "|" operator) two or more |
| * of those <code>SWT</code> style constants. The class description |
| * lists the style constants that are applicable to the class. |
| * Style bits are also inherited from superclasses. |
| * </p> |
| * |
| * @param parent a composite control which will be the parent of the new instance (cannot be null) |
| * @param style the style of control to construct |
| * @param index the zero-relative index at which to store the receiver in its parent |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> |
| * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> |
| * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> |
| * </ul> |
| * |
| * @see SWT#DROP_DOWN |
| * @see Widget#checkSubclass |
| * @see Widget#getStyle |
| */ |
| public CoolItem (CoolBar parent, int style, int index) { |
| super(parent, style); |
| this.parent = parent; |
| parent.createItem (this, index); |
| calculateChevronTrim (); |
| } |
| /** |
| * Adds the listener to the collection of listeners that will |
| * be notified when the control is selected by the user, by sending it one |
| * of the messages defined in the <code>SelectionListener</code> |
| * interface. |
| * <p> |
| * If <code>widgetSelected</code> is called when the mouse is over |
| * the drop-down arrow (or 'chevron') portion of the cool item, |
| * the event object detail field contains the value <code>SWT.ARROW</code>, |
| * and the x and y fields in the event object represent the point at |
| * the bottom left of the chevron, where the menu should be popped up. |
| * <code>widgetDefaultSelected</code> is not called. |
| * </p> |
| * |
| * @param listener the listener which should be notified when the control is selected by the user |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see SelectionListener |
| * @see #removeSelectionListener |
| * @see SelectionEvent |
| * |
| * @since 2.0 |
| */ |
| public void addSelectionListener(SelectionListener listener) { |
| checkWidget(); |
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); |
| TypedListener typedListener = new TypedListener (listener); |
| addListener (SWT.Selection,typedListener); |
| addListener (SWT.DefaultSelection,typedListener); |
| } |
| protected void checkSubclass () { |
| if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); |
| } |
| /* |
| * Find the trim size of the Toolbar widget in the current platform. |
| */ |
| void calculateChevronTrim () { |
| ToolBar tb = new ToolBar (parent, SWT.FLAT); |
| ToolItem ti = new ToolItem (tb, SWT.PUSH); |
| Image image = new Image (display, 1, 1); |
| ti.setImage (image); |
| Point size = tb.computeSize (SWT.DEFAULT, SWT.DEFAULT); |
| size = parent.fixPoint(size.x, size.y); |
| CHEVRON_HORIZONTAL_TRIM = size.x - 1; |
| CHEVRON_VERTICAL_TRIM = size.y - 1; |
| tb.dispose (); |
| ti.dispose (); |
| image.dispose (); |
| } |
| /** |
| * Returns the preferred size of the receiver. |
| * <p> |
| * The <em>preferred size</em> of a <code>CoolItem</code> is the size that |
| * it would best be displayed at. The width hint and height hint arguments |
| * allow the caller to ask the instance questions such as "Given a particular |
| * width, how high does it need to be to show all of the contents?" |
| * To indicate that the caller does not wish to constrain a particular |
| * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint. |
| * </p> |
| * |
| * @param wHint the width hint (can be <code>SWT.DEFAULT</code>) |
| * @param hHint the height hint (can be <code>SWT.DEFAULT</code>) |
| * @return the preferred size |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see Layout |
| * @see #getBounds |
| * @see #getSize |
| * @see Control#getBorderWidth |
| * @see Scrollable#computeTrim |
| * @see Scrollable#getClientArea |
| */ |
| public Point computeSize (int wHint, int hHint) { |
| checkWidget(); |
| int width = wHint, height = hHint; |
| if (wHint == SWT.DEFAULT) width = 32; |
| if (hHint == SWT.DEFAULT) height = 32; |
| if ((parent.style & SWT.VERTICAL) != 0) { |
| height += MINIMUM_WIDTH; |
| } else { |
| width += MINIMUM_WIDTH; |
| } |
| return new Point (width, height); |
| } |
| public void dispose () { |
| if (isDisposed()) return; |
| |
| /* |
| * Must call parent.destroyItem() before super.dispose(), since it needs to |
| * query the bounds to properly remove the item. |
| */ |
| parent.destroyItem(this); |
| super.dispose (); |
| parent = null; |
| control = null; |
| |
| /* |
| * Although the parent for the chevron is the CoolBar (CoolItem can not be the parent) |
| * it has to be disposed with the item |
| */ |
| if (chevron != null && !chevron.isDisposed()) chevron.dispose(); |
| chevron = null; |
| if (arrowImage != null && !arrowImage.isDisposed()) arrowImage.dispose(); |
| arrowImage = null; |
| } |
| |
| Image createArrowImage (int width, int height) { |
| Point point = parent.fixPoint(width, height); |
| width = point.x; |
| height = point.y; |
| Color foreground = parent.getForeground (); |
| Color black = display.getSystemColor (SWT.COLOR_BLACK); |
| Color background = parent.getBackground (); |
| |
| PaletteData palette = new PaletteData (new RGB[]{foreground.getRGB(), background.getRGB(), black.getRGB()}); |
| ImageData imageData = new ImageData (width, height, 4, palette); |
| imageData.transparentPixel = 1; |
| Image image = new Image (display, imageData); |
| |
| GC gc = new GC (image, parent.getStyle() & SWT.RIGHT_TO_LEFT); |
| gc.setBackground (background); |
| gc.fillRectangle (0, 0, width, height); |
| gc.setForeground (black); |
| |
| int startX = 0 ; |
| if ((parent.style & SWT.VERTICAL) != 0) { |
| startX = width - CHEVRON_IMAGE_WIDTH; |
| } |
| int startY = height / 6; |
| int step = 2; |
| gc.drawLine (startX, startY, startX + step, startY + step); |
| gc.drawLine (startX, startY + (2 * step), startX + step, startY + step); |
| startX++; |
| gc.drawLine (startX, startY, startX + step, startY + step); |
| gc.drawLine (startX, startY + (2 * step), startX + step, startY + step); |
| startX += 3; |
| gc.drawLine (startX, startY, startX + step, startY + step); |
| gc.drawLine (startX, startY + (2 * step), startX + step, startY + step); |
| startX++; |
| gc.drawLine (startX, startY, startX + step, startY + step); |
| gc.drawLine (startX, startY + (2 * step), startX + step, startY + step); |
| gc.dispose (); |
| return image; |
| } |
| /** |
| * Returns a rectangle describing the receiver's size and location |
| * relative to its parent. |
| * |
| * @return the receiver's bounding rectangle |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Rectangle getBounds () { |
| checkWidget(); |
| return parent.fixRectangle(itemBounds.x, itemBounds.y, itemBounds.width, itemBounds.height); |
| } |
| Rectangle internalGetBounds () { |
| return new Rectangle(itemBounds.x, itemBounds.y, itemBounds.width, itemBounds.height); |
| } |
| /** |
| * Returns the control that is associated with the receiver. |
| * |
| * @return the control that is contained by the receiver |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Control getControl () { |
| checkWidget(); |
| return control; |
| } |
| /** |
| * Returns the minimum size that the cool item can |
| * be resized to using the cool item's gripper. |
| * |
| * @return a point containing the minimum width and height of the cool item, in pixels |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @since 2.0 |
| */ |
| public Point getMinimumSize () { |
| checkWidget(); |
| return parent.fixPoint(minimumWidth, minimumHeight); |
| } |
| /** |
| * Returns the receiver's parent, which must be a <code>CoolBar</code>. |
| * |
| * @return the receiver's parent |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public CoolBar getParent () { |
| checkWidget(); |
| return parent; |
| } |
| /** |
| * Returns a point describing the receiver's ideal size. |
| * The x coordinate of the result is the ideal width of the receiver. |
| * The y coordinate of the result is the ideal height of the receiver. |
| * |
| * @return the receiver's ideal size |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Point getPreferredSize () { |
| checkWidget(); |
| return parent.fixPoint(preferredWidth, preferredHeight); |
| } |
| /** |
| * Returns a point describing the receiver's size. The |
| * x coordinate of the result is the width of the receiver. |
| * The y coordinate of the result is the height of the |
| * receiver. |
| * |
| * @return the receiver's size |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Point getSize () { |
| checkWidget(); |
| return parent.fixPoint(itemBounds.width, itemBounds.height); |
| } |
| int internalGetMinimumWidth () { |
| int width = minimumWidth + MINIMUM_WIDTH; |
| if ((style & SWT.DROP_DOWN) != 0 && width < preferredWidth) { |
| width += CHEVRON_IMAGE_WIDTH + CHEVRON_HORIZONTAL_TRIM + CHEVRON_LEFT_MARGIN; |
| } |
| return width; |
| } |
| /* |
| * Called when the chevron is selected. |
| */ |
| void onSelection (Event ev) { |
| Rectangle bounds = chevron.getBounds(); |
| Event event = new Event(); |
| event.detail = SWT.ARROW; |
| if ((parent.style & SWT.VERTICAL) != 0) { |
| event.x = bounds.x + bounds.width; |
| event.y = bounds.y; |
| } else { |
| event.x = bounds.x; |
| event.y = bounds.y + bounds.height; |
| } |
| postEvent (SWT.Selection, event); |
| } |
| /** |
| * Removes the listener from the collection of listeners that |
| * will be notified when the control is selected by the user. |
| * |
| * @param listener the listener which should no longer be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see SelectionListener |
| * @see #addSelectionListener |
| * |
| * @since 2.0 |
| */ |
| public void removeSelectionListener(SelectionListener listener) { |
| checkWidget(); |
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); |
| if (eventTable == null) return; |
| eventTable.unhook (SWT.Selection, listener); |
| eventTable.unhook (SWT.DefaultSelection,listener); |
| } |
| void setBounds (int x, int y, int width, int height) { |
| itemBounds.x = x; |
| itemBounds.y = y; |
| itemBounds.width = width; |
| itemBounds.height = height; |
| if (control != null) { |
| int controlWidth = width - MINIMUM_WIDTH; |
| if ((style & SWT.DROP_DOWN) != 0 && width < preferredWidth) { |
| controlWidth -= CHEVRON_IMAGE_WIDTH + CHEVRON_HORIZONTAL_TRIM + CHEVRON_LEFT_MARGIN; |
| } |
| if (height > preferredHeight) { |
| y += (height - preferredHeight) / 2; |
| height = preferredHeight; |
| } |
| control.setBounds (parent.fixRectangle(x + MINIMUM_WIDTH, y, controlWidth, height)); |
| } |
| updateChevron(); |
| } |
| /** |
| * Sets the control that is associated with the receiver |
| * to the argument. |
| * |
| * @param control the new control that will be contained by the receiver |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li> |
| * <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setControl (Control control) { |
| checkWidget(); |
| if (control != null) { |
| if (control.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT); |
| if (control.parent != parent) error (SWT.ERROR_INVALID_PARENT); |
| } |
| this.control = control; |
| if (control != null) { |
| int controlWidth = itemBounds.width - MINIMUM_WIDTH; |
| if ((style & SWT.DROP_DOWN) != 0 && itemBounds.width < preferredWidth) { |
| controlWidth -= CHEVRON_IMAGE_WIDTH + CHEVRON_HORIZONTAL_TRIM + CHEVRON_LEFT_MARGIN; |
| } |
| control.setBounds (parent.fixRectangle(itemBounds.x + MINIMUM_WIDTH, itemBounds.y, controlWidth, itemBounds.height)); |
| } |
| } |
| /** |
| * Sets the minimum size that the cool item can be resized to |
| * using the cool item's gripper, to the point specified by the arguments. |
| * |
| * @param width the minimum width of the cool item, in pixels |
| * @param height the minimum height of the cool item, in pixels |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @since 2.0 |
| */ |
| public void setMinimumSize (int width, int height) { |
| checkWidget (); |
| Point point = parent.fixPoint(width, height); |
| minimumWidth = point.x; |
| minimumHeight = point.y; |
| } |
| /** |
| * Sets the minimum size that the cool item can be resized to |
| * using the cool item's gripper, to the point specified by the argument. |
| * |
| * @param size a point representing the minimum width and height of the cool item, in pixels |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the point is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @since 2.0 |
| */ |
| public void setMinimumSize (Point size) { |
| checkWidget (); |
| if (size == null) error(SWT.ERROR_NULL_ARGUMENT); |
| setMinimumSize(size.x, size.y); |
| } |
| /** |
| * Sets the receiver's ideal size to the point specified by the arguments. |
| * |
| * @param width the new ideal width for the receiver |
| * @param height the new ideal height for the receiver |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setPreferredSize (int width, int height) { |
| checkWidget(); |
| ideal = true; |
| Point point = parent.fixPoint(width, height); |
| preferredWidth = Math.max (point.x, MINIMUM_WIDTH); |
| preferredHeight = point.y; |
| } |
| /** |
| * Sets the receiver's ideal size to the point specified by the argument. |
| * |
| * @param size the new ideal size for the receiver |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the point is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setPreferredSize (Point size) { |
| checkWidget(); |
| if (size == null) error(SWT.ERROR_NULL_ARGUMENT); |
| setPreferredSize(size.x, size.y); |
| } |
| /** |
| * Sets the receiver's size to the point specified by the arguments. |
| * <p> |
| * Note: Attempting to set the width or height of the |
| * receiver to a negative number will cause that |
| * value to be set to zero instead. |
| * </p> |
| * |
| * @param width the new width for the receiver |
| * @param height the new height for the receiver |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setSize (int width, int height) { |
| checkWidget(); |
| Point point = parent.fixPoint(width, height); |
| width = Math.max(point.x, minimumWidth + MINIMUM_WIDTH); |
| height = point.y; |
| if (!ideal) { |
| preferredWidth = width; |
| preferredHeight = height; |
| } |
| itemBounds.width = requestedWidth = width; |
| itemBounds.height = height; |
| if (control != null) { |
| int controlWidth = width - MINIMUM_WIDTH; |
| if ((style & SWT.DROP_DOWN) != 0 && width < preferredWidth) { |
| controlWidth -= CHEVRON_IMAGE_WIDTH + CHEVRON_HORIZONTAL_TRIM + CHEVRON_LEFT_MARGIN; |
| } |
| control.setSize(parent.fixPoint(controlWidth, height)); |
| } |
| parent.relayout(); |
| updateChevron(); |
| } |
| /** |
| * Sets the receiver's size to the point specified by the argument. |
| * <p> |
| * Note: Attempting to set the width or height of the |
| * receiver to a negative number will cause them to be |
| * set to zero instead. |
| * </p> |
| * |
| * @param size the new size for the receiver |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the point is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setSize (Point size) { |
| checkWidget(); |
| if (size == null) error (SWT.ERROR_NULL_ARGUMENT); |
| setSize (size.x, size.y); |
| } |
| void updateChevron() { |
| if (control != null) { |
| int width = itemBounds.width; |
| if ((style & SWT.DROP_DOWN) != 0 && width < preferredWidth) { |
| if (chevron == null) { |
| chevron = new ToolBar (parent, SWT.FLAT | SWT.NO_FOCUS); |
| ToolItem toolItem = new ToolItem (chevron, SWT.PUSH); |
| toolItem.addListener (SWT.Selection, new Listener() { |
| public void handleEvent (Event event) { |
| CoolItem.this.onSelection (event); |
| } |
| }); |
| } |
| int controlHeight, currentImageHeight = 0; |
| if ((parent.style & SWT.VERTICAL) != 0) { |
| controlHeight = control.getSize ().x; |
| if (arrowImage != null) currentImageHeight = arrowImage.getBounds().width; |
| } else { |
| controlHeight = control.getSize ().y; |
| if (arrowImage != null) currentImageHeight = arrowImage.getBounds().height; |
| } |
| int height = Math.min (controlHeight, itemBounds.height); |
| int imageHeight = Math.max(1, height - CHEVRON_VERTICAL_TRIM); |
| if (currentImageHeight != imageHeight) { |
| Image image = createArrowImage (CHEVRON_IMAGE_WIDTH, imageHeight); |
| chevron.getItem (0).setImage (image); |
| if (arrowImage != null) arrowImage.dispose (); |
| arrowImage = image; |
| } |
| chevron.setBackground (parent.getBackground()); |
| chevron.setBounds (parent.fixRectangle ( |
| itemBounds.x + width - CHEVRON_LEFT_MARGIN - CHEVRON_IMAGE_WIDTH - CHEVRON_HORIZONTAL_TRIM, |
| itemBounds.y, |
| CHEVRON_IMAGE_WIDTH + CHEVRON_HORIZONTAL_TRIM, |
| height)); |
| chevron.setVisible(true); |
| } else { |
| if (chevron != null) { |
| chevron.setVisible(false); |
| } |
| } |
| } |
| } |
| } |