]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradientComposite.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.utils.ui / src / org / simantics / utils / ui / color / ColorGradientComposite.java
diff --git a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradientComposite.java b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradientComposite.java
new file mode 100644 (file)
index 0000000..3b43494
--- /dev/null
@@ -0,0 +1,548 @@
+/*******************************************************************************\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
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.jface.util.IPropertyChangeListener;\r
+import org.eclipse.jface.util.PropertyChangeEvent;\r
+import org.eclipse.jface.viewers.CellEditor;\r
+import org.eclipse.jface.viewers.ColorCellEditor;\r
+import org.eclipse.jface.viewers.ICellEditorListener;\r
+import org.eclipse.jface.viewers.ICellModifier;\r
+import org.eclipse.jface.viewers.ILabelProviderListener;\r
+import org.eclipse.jface.viewers.ISelectionChangedListener;\r
+import org.eclipse.jface.viewers.IStructuredContentProvider;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.viewers.ITableLabelProvider;\r
+import org.eclipse.jface.viewers.SelectionChangedEvent;\r
+import org.eclipse.jface.viewers.TableViewer;\r
+import org.eclipse.jface.viewers.TextCellEditor;\r
+import org.eclipse.jface.viewers.Viewer;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.layout.FillLayout;\r
+import org.eclipse.swt.layout.FormAttachment;\r
+import org.eclipse.swt.layout.FormData;\r
+import org.eclipse.swt.layout.FormLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.ColorDialog;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableColumn;\r
+import org.eclipse.swt.widgets.TableItem;\r
+\r
+/**\r
+ * Widget to create and edit color gradients\r
+ * \r
+ * @author Marko Luukkainen\r
+ *\r
+ */\r
+public class ColorGradientComposite extends Composite implements ISelectionChangedListener, ICellEditorListener, IPropertyChangeListener{\r
+       private static int ICON_WIDTH = 36;\r
+       private static int ICON_HEIGHT = 14;\r
+       \r
+       private static final String COLOR_ID = "Color";\r
+       private static final String VALUE_ID = "Value";\r
+       \r
+       \r
+       private ColorGradientCanvas gradientComposite;\r
+       //private Table table;\r
+       private TableViewer viewer;\r
+       private Button addButton;\r
+       private Button editButton;\r
+       private Button removeButton;\r
+       private Button rgbButton;\r
+       private Button hsvButton;\r
+       private int type = ColorGradient.RGB;\r
+       \r
+       private ArrayList<ColorValue> values = new ArrayList<ColorValue>();\r
+       //private ArrayList<Image> images = new ArrayList<Image>();\r
+       //private HashMap<TableItem,ColorValue> items = new HashMap<TableItem,ColorValue>();\r
+       private HashMap<ColorValue,Image> images = new HashMap<ColorValue,Image>();\r
+       \r
+       \r
+       \r
+       public ColorGradientComposite(Composite parent, int style) {\r
+               super(parent,style);\r
+           FormLayout layout = new FormLayout();\r
+           this.setLayout(layout);\r
+           gradientComposite = new ColorGradientCanvas(this,SWT.HORIZONTAL);\r
+           \r
+           Group typeComposite = new Group(this,SWT.NONE);\r
+           typeComposite.setText("Color interpolation type");\r
+           \r
+           typeComposite.setLayout(new FillLayout(SWT.HORIZONTAL));\r
+           Label rgbLabel = new Label(typeComposite,SWT.NONE);\r
+           rgbLabel.setText("RGB");\r
+           rgbButton = new Button(typeComposite,SWT.RADIO);\r
+           rgbButton.setSelection(true);\r
+           rgbButton.addSelectionListener(new SelectionListener() {\r
+               public void widgetDefaultSelected(SelectionEvent e) {\r
+                       widgetSelected(e);\r
+               }\r
+               public void widgetSelected(SelectionEvent e) {\r
+                       rgbButton.setSelection(true);\r
+                       hsvButton.setSelection(false);\r
+                       type = ColorGradient.RGB;\r
+                       gradientComposite.setGradient(new ColorGradient(values,type));\r
+               }\r
+           });\r
+           Label hsvLabel = new Label(typeComposite,SWT.NONE);\r
+           hsvLabel.setText("HSV");\r
+           hsvButton = new Button(typeComposite,SWT.RADIO);\r
+           hsvButton.addSelectionListener(new SelectionListener() {\r
+               public void widgetDefaultSelected(SelectionEvent e) {\r
+                       widgetSelected(e);\r
+               }\r
+               public void widgetSelected(SelectionEvent e) {\r
+                       hsvButton.setSelection(true);\r
+                       rgbButton.setSelection(false);\r
+                       type = ColorGradient.HSV;\r
+                       gradientComposite.setGradient(new ColorGradient(values,type));\r
+               }\r
+           });\r
+           viewer = new TableViewer(this,SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);\r
+           //table = new Table(this,SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);\r
+           final Table table = viewer.getTable();\r
+           table.setLinesVisible(true);\r
+           table.setHeaderVisible(true);\r
+           \r
+           viewer.addSelectionChangedListener(this);\r
+           viewer.addPostSelectionChangedListener(this);\r
+           \r
+           TableColumn column = new TableColumn(table,SWT.RIGHT);\r
+           column.setText("Color");\r
+           column.setWidth(40);\r
+           column.setMoveable(false);\r
+           column.setResizable(false);\r
+           column = new TableColumn(table,SWT.LEFT);\r
+           column.setText("Value");\r
+           column.setWidth(300);\r
+           column.setMoveable(false);\r
+           \r
+           viewer.setColumnProperties(new String[]{COLOR_ID,VALUE_ID});\r
+           \r
+           viewer.setLabelProvider(new TableLabelProvider());\r
+           viewer.setContentProvider(new TableContentProvider());\r
+           viewer.setInput(values);\r
+           \r
+           final ColorCellEditor colorEditor = new ColorCellEditor(table);\r
+           final TextCellEditor valueEditor = new TextCellEditor(table);\r
+           colorEditor.addListener(this);\r
+           valueEditor.addListener(this);\r
+           valueEditor.addPropertyChangeListener(this);\r
+           viewer.setCellEditors(new CellEditor[]{colorEditor,valueEditor});\r
+           \r
+           viewer.setCellModifier(new TableCellEditorModifier());    \r
+           \r
+           \r
+           Composite buttonComposite = new Composite(this,SWT.NONE);\r
+           \r
+           \r
+           buttonComposite.setLayout(new FillLayout(SWT.HORIZONTAL));\r
+           \r
+           addButton = new Button(buttonComposite,SWT.PUSH);\r
+           addButton.setText("Add new color");\r
+           addButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { \r
+               public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {    \r
+                       ColorDialog dialog = new ColorDialog(ColorGradientComposite.this.getShell(), SWT.NONE);\r
+                \r
+                RGB rgb = dialog.open();\r
+                if (rgb != null) {\r
+                    Color c = new Color(rgb.red,rgb.green,rgb.blue);\r
+                    Double value;\r
+                    if (values.size() == 0) {\r
+                       value = 0.0;\r
+                    } else if (values.size() == 1) {\r
+                       value = 100.0;\r
+                    } else {\r
+                       // FIXME : insert some logic here\r
+                       value = 100.0 * Math.random();\r
+                    }\r
+                    \r
+                    addColor(c,value);\r
+                }\r
+            }\r
+        });\r
+           editButton = new Button(buttonComposite,SWT.PUSH);\r
+           editButton.setText("Edit color");\r
+           editButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { \r
+               public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {    \r
+                       TableItem selection[] = table.getSelection();\r
+                       if (selection.length > 0) {\r
+                               TableItem selected = selection[0];\r
+                               Object obj = selected.getData();\r
+                               if (obj instanceof ColorValue) {\r
+                                       ColorDialog dialog = new ColorDialog(ColorGradientComposite.this.getShell(), SWT.NONE);\r
+                                       dialog.setRGB(getRGB(((ColorValue)obj).getColor()));\r
+                                       RGB rgb = dialog.open();\r
+                        if (rgb != null) {\r
+                               modifyColorValueColor((ColorValue)obj,rgb);\r
+                        }\r
+                               }                       \r
+                       }\r
+               }\r
+        });\r
+           editButton.setEnabled(false);\r
+           removeButton = new Button(buttonComposite,SWT.PUSH);\r
+           removeButton.setText("Remove color");\r
+           removeButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { \r
+               public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {    \r
+                       TableItem selection[] = table.getSelection();\r
+                       if (selection.length > 0) {\r
+                               TableItem selected = selection[0];\r
+                               Object o = selected.getData();\r
+                               if (o instanceof ColorValue) {\r
+                                       Image i = images.get(o);\r
+                                       i.dispose();\r
+                                       images.remove(o);\r
+                                       values.remove(o);\r
+                                       updateWidgets();\r
+                               }                       \r
+                       }\r
+               }\r
+        });\r
+           removeButton.setEnabled(false);\r
+           \r
+           FormData gradientData = new FormData();\r
+           gradientData.top = new FormAttachment(0,0);\r
+           gradientData.left = new FormAttachment(0,0);\r
+           gradientData.right = new FormAttachment(100,0);\r
+           gradientData.height = 40;\r
+           gradientComposite.setLayoutData(gradientData);\r
+              \r
+           FormData typeData = new FormData();     \r
+           typeData.left = new FormAttachment(0,0);\r
+           typeData.right = new FormAttachment(100,0);\r
+           typeData.top = new FormAttachment(gradientComposite,0,SWT.BOTTOM);\r
+           typeData.height = 20;\r
+           typeComposite.setLayoutData(typeData);\r
+           \r
+           FormData buttonData = new FormData();           \r
+           buttonData.left = new FormAttachment(0,0);\r
+           buttonData.right = new FormAttachment(100,0);\r
+           buttonData.bottom = new FormAttachment(100,0);\r
+           buttonData.height = 30;\r
+           buttonComposite.setLayoutData(buttonData);\r
+           \r
+           FormData viewerData = new FormData();           \r
+           viewerData.top = new FormAttachment(typeComposite,0,SWT.BOTTOM);\r
+           viewerData.left = new FormAttachment(0,0);\r
+           viewerData.right = new FormAttachment(100,0);\r
+           viewerData.bottom = new FormAttachment(buttonComposite,0,SWT.TOP);\r
+           table.setLayoutData(viewerData);\r
+           \r
+           \r
+       }\r
+       /*\r
+       private void addColorValueToTable(ColorValue value) {\r
+               TableItem item = new TableItem(table,SWT.NONE);\r
+               item.setText(Double.toString(value.getValue()));\r
+               Image image = ColorIconCreator.createImage(value.getColor(), 14);\r
+               item.setImage(image);\r
+               images.add(image);\r
+               items.put(item,value);\r
+       }\r
+       */\r
+       /*\r
+       private void sortItems() {\r
+               for (Image i : images)\r
+                       i.dispose();\r
+               for (TableItem item : table.getItems())\r
+                       if(!item.isDisposed())\r
+                               item.dispose();\r
+               items.clear();\r
+               Collections.sort(values,new ColorValueComparator());\r
+               for (ColorValue value : values) {\r
+                       addColorValueToTable(value);\r
+               }\r
+       }\r
+       */\r
+       public void addColor(Color color, double value) {\r
+               addColor(new ColorValue(color,value));\r
+       }\r
+       \r
+       public void addColor(ColorValue value) {\r
+               values.add(value);\r
+               Image image = ColorIconCreator.createImage(value.getColor(), ICON_WIDTH, ICON_HEIGHT);\r
+               images.put(value,image);\r
+               updateWidgets();\r
+               //viewer.refresh(true);\r
+       }\r
+       \r
+       private void updateWidgets() {\r
+               Collections.sort(values,new ColorValueComparator());    \r
+               gradientComposite.setGradient(new ColorGradient(values,type));\r
+               viewer.refresh();\r
+               \r
+       }\r
+       /*\r
+       public void addColor(ColorValue value) {\r
+               values.add(value);\r
+               sortItems();\r
+               // sortItem creates new menuitems, which makes selectedItem disposed\r
+               for (TableItem item : items.keySet() ) {\r
+                       if (items.get(item) == value) {\r
+                               gradientComposite.setGradient(new ColorGradient(values,type));\r
+                               return;\r
+                       }\r
+                       \r
+               }\r
+               gradientComposite.setGradient(new ColorGradient(values,type));\r
+       }\r
+       */\r
+       public ColorGradient getGradient() {\r
+               return new ColorGradient(values,type);\r
+       }\r
+       /*\r
+       public void dispose() {\r
+               for (Image i : images)\r
+                       i.dispose();\r
+               if (!table.isDisposed()) {\r
+                       for (TableItem item : table.getItems())\r
+                               if(!item.isDisposed())\r
+                                       item.dispose();\r
+                       table.dispose();\r
+               }\r
+       }\r
+       */\r
+       public void dispose() {\r
+               for (Image i : images.values())\r
+                       i.dispose();\r
+               \r
+       }\r
+       \r
+       public void setGradient(ColorGradient gradient) {\r
+               for (Image i : images.values())\r
+                       i.dispose();\r
+               values.clear();\r
+               images.clear();\r
+               type = gradient.getType();\r
+               for (ColorValue value : gradient.getColorValues())\r
+                       addColor(value);\r
+               \r
+       }\r
+       \r
+       \r
+//     private org.eclipse.swt.graphics.Color getSWTColor(Color color){\r
+//             org.eclipse.swt.graphics.Color swtColor = new org.eclipse.swt.graphics.Color(Display.getCurrent(), color.getR(), color.getG(), color.getB());   \r
+//             return swtColor;\r
+//     }\r
+       \r
+       private RGB getRGB(Color color) {\r
+               RGB rgb = new RGB(color.getR(),color.getG(),color.getB());\r
+               return rgb;\r
+       }\r
+       \r
+       private void modifyColorValueValue(ColorValue cValue, String string) {\r
+               try {\r
+                       double d = Double.parseDouble(string);\r
+                       values.remove(cValue);\r
+                       Image image = images.get(cValue);\r
+                       images.remove(cValue);\r
+                       ColorValue newCValue = new ColorValue(cValue.getColor(),d);\r
+                       values.add(newCValue);\r
+                       images.put(newCValue,image);\r
+                       updateWidgets();\r
+                       \r
+               } catch (NumberFormatException e) {\r
+                       return;\r
+               }\r
+       }\r
+       \r
+       private void modifyColorValueColor(ColorValue cValue, RGB rgb) {\r
+               values.remove(cValue);\r
+               Image oldImage = images.get(cValue);\r
+               oldImage.dispose();\r
+               images.remove(cValue);\r
+               \r
+               Color newColor = new Color(rgb.red,rgb.green,rgb.blue);\r
+               ColorValue newCValue = new ColorValue(newColor,cValue.getValue());\r
+               values.add(newCValue);\r
+               Image newImage = ColorIconCreator.createImage(newColor, ICON_WIDTH, ICON_HEIGHT);\r
+               images.put(newCValue,newImage);\r
+               updateWidgets();\r
+       }\r
+       \r
+       /**\r
+        * Enables and disables "Edit color" and "Remove color" buttons depending on selected item\r
+        */\r
+       public void selectionChanged(SelectionChangedEvent event) {\r
+               Object obj = ((IStructuredSelection)event.getSelection()).getFirstElement();\r
+               if (obj == null) {\r
+                       editButton.setEnabled(false);\r
+                       removeButton.setEnabled(false);\r
+               } else {\r
+                       editButton.setEnabled(true);\r
+                       removeButton.setEnabled(true);\r
+               }\r
+       }\r
+       \r
+       /*\r
+        * FIXME :\r
+        * If item is opened for editing selectionChanged won't get null selection and\r
+        * "Edit" & "Remove" buttons are enabled when there's no valid selection\r
+        * \r
+        * There seems to be no way to get event when cellEditor is activated...\r
+        */\r
+       \r
+       public void applyEditorValue() {\r
+               // TODO Auto-generated method stub\r
+               editButton.setEnabled(false);\r
+               removeButton.setEnabled(false); \r
+       }\r
+       \r
+       public void cancelEditor() {\r
+               // TODO Auto-generated method stub\r
+               editButton.setEnabled(false);\r
+               removeButton.setEnabled(false); \r
+       }\r
+       \r
+       public void editorValueChanged(boolean oldValidState, boolean newValidState) {\r
+               // TODO Auto-generated method stub\r
+               editButton.setEnabled(false);\r
+               removeButton.setEnabled(false); \r
+       }\r
+       \r
+       public void propertyChange(PropertyChangeEvent event) {\r
+               editButton.setEnabled(false);\r
+               removeButton.setEnabled(false); \r
+               \r
+       }\r
+       /**\r
+        * @author Marko Luukkainen\r
+        *\r
+        */\r
+       private class TableLabelProvider implements ITableLabelProvider {\r
+               private ArrayList<ILabelProviderListener> listeners = new ArrayList<ILabelProviderListener>();\r
+                               \r
+               /* (non-Javadoc)\r
+                * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()\r
+                */\r
+               public void dispose() {\r
+                                               \r
+               }\r
+               /* (non-Javadoc)\r
+                * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)\r
+                */\r
+               public Image getColumnImage(Object element, int columnIndex) {\r
+                       //System.out.println("TableLabelProvider.getColumnImage() " + element + " , " + columnIndex);\r
+                       ColorValue value = (ColorValue)element;\r
+                       if (columnIndex == 0)\r
+                               return images.get(value);\r
+                       return null;\r
+               }\r
+               /* (non-Javadoc)\r
+                * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)\r
+                */\r
+               public String getColumnText(Object element, int columnIndex) {\r
+                       //System.out.println("TableLabelProvider.getColumnText() " + element + " , " + columnIndex);\r
+                       ColorValue value = (ColorValue)element;\r
+                       if (columnIndex == 1)\r
+                               return Double.toString(value.getValue());\r
+                       return null;\r
+               }\r
+               /* (non-Javadoc)\r
+                * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)\r
+                */\r
+               public boolean isLabelProperty(Object element, String property) {\r
+                       return true;\r
+               }\r
+               /* (non-Javadoc)\r
+                * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)\r
+                */\r
+               public void addListener(ILabelProviderListener listener) {\r
+                       if(!listeners.contains(listener))\r
+                               listeners.add(listener);                        \r
+               }\r
+               /* (non-Javadoc)\r
+                * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)\r
+                */\r
+               public void removeListener(ILabelProviderListener listener) {\r
+                       listeners.remove(listener);\r
+               }\r
+               \r
+               \r
+       }\r
+       \r
+       /**\r
+        * @author Marko Luukkainen\r
+        *\r
+        */\r
+       private class TableContentProvider implements IStructuredContentProvider {\r
+               public void dispose() {\r
+                       \r
+               }\r
+               public Object[] getElements(Object inputElement) {\r
+                       ColorValue valueArray[] = new ColorValue[values.size()];\r
+                       // values.toArray(valueArray);\r
+            // to get correct ordering (smallest last)\r
+            // we must reverse the order of the list\r
+            for (int i = 0; i < values.size(); i++) {\r
+                           valueArray[i] = values.get(values.size() - 1 -i);\r
+            }\r
+            //System.out.println("TableContentProvider.getElements() : array size " + valueArray.length);\r
+                       return valueArray;\r
+               }\r
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
+                       //System.out.println("TableContentProvider.inputChanged()");\r
+                       \r
+               }\r
+       }\r
+       \r
+       /**\r
+        * @author Marko Luukkainen\r
+        *\r
+        */\r
+       private class TableCellEditorModifier implements ICellModifier {\r
+               public boolean canModify(Object element, String property) {\r
+                       //System.out.println("TableCellEditorModifier.canModify()" + element + " , " + property);\r
+                       if (property == VALUE_ID)\r
+                               return true;\r
+                       // this is commented out because it's hard so select the row when both rows have editors\r
+                       // now the color can be changed with "Edit Color" button\r
+                       //if (property == COLOR_ID)\r
+                       //      return true;\r
+                       return false;\r
+               }\r
+               public Object getValue(Object element, String property) {\r
+                       //System.out.println("TableCellEditorModifier.getValue()" + element + " , " + property);\r
+                       if (property == VALUE_ID)\r
+                               return Double.toString(((ColorValue)element).getValue());\r
+                       if (property == COLOR_ID) \r
+                               return getRGB(((ColorValue)element).getColor());\r
+                       return null;\r
+                       \r
+               }\r
+               public void modify(Object element, String property, Object value) {\r
+                       TableItem item = (TableItem)element;\r
+                       Object obj = item.getData();\r
+                       //System.out.println("TableCellEditorModifier.modify()" + element + " , " + property + " , " + value);\r
+                       if (property == VALUE_ID)\r
+                               modifyColorValueValue((ColorValue)obj,(String)value);\r
+                       if (property == COLOR_ID)\r
+                               modifyColorValueColor((ColorValue)obj,(RGB)value);\r
+               }\r
+               \r
+       }\r
+}\r
+\r
+       \r