-/*******************************************************************************\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();
+ }
+ }
+
+ }
+}