1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.gui.components.range2;
21
22 import java.util.ArrayList;
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public class RangedValueController
50 {
51 private Range range = null;
52 private double rawValue;
53 private final ArrayList<RangedValueListener> listeners = new ArrayList<RangedValueListener>();
54 private double scalingFactor=1.0;
55
56 private RangedValue rangedValue= new RangedValue();
57 private RangedValuePolicy policy;
58
59 private TickCalculator tickCalculator = null;
60 private Tick[] lastTicksUsed = null;
61 private boolean snapToTicks = false;
62
63
64
65
66
67
68
69
70 protected Range createDefaultRange()
71 {
72 return new LinearRange();
73 }
74
75
76
77
78
79 public Range getRange()
80 {
81 if (range == null) {
82 range = createDefaultRange();
83 }
84 return range;
85 }
86
87
88
89
90
91
92 public void setRange(Range newRange)
93 {
94
95
96 range = newRange;
97
98 if (range != null) {
99
100 setRangedValue(new RangedValue(getMinimum(),getMaximum(),getRawValue()));
101 }
102 }
103
104
105
106
107
108
109 public void setRangedValue(RangedValue v) {
110 if (snapToTicks && lastTicksUsed != null) {
111 final Tick[] ticks = lastTicksUsed;
112 double value = v.getValue();
113 for (int i = 1; i < ticks.length; i++) {
114 if (ticks[i-1].absolute == value) break;
115 if (ticks[i-1].absolute < value && ticks[i].absolute > value) {
116 if (ticks[i].absolute-value < value - ticks[i-1].absolute) {
117 value = ticks[i].absolute;
118 } else {
119 value = ticks[i-1].absolute;
120 }
121 break;
122 }
123 }
124 v = new RangedValue(v.getMinimum(), v.getMaximum(), value);
125 }
126 final double raw=v.getValue();
127
128
129 final Range r = getRange();
130
131 v = new RangedValue(r.validate(v.getMinimum()),r.validate(v.getMaximum()), r.validate(v.getValue()));
132
133
134 v = validatePolicies(v);
135
136
137 v = new RangedValue(r.validate(v.getMinimum()),r.validate(v.getMaximum()), r.validate(v.getValue()));
138
139
140 boolean chMin = (getMinimum() != v.getMinimum());
141 boolean chMax = (getMaximum() != v.getMaximum());
142 boolean chVal = (getValue() != v.getValue());
143
144
145 if (chMin || chMax || chVal) {
146 rangedValue=new RangedValue(v.getMinimum(),v.getMaximum(),v.getValue());
147 }
148
149 boolean chRaw= raw!=rawValue;
150 if (chRaw) {
151 rawValue=raw;
152 }
153
154
155 fireValueChange(chMin, chMax, chVal, chRaw);
156
157 }
158
159
160
161
162
163
164 public RangedValue getRangedValue() {
165 if (rangedValue==null) {
166 rangedValue= new RangedValue();
167 }
168 return rangedValue;
169 }
170
171
172
173
174
175
176
177
178
179 public double getMinimum()
180 {
181 return getRangedValue().getMinimum();
182 }
183
184
185
186
187
188
189
190
191
192 public double getMaximum()
193 {
194 return getRangedValue().getMaximum();
195 }
196
197
198
199
200
201
202
203
204 public double getValue()
205 {
206 return getRangedValue().getValue();
207 }
208
209
210
211
212
213
214
215
216
217
218
219
220
221 public void setValue(double value)
222 {
223 setValue(getMinimum(), getMaximum(), value);
224 }
225
226
227
228
229
230
231
232
233
234
235
236
237 public void setMinimum(double value)
238 {
239 setValue(value, getMaximum(), getValue());
240 }
241
242
243
244
245
246
247
248
249
250
251
252
253 public void setMaximum(double value)
254 {
255 setValue(getMinimum(), value, getValue());
256 }
257
258
259
260
261
262
263 public RangedValue validatePolicies(RangedValue values)
264 {
265
266 if (policy!=null) {
267 values = policy.validate(values);
268 }
269
270
271 return TrimValuePolicy.trim(values);
272
273 }
274
275
276
277
278
279
280
281
282
283
284
285
286 public synchronized void setValue(double minimum, double maximum,
287 double value)
288 {
289 setRangedValue(new RangedValue(minimum,maximum,value));
290 }
291
292
293
294
295
296
297 protected void fireValueChange(RangedValueEvent event)
298 {
299 if (event == null) {
300 return;
301 }
302
303 synchronized (this) {
304 final int n = listeners.size();
305
306 for (int i = 0; i < n; i++) {
307 (listeners.get(i)).valueChanged(event);
308 }
309 }
310 }
311
312 protected void fireValueChange(boolean min, boolean max, boolean val, boolean raw)
313 {
314 if (min || max || val || raw) {
315 RangedValueEvent event = new RangedValueEvent(this, min, max, val, raw);
316 fireValueChange(event);
317 }
318 }
319
320 protected void firePolicyAdded()
321 {
322 fireValueChange(new RangedValueEvent(this, true));
323 }
324
325 protected void firePolicyRemoved()
326 {
327 fireValueChange(new RangedValueEvent(this, false));
328 }
329
330
331
332
333
334
335
336 public synchronized void setPolicy(RangedValuePolicy policy)
337 {
338 this.policy= policy;
339
340 firePolicyAdded();
341 }
342
343
344
345
346
347
348 public void addRangedValueListener(RangedValueListener listener)
349 {
350 if (listener == null) {
351 return;
352 }
353
354 if (listeners.contains(listener)) {
355 return;
356 }
357
358 synchronized (listeners) {
359 listeners.add(listener);
360 }
361 }
362
363
364
365
366
367
368 public void removeRangedValueListener(RangedValueListener listener)
369 {
370 if (listener == null) {
371 return;
372 }
373
374 synchronized (listeners) {
375 listeners.remove(listener);
376 }
377 }
378
379
380
381
382
383
384 public synchronized double getRelativeValue()
385 {
386 if (scalingFactor==1.0) {
387 return getRange().toRelative(getValue(),getRangedValue());
388 }
389 return getRange().toRelative(getValue(),getRangedValue())*scalingFactor;
390 }
391
392
393
394
395
396
397 public void setRelativeValue(double value)
398 {
399 if (scalingFactor==1.0) {
400 setValue(getRange().toAbsolute(value,getRangedValue()));
401 } else {
402 setValue(getRange().toAbsolute(value/scalingFactor,getRangedValue()));
403 }
404 }
405
406
407
408
409
410
411 public double getRawValue() {
412 return rawValue;
413 }
414
415
416
417
418
419
420
421
422 public double validate(double value) {
423 double v= getRange().validate(value);
424 RangedValue val= new RangedValue(getMinimum(),getMaximum(),v);
425 val = validatePolicies(val);
426 return val.getValue();
427 }
428
429
430
431
432
433
434 public double getScalingFactor() {
435 return scalingFactor;
436 }
437
438
439
440
441
442
443 public void setScalingFactor(double scalingFactor) {
444 this.scalingFactor = scalingFactor;
445 }
446
447
448
449
450
451
452 public RangedValuePolicy getPolicy() {
453 return policy;
454 }
455
456
457
458
459
460
461 public synchronized void addPolicy(RangedValuePolicy p) {
462 if (p==null) return;
463
464 if (policy==null) {
465 policy=p;
466 } else {
467 policy.addPeerPolicy(p);
468 }
469
470 setRangedValue(new RangedValue(getMinimum(),getMaximum(),getRawValue()));
471
472 firePolicyAdded();
473 }
474
475
476
477
478
479
480 public void removePolicy(RangedValuePolicy p) {
481 if (p==null) {
482 return;
483 }
484 if (policy!=null) {
485 RangedValuePolicy pp= policy;
486 policy= policy.removePeerPolicy(p);
487 if (pp!=policy) {
488 setRangedValue(new RangedValue(getMinimum(),getMaximum(),getRawValue()));
489 firePolicyAdded();
490 }
491 }
492 }
493
494
495
496
497
498
499 public void removePolicyByType(Class<? extends RangedValuePolicy> c) {
500 if (c==null) {
501 return;
502 }
503 if (policy!=null) {
504 RangedValuePolicy pp= policy;
505 policy= policy.removePeerPolicyByType(c);
506 if (pp!=policy) {
507 setRangedValue(new RangedValue(getMinimum(),getMaximum(),getRawValue()));
508 firePolicyAdded();
509 }
510 }
511 }
512
513
514
515
516
517
518
519
520 public double toRelative(double d) {
521 if (scalingFactor==1.0) {
522 return getRange().toRelative(d,getRangedValue());
523 }
524 return getRange().toRelative(d, getRangedValue())*scalingFactor;
525 }
526
527
528
529
530
531
532
533
534 public Tick[] calculateTicks(int w, TickParameters measurer) {
535 if (tickCalculator != null) {
536 lastTicksUsed = tickCalculator.calculateTicks(w, measurer, getRange(), getRangedValue());
537 } else {
538 lastTicksUsed = getRange().getDefaultTickCalculator().calculateTicks(w, measurer, getRange(), getRangedValue());
539 }
540 return lastTicksUsed;
541 }
542
543
544
545
546
547
548
549
550 public double toAbsolute(double proportional) {
551 if (scalingFactor==1.0) {
552 return getRange().toAbsolute(proportional,getRangedValue());
553 }
554 return getRange().toAbsolute(proportional/scalingFactor, getRangedValue());
555 }
556
557
558
559
560
561
562
563 public Tick[] calculateTicks(int width) {
564 if (tickCalculator != null) {
565 lastTicksUsed = tickCalculator.calculateTicks(width, getRange(), getRangedValue());
566 } else {
567 lastTicksUsed = getRange().getDefaultTickCalculator().calculateTicks(width, getRange(), getRangedValue());
568 }
569 return lastTicksUsed;
570 }
571
572
573
574
575
576
577
578
579 public void setTickCalculator(TickCalculator calculator) {
580 this.tickCalculator = calculator;
581 }
582
583
584
585
586
587
588
589
590 public TickCalculator getTickCalculator() {
591 return this.tickCalculator;
592 }
593
594
595
596
597
598
599
600 public void setSnapToTicks(boolean snapToTicks) {
601 if (this.snapToTicks == snapToTicks) return;
602 this.snapToTicks = snapToTicks;
603 setValue(getValue());
604 }
605
606
607
608
609
610
611
612 public boolean isSnapToTicks() {
613 return snapToTicks;
614 }
615
616 }
617
618