/***************************************************************************** * Copyright (c) 2011 CEA LIST. * * 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: * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation *****************************************************************************/ package org.eclipse.papyrus.infra.gmfdiag.widgets.editors; import org.eclipse.core.databinding.observable.ChangeEvent; import org.eclipse.core.databinding.observable.IChangeListener; import org.eclipse.gmf.runtime.diagram.ui.properties.sections.appearance.ColorPalettePopup; import org.eclipse.gmf.runtime.draw2d.ui.figures.FigureUtilities; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.papyrus.infra.widgets.editors.AbstractValueEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.SelectionEvent; 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.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; public class ColorPickerEditor extends AbstractValueEditor implements IChangeListener { protected Button colorPicker; protected ColorPalettePopup colorPickerPopup; protected RGB color; protected Rectangle colorBounds; protected Image backgroundImage; protected int defaultColor = 0; public static final Rectangle defaultColorBoundsWithoutImage = new Rectangle(0, 0, 15, 15); public static final Rectangle defaultColorBoundsWithImage = new Rectangle(0, 12, 16, 4); public ColorPickerEditor(Composite parent, int style) { super(parent, style); colorPicker = new Button(this, SWT.PUSH); doSetColor(0); colorPicker.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { ColorPalettePopup colorPickerPopup = new ColorPalettePopup(getShell(), IDialogConstants.BUTTON_BAR_HEIGHT); colorPickerPopup.setPreviousColor(getValue()); Rectangle r = colorPicker.getBounds(); Point location = colorPicker.getParent().toDisplay(r.x, r.y); colorPickerPopup.open(new Point(location.x, location.y + r.height)); if(colorPickerPopup.getSelectedColor() == null && !colorPickerPopup.useDefaultColor()) { return; } setColor(colorPickerPopup.getSelectedColor()); commit(); } public void widgetDefaultSelected(SelectionEvent e) { //Nothing } }); } @Override protected void doBinding() { //We don't do a real databinding here if(modelProperty != null) { getParent().addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { ColorPickerEditor.this.dispose(); } }); modelProperty.addChangeListener(this); handleChange(null); } } @Override public void dispose() { if(modelProperty != null) { modelProperty.removeChangeListener(this); } super.dispose(); } /** Sets the color & updates the ModelProperty */ private void setColor(RGB color) { int colorValue = color == null ? defaultColor : FigureUtilities.RGBToInteger(color); doSetColor(colorValue); if(modelProperty != null) { modelProperty.setValue(colorValue); } } /** Updates the color without updating the ModelProperty */ private void doSetColor(int color) { this.color = FigureUtilities.integerToRGB(color); updateButton(); } /** * Sets the image for a color button (square filled with the color that button represents) * * @see GradientFieldEditor#setButtonImage(RGB) */ private void updateButton() { // First, dispose the current image, if any Image image = colorPicker.getImage(); if(image != null) { image.dispose(); } Display display = colorPicker.getDisplay(); // Now set the new image based on rgbColor Color color = new Color(display, this.color); //TODO : Find a way to instantiate a transparent image (Instead of a default-white one) image = backgroundImage == null ? new Image(display, 16, 16) : new Image(display, backgroundImage.getBounds()); GC gc = new GC(image); gc.fillRectangle(image.getBounds()); gc.setBackground(colorPicker.getBackground()); gc.fillRectangle(image.getBounds()); gc.setBackground(color); gc.setForeground(color); if(backgroundImage != null) { gc.fillRectangle(defaultColorBoundsWithImage); gc.drawImage(backgroundImage, 0, 0); } else { gc.fillRectangle(defaultColorBoundsWithoutImage); gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK)); gc.drawRectangle(defaultColorBoundsWithoutImage); } gc.dispose(); color.dispose(); colorPicker.setImage(image); } public void setImage(Image image) { this.backgroundImage = image; } public void setColorBounds(Rectangle rectangle) { this.colorBounds = rectangle; } @Override public Integer getValue() { if(color == null) { return defaultColor; } return FigureUtilities.RGBToInteger(color); } @Override public Object getEditableType() { return Integer.class; } @Override public void setReadOnly(boolean readOnly) { colorPicker.setEnabled(!readOnly); } @Override public boolean isReadOnly() { return !colorPicker.isEnabled(); } @Override public void setToolTipText(String text) { setLabelToolTipText(text); } public void handleChange(ChangeEvent event) { if(modelProperty != null) { Integer value = (Integer)modelProperty.getValue(); if(value == null) { value = 0; } doSetColor(value); } } @Override public void refreshValue() { handleChange(null); } /** * Sets the default color for this Editor. The default color * will be set when the "Default" button is pressed. * * @param color * The default color for this editor */ public void setDefaultColor(int color) { this.defaultColor = color; } }