Not a big win over Java:
1 import java.awt.*;
2 import java.awt.event.*;
3 import java.awt.image.*;
4
5 public class ColorSlider extends Canvas implements MouseListener, MouseMotionListener {
6
7 public static final int HORIZONTAL = 1;
8 public static final int VERTICAL = 2;
9
10 /* This is written from the perspective of a horizontal bar */
11
12 int barLeft = 10;
13 int barRight = 190;
14 int barTop = 6, barBottom = 12;
15
16 int preferredMajor = 200;
17 int preferredMinor = barTop + barBottom;
18
19 int bubblePos = 50, tempBubblePos = 50;
20
21 boolean dragging;
22
23 int orientation;
24
25 double value, minimum, maximum;
26
27 int mode = RGBColor.HSV_MODE;
28 RGBColor startColor = new RGBColor (), endColor = new RGBColor ();
29 Color bubbleColor, ghostBubbleColor;
30
31 int bubbleWidth = 1, bubbleHeight = 9;
32
33 double unitIncrement, blockIncrement = 0.1;
34
35 Image image;
36
37 ColorSlider (int orientation, double minimum, double maximum, double unitIncrement, double value) {
38 super ();
39 setSize (200, 30);
40 addMouseListener (this);
41 addMouseMotionListener (this);
42 this.orientation = orientation;
43 this.value = value;
44 this.minimum = minimum;
45 this.maximum = maximum;
46 this.unitIncrement = unitIncrement;
47 startColor.setRGB (0f, 0f, 1f);
48 endColor.setRGB (1f, 0f, 0f);
49 }
50
51 public Dimension getPreferredSize () {
52 int w, h;
53 if (orientation == HORIZONTAL) {
54 w = preferredMajor;
55 h = preferredMinor;
56 } else {
57 w = preferredMajor;
58 h = preferredMinor;
59 }
60 return new Dimension (w, h);
61 }
62 public Dimension getMinimumSize () {
63 int w, h;
64 if (orientation == HORIZONTAL) {
65 w = preferredMajor;
66 h = preferredMinor;
67 } else {
68 w = preferredMajor;
69 h = preferredMinor;
70 }
71 return new Dimension (w, h);
72 }
73 ColorSlider (double minimum, double maximum, double unitIncrement, double value) {
74 this (HORIZONTAL, minimum, maximum, unitIncrement, value);
75 }
76
77 public void setSize (Dimension d) {
78 super.setSize (d);
79 if (orientation == HORIZONTAL) {
80 barRight = d.width - 10;
81 } else {
82 barRight = d.height - 10;
83 }
84 drawImage ();
85 }
86
87 public void setColors (RGBColor c1, RGBColor c2) {
88 startColor.copy (c1);
89 endColor.copy (c2);
90 drawImage ();
91 }
92
93 public void setMode (int mode) {
94 this.mode = mode;
95 }
96
97 void drawImage () {
98 Dimension d = getSize ();
99 int w = d.width;
100 int h = d.height;
101 int [] pixels;
102 if (orientation == HORIZONTAL) {
103 h = barBottom - barTop;
104 w -= 20;
105 pixels = new int [w * h];
106 for (int x = 0; x < w; x++) {
107 int c = RGBColor.interp (startColor, endColor, mode, (float)x / w).getARGB() | 0xff000000;
108 for (int y = 0; y < h; y++) {
109 pixels [x + y * w] = c;
110 }
111 }
112 } else {
113 w = barBottom - barTop;
114 h -= 20;
115 pixels = new int [w * h];
116 int i = 0;
117 for (int y = 0; y < h; y++) {
118 int c = RGBColor.interp (startColor, endColor, mode, (float) y / h).getARGB() | 0xff000000;
119 for (int x = 0; x < w; x++) {
120 pixels [i++] = c;
121 }
122 }
123 }
124
125 ImageProducer imageSource = new MemoryImageSource(w, h, pixels, 0, w);
126 image = Toolkit.getDefaultToolkit().createImage(imageSource);
127 }
128
129 public void mouseDragged(MouseEvent e) {
130
131 if (!dragging) return;
132
133 int minor = getMinor (e);
134 int major = getMajor (e);
135 Dimension d = getSize ();
136 int minorMax = orientation == HORIZONTAL ? d.height : d.width;
137 if (minor > 0 && minor < minorMax) {
138 if (major < barLeft) {
139 debug ("Too far left: " + e);
140 tempBubblePos = 0;
141 } else if (major > barRight) {
142 debug ("Too far right: " + e);
143 tempBubblePos = barRight;
144 } else {
145 debug ("Perfect: " + e);
146 tempBubblePos = major;
147 }
148 repaint ();
149 } else {
150 debug ("Out of range: " + e);
151 }
152 }
153
154 public void mouseReleased (MouseEvent e) {
155 debug ("Released: " + e);
156 bubblePos = tempBubblePos;
157 dragging = false;
158 repaint ();
159 adjust (AdjustmentEvent.TRACK);
160 }
161
162 int getMajor (MouseEvent e) {
163 if (orientation == HORIZONTAL) {
164 return e.getX ();
165 } else {
166 return e.getY ();
167 }
168 }
169 int getMinor (MouseEvent e) {
170 if (orientation == HORIZONTAL) {
171 return e.getY ();
172 } else {
173 return e.getX ();
174 }
175 }
176 public void mousePressed (MouseEvent e) {
177
178 int minor = getMinor (e);
179 int major = getMajor (e);
180 if (major < barLeft) {
181 debug ("Too far left: " + e);
182 tempBubblePos -= blockIncrement;
183 tempBubblePos = Math.max (tempBubblePos, barLeft);
184 } else if (major > barRight) {
185 debug ("Too far right: " + e);
186 tempBubblePos += blockIncrement;
187 tempBubblePos = Math.min (tempBubblePos, barRight);
188 } else {
189 debug ("Perfect: " + e);
190 tempBubblePos = major;
191 dragging = true;
192 }
193
194 repaint ();
195 debug ("Pressed: " + e);
196 }
197
198 public void mouseEntered(MouseEvent e) {}
199 public void mouseExited(MouseEvent e) {}
200 public void mouseClicked(MouseEvent e) {}
201 public void mouseMoved(MouseEvent e) {}
202
203
204 public void update(Graphics g) {
205
206 Dimension d = getSize ();
207 Image dblBuf = createImage (d.width, d.height);
208 Graphics dblBufGC = dblBuf.getGraphics();
209 paint(dblBufGC);
210 g.drawImage(dblBuf, 0, 0, this);
211 }
212
213 public final void paint (Graphics g) {
214
215 final Dimension d = getSize ();
216 int w, h;
217
218 if (image == null) setSize (getSize ());
219
220
221 if (orientation == HORIZONTAL) {
222 w = d.width;
223 h = preferredMinor;
224 final int top = (d.height - h) / 2;
225 g.drawImage (image, barLeft, barTop + top, null);
226
227 g.drawRect (barLeft, barTop + top, barRight - barLeft, barBottom - barTop);
228 //top of position marker
229 g.fillRect (bubblePos - bubbleWidth, top,
230 bubbleWidth * 2, barTop);
231 //bottom of position marker
232 g.fillRect (bubblePos - bubbleWidth, barBottom + top,
233 bubbleWidth * 2, h - barBottom);
234
235 //top of temp position marker
236 g.fillRect (tempBubblePos - bubbleWidth, top,
237 bubbleWidth * 2, barTop);
238 //bottom of temp position marker
239 g.fillRect (tempBubblePos - bubbleWidth, barBottom + top,
240 bubbleWidth * 2, h - barBottom);
241
242
243 }
244 }
245
246 public static void main (String [] argv) {
247 Frame f = new Frame ("ColorSlider");
248 f.add (new ColorSlider (ColorSlider.HORIZONTAL, 0, 1, 0.1, 0.5));
249 f.pack();
250 f.setSize (800, 600);
251 f.setVisible(true);
252 while (true) {}
253 }
254
255 AdjustmentListener adjustmentListener = null;
256 public void addAdjustmentListener(AdjustmentListener l) {
257 adjustmentListener = AWTEventMulticaster.add(adjustmentListener, l);
258 }
259 public void removeAdjustmentListener(AdjustmentListener l) {
260 adjustmentListener = AWTEventMulticaster.remove(adjustmentListener, l);
261 }
262
263 public void adjust (int type) {
264 AdjustmentEvent e = new MyAdjustmentEvent (this, 0, type, value);
265
266 if (adjustmentListener != null) {
267 adjustmentListener.adjustmentValueChanged(e);
268 }
269 }
270
271 public double getValue () {
272 value = ((double) bubblePos - barLeft) / (barRight - barLeft);
273 return value * maximum + minimum;
274 }
275 public void setValue (double value) {
276 value -= minimum;
277 value /= maximum;
278 this.value = value;
279 bubblePos = barLeft + (int) (value * (barRight - barLeft));
280 tempBubblePos = bubblePos;
281 repaint ();
282 }
283
284 void debug (String str) {
285 //System.out.println (str);
286 }
287
288 }
289
290 class MyAdjustmentEvent extends AdjustmentEvent {
291
292 Object obj;
293 MyAdjustmentEvent (ColorSlider cs, int a, int b, double c) {
294 super (new Scrollbar (), a, b, (int) (c * 100));
295 obj = cs;
296 }
297 public Object getSource () {
298 return obj;
299 }
300 }