| /******************************************************************************* |
| * Copyright (c) 2011 Laurent CARON |
| * 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: |
| * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API |
| *******************************************************************************/ |
| package org.mihalis.opal.opalDialog; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.SWTException; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.GC; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Event; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Listener; |
| import org.eclipse.swt.widgets.Widget; |
| import org.mihalis.opal.utils.SWTGraphicUtil; |
| |
| /** |
| * Instance of this class are composite that represents a choice like in Windows |
| * Vista and Seven. It is composed of a green arrow, instruction and text |
| */ |
| public class ChoiceWidget extends Composite { |
| |
| /** The old image. */ |
| private Image oldImage; |
| |
| /** The choice item. */ |
| private ChoiceItem choiceItem; |
| |
| /** The image. */ |
| private Label image; |
| |
| /** The instruction. */ |
| private Label instruction; |
| |
| /** The text. */ |
| private Label text; |
| |
| /** The selection listeners. */ |
| private final List<SelectionListener> selectionListeners; |
| |
| /** The selection. */ |
| private boolean selection; |
| |
| /** The inside composite. */ |
| private boolean insideComposite; |
| |
| /** The inside image. */ |
| private boolean insideImage; |
| |
| /** The inside text. */ |
| private boolean insideText; |
| |
| /** The inside instruction. */ |
| private boolean insideInstruction; |
| |
| /** |
| * Constructs a new instance of this class given its parent and a style |
| * value describing its behavior and appearance. |
| * <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 widget which will be the parent of the new instance |
| * (cannot be null) |
| * @param style the style of widget to construct |
| * @see Composite#Composite(Composite, int) |
| * @see SWT#NO_BACKGROUND |
| * @see SWT#NO_FOCUS |
| * @see SWT#NO_MERGE_PAINTS |
| * @see SWT#NO_REDRAW_RESIZE |
| * @see SWT#NO_RADIO_GROUP |
| * @see SWT#EMBEDDED |
| * @see SWT#DOUBLE_BUFFERED |
| * @see Widget#getStyle |
| * @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> |
| * </ul> |
| */ |
| public ChoiceWidget(final Composite parent, final int style) { |
| super(parent, style); |
| |
| this.setBackgroundMode(SWT.INHERIT_DEFAULT); |
| this.setLayout(new GridLayout(2, false)); |
| |
| buildGreenArrow(); |
| buildInstruction(); |
| buildText(); |
| addMouseListeners(); |
| |
| this.selectionListeners = new ArrayList<SelectionListener>(); |
| this.addListener(SWT.Resize, new Listener() { |
| @Override |
| public void handleEvent(final Event event) { |
| drawComposite(); |
| } |
| }); |
| |
| } |
| |
| /** |
| * Build the green arrow. |
| */ |
| private void buildGreenArrow() { |
| final Image greenArrow = SWTGraphicUtil.createImageFromFile("images/arrowGreenRight.png"); |
| this.image = new Label(this, SWT.NONE); |
| this.image.setImage(greenArrow); |
| this.image.setLayoutData(new GridData(GridData.CENTER, GridData.BEGINNING, false, false, 1, 2)); |
| SWTGraphicUtil.addDisposer(this, greenArrow); |
| } |
| |
| /** |
| * Build the instruction. |
| */ |
| private void buildInstruction() { |
| final Color color = new Color(Display.getCurrent(), 35, 107, 178); |
| SWTGraphicUtil.addDisposer(this, color); |
| |
| this.instruction = new Label(this, SWT.NONE); |
| this.instruction.setForeground(color); |
| this.instruction.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false)); |
| } |
| |
| /** |
| * Build the panel. |
| */ |
| private void buildText() { |
| this.text = new Label(this, SWT.NONE); |
| this.text.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); |
| this.text.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, true)); |
| } |
| |
| /** |
| * Add mouse listeners. |
| */ |
| private void addMouseListeners() { |
| final Listener mouseEnterListener = new Listener() { |
| |
| @Override |
| public void handleEvent(final Event event) { |
| |
| if (event.widget.equals(ChoiceWidget.this)) { |
| ChoiceWidget.this.insideComposite = true; |
| } |
| |
| if (event.widget.equals(ChoiceWidget.this.image)) { |
| ChoiceWidget.this.insideImage = true; |
| } |
| if (event.widget.equals(ChoiceWidget.this.text)) { |
| ChoiceWidget.this.insideText = true; |
| } |
| if (event.widget.equals(ChoiceWidget.this.instruction)) { |
| ChoiceWidget.this.insideInstruction = true; |
| } |
| |
| drawComposite(); |
| } |
| }; |
| |
| final Listener mouseExitListener = new Listener() { |
| |
| @Override |
| public void handleEvent(final Event event) { |
| if (event.widget.equals(ChoiceWidget.this)) { |
| ChoiceWidget.this.insideComposite = false; |
| } |
| |
| if (event.widget.equals(ChoiceWidget.this.image)) { |
| ChoiceWidget.this.insideImage = false; |
| } |
| if (event.widget.equals(ChoiceWidget.this.text)) { |
| ChoiceWidget.this.insideText = false; |
| } |
| if (event.widget.equals(ChoiceWidget.this.instruction)) { |
| ChoiceWidget.this.insideInstruction = false; |
| } |
| drawComposite(); |
| } |
| }; |
| |
| final Listener mouseClickListener = new Listener() { |
| |
| @Override |
| public void handleEvent(final Event event) { |
| for (final SelectionListener selectionListener : ChoiceWidget.this.selectionListeners) { |
| selectionListener.widgetSelected(null); |
| } |
| } |
| }; |
| |
| addListener(SWT.MouseEnter, mouseEnterListener); |
| this.image.addListener(SWT.MouseEnter, mouseEnterListener); |
| this.text.addListener(SWT.MouseEnter, mouseEnterListener); |
| this.instruction.addListener(SWT.MouseEnter, mouseEnterListener); |
| |
| addListener(SWT.MouseExit, mouseExitListener); |
| this.image.addListener(SWT.MouseExit, mouseExitListener); |
| this.text.addListener(SWT.MouseExit, mouseExitListener); |
| this.instruction.addListener(SWT.MouseExit, mouseExitListener); |
| |
| addListener(SWT.MouseUp, mouseClickListener); |
| this.image.addListener(SWT.MouseUp, mouseClickListener); |
| this.text.addListener(SWT.MouseUp, mouseClickListener); |
| this.instruction.addListener(SWT.MouseUp, mouseClickListener); |
| } |
| |
| /** |
| * Draw the composite. |
| */ |
| private void drawComposite() { |
| |
| final Rectangle rect = this.getClientArea(); |
| final Image newImage = new Image(getDisplay(), Math.max(1, rect.width), Math.max(1, rect.height)); |
| |
| final GC gc = new GC(newImage); |
| |
| final boolean inside = this.insideComposite || this.insideImage || this.insideInstruction || this.insideText; |
| |
| if (!inside && !this.selection) { |
| gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); |
| gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); |
| gc.drawRectangle(rect.x, rect.y, rect.width, rect.height); |
| } else { |
| // The mouse is over OR the item is selected |
| final Color gradientColor = inside ? new Color(getDisplay(), 220, 231, 243) : new Color(getDisplay(), 241, 241, 241); |
| final Color borderColor = inside ? new Color(getDisplay(), 35, 107, 178) : new Color(getDisplay(), 192, 192, 192); |
| |
| gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); |
| gc.setBackground(gradientColor); |
| gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, true); |
| |
| gc.setForeground(borderColor); |
| gc.drawRoundRectangle(rect.x, rect.y, rect.width - 1, rect.height - 1, 2, 2); |
| |
| gradientColor.dispose(); |
| borderColor.dispose(); |
| } |
| gc.dispose(); |
| |
| this.setBackgroundImage(newImage); |
| if (this.oldImage != null) { |
| this.oldImage.dispose(); |
| } |
| this.oldImage = newImage; |
| |
| } |
| |
| /** |
| * Gets the choice item. |
| * |
| * @return the current choice item |
| */ |
| public ChoiceItem getChoiceItem() { |
| return this.choiceItem; |
| } |
| |
| /** |
| * Sets the choice item. |
| * |
| * @param choiceItem the choiceItem to set |
| */ |
| public void setChoiceItem(final ChoiceItem choiceItem) { |
| this.choiceItem = choiceItem; |
| this.instruction.setText(choiceItem.getInstruction()); |
| this.text.setText(choiceItem.getText()); |
| } |
| |
| /** |
| * Add a selection listener to this widget. |
| * |
| * @param listener listener to add |
| */ |
| public void addSelectionListener(final SelectionListener listener) { |
| this.selectionListeners.add(listener); |
| } |
| |
| /** |
| * Remove a selection listener. |
| * |
| * @param listener listener to remove |
| */ |
| public void removeSelectionListener(final SelectionListener listener) { |
| this.selectionListeners.remove(listener); |
| } |
| |
| /** |
| * Sets the selection. |
| * |
| * @param selection the new selection |
| */ |
| public void setSelection(final boolean selection) { |
| this.selection = selection; |
| } |
| |
| } |