1 package org.catacomb.druid.swing;
2
3 import org.catacomb.druid.event.LabelActor;
4 import org.catacomb.interlish.structure.MouseActor;
5 import org.catacomb.interlish.structure.MouseSource;
6
7
8 import java.awt.Color;
9 import java.awt.Dimension;
10 import java.awt.Graphics;
11 import java.awt.event.InputEvent;
12 import java.awt.event.MouseEvent;
13 import java.awt.event.MouseListener;
14 import java.awt.event.MouseMotionListener;
15
16 import javax.swing.JPanel;
17
18
19 public class DFloatSlider extends JPanel
20 implements MouseSource, MouseListener, MouseMotionListener {
21
22 static final long serialVersionUID = 1001;
23
24
25 DFloat dFloat;
26
27 LabelActor labelActor;
28
29
30 double value;
31
32
33 int iscale;
34
35 int state;
36 final static int NONE = 0;
37 final static int DRAG = 1;
38
39
40 double linmin;
41 double linmax;
42 double linvalue;
43
44 String label;
45
46 int xslider;
47
48
49
50 int xdown;
51 int ydown;
52 double linvaluedown;
53 long downtime;
54
55
56 Color bgColor;
57 RolloverEffect rollover;
58
59
60 public DFloatSlider(DFloat df, double v, double min, double max, int scl) {
61 dFloat = df;
62
63 addMouseListener(this);
64 addMouseMotionListener(this);
65
66 attachRollover();
67
68 setScale(scl);
69 setRange(min, max);
70 setValue(v);
71 }
72
73
74 public void setScale(int isc) {
75 iscale = isc;
76 }
77
78
79 public void setRange(double min, double max) {
80 if (isLog()) {
81 linmin = mylog(min);
82 linmax = mylog(max);
83
84 } else {
85 linmin = min;
86 linmax = max;
87 }
88
89 }
90
91
92 public void setMouseActor(MouseActor ma) {
93 addMouseListener(new DMouseRelay(ma));
94 }
95
96
97 public void setLabel(String s) {
98 label = s;
99 }
100
101
102 public void setBg(Color col) {
103 setBackground(col);
104 bgColor = col;
105 rollover.setBg(col);
106 }
107
108
109 public boolean isLog() {
110 return (iscale == DFloat.LOG);
111 }
112
113
114 private double mylog(double vin) {
115 double v = vin;
116 double xmin = 1.e-99;
117 if (v <= xmin) {
118 v = xmin;
119 }
120 double ret = Math.log(v);
121 return ret;
122 }
123
124
125 public void attachRollover() {
126 rollover = new RolloverEffect(this);
127 addMouseListener(rollover);
128 }
129
130
131 public void setLabelActor(LabelActor lact) {
132 labelActor = lact;
133 }
134
135
136
137
138
139
140
141
142
143 public double getValue() {
144 return value;
145 }
146
147
148 public void setValue(double d) {
149 value = d;
150 linvalue = toLin(d);
151 ensureInRange();
152 }
153
154
155 public double toLin(double d) {
156 double ret = d;
157 if (isLog()) {
158 ret = mylog(value);
159 }
160 return ret;
161 }
162
163
164 public double fromLin(double d) {
165 double ret = d;
166 if (isLog()) {
167 ret = Math.exp(d);
168 }
169 return ret;
170 }
171
172
173
174 public void export() {
175 value = fromLin(linvalue);
176
177 dFloat.setFromSlider(value);
178 }
179
180
181
182 private void ensureInRange() {
183 if (linvalue < linmin) {
184 linvalue = linmin;
185 }
186 if (linvalue > linmax) {
187 linvalue = linmax;
188 }
189 }
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204 public Dimension getMinimumSize() {
205 return new Dimension(80, 20);
206 }
207
208
209 public Dimension getPreferredSize() {
210 return new Dimension(140, 22);
211 }
212
213
214
215 public void paintComponent(Graphics g) {
216 realPaint(g);
217 }
218
219
220
221 public void realPaint(Graphics g) {
222 int w = getWidth();
223 int h = getHeight();
224 if (bgColor == null) {
225 bgColor = getBackground();
226 }
227 g.setColor(bgColor);
228 g.fillRect(0, 0, w, h);
229
230 paintArrows(g);
231
232 paintKnob(g);
233
234 if (label != null) {
235 g.setColor(Color.black);
236 g.drawString(label, 40, 20);
237 }
238 }
239
240
241
242 private void paintArrows(Graphics g) {
243 int w = getWidth();
244 int h = getHeight();
245
246 Color cbg = bgColor;
247 Color cbr = cbg.brighter();
248 Color cdk = cbg.darker();
249
250 int hh = h / 2;
251 g.setColor(cbr);
252 g.drawLine(4, hh, 15, 4);
253
254 g.drawLine(w - 15, h - 4, w - 15, 4);
255
256
257
258
259 g.setColor(cdk);
260 g.drawLine(15, 4, 15, h - 4);
261
262
263
264 g.drawLine(4, hh, 15, h - 4);
265
266 g.drawLine(w - 15, h - 4, w - 4, hh);
267 g.drawLine(w - 15, 4, w - 4, hh);
268
269 }
270
271
272 private void paintKnob(Graphics g) {
273 int width = getWidth();
274 int height = getHeight();
275 int hh = height / 2;
276
277 double f = (linvalue - linmin) / (linmax - linmin);
278 int icen = (int)(25 + f * (width - 50));
279 if (icen < 25) {
280 icen = 25;
281 }
282 if (icen > width - 25) {
283 icen = width - 25;
284 }
285 drawUpButton(g, icen, hh, 5, 5);
286
287 xslider = icen;
288 }
289
290
291 private void drawUpButton(Graphics g, int icx, int icy, int hw, int hh) {
292 Color c = getBackground();
293
294 g.setColor(c.darker());
295 g.drawLine(icx - hw - 1, icy + hh + 1, icx + hw + 1, icy + hh + 1);
296 g.drawLine(icx - hw, icy + hh, icx + hw, icy + hh);
297
298 g.drawLine(icx + hw + 1, icy - hh - 1, icx + hw + 1, icy + hh + 1);
299 g.drawLine(icx + hw, icy - hh, icx + hw, icy + hh);
300
301
302 g.setColor(c.brighter());
303 g.drawLine(icx - hw - 1, icy - hh - 1, icx + hw + 1, icy - hh - 1);
304 g.drawLine(icx - hw, icy - hh, icx + hw, icy - hh);
305
306 g.drawLine(icx - hw - 1, icy - hh - 1, icx - hw - 1, icy + hh + 1);
307 g.drawLine(icx - hw, icy - hh, icx - hw, icy + hh);
308
309
310
311 }
312
313
314 public void nudgeLeft() {
315 nudge(-0.02);
316 }
317
318
319 public void nudgeRight() {
320 nudge(0.02);
321 }
322
323
324 public void nudge(double f) {
325
326
327
328
329 linvalue += f * (linmax - linmin);
330
331
332 ensureInRange();
333 export();
334 repaint();
335 }
336
337
338 public void rsfMouseDown(int x, int y, long when, int button) {
339
340
341 xdown = x;
342 ydown = y;
343 linvaluedown = linvalue;
344 downtime = when;
345
346 state = NONE;
347
348
349
350
351 if (x > 15 && x < getWidth() - 15) {
352 state = DRAG;
353
354 } else if (x < 15) {
355 nudgeLeft();
356
357 } else if (x > getWidth() - 15) {
358 nudgeRight();
359 }
360 }
361
362
363 public void rsfMouseUp(int x, int y) {
364 }
365
366
367
368 public void rsfMouseDrag(int x, int y) {
369 int height = getHeight();
370 int width = getWidth();
371
372 double f = 0.0;
373 if (y > height + 40) {
374 f = 0.01 * (height + 40 - y);
375 } else if (y < -40) {
376 f = 0.01 * (40 + y);
377 }
378
379
380 if (state == DRAG) {
381 double dr = (Math.pow(10.0, f) * (x - xdown)) / (width - 30);
382 linvalue = linvaluedown + dr * (linmax - linmin);
383 ensureInRange();
384 export();
385 repaint();
386 }
387 }
388
389
390
391
392
393 public void mouseDragged(MouseEvent e) {
394 int x = e.getX();
395 int y = e.getY();
396 rsfMouseDrag(x, y);
397 }
398
399
400 public void mouseMoved(MouseEvent e) {
401 }
402
403
404 public void mousePressed(MouseEvent e) {
405 int x = e.getX();
406 int y = e.getY();
407 long when = e.getWhen();
408 int modif = e.getModifiers();
409 int button = 0;
410 if (modif == InputEvent.BUTTON1_MASK) {
411 button = 1;
412 } else if (modif == InputEvent.BUTTON2_MASK) {
413 button = 2;
414 } else if (modif == InputEvent.BUTTON3_MASK) {
415 button = 3;
416 }
417 rsfMouseDown(x, y, when, button);
418 }
419
420
421
422 public void mouseReleased(MouseEvent e) {
423 int x = e.getX();
424 int y = e.getY();
425 rsfMouseUp(x, y);
426 }
427
428
429
430 public void mouseEntered(MouseEvent e) {
431 requestFocus();
432 }
433
434
435 public void mouseExited(MouseEvent e) {
436 }
437
438
439 public void mouseClicked(MouseEvent e) {
440 requestFocus();
441 }
442
443
444 public double getTotalRange() {
445 double ret = 1.0;
446 if (isLog()) {
447 ret = linmax - linmin;
448 } else {
449 ret = Math.pow(10., linmax) - Math.pow(10., linmin);
450 }
451 return ret;
452 }
453
454 }