]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradientAdjustingCanvas.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.utils.ui / src / org / simantics / utils / ui / color / ColorGradientAdjustingCanvas.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.utils.ui.color;
13
14 import java.util.ArrayList;
15 import java.util.List;
16
17 import org.eclipse.jface.viewers.ISelection;
18 import org.eclipse.jface.viewers.ISelectionChangedListener;
19 import org.eclipse.jface.viewers.ISelectionProvider;
20 import org.eclipse.jface.viewers.SelectionChangedEvent;
21 import org.eclipse.jface.viewers.StructuredSelection;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.events.MouseEvent;
24 import org.eclipse.swt.events.MouseListener;
25 import org.eclipse.swt.events.MouseMoveListener;
26 import org.eclipse.swt.graphics.Color;
27 import org.eclipse.swt.graphics.GC;
28 import org.eclipse.swt.graphics.Image;
29 import org.eclipse.swt.graphics.Rectangle;
30 import org.eclipse.swt.widgets.Composite;
31 import org.eclipse.swt.widgets.Display;
32
33 /**
34  * 
35  * Canvas that shows color gradients and color positions.
36  * Without READ_ONLY style the canvas allows user to drag color positions.
37  * 
38  * @author Marko Luukkainen
39  *
40  */
41 public class ColorGradientAdjustingCanvas extends ColorGradientCanvas implements ISelectionProvider{
42         
43         ColorValue[] values;
44         int last;
45         int coords[];
46         int size = 8;
47         int sized2 = 4;
48         int width;
49         int height;
50         
51         int selectedValueIndex = -1;
52         
53         public ColorGradientAdjustingCanvas(Composite parent, int style) {
54                 super(parent,style|SWT.DOUBLE_BUFFERED|SWT.NO_BACKGROUND);
55                 addMouseListener(new MouseListener() {
56                         
57                         @Override
58                         public void mouseUp(MouseEvent e) {
59                                 
60                         }
61                         
62                         @Override
63                         public void mouseDown(MouseEvent e) {
64                                 // store and reset selection
65                                 int prev = selectedValueIndex;
66                                 selectedValueIndex = -1;
67                                 
68                                 // locate closest ColorValue, and select it.
69                                 int d = Integer.MAX_VALUE;
70                                 for (int i = 0; i <= last; i++) {
71                                         int x = coords[i*2];
72                                 int y = coords[i*2+1];
73                                 int dx = Math.abs(x - e.x);
74                                 int dy = Math.abs(y - e.y);
75                                 if ((dx < size) &&
76                                         (dy < size)) {
77                                         int dd = dx+dy;
78                                         if (dd < d) {
79                                                 selectedValueIndex = i;
80                                                 d = dd;
81                                         }
82                                 }
83                                 }
84                                 // if selection was changed, update it.
85                                 if (prev != selectedValueIndex) {
86                                         updateSelection();
87                                         redraw();
88                                 }
89                         }
90                         
91                         @Override
92                         public void mouseDoubleClick(MouseEvent e) {
93                                 
94                         }
95                 });
96                 if ((style&SWT.READ_ONLY) == 0) {
97                         addMouseMoveListener(new MouseMoveListener() {
98                                 
99                                 @Override
100                                 public void mouseMove(MouseEvent e) {
101                                         if ((e.stateMask & SWT.BUTTON1)>0) {
102                                                 if (selectedValueIndex > 0 && selectedValueIndex < last) {
103                                                         double d;
104                                                         if ((ColorGradientAdjustingCanvas.this.style | SWT.HORIZONTAL) > 0) {
105                                                                 d = (double)e.x/(double)width;
106                                                         } else {
107                                                                 d = (double)e.y/(double)height;
108                                                         }
109                                                         double r = max-min;
110                                                         d *= r;
111                                                         d += min;
112                                                         double offset = r*0.015;
113                                                         if (d <= values[selectedValueIndex-1].getValue()+offset)
114                                                                 d = values[selectedValueIndex-1].getValue()+offset;
115                                                         else if (d >= values[selectedValueIndex+1].getValue()-offset)
116                                                                 d = values[selectedValueIndex+1].getValue()-offset;
117                                                         values[selectedValueIndex]._setValue(d);
118                                                         calculateCoords(width, height);
119                                                         redraw();
120                                                 }
121                                         }
122                                         
123                                 }
124                         });
125                 }
126
127         }
128         
129         public void setGradient(ColorGradient gradient) {
130                 int prevSize = 0;
131                 if (values != null)
132                         prevSize = values.length;
133                 
134                 values = gradient.getColorValueArray();
135                 last = values.length-1;
136                 coords = new int[values.length*2];
137                 super.setGradient(gradient);
138                 if (selectedValueIndex >= 0 && prevSize != values.length) {
139                         selectedValueIndex = -1;
140                         updateSelection();
141                 } else {
142                         updateSelection();
143                 }
144         }
145         
146         double min;
147         double max;
148         
149         private void calculateCoords(int width, int height) {
150                 this.width = width;
151                 this.height = height;
152                 
153                 min = values[0].getValue();
154                 max = values[last].getValue();
155                 
156                 if ((ColorGradientAdjustingCanvas.this.style & SWT.HORIZONTAL) > 0) {
157                         for (int i = 0; i <= last ; i++) {
158                                 int y = height / 2;
159                                 double d =  values[i].getValue();
160                                 int x = (int)(((d-min)/(max-min))*(double)width);
161                                 coords[i*2] = x;
162                                 coords[i*2+1] = y;
163                         }
164                 } else {
165                         for (int i = 0; i <= last ; i++) {
166                                 int x = width / 2;
167                                 double d =  values[i].getValue();
168                                 int y = (int)(((d-min)/(max-min))*(double)height);
169                                 coords[i*2] = x;
170                                 coords[i*2+1] = y;
171                         }
172                 }
173         }
174
175         
176         @Override
177         protected void paintGradient(GC gc, Rectangle clip) {
178                 if (values != null && values.length > 0) {
179                         Image image = gradient.getGradientImage(clip.width,clip.height,ColorGradientAdjustingCanvas.this.style);
180                         gc.drawImage(image, 0, 0);
181                         image.dispose();        
182                         calculateCoords(clip.width, clip.height);
183
184                         Color white = new Color(gc.getDevice(), 255,255,255);
185                         Color yellow = new Color(gc.getDevice(), 255,230,0);
186                         Color black = new Color(gc.getDevice(), 0, 0, 0);
187                         for (int i = 0; i <= last ; i++) {
188                                 int x = coords[i*2];
189                                 int y = coords[i*2+1];
190                                 gc.setForeground(black);
191                                 if (selectedValueIndex == i)
192                                         gc.setBackground(yellow);
193                                 else
194                                         gc.setBackground(white);
195                                 if (i == 0 || i == last ) {
196                                         gc.fillRectangle(x-sized2, y-sized2, size, size);
197                                         gc.drawRectangle(x-sized2, y-sized2, size, size);
198                                 } else {
199                                         gc.fillOval(x-sized2, y-sized2, size, size);
200                                         gc.drawOval(x-sized2, y-sized2, size, size);
201                                 }
202                         }
203                         
204                         white.dispose();
205                         black.dispose();
206                         yellow.dispose();
207                 } else {
208                         gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
209                         gc.fillRectangle(clip);
210                 }
211         }
212         
213         private ISelection selection = new StructuredSelection();
214         private List<ISelectionChangedListener> listeners = new ArrayList<>();
215
216         @Override
217         public void addSelectionChangedListener(ISelectionChangedListener listener) {
218                 listeners.add(listener);
219         }
220
221         @Override
222         public ISelection getSelection() {
223         return selection;
224         }
225
226         @Override
227         public void removeSelectionChangedListener(ISelectionChangedListener listener) {
228                 listeners.remove(listener);
229         }
230
231         @Override
232         public void setSelection(ISelection selection) {
233                 ColorValue value = (ColorValue)((StructuredSelection)selection).getFirstElement();
234                 selectedValueIndex = gradient.getColorValues().indexOf(value);
235         }
236         
237         private void updateSelection() {
238                 if (selectedValueIndex < 0)
239                         selection = new StructuredSelection();
240                 else
241                         selection = new StructuredSelection(values[selectedValueIndex]);
242                 
243                 for (ISelectionChangedListener l : listeners) {
244                         l.selectionChanged(new SelectionChangedEvent(this, selection));
245                 }
246         }
247         
248         public int getPointSize() {
249                 return size;
250         }
251         
252         public void setPointSize(int size) {
253                 this.size = size;
254                 this.sized2 = size/2;
255         }
256         
257
258 }