Fix time range synchronization issues
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / widgets / timegraph / widgets / TimeGraphScale.java
1 /*****************************************************************************
2 * Copyright (c) 2007, 2008 Intel Corporation, 2010, 2012 Ericsson.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Intel Corporation - Initial API and implementation
10 * Ruslan A. Scherbakov, Intel - Initial API and implementation
11 * Alvaro Sanchez-Leon - Updated for TMF
12 * Patrick Tasse - Refactoring
13 *
14 *****************************************************************************/
15
16 package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets;
17
18 import java.text.SimpleDateFormat;
19 import java.util.Calendar;
20 import java.util.Date;
21
22 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;
23 import org.eclipse.swt.SWT;
24 import org.eclipse.swt.events.MouseEvent;
25 import org.eclipse.swt.events.MouseListener;
26 import org.eclipse.swt.events.MouseMoveListener;
27 import org.eclipse.swt.events.PaintEvent;
28 import org.eclipse.swt.graphics.GC;
29 import org.eclipse.swt.graphics.Point;
30 import org.eclipse.swt.graphics.Rectangle;
31 import org.eclipse.swt.widgets.Composite;
32
33 /**
34 * Implementation of the scale for the time graph view.
35 *
36 * This goes above the "gantt chart" area.
37 *
38 * @version 1.0
39 * @author Alvaro Sanchez-Leon
40 * @author Patrick Tasse
41 */
42 public class TimeGraphScale extends TimeGraphBaseControl implements
43 MouseListener, MouseMoveListener {
44
45 /**
46 * Standard constructor
47 *
48 * @param parent
49 * The parent composite object
50 * @param colors
51 * The color scheme to use
52 */
53 public TimeGraphScale(Composite parent, TimeGraphColorScheme colors) {
54 super(parent, colors, SWT.NO_BACKGROUND | SWT.NO_FOCUS | SWT.DOUBLE_BUFFERED);
55 addMouseListener(this);
56 addMouseMoveListener(this);
57 }
58
59 private static final long SEC_IN_NS = 1000000000;
60 private static final long MIN_IN_NS = 60 * SEC_IN_NS;
61 private static final long HOUR_IN_NS = 60 * MIN_IN_NS;
62 private static final long DAY_IN_NS = 24 * HOUR_IN_NS;
63 private static final long MONTH_IN_NS = 31 * DAY_IN_NS; // upper limit
64 private static final long YEAR_IN_NS = 366 * DAY_IN_NS; // upper limit
65
66 private static final double LOG10_1 = Math.log10(1);
67 private static final double LOG10_2 = Math.log10(2);
68 private static final double LOG10_3 = Math.log10(3);
69 private static final double LOG10_5 = Math.log10(5);
70
71 private static final Calendar GREGORIAN_CALENDAR = Calendar.getInstance();
72
73 private ITimeDataProvider _timeProvider;
74 private int _dragState = 0;
75 private int _dragX0 = 0;
76 private int _dragX = 0;
77 private long _time0bak;
78 private long _time1bak;
79 private boolean _isInUpdate;
80 private final Rectangle _rect0 = new Rectangle(0, 0, 0, 0);
81 private int _height;
82
83 /**
84 * Assign the time provider for this scale
85 *
86 * @param timeProvider
87 * The provider to use
88 */
89 public void setTimeProvider(ITimeDataProvider timeProvider) {
90 _timeProvider = timeProvider;
91 }
92
93 private long _timeDelta;
94
95 @Override
96 public Point computeSize(int wHint, int hHint, boolean changed) {
97 return super.computeSize(wHint, _height, changed);
98 }
99
100 /**
101 * Set the height of the scale
102 *
103 * @param height
104 * The height to use
105 */
106 public void setHeight(int height) {
107 this._height = height;
108 }
109
110 private void calcTimeDelta(int width, double pixelsPerNanoSec) {
111 double minDelta = (pixelsPerNanoSec == 0) ? YEAR_IN_NS : width / pixelsPerNanoSec;
112 long unit = 1;
113 if (_timeProvider != null && _timeProvider.isCalendarFormat()) {
114 if (minDelta > 6 * MONTH_IN_NS) {
115 unit = YEAR_IN_NS;
116 } else if (minDelta > 3 * MONTH_IN_NS) {
117 unit = 6 * MONTH_IN_NS;
118 } else if (minDelta > 10 * DAY_IN_NS) {
119 unit = MONTH_IN_NS;
120 } else if (minDelta > 12 * HOUR_IN_NS) {
121 unit = DAY_IN_NS;
122 } else if (minDelta > 3 * HOUR_IN_NS) {
123 unit = 6 * HOUR_IN_NS;
124 } else if (minDelta > 30 * MIN_IN_NS) {
125 unit = HOUR_IN_NS;
126 } else if (minDelta > 10 * MIN_IN_NS) {
127 unit = 15 * MIN_IN_NS;
128 } else if (minDelta > 30 * SEC_IN_NS) {
129 unit = MIN_IN_NS;
130 } else if (minDelta > 20 * SEC_IN_NS) {
131 unit = 30 * SEC_IN_NS;
132 } else if (minDelta <= 1) {
133 _timeDelta = 1;
134 return;
135 }
136 }
137 double log = Math.log10(minDelta / unit);
138 long pow10 = (long) log;
139 double remainder = log - pow10;
140 if (remainder < LOG10_1) {
141 _timeDelta = (long) Math.pow(10, pow10) * unit;
142 } else if (remainder < LOG10_2) {
143 _timeDelta = 2 * (long) Math.pow(10, pow10) * unit;
144 } else if (remainder < LOG10_3 && unit >= HOUR_IN_NS && unit < YEAR_IN_NS) {
145 _timeDelta = 3 * (long) Math.pow(10, pow10) * unit;
146 } else if (remainder < LOG10_5) {
147 _timeDelta = 5 * (long) Math.pow(10, pow10) * unit;
148 } else {
149 _timeDelta = 10 * (long) Math.pow(10, pow10) * unit;
150 }
151 }
152
153 private static TimeDraw TIMEDRAW_NANOSEC = new TimeDrawNanosec();
154 private static TimeDraw TIMEDRAW_MICROSEC = new TimeDrawMicrosec();
155 private static TimeDraw TIMEDRAW_MILLISEC = new TimeDrawMillisec();
156 private static TimeDraw TIMEDRAW_SEC = new TimeDrawSec();
157 private static TimeDraw TIMEDRAW_ABS_NANOSEC = new TimeDrawAbsNanoSec();
158 private static TimeDraw TIMEDRAW_ABS_MICROSEC = new TimeDrawAbsMicroSec();
159 private static TimeDraw TIMEDRAW_ABS_MILLISEC = new TimeDrawAbsMillisec();
160 private static TimeDraw TIMEDRAW_ABS_SEC = new TimeDrawAbsSec();
161 private static TimeDraw TIMEDRAW_ABS_MIN = new TimeDrawAbsMin();
162 private static TimeDraw TIMEDRAW_ABS_HRS = new TimeDrawAbsHrs();
163 private static TimeDraw TIMEDRAW_ABS_DAY = new TimeDrawAbsDay();
164 private static TimeDraw TIMEDRAW_ABS_MONTH = new TimeDrawAbsMonth();
165 private static TimeDraw TIMEDRAW_ABS_YEAR = new TimeDrawAbsYear();
166
167 TimeDraw getTimeDraw(long timeDelta) {
168 TimeDraw timeDraw;
169 if (_timeProvider != null && _timeProvider.isCalendarFormat()) {
170 if (timeDelta >= YEAR_IN_NS) {
171 timeDraw = TIMEDRAW_ABS_YEAR;
172 } else if (timeDelta >= MONTH_IN_NS) {
173 timeDraw = TIMEDRAW_ABS_MONTH;
174 } else if (timeDelta >= DAY_IN_NS) {
175 timeDraw = TIMEDRAW_ABS_DAY;
176 } else if (timeDelta >= HOUR_IN_NS) {
177 timeDraw = TIMEDRAW_ABS_HRS;
178 } else if (timeDelta >= MIN_IN_NS) {
179 timeDraw = TIMEDRAW_ABS_MIN;
180 } else if (timeDelta >= SEC_IN_NS) {
181 timeDraw = TIMEDRAW_ABS_SEC;
182 } else if (timeDelta >= 1000000) {
183 timeDraw = TIMEDRAW_ABS_MILLISEC;
184 } else if (timeDelta >= 1000) {
185 timeDraw = TIMEDRAW_ABS_MICROSEC;
186 } else {
187 timeDraw = TIMEDRAW_ABS_NANOSEC;
188 }
189 return timeDraw;
190 }
191 if (timeDelta >= 1000000000) {
192 timeDraw = TIMEDRAW_SEC;
193 } else if (timeDelta >= 1000000) {
194 timeDraw = TIMEDRAW_MILLISEC;
195 } else if (timeDelta >= 1000) {
196 timeDraw = TIMEDRAW_MICROSEC;
197 } else {
198 timeDraw = TIMEDRAW_NANOSEC;
199 }
200 return timeDraw;
201 }
202
203 @Override
204 void paint(Rectangle rect, PaintEvent e) {
205
206 if (_isInUpdate || null == _timeProvider) {
207 return;
208 }
209
210 GC gc = e.gc;
211 gc.fillRectangle(rect);
212
213 long time0 = _timeProvider.getTime0();
214 long time1 = _timeProvider.getTime1();
215 long selectedTime = _timeProvider.getSelectedTime();
216 int leftSpace = _timeProvider.getNameSpace();
217 int timeSpace = _timeProvider.getTimeSpace();
218
219 gc.setBackground(_colors.getColor(TimeGraphColorScheme.TOOL_BACKGROUND));
220 gc.setForeground(_colors.getColor(TimeGraphColorScheme.TOOL_FOREGROUND));
221 Utils.init(_rect0, rect);
222
223 // draw top left area
224 _rect0.width = leftSpace;
225 _rect0.x += 4;
226 _rect0.width -= 4;
227 Rectangle absHeaderRect = new Rectangle(_rect0.x, _rect0.y, _rect0.width, _rect0.height);
228 _rect0.x -= 4;
229 _rect0.width += 4;
230
231 // prepare and draw right rect of the timescale
232 _rect0.x += leftSpace;
233 _rect0.width = rect.width - leftSpace;
234
235 // draw bottom border and erase all other area
236 gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width - 1,
237 rect.y + rect.height - 1);
238 _rect0.height--;
239 gc.fillRectangle(_rect0);
240
241 if (3 == _dragState && null != _timeProvider) {
242 // draw selected zoom region background
243 gc.setBackground(_colors.getBkColor(true, false, true));
244 if (_dragX0 < _dragX) {
245 gc.fillRectangle(new Rectangle(leftSpace + _dragX0, _rect0.y, _dragX - _dragX0, _rect0.height));
246 } else if (_dragX0 > _dragX) {
247 gc.fillRectangle(new Rectangle(leftSpace + _dragX, _rect0.y, _dragX0 - _dragX, _rect0.height));
248 }
249 }
250
251 if (time1 <= time0 || timeSpace < 2) {
252 return;
253 }
254
255 int numDigits = calculateDigits(time0, time1);
256
257 int labelWidth = gc.getCharWidth('0') * numDigits;
258 double pixelsPerNanoSec = (timeSpace <= RIGHT_MARGIN) ? 0 :
259 (double) (timeSpace - RIGHT_MARGIN) / (time1 - time0);
260 calcTimeDelta(labelWidth, pixelsPerNanoSec);
261
262 TimeDraw timeDraw = getTimeDraw(_timeDelta);
263
264 // draw selected zoom region lines
265 if (3 == _dragState && null != _timeProvider) {
266 gc.drawLine(leftSpace + _dragX0, rect.y, leftSpace + _dragX0, rect.y + rect.height);
267 gc.drawLine(leftSpace + _dragX, rect.y, leftSpace + _dragX, rect.y + rect.height);
268 }
269
270 if (_rect0.isEmpty()) {
271 return;
272 }
273
274 // draw selected time
275 int x = _rect0.x + (int) ((selectedTime - time0) * pixelsPerNanoSec);
276 if (x >= _rect0.x && x < _rect0.x + _rect0.width) {
277 gc.setForeground(_colors.getColor(TimeGraphColorScheme.SELECTED_TIME));
278 gc.drawLine(x, _rect0.y + _rect0.height - 6, x, _rect0.y
279 + _rect0.height);
280 gc.setForeground(_colors.getColor(TimeGraphColorScheme.TOOL_FOREGROUND));
281 }
282
283 // draw time scale ticks
284 _rect0.y = rect.y;
285 _rect0.height = rect.height - 4;
286 _rect0.width = labelWidth;
287
288 long time;
289 if (_timeProvider != null && _timeProvider.isCalendarFormat()) {
290 time = floorToCalendar(time0, _timeDelta);
291 } else {
292 time = (time0 / _timeDelta) * _timeDelta;
293 if (time != time0) {
294 time += _timeDelta;
295 }
296 }
297
298 int y = _rect0.y + _rect0.height;
299
300 if (_timeProvider != null && _timeProvider.isCalendarFormat()) {
301 timeDraw.drawAbsHeader(gc, time, absHeaderRect);
302 }
303
304 while (true) {
305 x = rect.x + leftSpace + (int) (Math.floor((time - time0) * pixelsPerNanoSec));
306 if (x >= rect.x + leftSpace + rect.width - _rect0.width) {
307 break;
308 }
309 if (x >= rect.x + leftSpace) {
310 gc.drawLine(x, y, x, y + 4);
311 _rect0.x = x;
312 if (x + _rect0.width <= rect.x + rect.width) {
313 timeDraw.draw(gc, time, _rect0);
314 }
315 }
316 if (pixelsPerNanoSec == 0 || time > Long.MAX_VALUE - _timeDelta || _timeDelta == 0) {
317 break;
318 }
319 if (_timeProvider != null && _timeProvider.isCalendarFormat()) {
320 if (_timeDelta >= YEAR_IN_NS) {
321 long millis = time / 1000000L;
322 GREGORIAN_CALENDAR.setTime(new Date(millis));
323 GREGORIAN_CALENDAR.add(Calendar.YEAR, (int) (_timeDelta / YEAR_IN_NS));
324 millis = GREGORIAN_CALENDAR.getTimeInMillis();
325 time = millis * 1000000L;
326 } else if (_timeDelta >= MONTH_IN_NS) {
327 long millis = time / 1000000L;
328 GREGORIAN_CALENDAR.setTime(new Date(millis));
329 GREGORIAN_CALENDAR.add(Calendar.MONTH, (int) (_timeDelta / MONTH_IN_NS));
330 millis = GREGORIAN_CALENDAR.getTimeInMillis();
331 time = millis * 1000000L;
332 } else if (_timeDelta >= DAY_IN_NS) {
333 long millis = time / 1000000L;
334 GREGORIAN_CALENDAR.setTime(new Date(millis));
335 GREGORIAN_CALENDAR.add(Calendar.DAY_OF_MONTH, (int) (_timeDelta / DAY_IN_NS));
336 millis = GREGORIAN_CALENDAR.getTimeInMillis();
337 time = millis * 1000000L;
338 } else {
339 time += _timeDelta;
340 }
341 } else {
342 time += _timeDelta;
343 }
344 }
345 }
346
347 private long floorToCalendar(long time, long timeDelta) {
348 if (_timeDelta >= YEAR_IN_NS) {
349 GREGORIAN_CALENDAR.setTime(new Date(time / 1000000));
350 int year = GREGORIAN_CALENDAR.get(Calendar.YEAR);
351 int yearDelta = (int) (timeDelta / YEAR_IN_NS);
352 year = (year / yearDelta) * yearDelta;
353 GREGORIAN_CALENDAR.set(Calendar.YEAR, year);
354 GREGORIAN_CALENDAR.set(Calendar.MONTH, 0); // January 1st of year
355 GREGORIAN_CALENDAR.set(Calendar.DAY_OF_MONTH, 1);
356 GREGORIAN_CALENDAR.set(Calendar.HOUR_OF_DAY, 0);
357 GREGORIAN_CALENDAR.set(Calendar.MINUTE, 0);
358 GREGORIAN_CALENDAR.set(Calendar.SECOND, 0);
359 GREGORIAN_CALENDAR.set(Calendar.MILLISECOND, 0);
360 time = GREGORIAN_CALENDAR.getTimeInMillis() * 1000000;
361 } else if (_timeDelta >= MONTH_IN_NS) {
362 GREGORIAN_CALENDAR.setTime(new Date(time / 1000000));
363 int month = GREGORIAN_CALENDAR.get(Calendar.MONTH);
364 int monthDelta = (int) (timeDelta / MONTH_IN_NS);
365 month = (month / monthDelta) * monthDelta;
366 GREGORIAN_CALENDAR.set(Calendar.MONTH, month);
367 GREGORIAN_CALENDAR.set(Calendar.DAY_OF_MONTH, 1); // 1st of month
368 GREGORIAN_CALENDAR.set(Calendar.HOUR_OF_DAY, 0);
369 GREGORIAN_CALENDAR.set(Calendar.MINUTE, 0);
370 GREGORIAN_CALENDAR.set(Calendar.SECOND, 0);
371 GREGORIAN_CALENDAR.set(Calendar.MILLISECOND, 0);
372 time = GREGORIAN_CALENDAR.getTimeInMillis() * 1000000;
373 } else {
374 long offset = GREGORIAN_CALENDAR.getTimeZone().getOffset(time / 1000000L) * 1000000L;
375 time += offset;
376 time = (time / timeDelta) * timeDelta;
377 time -= offset;
378 }
379 return time;
380 }
381
382 private int calculateDigits(long time0, long time1) {
383 int numDigits = 5;
384 long timeRange = time1 - time0;
385
386 if (_timeProvider.isCalendarFormat()) {
387 // Calculate the number of digits to represent the minutes provided
388 // 11:222
389 // HH:mm:ss
390 numDigits += 8;
391 if (timeRange < 10000) {
392 // HH:11:222:333:444__
393 numDigits += 10;
394 } else if (timeRange < 10000000) {
395 // HH:11:222:333__
396 numDigits += 6;
397 }
398 } else {
399 long sec = time1 / 1000000000;
400 numDigits = Long.toString(sec).length();
401 int thousandGroups = (numDigits - 1) / 3;
402 numDigits += thousandGroups;
403 numDigits += 12; // .000 000 000
404 }
405
406 return numDigits;
407 }
408
409 @Override
410 public void mouseDown(MouseEvent e) {
411 getParent().setFocus();
412 if (_dragState == 0 && null != _timeProvider) {
413 int x = e.x - _timeProvider.getNameSpace();
414 if (1 == e.button && x > 0) {
415 setCapture(true);
416 _dragState = 1;
417 } else if (3 == e.button) {
418 _dragState = 3;
419 }
420 if (x < 0) {
421 x = 0;
422 } else if (x > getSize().x - _timeProvider.getNameSpace()) {
423 x = getSize().x - _timeProvider.getNameSpace();
424 }
425 _dragX = _dragX0 = x;
426 _time0bak = _timeProvider.getTime0();
427 _time1bak = _timeProvider.getTime1();
428 }
429 }
430
431 @Override
432 public void mouseUp(MouseEvent e) {
433 if (e.button == 1 && _dragState == 1) {
434 setCapture(false);
435 _dragState = 0;
436
437 // Notify time provider to check the need for listener notification
438 if (_dragX != _dragX0 && _timeProvider.getTime0() != _timeProvider.getTime1()) {
439 _timeProvider.setStartFinishTimeNotify(_timeProvider.getTime0(), _timeProvider.getTime1());
440 }
441 } else if (e.button == 3 && _dragState == 3 && null != _timeProvider) {
442 _dragState = 0;
443 if (_dragX0 == _dragX || _timeProvider.getTime0() == _timeProvider.getTime1()) {
444 redraw();
445 return;
446 }
447 int timeSpace = _timeProvider.getTimeSpace();
448 int leftSpace = _timeProvider.getNameSpace();
449 int x = Math.max(0, e.x - leftSpace);
450 if (timeSpace > 0) {
451 _dragX = x;
452 if (_dragX0 > _dragX) { // drag right to left
453 _dragX = _dragX0;
454 _dragX0 = x;
455 }
456 long time0 = _time0bak + (long) ((_time1bak - _time0bak) * ((double) _dragX0 / timeSpace));
457 long time1 = _time0bak + (long) ((_time1bak - _time0bak) * ((double) _dragX / timeSpace));
458
459 _timeProvider.setStartFinishTimeNotify(time0, time1);
460 _time0bak = _timeProvider.getTime0();
461 _time1bak = _timeProvider.getTime1();
462 }
463 }
464 }
465
466 @Override
467 public void mouseMove(MouseEvent e) {
468 if (_dragX0 < 0 || _dragState == 0 || _timeProvider == null) {
469 return;
470 }
471 Point size = getSize();
472 int leftSpace = _timeProvider.getNameSpace();
473 int timeSpace = _timeProvider.getTimeSpace();
474 int x = e.x - leftSpace;
475 if (1 == _dragState) {
476 if (x > 0 && size.x > leftSpace && _dragX != x) {
477 _dragX = x;
478 if (_timeProvider.getTime0() == _timeProvider.getTime1()) {
479 return;
480 }
481 long interval = (long) ((_time1bak - _time0bak) * ((double) _dragX0 / _dragX));
482 if (interval == Long.MAX_VALUE) {
483 _timeProvider.setStartFinishTime(_time0bak, Long.MAX_VALUE);
484 } else {
485 long time1 = _time0bak + (long) ((_time1bak - _time0bak) * ((double) _dragX0 / _dragX));
486 _timeProvider.setStartFinishTime(_time0bak, time1);
487 }
488 }
489 } else if (3 == _dragState) {
490 if (x < 0) {
491 _dragX = 0;
492 } else if (x > timeSpace) {
493 _dragX = timeSpace;
494 } else {
495 _dragX = x;
496 }
497 redraw();
498 }
499 }
500
501 @Override
502 public void mouseDoubleClick(MouseEvent e) {
503 if (e.button == 1 && null != _timeProvider && _timeProvider.getTime0() != _timeProvider.getTime1() && (e.stateMask & SWT.BUTTON_MASK) == 0) {
504 _timeProvider.resetStartFinishTime();
505 _timeProvider.notifyStartFinishTime();
506 _time0bak = _timeProvider.getTime0();
507 _time1bak = _timeProvider.getTime1();
508 }
509 }
510 }
511
512 abstract class TimeDraw {
513 static String S = "" ; //$NON-NLS-1$
514 static String S0 = "0" ; //$NON-NLS-1$
515 static String S00 = "00"; //$NON-NLS-1$
516 protected static final SimpleDateFormat stimeformat = new SimpleDateFormat("HH:mm:ss"); //$NON-NLS-1$
517 protected static final SimpleDateFormat stimeformatheader = new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$
518 protected static final SimpleDateFormat sminformat = new SimpleDateFormat("HH:mm"); //$NON-NLS-1$
519 protected static final SimpleDateFormat sminformatheader = new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$
520 protected static final SimpleDateFormat shrsformat = new SimpleDateFormat("MMM dd HH:mm"); //$NON-NLS-1$
521 protected static final SimpleDateFormat shrsformatheader = new SimpleDateFormat("yyyy"); //$NON-NLS-1$
522 protected static final SimpleDateFormat sdayformat = new SimpleDateFormat("MMM dd"); //$NON-NLS-1$
523 protected static final SimpleDateFormat sdayformatheader = new SimpleDateFormat("yyyy"); //$NON-NLS-1$
524 protected static final SimpleDateFormat smonthformat = new SimpleDateFormat("yyyy MMM"); //$NON-NLS-1$
525 protected static final SimpleDateFormat syearformat = new SimpleDateFormat("yyyy"); //$NON-NLS-1$
526
527 static String sep(long n) {
528 StringBuilder retVal = new StringBuilder();
529 String s = Long.toString(n);
530 for (int i = 0; i < s.length(); i++) {
531 int pos = s.length() - i - 1;
532 retVal.append(s.charAt(i));
533 if (pos % 3 == 0 && pos != 0) {
534 retVal.append(' ');
535 }
536 }
537 return retVal.toString();
538 }
539
540 static String pad(long n) {
541 String s;
542 if (n < 10) {
543 s = S00;
544 } else if (n < 100) {
545 s = S0;
546 } else {
547 s = S;
548 }
549 return s + n;
550 }
551
552 public abstract void draw(GC gc, long time, Rectangle rect);
553
554 public void drawAbsHeader(GC gc, long time, Rectangle absHeaderRect) {
555 // Override to draw absolute time header
556 // This is for the time information not shown in the draw of each tick
557 }
558
559 public abstract String hint();
560 }
561
562 class TimeDrawSec extends TimeDraw {
563 static String _hint = "sec"; //$NON-NLS-1$
564
565 @Override
566 public void draw(GC gc, long time, Rectangle rect) {
567 time /= 1000000000;
568 Utils.drawText(gc, sep(time), rect, true);
569 }
570
571 @Override
572 public String hint() {
573 return _hint;
574 }
575 }
576
577 class TimeDrawMillisec extends TimeDraw {
578 static String _hint = "0.000"; //$NON-NLS-1$
579
580 @Override
581 public void draw(GC gc, long time, Rectangle rect) {
582 time /= 1000000;
583 long ms = time % 1000;
584 time /= 1000;
585 Utils.drawText(gc, sep(time) + "." + pad(ms), rect, true); //$NON-NLS-1$
586 }
587
588 @Override
589 public String hint() {
590 return _hint;
591 }
592 }
593
594 class TimeDrawMicrosec extends TimeDraw {
595 static String _hint = "0.000 000"; //$NON-NLS-1$
596
597 @Override
598 public void draw(GC gc, long time, Rectangle rect) {
599 time /= 1000;
600 long mcs = time % 1000;
601 time /= 1000;
602 long ms = time % 1000;
603 time /= 1000;
604 Utils.drawText(gc, sep(time) + "." + pad(ms) + " " + pad(mcs), rect, true); //$NON-NLS-1$ //$NON-NLS-2$
605 }
606
607 @Override
608 public String hint() {
609 return _hint;
610 }
611 }
612
613 class TimeDrawNanosec extends TimeDraw {
614 static String _hint = "0.000 000 000"; //$NON-NLS-1$
615
616 @Override
617 public void draw(GC gc, long time, Rectangle rect) {
618 long ns = time % 1000;
619 time /= 1000;
620 long mcs = time % 1000;
621 time /= 1000;
622 long ms = time % 1000;
623 time /= 1000;
624 Utils.drawText(gc, sep(time) + "." + pad(ms) + " " + pad(mcs) + " " + pad(ns), rect, true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
625 }
626
627 @Override
628 public String hint() {
629 return _hint;
630 }
631 }
632
633 class TimeDrawAbsYear extends TimeDraw {
634 static String _hint = "YYYY"; //$NON-NLS-1$
635
636 @Override
637 public void draw(GC gc, long time, Rectangle rect) {
638 String stime = syearformat.format(new Date(time / 1000000));
639 Utils.drawText(gc, stime, rect, true);
640 }
641
642 @Override
643 public String hint() {
644 return _hint;
645 }
646 }
647
648 class TimeDrawAbsMonth extends TimeDraw {
649 static String _hint = "YYYY Mmm"; //$NON-NLS-1$
650
651 @Override
652 public void draw(GC gc, long time, Rectangle rect) {
653 String stime = smonthformat.format(new Date(time / 1000000));
654 Utils.drawText(gc, stime, rect, true);
655 }
656
657 @Override
658 public String hint() {
659 return _hint;
660 }
661 }
662
663 class TimeDrawAbsDay extends TimeDraw {
664 static String _hint = "Mmm dd"; //$NON-NLS-1$
665
666 @Override
667 public void draw(GC gc, long time, Rectangle rect) {
668 String stime = sdayformat.format(new Date(time / 1000000));
669 Utils.drawText(gc, stime, rect, true);
670 }
671
672 @Override
673 public void drawAbsHeader(GC gc, long time, Rectangle rect) {
674 String header = sdayformatheader.format(new Date(time / 1000000));
675 int headerwidth = gc.stringExtent(header).x + 4;
676 if (headerwidth <= rect.width) {
677 rect.x += (rect.width - headerwidth);
678 Utils.drawText(gc, header, rect, true);
679 }
680 }
681
682 @Override
683 public String hint() {
684 return _hint;
685 }
686 }
687
688 class TimeDrawAbsHrs extends TimeDraw {
689 static String _hint = "Mmm dd HH:mm"; //$NON-NLS-1$
690
691 @Override
692 public void draw(GC gc, long time, Rectangle rect) {
693 String stime = shrsformat.format(new Date(time / 1000000));
694 Utils.drawText(gc, stime, rect, true);
695 }
696
697 @Override
698 public void drawAbsHeader(GC gc, long time, Rectangle rect) {
699 String header = shrsformatheader.format(new Date(time / 1000000));
700 int headerwidth = gc.stringExtent(header).x + 4;
701 if (headerwidth <= rect.width) {
702 rect.x += (rect.width - headerwidth);
703 Utils.drawText(gc, header, rect, true);
704 }
705 }
706
707 @Override
708 public String hint() {
709 return _hint;
710 }
711 }
712
713 class TimeDrawAbsMin extends TimeDraw {
714 static String _hint = "HH:mm"; //$NON-NLS-1$
715
716 @Override
717 public void draw(GC gc, long time, Rectangle rect) {
718 String stime = sminformat.format(new Date(time / 1000000));
719 Utils.drawText(gc, stime, rect, true);
720 }
721
722 @Override
723 public void drawAbsHeader(GC gc, long time, Rectangle rect) {
724 String header = sminformatheader.format(new Date(time / 1000000));
725 int headerwidth = gc.stringExtent(header).x + 4;
726 if (headerwidth <= rect.width) {
727 rect.x += (rect.width - headerwidth);
728 Utils.drawText(gc, header, rect, true);
729 }
730 }
731
732
733 @Override
734 public String hint() {
735 return _hint;
736 }
737 }
738
739 class TimeDrawAbsSec extends TimeDraw {
740 static String _hint = "HH:mm:ss"; //$NON-NLS-1$
741
742 @Override
743 public void draw(GC gc, long time, Rectangle rect) {
744 String stime = stimeformat.format(new Date(time / 1000000));
745 Utils.drawText(gc, stime, rect, true);
746 }
747
748 @Override
749 public void drawAbsHeader(GC gc, long time, Rectangle rect) {
750 String header = stimeformatheader.format(new Date(time / 1000000));
751 int headerwidth = gc.stringExtent(header).x + 4;
752 if (headerwidth <= rect.width) {
753 rect.x += (rect.width - headerwidth);
754 Utils.drawText(gc, header, rect, true);
755 }
756 }
757
758 @Override
759 public String hint() {
760 return _hint;
761 }
762 }
763
764 class TimeDrawAbsMillisec extends TimeDraw {
765 static String _hint = "HH:ss:ms"; //$NON-NLS-1$
766
767 @Override
768 public void draw(GC gc, long time, Rectangle rect) {
769 String stime = stimeformat.format(new Date(time / 1000000));
770 String ns = Utils.formatNs(time, Resolution.MILLISEC);
771
772 Utils.drawText(gc, stime + "." + ns, rect, true); //$NON-NLS-1$
773 }
774
775 @Override
776 public void drawAbsHeader(GC gc, long time, Rectangle rect) {
777 String header = stimeformatheader.format(new Date(time / 1000000));
778 int headerwidth = gc.stringExtent(header).x + 4;
779 if (headerwidth <= rect.width) {
780 rect.x += (rect.width - headerwidth);
781 Utils.drawText(gc, header, rect, true);
782 }
783 }
784
785 @Override
786 public String hint() {
787 return _hint;
788 }
789 }
790
791 class TimeDrawAbsMicroSec extends TimeDraw {
792 static String _hint = "HH:ss:ms:mcs"; //$NON-NLS-1$
793
794 @Override
795 public void draw(GC gc, long time, Rectangle rect) {
796 String stime = stimeformat.format(new Date(time / 1000000));
797 String micr = Utils.formatNs(time, Resolution.MICROSEC);
798 Utils.drawText(gc, stime + "." + micr, rect, true); //$NON-NLS-1$
799 }
800
801 @Override
802 public void drawAbsHeader(GC gc, long time, Rectangle rect) {
803 String header = stimeformatheader.format(new Date(time / 1000000));
804 int headerwidth = gc.stringExtent(header).x + 4;
805 if (headerwidth <= rect.width) {
806 rect.x += (rect.width - headerwidth);
807 Utils.drawText(gc, header, rect, true);
808 }
809 }
810
811 @Override
812 public String hint() {
813 return _hint;
814 }
815 }
816
817 class TimeDrawAbsNanoSec extends TimeDraw {
818 static String _hint = "HH:ss:ms:mcs:ns"; //$NON-NLS-1$
819
820 @Override
821 public void draw(GC gc, long time, Rectangle rect) {
822 String stime = stimeformat.format(new Date(time / 1000000));
823 String ns = Utils.formatNs(time, Resolution.NANOSEC);
824 Utils.drawText(gc, stime + "." + ns, rect, true); //$NON-NLS-1$
825 }
826
827 @Override
828 public void drawAbsHeader(GC gc, long time, Rectangle rect) {
829 String header = stimeformatheader.format(new Date(time / 1000000));
830 int headerwidth = gc.stringExtent(header).x + 4;
831 if (headerwidth <= rect.width) {
832 rect.x += (rect.width - headerwidth);
833 Utils.drawText(gc, header, rect, true);
834 }
835 }
836
837 @Override
838 public String hint() {
839 return _hint;
840 }
841 }
This page took 0.04978 seconds and 5 git commands to generate.