1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package de.jaret.util.ui.timebars.swt.renderer;
21
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import org.eclipse.swt.graphics.GC;
26 import org.eclipse.swt.graphics.Point;
27 import org.eclipse.swt.graphics.Rectangle;
28 import org.eclipse.swt.printing.Printer;
29
30 import de.jaret.util.date.Interval;
31 import de.jaret.util.date.JaretDate;
32 import de.jaret.util.date.holidayenumerator.HolidayEnumerator;
33 import de.jaret.util.date.iterator.DateIterator;
34 import de.jaret.util.date.iterator.DayIterator;
35 import de.jaret.util.date.iterator.HourIterator;
36 import de.jaret.util.date.iterator.MillisecondIterator;
37 import de.jaret.util.date.iterator.MinuteIterator;
38 import de.jaret.util.date.iterator.MonthIterator;
39 import de.jaret.util.date.iterator.SecondIterator;
40 import de.jaret.util.date.iterator.WeekIterator;
41 import de.jaret.util.date.iterator.YearIterator;
42 import de.jaret.util.swt.SwtGraphicsHelper;
43 import de.jaret.util.ui.timebars.TimeBarViewerDelegate;
44 import de.jaret.util.ui.timebars.TimeBarViewerInterface;
45 import de.jaret.util.ui.timebars.model.PPSInterval;
46 import de.jaret.util.ui.timebars.strategy.ITickProvider;
47 import de.jaret.util.ui.timebars.swt.TimeBarViewer;
48
49
50
51
52
53
54
55
56
57 public class BoxTimeScaleRenderer extends RendererBase implements TimeScaleRenderer, ITickProvider {
58
59 private static final int DEFAULT_NUMBER_OF_STRIPS = 3;
60
61
62 protected static final int BOXHEIGHT = 20;
63
64
65 protected static final int ADDITIONALGAP = 7;
66
67
68 protected static final int GAP = 3;
69
70
71 protected static final int SETBONUS = 5;
72
73
74 protected int _textHeight = -1;
75
76
77 protected int _numberOfStrips = DEFAULT_NUMBER_OF_STRIPS;
78
79
80 private double _lastPPS = -1;
81
82
83 protected HolidayEnumerator _holidayEnumerator;
84
85
86 protected List<DateIterator> _iterators;
87
88
89 protected List<DateIterator.Format> _formats;
90
91
92 protected List<Boolean> _enable;
93
94
95 protected List<JaretDate> _majorTicks;
96
97 protected List<JaretDate> _minorTicks;
98
99
100
101
102
103
104 public BoxTimeScaleRenderer(Printer printer) {
105 super(printer);
106 initIterators();
107 }
108
109
110
111
112 private void initIterators() {
113 _iterators = new ArrayList<DateIterator>();
114 _formats = new ArrayList<DateIterator.Format>();
115 _enable = new ArrayList<Boolean>();
116
117 _iterators.add(new MillisecondIterator(100));
118 _formats.add(DateIterator.Format.LONG);
119 _enable.add(true);
120
121 _iterators.add(new MillisecondIterator(500));
122 _formats.add(DateIterator.Format.LONG);
123 _enable.add(true);
124
125 _iterators.add(new SecondIterator(1));
126 _formats.add(DateIterator.Format.LONG);
127 _enable.add(true);
128
129 _iterators.add(new SecondIterator(5));
130 _formats.add(DateIterator.Format.LONG);
131 _enable.add(true);
132
133 _iterators.add(new SecondIterator(30));
134 _formats.add(DateIterator.Format.LONG);
135 _enable.add(true);
136
137 _iterators.add(new MinuteIterator(1));
138 _formats.add(DateIterator.Format.LONG);
139 _enable.add(true);
140
141 _iterators.add(new MinuteIterator(10));
142 _formats.add(DateIterator.Format.LONG);
143 _enable.add(true);
144
145 _iterators.add(new MinuteIterator(30));
146 _formats.add(DateIterator.Format.LONG);
147 _enable.add(true);
148
149 _iterators.add(new HourIterator(3));
150 _formats.add(DateIterator.Format.LONG);
151 _enable.add(true);
152
153 _iterators.add(new HourIterator(12));
154 _formats.add(DateIterator.Format.LONG);
155 _enable.add(true);
156
157 _iterators.add(new DayIterator());
158 _formats.add(DateIterator.Format.LONG);
159 _enable.add(true);
160
161 _iterators.add(new WeekIterator());
162 _formats.add(DateIterator.Format.LONG);
163 _enable.add(true);
164
165 _iterators.add(new MonthIterator());
166 _formats.add(DateIterator.Format.LONG);
167 _enable.add(true);
168
169 _iterators.add(new YearIterator());
170 _formats.add(DateIterator.Format.LONG);
171 _enable.add(true);
172 }
173
174
175
176
177 public BoxTimeScaleRenderer() {
178 super(null);
179 initIterators();
180 }
181
182
183
184
185
186
187 public void setHolidayEnumerator(HolidayEnumerator he) {
188 _holidayEnumerator = he;
189 }
190
191
192
193
194 public void draw(GC gc, Rectangle drawingArea, TimeBarViewerDelegate delegate, boolean top, boolean printing) {
195
196 if (_lastPPS != delegate.getPixelPerSecond()) {
197 checkStrips(gc, delegate, delegate.getStartDate());
198 _lastPPS = delegate.getPixelPerSecond();
199 }
200 if (_textHeight == -1) {
201 Point p = gc.textExtent("Q");
202 _textHeight = p.y;
203 }
204
205 int lineWidth = gc.getLineWidth();
206 if (printing) {
207 gc.setLineWidth(getDefaultLineWidth());
208 }
209
210 _majorTicks = new ArrayList<JaretDate>();
211 _minorTicks = new ArrayList<JaretDate>();
212
213 if (!delegate.hasVariableXScale()) {
214
215 drawStrips(gc, drawingArea, delegate, top, printing, delegate.getStartDate().copy(), delegate
216 .getStartDate().copy().advanceSeconds(delegate.getSecondsDisplayed() + 1));
217 } else {
218
219 JaretDate startDate = delegate.getStartDate().copy();
220 JaretDate endDate = delegate.getStartDate().copy().advanceSeconds(delegate.getSecondsDisplayed() + 1);
221 List<Interval> ppsIntervals = delegate.getPpsRow().getIntervals(startDate, endDate);
222
223 if (ppsIntervals.size() == 0) {
224 drawStrips(gc, drawingArea, delegate, top, printing, delegate.getStartDate().copy(), delegate
225 .getStartDate().copy().advanceSeconds(delegate.getSecondsDisplayed() + 1));
226 } else {
227 JaretDate d = startDate.copy();
228 while (d.compareTo(endDate) < 0) {
229
230 checkStrips(gc, delegate, d);
231 PPSInterval ppsInterval = delegate.getPPSInterval(d);
232 JaretDate e;
233 if (ppsInterval != null) {
234 e = ppsInterval.getEnd();
235 } else {
236 PPSInterval nextInterval = delegate.nextPPSInterval(d);
237 if (nextInterval != null) {
238 e = nextInterval.getBegin();
239 } else {
240 e = endDate;
241 }
242 }
243 drawStrips(gc, drawingArea, delegate, top, printing, d, e);
244 d = e;
245 }
246 _lastPPS = -1;
247 }
248 }
249 gc.setLineWidth(lineWidth);
250 }
251
252
253
254
255
256
257
258
259
260
261
262
263 private void drawStrips(GC gc, Rectangle drawingArea, TimeBarViewerDelegate delegate, boolean top,
264 boolean printing, JaretDate startDate, JaretDate endDate) {
265 boolean horizontal = delegate.getOrientation().equals(TimeBarViewerInterface.Orientation.HORIZONTAL);
266
267 Rectangle clipSave = gc.getClipping();
268
269 if (horizontal) {
270
271 int sx = delegate.xForDate(startDate);
272 Rectangle destRect = new Rectangle(sx, drawingArea.y, delegate.xForDate(endDate) - sx, drawingArea.height);
273 gc.setClipping(destRect.intersection(clipSave));
274
275 int ox = drawingArea.x;
276 int basey = top ? drawingArea.y + drawingArea.height : drawingArea.y + scaleY(BOXHEIGHT);
277
278 int drawn = 0;
279
280 for (int i = 0; i < _iterators.size() && drawn < _numberOfStrips; i++) {
281 DateIterator it = _iterators.get(i);
282 if (_enable.get(i)) {
283 drawn++;
284 it.reInitialize(startDate, endDate.copy().advanceMillis(it.getApproxStepMilliSeconds()));
285 while (it.hasNextDate()) {
286 JaretDate d = it.getNextDate();
287 String label = it.getLabel(d, _formats.get(i));
288
289
290 if (drawn==1) {
291 _minorTicks.add(d);
292 } else if(drawn==2) {
293 _majorTicks.add(d);
294 }
295
296 int x = delegate.xForDate(d);
297 gc.drawLine(x, basey, x, basey - scaleY(BOXHEIGHT));
298 int yy = (scaleY(BOXHEIGHT) - _textHeight) / 2;
299 gc.drawString(label, x + scaleX(GAP), basey - yy - _textHeight);
300 }
301 if (top) {
302 gc.drawLine(ox, basey - scaleY(BOXHEIGHT), ox + drawingArea.width, basey - scaleY(BOXHEIGHT));
303 } else {
304 gc.drawLine(ox, basey, ox + drawingArea.width, basey);
305 }
306 basey = basey + (top ? -scaleY(BOXHEIGHT) : scaleY(BOXHEIGHT));
307 }
308 }
309 } else {
310
311
312 int sy = delegate.xForDate(startDate);
313 Rectangle destRect = new Rectangle(drawingArea.x, sy, drawingArea.width, delegate.xForDate(endDate) - sy);
314 gc.setClipping(destRect.intersection(clipSave));
315
316 int oy = drawingArea.y;
317 int basex = top ? drawingArea.x + drawingArea.width : drawingArea.x + scaleX(BOXHEIGHT);
318
319 int drawn = 0;
320
321 for (int i = 0; i < _iterators.size() && drawn < _numberOfStrips; i++) {
322 DateIterator it = _iterators.get(i);
323 if (_enable.get(i)) {
324 drawn++;
325 it.reInitialize(startDate, endDate.copy().advanceMillis(it.getApproxStepMilliSeconds()));
326 while (it.hasNextDate()) {
327 JaretDate d = it.getNextDate();
328 String label = it.getLabel(d, _formats.get(i));
329
330
331 if (drawn==1) {
332 _minorTicks.add(d);
333 } else if(drawn==2) {
334 _majorTicks.add(d);
335 }
336
337 int y = delegate.xForDate(d);
338 gc.drawLine(basex, y, basex - scaleX(BOXHEIGHT), y);
339 int xx = (scaleX(BOXHEIGHT) - _textHeight) / 2;
340 SwtGraphicsHelper.drawStringVertical(gc, label, basex - xx - _textHeight, y + scaleY(GAP));
341 }
342 if (top) {
343 gc.drawLine(basex - scaleX(BOXHEIGHT), oy, basex - scaleX(BOXHEIGHT), oy + drawingArea.height);
344 } else {
345 gc.drawLine(basex, oy, basex, oy + drawingArea.height);
346 }
347 basex = basex + (top ? -scaleX(BOXHEIGHT) : scaleX(BOXHEIGHT));
348 }
349 }
350 }
351 gc.setClipping(clipSave);
352 }
353
354
355
356
357
358
359
360
361 private void checkStrips(GC gc, TimeBarViewerDelegate delegate, JaretDate startDate) {
362 for (int i = 0; i < _iterators.size(); i++) {
363 DateIterator it = _iterators.get(i);
364 it.reInitialize(startDate, null);
365 if (it.previewNextDate() != null) {
366 JaretDate current = it.getNextDate();
367 JaretDate next = it.getNextDate();
368 int width = delegate.xForDate(next) - delegate.xForDate(current);
369 String label = it.getLabel(current, DateIterator.Format.LONG);
370 Point p = gc.textExtent(label);
371 int bonus = _enable.get(i) && _formats.get(i).equals(DateIterator.Format.LONG) ? SETBONUS : 0;
372 if (width > p.x + GAP + ADDITIONALGAP - bonus) {
373 _enable.set(i, true);
374 _formats.set(i, DateIterator.Format.LONG);
375 } else {
376 label = it.getLabel(current, DateIterator.Format.MEDIUM);
377 p = gc.textExtent(label);
378 bonus = _enable.get(i) && _formats.get(i).equals(DateIterator.Format.MEDIUM) ? SETBONUS : 0;
379 if (width > p.x + GAP + ADDITIONALGAP - bonus) {
380 _enable.set(i, true);
381 _formats.set(i, DateIterator.Format.MEDIUM);
382 } else {
383 label = it.getLabel(current, DateIterator.Format.SHORT);
384 p = gc.textExtent(label);
385 bonus = _enable.get(i) && _formats.get(i).equals(DateIterator.Format.SHORT) ? SETBONUS : 0;
386 if (width > p.x + GAP + ADDITIONALGAP - bonus) {
387 _enable.set(i, true);
388 _formats.set(i, DateIterator.Format.SHORT);
389 } else {
390 _enable.set(i, false);
391 }
392 }
393 }
394 } else {
395 _enable.set(i, false);
396 }
397 }
398
399 }
400
401
402
403
404 public String getToolTipText(TimeBarViewer tbv, Rectangle drawingArea, int x, int y) {
405 String str = null;
406 JaretDate date = tbv.dateForX(x);
407 str = date.toDisplayString();
408 if (_holidayEnumerator != null) {
409 if (_holidayEnumerator.isHoliday(date.getDate()) || _holidayEnumerator.isSpecialDay(date.getDate())) {
410 str += "\n" + _holidayEnumerator.getDayName(date.getDate());
411 }
412 }
413 return str;
414 }
415
416
417
418
419 public int getHeight() {
420 if (_printer == null) {
421 return _numberOfStrips * BOXHEIGHT;
422 } else {
423 return scaleY(_numberOfStrips * BOXHEIGHT);
424 }
425 }
426
427
428
429
430 public void dispose() {
431
432 }
433
434
435
436
437 public TimeScaleRenderer createPrintRenderer(Printer printer) {
438 return new BoxTimeScaleRenderer(printer);
439 }
440
441
442
443
444
445
446 public int getNumberOfStrips() {
447 return _numberOfStrips;
448 }
449
450
451
452
453
454
455 public void setNumberOfStrips(int numberOfStrips) {
456 _numberOfStrips = numberOfStrips;
457 }
458
459
460
461
462 public List<JaretDate> getMajorTicks(TimeBarViewerDelegate delegate) {
463 return _majorTicks;
464 }
465
466
467
468
469 public List<JaretDate> getMinorTicks(TimeBarViewerDelegate delegate) {
470 return _minorTicks;
471 }
472
473
474
475
476
477
478 public void setCorrectDST(boolean correctDST) {
479 for (DateIterator iterator : _iterators) {
480 iterator.setCorrectDST(correctDST);
481 }
482 }
483
484
485
486
487
488 public boolean supportsOptimizedScrolling() {
489 return true;
490 }
491
492 }