]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorComposite.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.utils.ui / src / org / simantics / utils / ui / color / ColorComposite.java
index 7e86056af3b749dfc745c352fb0b5d20c6142b60..c34d90535064fa360bf08e35e839a6d7b0582bd7 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.utils.ui.color;\r
-\r
-import org.eclipse.jface.layout.GridDataFactory;\r
-import org.eclipse.jface.layout.GridLayoutFactory;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.events.ModifyEvent;\r
-import org.eclipse.swt.events.ModifyListener;\r
-import org.eclipse.swt.events.MouseEvent;\r
-import org.eclipse.swt.events.MouseListener;\r
-import org.eclipse.swt.events.MouseMoveListener;\r
-import org.eclipse.swt.events.SelectionAdapter;\r
-import org.eclipse.swt.events.SelectionEvent;\r
-import org.eclipse.swt.graphics.GC;\r
-import org.eclipse.swt.graphics.Rectangle;\r
-import org.eclipse.swt.layout.GridLayout;\r
-import org.eclipse.swt.widgets.Button;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Label;\r
-import org.eclipse.swt.widgets.TabFolder;\r
-import org.eclipse.swt.widgets.TabItem;\r
-import org.eclipse.swt.widgets.Text;\r
-\r
-/**\r
- * \r
- * Widget to edit colors\r
- * \r
- * @author Marko Luukkainen\r
- *\r
- */\r
-public class ColorComposite extends Composite{\r
-       \r
-       \r
-       private Color color;\r
-       private ColorGradient rGradient;\r
-       private ColorGradient gGradient;\r
-       private ColorGradient bGradient;\r
-       private ColorGradient hGradient;\r
-       private ColorGradient sGradient;\r
-       private ColorGradient vGradient;\r
-       private ColorGradient colorGradient;\r
-       \r
-       TabFolder tabFolder;\r
-       \r
-       Text rText;\r
-       Text gText;\r
-       Text bText;\r
-       IntGradientWidget rCanvas;\r
-       IntGradientWidget gCanvas;\r
-       IntGradientWidget bCanvas;\r
-       ColorGradientCanvas colorCanvas;\r
-       \r
-       Text hText;\r
-       Text sText;\r
-       Text vText;\r
-       GradientWidget hCanvas;\r
-       GradientWidget sCanvas;\r
-       GradientWidget vCanvas;\r
-       \r
-       Button dynamicButton;\r
-       \r
-       boolean dynamic = true;\r
-       \r
-       \r
-       public ColorComposite(Composite parent, int style) {\r
-               super(parent,style);\r
-               \r
-               GridLayout layout = new GridLayout();\r
-               layout.makeColumnsEqualWidth = true;\r
-               layout.numColumns = 1;\r
-               this.setLayout(layout);\r
-               \r
-               colorCanvas = new ColorGradientCanvas(this,SWT.BORDER|SWT.HORIZONTAL);\r
-               \r
-               tabFolder = new TabFolder(this, SWT.NONE);\r
-               \r
-               TabItem rgbTab = new TabItem(tabFolder, SWT.NONE);\r
-               rgbTab.setText("RGB");\r
-               Composite rgbComposite = new Composite(tabFolder, SWT.NONE);\r
-               \r
-               rgbTab.setControl(rgbComposite);\r
-               \r
-               Label rLabel = new Label(rgbComposite,SWT.NONE);\r
-               rLabel.setText("Red");\r
-               rCanvas = new IntGradientWidget(rgbComposite,SWT.BORDER|SWT.HORIZONTAL){\r
-                       @Override\r
-                       protected void updatePosition(int value) {\r
-                               Color newColor = new Color(value,color.getG(),color.getB());\r
-                               setColor(newColor);\r
-                       }\r
-               };\r
-               rText = new Text(rgbComposite,SWT.BORDER);\r
-               rText.addModifyListener(new IntColorModifyListener() {\r
-                       \r
-                       @Override\r
-                       void setValue(int value) {\r
-                               Color newColor = new Color(value,color.getG(),color.getB());\r
-                               setColor(newColor);\r
-                       }\r
-               });\r
-               \r
-               Label gLabel = new Label(rgbComposite,SWT.NONE);\r
-               gLabel.setText("Green");\r
-               gCanvas = new IntGradientWidget(rgbComposite,SWT.BORDER|SWT.HORIZONTAL) {\r
-                       @Override\r
-                       protected void updatePosition(int value) {\r
-                               Color newColor = new Color(color.getR(),value,color.getB());\r
-                               setColor(newColor);\r
-                       }\r
-               };\r
-               gText = new Text(rgbComposite,SWT.BORDER);\r
-               gText.addModifyListener(new IntColorModifyListener() {\r
-                       \r
-                       @Override\r
-                       void setValue(int value) {\r
-                               Color newColor = new Color(color.getR(),value,color.getB());\r
-                               setColor(newColor);\r
-                       }\r
-               });\r
-               \r
-               Label bLabel = new Label(rgbComposite,SWT.NONE);\r
-               bLabel.setText("Blue");\r
-               bCanvas = new IntGradientWidget(rgbComposite,SWT.BORDER|SWT.HORIZONTAL) {\r
-                       @Override\r
-                       protected void updatePosition(int value) {\r
-                               Color newColor = new Color(color.getR(),color.getG(),value);\r
-                               setColor(newColor);\r
-                       }\r
-               };\r
-               bText = new Text(rgbComposite,SWT.BORDER);\r
-               bText.addModifyListener(new IntColorModifyListener() {\r
-                       \r
-                       @Override\r
-                       void setValue(int value) {\r
-                               Color newColor = new Color(color.getR(),color.getG(),value);\r
-                               setColor(newColor);\r
-                       }\r
-               });\r
-               \r
-               TabItem hsvTab = new TabItem(tabFolder, SWT.NONE);\r
-               hsvTab.setText("HSV");\r
-               Composite hsvComposite = new Composite(tabFolder, SWT.NONE);\r
-               \r
-               hsvTab.setControl(hsvComposite);\r
-               \r
-               Label hLabel = new Label(hsvComposite,SWT.NONE);\r
-               hLabel.setText("Hue");\r
-               hCanvas = new GradientWidget(hsvComposite,SWT.BORDER|SWT.HORIZONTAL) {\r
-                       @Override\r
-                       protected boolean updatePosition(double d) {\r
-                               Color newColor = new Color(d*360.0,color.getS(),color.getV());\r
-                               setColor(newColor);\r
-                               return true;\r
-                       }\r
-                       \r
-                       @Override\r
-                       protected void setPosition(double d) {\r
-                               super.setPosition(d/360.0);\r
-                       }\r
-               };\r
-               hText = new Text(hsvComposite,SWT.BORDER);\r
-               hText.addModifyListener(new DoubleColorModifyListener(0.,360.) {\r
-                       \r
-                       @Override\r
-                       void setValue(double value) {\r
-                               Color newColor = new Color(value,color.getS(),color.getV());\r
-                               setColor(newColor);\r
-                       }\r
-               });\r
-               \r
-               Label sLabel = new Label(hsvComposite,SWT.NONE);\r
-               sLabel.setText("Saturation");\r
-               sCanvas = new GradientWidget(hsvComposite,SWT.BORDER|SWT.HORIZONTAL) {\r
-                       @Override\r
-                       protected boolean updatePosition(double d) {\r
-                               Color newColor = new Color(color.getH(),d,color.getV());\r
-                               setColor(newColor);\r
-                               return true;\r
-                       }\r
-               };\r
-               sText = new Text(hsvComposite,SWT.BORDER);\r
-               sText.addModifyListener(new DoubleColorModifyListener(0.,1.) {\r
-                       \r
-                       @Override\r
-                       void setValue(double value) {\r
-                               Color newColor = new Color(color.getH(),value,color.getV());\r
-                               setColor(newColor);\r
-                       }\r
-               });\r
-               \r
-               Label vLabel = new Label(hsvComposite,SWT.NONE);\r
-               vLabel.setText("Value");\r
-               vCanvas = new GradientWidget(hsvComposite,SWT.BORDER|SWT.HORIZONTAL) {\r
-                       @Override\r
-                       protected boolean updatePosition(double d) {\r
-                               Color newColor = new Color(color.getH(),color.getS(),d);\r
-                               setColor(newColor);\r
-                               return true;\r
-                       }\r
-               };\r
-               vText = new Text(hsvComposite,SWT.BORDER);\r
-               vText.addModifyListener(new DoubleColorModifyListener(0.,1.) {\r
-                       \r
-                       @Override\r
-                       void setValue(double value) {\r
-                               Color newColor = new Color(color.getH(),color.getS(),value);\r
-                               setColor(newColor);\r
-                       }\r
-               });\r
-               \r
-               TabItem settingsTab = new TabItem(tabFolder, SWT.NONE);\r
-               settingsTab.setText("Settings");\r
-               Composite settingsComposite = new Composite(tabFolder, SWT.NONE);\r
-               \r
-               settingsTab.setControl(settingsComposite);\r
-               \r
-               dynamicButton = new Button(settingsComposite, SWT.CHECK);\r
-               dynamicButton.setText("Dynamic widgets");\r
-               dynamicButton.setSelection(dynamic);\r
-               dynamicButton.addSelectionListener(new SelectionAdapter() {\r
-                       @Override\r
-                       public void widgetSelected(SelectionEvent e) {\r
-                               dynamic = dynamicButton.getSelection();\r
-                               updateWidgets();\r
-                       }\r
-               });\r
-\r
-               GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).applyTo(rgbComposite);\r
-               GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).applyTo(hsvComposite);\r
-               GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).applyTo(settingsComposite);\r
-               GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(rgbComposite);\r
-               GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(hsvComposite);\r
-               GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(settingsComposite);\r
-               GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(tabFolder);\r
-               \r
-               GridDataFactory.fillDefaults().hint(-1, 32).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(colorCanvas);\r
-               GridDataFactory.fillDefaults().hint(-1, 16).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(rCanvas);\r
-               GridDataFactory.fillDefaults().hint(-1, 16).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(gCanvas);\r
-               GridDataFactory.fillDefaults().hint(-1, 16).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(bCanvas);\r
-               GridDataFactory.fillDefaults().hint(-1, 16).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(hCanvas);\r
-               GridDataFactory.fillDefaults().hint(-1, 16).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(sCanvas);\r
-               GridDataFactory.fillDefaults().hint(-1, 16).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(vCanvas);\r
-               GridDataFactory.fillDefaults().hint(20, 15).grab(false, false).applyTo(rText);\r
-               GridDataFactory.fillDefaults().hint(20, 15).grab(false, false).applyTo(gText);\r
-               GridDataFactory.fillDefaults().hint(20, 15).grab(false, false).applyTo(bText);\r
-               GridDataFactory.fillDefaults().hint(20, 15).grab(false, false).applyTo(hText);\r
-               GridDataFactory.fillDefaults().hint(20, 15).grab(false, false).applyTo(sText);\r
-               GridDataFactory.fillDefaults().hint(20, 15).grab(false, false).applyTo(vText);\r
-               \r
-               if (color == null)\r
-                       setColor(new Color(255,255,255));\r
-               else\r
-                       setColor(color);\r
-       }\r
-       \r
-       private abstract class IntColorModifyListener implements ModifyListener {\r
-               boolean modify = false;\r
-               @Override\r
-               public void modifyText(ModifyEvent e) {\r
-                       if (internalUpdate)\r
-                               return;\r
-                       if (modify)\r
-                               return;\r
-                       modify = true;\r
-                       Text text = (Text)e.widget;\r
-                       try {\r
-                               int value = Integer.parseInt(text.getText());\r
-                               if (value < 0)\r
-                                       value = 0;\r
-                               if (value > 255)\r
-                                       value = 255;\r
-                               setValue(value);\r
-                       } catch (NumberFormatException err) {\r
-                               \r
-                       }\r
-                       modify = false;\r
-                       \r
-               }\r
-               \r
-               abstract void setValue(int value);\r
-       }\r
-\r
-       private abstract class DoubleColorModifyListener implements ModifyListener {\r
-               boolean modify = false;\r
-               double min;\r
-               double max;\r
-               \r
-               public DoubleColorModifyListener( double min, double max) {\r
-                       this.min = min;\r
-                       this.max = max;\r
-               }\r
-               \r
-               @Override\r
-               public void modifyText(ModifyEvent e) {\r
-                       if (internalUpdate)\r
-                               return;\r
-                       if (modify)\r
-                               return;\r
-                       modify = true;\r
-                       Text text = (Text)e.widget;\r
-                       try {\r
-                               double value = Integer.parseInt(text.getText());\r
-                               if (value < min) {\r
-                                       value = min;\r
-                               } else if (value > max)\r
-                                       value = max;\r
-                               setValue(value);\r
-                       } catch (NumberFormatException err) {\r
-                               \r
-                       }\r
-                       modify = false;                 \r
-               }\r
-\r
-               \r
-               abstract void setValue(double value);\r
-       }\r
-       \r
-       public void setColor(Color color) {\r
-               this.color = color;\r
-               updateWidgets();\r
-       }\r
-       \r
-       public Color getColor() {\r
-               return color;\r
-       }\r
-       \r
-       private void updateGradients() {\r
-               if (dynamic) {\r
-                       rGradient = new ColorGradient(new ColorValue[]{\r
-                                               new ColorValue(new Color(0,color.getG(),color.getB()),0.0),\r
-                                               new ColorValue(new Color(255,color.getG(),color.getB()),1.0)});\r
-                       gGradient = new ColorGradient(new ColorValue[]{\r
-                                       new ColorValue(new Color(color.getR(),0,color.getB()),0.0),\r
-                                       new ColorValue(new Color(color.getR(),255,color.getB()),1.0)});\r
-                       bGradient = new ColorGradient(new ColorValue[]{\r
-                                       new ColorValue(new Color(color.getR(),color.getG(),0),0.0),\r
-                                       new ColorValue(new Color(color.getR(),color.getG(),255),1.0)});\r
-                       // hue is interpolated along the shortest route, using just 0 and 360 would result in constant color. \r
-                       hGradient = new ColorGradient(new ColorValue[]{\r
-                                       new ColorValue(new Color(0.0,color.getS(),color.getV()),0.0),\r
-                                       new ColorValue(new Color(90.0,color.getS(),color.getV()),0.25),\r
-                                       new ColorValue(new Color(180.0,color.getS(),color.getV()),0.5),\r
-                                       new ColorValue(new Color(270.0,color.getS(),color.getV()),0.75),\r
-                                       new ColorValue(new Color(360.0,color.getS(),color.getV()),1.0)}, ColorGradient.HSV);\r
-                       sGradient = new ColorGradient(new ColorValue[]{\r
-                                       new ColorValue(new Color(color.getH(),0.0,color.getV()),0.0),\r
-                                       new ColorValue(new Color(color.getH(),1.0,color.getV()),1.0)}, ColorGradient.HSV);\r
-                       vGradient = new ColorGradient(new ColorValue[]{\r
-                                       new ColorValue(new Color(color.getH(),color.getS(),0.0),0.0),\r
-                                       new ColorValue(new Color(color.getH(),color.getS(),1.0),1.0)}, ColorGradient.HSV);\r
-               } else {\r
-                       rGradient = new ColorGradient(new ColorValue[]{\r
-                                       new ColorValue(new Color(0,0,0),0.0),\r
-                                       new ColorValue(new Color(255,0,0),1.0)});\r
-                       gGradient = new ColorGradient(new ColorValue[]{\r
-                                       new ColorValue(new Color(0,0,0),0.0),\r
-                                       new ColorValue(new Color(0,255,0),1.0)});\r
-                       bGradient = new ColorGradient(new ColorValue[]{\r
-                                       new ColorValue(new Color(0,0,0),0.0),\r
-                                       new ColorValue(new Color(0,0,255),1.0)});\r
-                       // hue is interpolated along the shortest route, using just 0 and 360 would result in constant color. \r
-                       hGradient = new ColorGradient(new ColorValue[]{\r
-                                       new ColorValue(new Color(0.0,1.0,1.0),0.0),\r
-                                       new ColorValue(new Color(90.0,1.0,1.0),0.25),\r
-                                       new ColorValue(new Color(180.0,1.0,1.0),0.5),\r
-                                       new ColorValue(new Color(270.0,1.0,1.0),0.75),\r
-                                       new ColorValue(new Color(360.0,1.0,1.0),1.0)}, ColorGradient.HSV);\r
-                       sGradient = new ColorGradient(new ColorValue[]{\r
-                                       new ColorValue(new Color(color.getH(),0.0,1.0),0.0),\r
-                                       new ColorValue(new Color(color.getH(),1.0,1.0),1.0)}, ColorGradient.HSV);\r
-                       vGradient = new ColorGradient(new ColorValue[]{\r
-                                       new ColorValue(new Color(color.getH(),1.0,0.0),0.0),\r
-                                       new ColorValue(new Color(color.getH(),1.0,1.0),1.0)}, ColorGradient.HSV);\r
-               }\r
-               \r
-               colorGradient = new ColorGradient(new ColorValue[]{\r
-                               new ColorValue(new Color(color.getR(),color.getG(),color.getB()),0.0)});\r
-       \r
-       }\r
-       \r
-       private boolean internalUpdate = false;\r
-       \r
-       private void updateWidgets() {\r
-               if (internalUpdate)\r
-                       return;\r
-               internalUpdate = true;\r
-               updateGradients();\r
-               rCanvas.setGradient(rGradient);\r
-               gCanvas.setGradient(gGradient);\r
-               bCanvas.setGradient(bGradient);\r
-               hCanvas.setGradient(hGradient);\r
-               sCanvas.setGradient(sGradient);\r
-               vCanvas.setGradient(vGradient);\r
-               colorCanvas.setGradient(colorGradient);\r
-               \r
-               rCanvas.setPosition(color.getR());\r
-               gCanvas.setPosition(color.getG());\r
-               bCanvas.setPosition(color.getB());\r
-               hCanvas.setPosition(color.getH());\r
-               sCanvas.setPosition(color.getS());\r
-               vCanvas.setPosition(color.getV());\r
-               \r
-               if(!rText.isFocusControl())\r
-                       rText.setText(Integer.toString(color.getR()));\r
-               if(!gText.isFocusControl())\r
-                       gText.setText(Integer.toString(color.getG()));\r
-               if(!bText.isFocusControl())\r
-                       bText.setText(Integer.toString(color.getB()));\r
-               if(!hText.isFocusControl())\r
-                       hText.setText(Double.toString(color.getH()));\r
-               if(!sText.isFocusControl())\r
-                       sText.setText(Double.toString(color.getS()));\r
-               if(!vText.isFocusControl())\r
-                       vText.setText(Double.toString(color.getV()));   \r
-               internalUpdate = false;\r
-       }\r
-       \r
-       private abstract static class IntGradientWidget extends GradientWidget {\r
-\r
-               public IntGradientWidget(Composite parent, int style) {\r
-                       super(parent, style);\r
-               }\r
-               \r
-               @Override\r
-               protected boolean updatePosition(double d) {\r
-                       int value = (int)(d * 255);\r
-                       if (value < 0)\r
-                               value = 0;\r
-                       if (value > 255)\r
-                               value = 255;\r
-                       updatePosition(value);\r
-                       return true;\r
-               }\r
-               protected abstract void updatePosition(int value);\r
-               \r
-               protected void setPosition(int value) {\r
-                       double d = ((double)value)/255.0;\r
-                       setPosition(d);\r
-               }\r
-               \r
-       }\r
-       \r
-       private abstract static class GradientWidget extends ColorGradientCanvas {\r
-\r
-               int pos = -1;\r
-               double posD = -1.0;\r
-               \r
-               int size = 8;\r
-               int sized2 = 4;\r
-               \r
-               \r
-               \r
-               public GradientWidget(Composite parent, int style) {\r
-                       super(parent, style);\r
-                       this.addMouseListener(new MouseListener() {                     \r
-                               @Override\r
-                               public void mouseDown(MouseEvent e) {\r
-                                       if (e.button == 1) {\r
-                                               update(e);\r
-                                       }\r
-                               }\r
-                               \r
-                               @Override\r
-                               public void mouseUp(MouseEvent e) {}\r
-                               @Override\r
-                               public void mouseDoubleClick(MouseEvent e) {}\r
-                       });\r
-                       this.addMouseMoveListener(new MouseMoveListener() {\r
-                               \r
-                               @Override\r
-                               public void mouseMove(MouseEvent e) {\r
-                                       if ((e.stateMask & SWT.BUTTON1)>0) {\r
-                                               update(e);\r
-                                       }\r
-                               }\r
-                       });\r
-               }\r
-               \r
-               protected void update(MouseEvent e) {\r
-                       Rectangle r = getClientArea();\r
-                       double d;\r
-                       if ((style & SWT.HORIZONTAL) > 0) {\r
-                               d = (double)e.x / (double)r.width;\r
-                       } else {\r
-                               d = (double)e.y / (double)r.height;\r
-                       }\r
-                       if (d < 0.0)\r
-                               d = 0.0;\r
-                       else if (d > 1.0)\r
-                               d = 1.0;\r
-                       if (updatePosition(d)) {\r
-                               if ((style & SWT.HORIZONTAL) > 0) {\r
-                                       pos = (int)(d*((double)r.width));\r
-                               } else {\r
-                                       pos = (int)(d*((double)r.height));\r
-                               }\r
-                               posD = d;\r
-                       }\r
-               }\r
-               \r
-               protected abstract boolean updatePosition(double d);\r
-               \r
-               protected void setPosition(double d) {\r
-                       if (d == posD)\r
-                               return;\r
-                       _setPosition(d);                                                \r
-               }\r
-               \r
-               private void _setPosition(double d) {\r
-                       Rectangle r = getClientArea();\r
-                       posD = d;\r
-                       if (posD >= 0.0) {\r
-                               if ((style & SWT.HORIZONTAL) > 0) {\r
-                                       pos = (int)(d * (double)r.width);\r
-                               } else {\r
-                                       pos = (int)(d * (double)r.height);\r
-                               }\r
-                       } else {\r
-                               pos = -1;\r
-                       }\r
-               }\r
-               \r
-               Rectangle prevClip;\r
-               @Override\r
-               protected void paintGradient(GC gc, Rectangle clip) {\r
-                       super.paintGradient(gc, clip);\r
-                       if (!clip.equals(prevClip)) {\r
-                               prevClip = clip;\r
-                               _setPosition(posD);\r
-                       }\r
-                       \r
-                       if (pos >= 0) {\r
-                               org.eclipse.swt.graphics.Color white = new org.eclipse.swt.graphics.Color(gc.getDevice(), 255,255,255);\r
-                               org.eclipse.swt.graphics.Color black = new org.eclipse.swt.graphics.Color(gc.getDevice(), 0, 0, 0);\r
-                               gc.setForeground(black);\r
-                               gc.setBackground(white);\r
-                               int x;\r
-                               int y;\r
-                               if ((style & SWT.HORIZONTAL) > 0) {\r
-                                       x = pos;\r
-                                       y = clip.height / 2;\r
-                               } else {\r
-                                       x = clip.width / 2;\r
-                                       y = pos;\r
-                               }\r
-                               gc.fillOval(x-sized2, y-sized2, size, size);\r
-                               gc.drawOval(x-sized2, y-sized2, size, size);\r
-                               \r
-                               white.dispose();\r
-                               black.dispose();\r
-                       }\r
-               }\r
-               \r
-       }\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * 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:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.utils.ui.color;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * 
+ * Widget to edit colors
+ * 
+ * @author Marko Luukkainen
+ *
+ */
+public class ColorComposite extends Composite{
+       
+       
+       private Color color;
+       private ColorGradient rGradient;
+       private ColorGradient gGradient;
+       private ColorGradient bGradient;
+       private ColorGradient hGradient;
+       private ColorGradient sGradient;
+       private ColorGradient vGradient;
+       private ColorGradient colorGradient;
+       
+       TabFolder tabFolder;
+       
+       Text rText;
+       Text gText;
+       Text bText;
+       IntGradientWidget rCanvas;
+       IntGradientWidget gCanvas;
+       IntGradientWidget bCanvas;
+       ColorGradientCanvas colorCanvas;
+       
+       Text hText;
+       Text sText;
+       Text vText;
+       GradientWidget hCanvas;
+       GradientWidget sCanvas;
+       GradientWidget vCanvas;
+       
+       Button dynamicButton;
+       
+       boolean dynamic = true;
+       
+       
+       public ColorComposite(Composite parent, int style) {
+               super(parent,style);
+               
+               GridLayout layout = new GridLayout();
+               layout.makeColumnsEqualWidth = true;
+               layout.numColumns = 1;
+               this.setLayout(layout);
+               
+               colorCanvas = new ColorGradientCanvas(this,SWT.BORDER|SWT.HORIZONTAL);
+               
+               tabFolder = new TabFolder(this, SWT.NONE);
+               
+               TabItem rgbTab = new TabItem(tabFolder, SWT.NONE);
+               rgbTab.setText("RGB");
+               Composite rgbComposite = new Composite(tabFolder, SWT.NONE);
+               
+               rgbTab.setControl(rgbComposite);
+               
+               Label rLabel = new Label(rgbComposite,SWT.NONE);
+               rLabel.setText("Red");
+               rCanvas = new IntGradientWidget(rgbComposite,SWT.BORDER|SWT.HORIZONTAL){
+                       @Override
+                       protected void updatePosition(int value) {
+                               Color newColor = new Color(value,color.getG(),color.getB());
+                               setColor(newColor);
+                       }
+               };
+               rText = new Text(rgbComposite,SWT.BORDER);
+               rText.addModifyListener(new IntColorModifyListener() {
+                       
+                       @Override
+                       void setValue(int value) {
+                               Color newColor = new Color(value,color.getG(),color.getB());
+                               setColor(newColor);
+                       }
+               });
+               
+               Label gLabel = new Label(rgbComposite,SWT.NONE);
+               gLabel.setText("Green");
+               gCanvas = new IntGradientWidget(rgbComposite,SWT.BORDER|SWT.HORIZONTAL) {
+                       @Override
+                       protected void updatePosition(int value) {
+                               Color newColor = new Color(color.getR(),value,color.getB());
+                               setColor(newColor);
+                       }
+               };
+               gText = new Text(rgbComposite,SWT.BORDER);
+               gText.addModifyListener(new IntColorModifyListener() {
+                       
+                       @Override
+                       void setValue(int value) {
+                               Color newColor = new Color(color.getR(),value,color.getB());
+                               setColor(newColor);
+                       }
+               });
+               
+               Label bLabel = new Label(rgbComposite,SWT.NONE);
+               bLabel.setText("Blue");
+               bCanvas = new IntGradientWidget(rgbComposite,SWT.BORDER|SWT.HORIZONTAL) {
+                       @Override
+                       protected void updatePosition(int value) {
+                               Color newColor = new Color(color.getR(),color.getG(),value);
+                               setColor(newColor);
+                       }
+               };
+               bText = new Text(rgbComposite,SWT.BORDER);
+               bText.addModifyListener(new IntColorModifyListener() {
+                       
+                       @Override
+                       void setValue(int value) {
+                               Color newColor = new Color(color.getR(),color.getG(),value);
+                               setColor(newColor);
+                       }
+               });
+               
+               TabItem hsvTab = new TabItem(tabFolder, SWT.NONE);
+               hsvTab.setText("HSV");
+               Composite hsvComposite = new Composite(tabFolder, SWT.NONE);
+               
+               hsvTab.setControl(hsvComposite);
+               
+               Label hLabel = new Label(hsvComposite,SWT.NONE);
+               hLabel.setText("Hue");
+               hCanvas = new GradientWidget(hsvComposite,SWT.BORDER|SWT.HORIZONTAL) {
+                       @Override
+                       protected boolean updatePosition(double d) {
+                               Color newColor = new Color(d*360.0,color.getS(),color.getV());
+                               setColor(newColor);
+                               return true;
+                       }
+                       
+                       @Override
+                       protected void setPosition(double d) {
+                               super.setPosition(d/360.0);
+                       }
+               };
+               hText = new Text(hsvComposite,SWT.BORDER);
+               hText.addModifyListener(new DoubleColorModifyListener(0.,360.) {
+                       
+                       @Override
+                       void setValue(double value) {
+                               Color newColor = new Color(value,color.getS(),color.getV());
+                               setColor(newColor);
+                       }
+               });
+               
+               Label sLabel = new Label(hsvComposite,SWT.NONE);
+               sLabel.setText("Saturation");
+               sCanvas = new GradientWidget(hsvComposite,SWT.BORDER|SWT.HORIZONTAL) {
+                       @Override
+                       protected boolean updatePosition(double d) {
+                               Color newColor = new Color(color.getH(),d,color.getV());
+                               setColor(newColor);
+                               return true;
+                       }
+               };
+               sText = new Text(hsvComposite,SWT.BORDER);
+               sText.addModifyListener(new DoubleColorModifyListener(0.,1.) {
+                       
+                       @Override
+                       void setValue(double value) {
+                               Color newColor = new Color(color.getH(),value,color.getV());
+                               setColor(newColor);
+                       }
+               });
+               
+               Label vLabel = new Label(hsvComposite,SWT.NONE);
+               vLabel.setText("Value");
+               vCanvas = new GradientWidget(hsvComposite,SWT.BORDER|SWT.HORIZONTAL) {
+                       @Override
+                       protected boolean updatePosition(double d) {
+                               Color newColor = new Color(color.getH(),color.getS(),d);
+                               setColor(newColor);
+                               return true;
+                       }
+               };
+               vText = new Text(hsvComposite,SWT.BORDER);
+               vText.addModifyListener(new DoubleColorModifyListener(0.,1.) {
+                       
+                       @Override
+                       void setValue(double value) {
+                               Color newColor = new Color(color.getH(),color.getS(),value);
+                               setColor(newColor);
+                       }
+               });
+               
+               TabItem settingsTab = new TabItem(tabFolder, SWT.NONE);
+               settingsTab.setText("Settings");
+               Composite settingsComposite = new Composite(tabFolder, SWT.NONE);
+               
+               settingsTab.setControl(settingsComposite);
+               
+               dynamicButton = new Button(settingsComposite, SWT.CHECK);
+               dynamicButton.setText("Dynamic widgets");
+               dynamicButton.setSelection(dynamic);
+               dynamicButton.addSelectionListener(new SelectionAdapter() {
+                       @Override
+                       public void widgetSelected(SelectionEvent e) {
+                               dynamic = dynamicButton.getSelection();
+                               updateWidgets();
+                       }
+               });
+
+               GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).applyTo(rgbComposite);
+               GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).applyTo(hsvComposite);
+               GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).applyTo(settingsComposite);
+               GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(rgbComposite);
+               GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(hsvComposite);
+               GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(settingsComposite);
+               GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(tabFolder);
+               
+               GridDataFactory.fillDefaults().hint(-1, 32).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(colorCanvas);
+               GridDataFactory.fillDefaults().hint(-1, 16).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(rCanvas);
+               GridDataFactory.fillDefaults().hint(-1, 16).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(gCanvas);
+               GridDataFactory.fillDefaults().hint(-1, 16).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(bCanvas);
+               GridDataFactory.fillDefaults().hint(-1, 16).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(hCanvas);
+               GridDataFactory.fillDefaults().hint(-1, 16).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(sCanvas);
+               GridDataFactory.fillDefaults().hint(-1, 16).grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(vCanvas);
+               GridDataFactory.fillDefaults().hint(20, 15).grab(false, false).applyTo(rText);
+               GridDataFactory.fillDefaults().hint(20, 15).grab(false, false).applyTo(gText);
+               GridDataFactory.fillDefaults().hint(20, 15).grab(false, false).applyTo(bText);
+               GridDataFactory.fillDefaults().hint(20, 15).grab(false, false).applyTo(hText);
+               GridDataFactory.fillDefaults().hint(20, 15).grab(false, false).applyTo(sText);
+               GridDataFactory.fillDefaults().hint(20, 15).grab(false, false).applyTo(vText);
+               
+               if (color == null)
+                       setColor(new Color(255,255,255));
+               else
+                       setColor(color);
+       }
+       
+       private abstract class IntColorModifyListener implements ModifyListener {
+               boolean modify = false;
+               @Override
+               public void modifyText(ModifyEvent e) {
+                       if (internalUpdate)
+                               return;
+                       if (modify)
+                               return;
+                       modify = true;
+                       Text text = (Text)e.widget;
+                       try {
+                               int value = Integer.parseInt(text.getText());
+                               if (value < 0)
+                                       value = 0;
+                               if (value > 255)
+                                       value = 255;
+                               setValue(value);
+                       } catch (NumberFormatException err) {
+                               
+                       }
+                       modify = false;
+                       
+               }
+               
+               abstract void setValue(int value);
+       }
+
+       private abstract class DoubleColorModifyListener implements ModifyListener {
+               boolean modify = false;
+               double min;
+               double max;
+               
+               public DoubleColorModifyListener( double min, double max) {
+                       this.min = min;
+                       this.max = max;
+               }
+               
+               @Override
+               public void modifyText(ModifyEvent e) {
+                       if (internalUpdate)
+                               return;
+                       if (modify)
+                               return;
+                       modify = true;
+                       Text text = (Text)e.widget;
+                       try {
+                               double value = Integer.parseInt(text.getText());
+                               if (value < min) {
+                                       value = min;
+                               } else if (value > max)
+                                       value = max;
+                               setValue(value);
+                       } catch (NumberFormatException err) {
+                               
+                       }
+                       modify = false;                 
+               }
+
+               
+               abstract void setValue(double value);
+       }
+       
+       public void setColor(Color color) {
+               this.color = color;
+               updateWidgets();
+       }
+       
+       public Color getColor() {
+               return color;
+       }
+       
+       private void updateGradients() {
+               if (dynamic) {
+                       rGradient = new ColorGradient(new ColorValue[]{
+                                               new ColorValue(new Color(0,color.getG(),color.getB()),0.0),
+                                               new ColorValue(new Color(255,color.getG(),color.getB()),1.0)});
+                       gGradient = new ColorGradient(new ColorValue[]{
+                                       new ColorValue(new Color(color.getR(),0,color.getB()),0.0),
+                                       new ColorValue(new Color(color.getR(),255,color.getB()),1.0)});
+                       bGradient = new ColorGradient(new ColorValue[]{
+                                       new ColorValue(new Color(color.getR(),color.getG(),0),0.0),
+                                       new ColorValue(new Color(color.getR(),color.getG(),255),1.0)});
+                       // hue is interpolated along the shortest route, using just 0 and 360 would result in constant color. 
+                       hGradient = new ColorGradient(new ColorValue[]{
+                                       new ColorValue(new Color(0.0,color.getS(),color.getV()),0.0),
+                                       new ColorValue(new Color(90.0,color.getS(),color.getV()),0.25),
+                                       new ColorValue(new Color(180.0,color.getS(),color.getV()),0.5),
+                                       new ColorValue(new Color(270.0,color.getS(),color.getV()),0.75),
+                                       new ColorValue(new Color(360.0,color.getS(),color.getV()),1.0)}, ColorGradient.HSV);
+                       sGradient = new ColorGradient(new ColorValue[]{
+                                       new ColorValue(new Color(color.getH(),0.0,color.getV()),0.0),
+                                       new ColorValue(new Color(color.getH(),1.0,color.getV()),1.0)}, ColorGradient.HSV);
+                       vGradient = new ColorGradient(new ColorValue[]{
+                                       new ColorValue(new Color(color.getH(),color.getS(),0.0),0.0),
+                                       new ColorValue(new Color(color.getH(),color.getS(),1.0),1.0)}, ColorGradient.HSV);
+               } else {
+                       rGradient = new ColorGradient(new ColorValue[]{
+                                       new ColorValue(new Color(0,0,0),0.0),
+                                       new ColorValue(new Color(255,0,0),1.0)});
+                       gGradient = new ColorGradient(new ColorValue[]{
+                                       new ColorValue(new Color(0,0,0),0.0),
+                                       new ColorValue(new Color(0,255,0),1.0)});
+                       bGradient = new ColorGradient(new ColorValue[]{
+                                       new ColorValue(new Color(0,0,0),0.0),
+                                       new ColorValue(new Color(0,0,255),1.0)});
+                       // hue is interpolated along the shortest route, using just 0 and 360 would result in constant color. 
+                       hGradient = new ColorGradient(new ColorValue[]{
+                                       new ColorValue(new Color(0.0,1.0,1.0),0.0),
+                                       new ColorValue(new Color(90.0,1.0,1.0),0.25),
+                                       new ColorValue(new Color(180.0,1.0,1.0),0.5),
+                                       new ColorValue(new Color(270.0,1.0,1.0),0.75),
+                                       new ColorValue(new Color(360.0,1.0,1.0),1.0)}, ColorGradient.HSV);
+                       sGradient = new ColorGradient(new ColorValue[]{
+                                       new ColorValue(new Color(color.getH(),0.0,1.0),0.0),
+                                       new ColorValue(new Color(color.getH(),1.0,1.0),1.0)}, ColorGradient.HSV);
+                       vGradient = new ColorGradient(new ColorValue[]{
+                                       new ColorValue(new Color(color.getH(),1.0,0.0),0.0),
+                                       new ColorValue(new Color(color.getH(),1.0,1.0),1.0)}, ColorGradient.HSV);
+               }
+               
+               colorGradient = new ColorGradient(new ColorValue[]{
+                               new ColorValue(new Color(color.getR(),color.getG(),color.getB()),0.0)});
+       
+       }
+       
+       private boolean internalUpdate = false;
+       
+       private void updateWidgets() {
+               if (internalUpdate)
+                       return;
+               internalUpdate = true;
+               updateGradients();
+               rCanvas.setGradient(rGradient);
+               gCanvas.setGradient(gGradient);
+               bCanvas.setGradient(bGradient);
+               hCanvas.setGradient(hGradient);
+               sCanvas.setGradient(sGradient);
+               vCanvas.setGradient(vGradient);
+               colorCanvas.setGradient(colorGradient);
+               
+               rCanvas.setPosition(color.getR());
+               gCanvas.setPosition(color.getG());
+               bCanvas.setPosition(color.getB());
+               hCanvas.setPosition(color.getH());
+               sCanvas.setPosition(color.getS());
+               vCanvas.setPosition(color.getV());
+               
+               if(!rText.isFocusControl())
+                       rText.setText(Integer.toString(color.getR()));
+               if(!gText.isFocusControl())
+                       gText.setText(Integer.toString(color.getG()));
+               if(!bText.isFocusControl())
+                       bText.setText(Integer.toString(color.getB()));
+               if(!hText.isFocusControl())
+                       hText.setText(Double.toString(color.getH()));
+               if(!sText.isFocusControl())
+                       sText.setText(Double.toString(color.getS()));
+               if(!vText.isFocusControl())
+                       vText.setText(Double.toString(color.getV()));   
+               internalUpdate = false;
+       }
+       
+       private abstract static class IntGradientWidget extends GradientWidget {
+
+               public IntGradientWidget(Composite parent, int style) {
+                       super(parent, style);
+               }
+               
+               @Override
+               protected boolean updatePosition(double d) {
+                       int value = (int)(d * 255);
+                       if (value < 0)
+                               value = 0;
+                       if (value > 255)
+                               value = 255;
+                       updatePosition(value);
+                       return true;
+               }
+               protected abstract void updatePosition(int value);
+               
+               protected void setPosition(int value) {
+                       double d = ((double)value)/255.0;
+                       setPosition(d);
+               }
+               
+       }
+       
+       private abstract static class GradientWidget extends ColorGradientCanvas {
+
+               int pos = -1;
+               double posD = -1.0;
+               
+               int size = 8;
+               int sized2 = 4;
+               
+               
+               
+               public GradientWidget(Composite parent, int style) {
+                       super(parent, style);
+                       this.addMouseListener(new MouseListener() {                     
+                               @Override
+                               public void mouseDown(MouseEvent e) {
+                                       if (e.button == 1) {
+                                               update(e);
+                                       }
+                               }
+                               
+                               @Override
+                               public void mouseUp(MouseEvent e) {}
+                               @Override
+                               public void mouseDoubleClick(MouseEvent e) {}
+                       });
+                       this.addMouseMoveListener(new MouseMoveListener() {
+                               
+                               @Override
+                               public void mouseMove(MouseEvent e) {
+                                       if ((e.stateMask & SWT.BUTTON1)>0) {
+                                               update(e);
+                                       }
+                               }
+                       });
+               }
+               
+               protected void update(MouseEvent e) {
+                       Rectangle r = getClientArea();
+                       double d;
+                       if ((style & SWT.HORIZONTAL) > 0) {
+                               d = (double)e.x / (double)r.width;
+                       } else {
+                               d = (double)e.y / (double)r.height;
+                       }
+                       if (d < 0.0)
+                               d = 0.0;
+                       else if (d > 1.0)
+                               d = 1.0;
+                       if (updatePosition(d)) {
+                               if ((style & SWT.HORIZONTAL) > 0) {
+                                       pos = (int)(d*((double)r.width));
+                               } else {
+                                       pos = (int)(d*((double)r.height));
+                               }
+                               posD = d;
+                       }
+               }
+               
+               protected abstract boolean updatePosition(double d);
+               
+               protected void setPosition(double d) {
+                       if (d == posD)
+                               return;
+                       _setPosition(d);                                                
+               }
+               
+               private void _setPosition(double d) {
+                       Rectangle r = getClientArea();
+                       posD = d;
+                       if (posD >= 0.0) {
+                               if ((style & SWT.HORIZONTAL) > 0) {
+                                       pos = (int)(d * (double)r.width);
+                               } else {
+                                       pos = (int)(d * (double)r.height);
+                               }
+                       } else {
+                               pos = -1;
+                       }
+               }
+               
+               Rectangle prevClip;
+               @Override
+               protected void paintGradient(GC gc, Rectangle clip) {
+                       super.paintGradient(gc, clip);
+                       if (!clip.equals(prevClip)) {
+                               prevClip = clip;
+                               _setPosition(posD);
+                       }
+                       
+                       if (pos >= 0) {
+                               org.eclipse.swt.graphics.Color white = new org.eclipse.swt.graphics.Color(gc.getDevice(), 255,255,255);
+                               org.eclipse.swt.graphics.Color black = new org.eclipse.swt.graphics.Color(gc.getDevice(), 0, 0, 0);
+                               gc.setForeground(black);
+                               gc.setBackground(white);
+                               int x;
+                               int y;
+                               if ((style & SWT.HORIZONTAL) > 0) {
+                                       x = pos;
+                                       y = clip.height / 2;
+                               } else {
+                                       x = clip.width / 2;
+                                       y = pos;
+                               }
+                               gc.fillOval(x-sized2, y-sized2, size, size);
+                               gc.drawOval(x-sized2, y-sized2, size, size);
+                               
+                               white.dispose();
+                               black.dispose();
+                       }
+               }
+               
+       }
+}