1 /*****************************************************************************
2 * Copyright (c) 2007, 2013 Intel Corporation, 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
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 *****************************************************************************/
15 package org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
;
17 import java
.text
.NumberFormat
;
18 import java
.text
.SimpleDateFormat
;
19 import java
.util
.Calendar
;
20 import java
.util
.Date
;
22 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.Resolution
;
23 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
24 import org
.eclipse
.swt
.SWT
;
25 import org
.eclipse
.swt
.events
.MouseEvent
;
26 import org
.eclipse
.swt
.events
.MouseListener
;
27 import org
.eclipse
.swt
.events
.MouseMoveListener
;
28 import org
.eclipse
.swt
.events
.PaintEvent
;
29 import org
.eclipse
.swt
.graphics
.GC
;
30 import org
.eclipse
.swt
.graphics
.Point
;
31 import org
.eclipse
.swt
.graphics
.Rectangle
;
32 import org
.eclipse
.swt
.widgets
.Composite
;
35 * Implementation of the scale for the time graph view.
37 * This goes above the "gantt chart" area.
40 * @author Alvaro Sanchez-Leon
41 * @author Patrick Tasse
43 public class TimeGraphScale
extends TimeGraphBaseControl
implements
44 MouseListener
, MouseMoveListener
{
47 * Standard constructor
50 * The parent composite object
52 * The color scheme to use
54 public TimeGraphScale(Composite parent
, TimeGraphColorScheme colors
) {
55 super(parent
, colors
, SWT
.NO_BACKGROUND
| SWT
.NO_FOCUS
| SWT
.DOUBLE_BUFFERED
);
56 addMouseListener(this);
57 addMouseMoveListener(this);
60 private static final long SEC_IN_NS
= 1000000000;
61 private static final long MIN_IN_NS
= 60 * SEC_IN_NS
;
62 private static final long HOUR_IN_NS
= 60 * MIN_IN_NS
;
63 private static final long DAY_IN_NS
= 24 * HOUR_IN_NS
;
64 private static final long MONTH_IN_NS
= 31 * DAY_IN_NS
; // upper limit
65 private static final long YEAR_IN_NS
= 366 * DAY_IN_NS
; // upper limit
67 private static final double LOG10_1
= Math
.log10(1);
68 private static final double LOG10_2
= Math
.log10(2);
69 private static final double LOG10_3
= Math
.log10(3);
70 private static final double LOG10_5
= Math
.log10(5);
72 private static final Calendar GREGORIAN_CALENDAR
= Calendar
.getInstance();
74 private ITimeDataProvider _timeProvider
;
75 private int _dragState
= 0;
76 private int _dragX0
= 0;
77 private int _dragX
= 0;
78 private long _time0bak
;
79 private long _time1bak
;
80 private boolean _isInUpdate
;
81 private final Rectangle _rect0
= new Rectangle(0, 0, 0, 0);
85 * Assign the time provider for this scale
90 public void setTimeProvider(ITimeDataProvider timeProvider
) {
91 _timeProvider
= timeProvider
;
94 private long _timeDelta
;
97 public Point
computeSize(int wHint
, int hHint
, boolean changed
) {
98 return super.computeSize(wHint
, _height
, changed
);
102 * Set the height of the scale
107 public void setHeight(int height
) {
108 this._height
= height
;
111 private void calcTimeDelta(int width
, double pixelsPerNanoSec
) {
112 double minDelta
= (pixelsPerNanoSec
== 0) ? YEAR_IN_NS
: width
/ pixelsPerNanoSec
;
114 if (_timeProvider
!= null && _timeProvider
.getTimeFormat().equals(TimeFormat
.CALENDAR
)) {
115 if (minDelta
> 6 * MONTH_IN_NS
) {
117 } else if (minDelta
> 3 * MONTH_IN_NS
) {
118 unit
= 6 * MONTH_IN_NS
;
119 } else if (minDelta
> 10 * DAY_IN_NS
) {
121 } else if (minDelta
> 12 * HOUR_IN_NS
) {
123 } else if (minDelta
> 3 * HOUR_IN_NS
) {
124 unit
= 6 * HOUR_IN_NS
;
125 } else if (minDelta
> 30 * MIN_IN_NS
) {
127 } else if (minDelta
> 10 * MIN_IN_NS
) {
128 unit
= 15 * MIN_IN_NS
;
129 } else if (minDelta
> 30 * SEC_IN_NS
) {
131 } else if (minDelta
> 20 * SEC_IN_NS
) {
132 unit
= 30 * SEC_IN_NS
;
133 } else if (minDelta
<= 1) {
138 double log
= Math
.log10(minDelta
/ unit
);
139 long pow10
= (long) log
;
140 double remainder
= log
- pow10
;
141 if (remainder
< LOG10_1
) {
142 _timeDelta
= (long) Math
.pow(10, pow10
) * unit
;
143 } else if (remainder
< LOG10_2
) {
144 _timeDelta
= 2 * (long) Math
.pow(10, pow10
) * unit
;
145 } else if (remainder
< LOG10_3
&& unit
>= HOUR_IN_NS
&& unit
< YEAR_IN_NS
) {
146 _timeDelta
= 3 * (long) Math
.pow(10, pow10
) * unit
;
147 } else if (remainder
< LOG10_5
) {
148 _timeDelta
= 5 * (long) Math
.pow(10, pow10
) * unit
;
150 _timeDelta
= 10 * (long) Math
.pow(10, pow10
) * unit
;
157 private static TimeDraw TIMEDRAW_NANOSEC
= new TimeDrawNanosec();
158 private static TimeDraw TIMEDRAW_MICROSEC
= new TimeDrawMicrosec();
159 private static TimeDraw TIMEDRAW_MILLISEC
= new TimeDrawMillisec();
160 private static TimeDraw TIMEDRAW_SEC
= new TimeDrawSec();
161 private static TimeDraw TIMEDRAW_ABS_NANOSEC
= new TimeDrawAbsNanoSec();
162 private static TimeDraw TIMEDRAW_ABS_MICROSEC
= new TimeDrawAbsMicroSec();
163 private static TimeDraw TIMEDRAW_ABS_MILLISEC
= new TimeDrawAbsMillisec();
164 private static TimeDraw TIMEDRAW_ABS_SEC
= new TimeDrawAbsSec();
165 private static TimeDraw TIMEDRAW_ABS_MIN
= new TimeDrawAbsMin();
166 private static TimeDraw TIMEDRAW_ABS_HRS
= new TimeDrawAbsHrs();
167 private static TimeDraw TIMEDRAW_ABS_DAY
= new TimeDrawAbsDay();
168 private static TimeDraw TIMEDRAW_ABS_MONTH
= new TimeDrawAbsMonth();
169 private static TimeDraw TIMEDRAW_ABS_YEAR
= new TimeDrawAbsYear();
170 private static TimeDraw TIMEDRAW_NUMBER
= new TimeDrawNumber();
172 TimeDraw
getTimeDraw(long timeDelta
) {
174 if (_timeProvider
!= null) {
176 if (_timeProvider
.getTimeFormat() == TimeFormat
.CALENDAR
) {
177 if (timeDelta
>= YEAR_IN_NS
) {
178 timeDraw
= TIMEDRAW_ABS_YEAR
;
179 } else if (timeDelta
>= MONTH_IN_NS
) {
180 timeDraw
= TIMEDRAW_ABS_MONTH
;
181 } else if (timeDelta
>= DAY_IN_NS
) {
182 timeDraw
= TIMEDRAW_ABS_DAY
;
183 } else if (timeDelta
>= HOUR_IN_NS
) {
184 timeDraw
= TIMEDRAW_ABS_HRS
;
185 } else if (timeDelta
>= MIN_IN_NS
) {
186 timeDraw
= TIMEDRAW_ABS_MIN
;
187 } else if (timeDelta
>= SEC_IN_NS
) {
188 timeDraw
= TIMEDRAW_ABS_SEC
;
189 } else if (timeDelta
>= 1000000) {
190 timeDraw
= TIMEDRAW_ABS_MILLISEC
;
191 } else if (timeDelta
>= 1000) {
192 timeDraw
= TIMEDRAW_ABS_MICROSEC
;
194 timeDraw
= TIMEDRAW_ABS_NANOSEC
;
197 } else if (_timeProvider
.getTimeFormat() == TimeFormat
.NUMBER
) {
198 timeDraw
= TIMEDRAW_NUMBER
;
203 if (timeDelta
>= 1000000000) {
204 timeDraw
= TIMEDRAW_SEC
;
205 } else if (timeDelta
>= 1000000) {
206 timeDraw
= TIMEDRAW_MILLISEC
;
207 } else if (timeDelta
>= 1000) {
208 timeDraw
= TIMEDRAW_MICROSEC
;
210 timeDraw
= TIMEDRAW_NANOSEC
;
216 void paint(Rectangle rect
, PaintEvent e
) {
218 if (_isInUpdate
|| null == _timeProvider
) {
223 gc
.fillRectangle(rect
);
225 long time0
= _timeProvider
.getTime0();
226 long time1
= _timeProvider
.getTime1();
227 long selectedTime
= _timeProvider
.getSelectedTime();
228 int leftSpace
= _timeProvider
.getNameSpace();
229 int timeSpace
= _timeProvider
.getTimeSpace();
231 gc
.setBackground(_colors
.getColor(TimeGraphColorScheme
.TOOL_BACKGROUND
));
232 gc
.setForeground(_colors
.getColor(TimeGraphColorScheme
.TOOL_FOREGROUND
));
233 Utils
.init(_rect0
, rect
);
235 // draw top left area
236 _rect0
.width
= leftSpace
;
239 Rectangle absHeaderRect
= new Rectangle(_rect0
.x
, _rect0
.y
, _rect0
.width
, _rect0
.height
);
243 // prepare and draw right rect of the timescale
244 _rect0
.x
+= leftSpace
;
245 _rect0
.width
= rect
.width
- leftSpace
;
247 // draw bottom border and erase all other area
248 gc
.drawLine(rect
.x
, rect
.y
+ rect
.height
- 1, rect
.x
+ rect
.width
- 1,
249 rect
.y
+ rect
.height
- 1);
251 gc
.fillRectangle(_rect0
);
253 if (3 == _dragState
&& null != _timeProvider
) {
254 // draw selected zoom region background
255 gc
.setBackground(_colors
.getBkColor(true, false, true));
256 if (_dragX0
< _dragX
) {
257 gc
.fillRectangle(new Rectangle(leftSpace
+ _dragX0
, _rect0
.y
, _dragX
- _dragX0
, _rect0
.height
));
258 } else if (_dragX0
> _dragX
) {
259 gc
.fillRectangle(new Rectangle(leftSpace
+ _dragX
, _rect0
.y
, _dragX0
- _dragX
, _rect0
.height
));
263 if (time1
<= time0
|| timeSpace
< 2) {
267 int numDigits
= calculateDigits(time0
, time1
);
269 int labelWidth
= gc
.getCharWidth('0') * numDigits
;
270 double pixelsPerNanoSec
= (timeSpace
<= RIGHT_MARGIN
) ?
0 :
271 (double) (timeSpace
- RIGHT_MARGIN
) / (time1
- time0
);
272 calcTimeDelta(labelWidth
, pixelsPerNanoSec
);
274 TimeDraw timeDraw
= getTimeDraw(_timeDelta
);
276 // draw selected zoom region lines
277 if (3 == _dragState
&& null != _timeProvider
) {
278 gc
.drawLine(leftSpace
+ _dragX0
, rect
.y
, leftSpace
+ _dragX0
, rect
.y
+ rect
.height
);
279 gc
.drawLine(leftSpace
+ _dragX
, rect
.y
, leftSpace
+ _dragX
, rect
.y
+ rect
.height
);
282 if (_rect0
.isEmpty()) {
286 // draw selected time
287 int x
= _rect0
.x
+ (int) ((selectedTime
- time0
) * pixelsPerNanoSec
);
288 if (x
>= _rect0
.x
&& x
< _rect0
.x
+ _rect0
.width
) {
289 gc
.setForeground(_colors
.getColor(TimeGraphColorScheme
.SELECTED_TIME
));
290 gc
.drawLine(x
, _rect0
.y
+ _rect0
.height
- 6, x
, _rect0
.y
292 gc
.setForeground(_colors
.getColor(TimeGraphColorScheme
.TOOL_FOREGROUND
));
295 // draw time scale ticks
297 _rect0
.height
= rect
.height
- 4;
298 _rect0
.width
= labelWidth
;
301 if (_timeProvider
!= null && _timeProvider
.getTimeFormat().equals(TimeFormat
.CALENDAR
)) {
302 time
= floorToCalendar(time0
, _timeDelta
);
304 time
= (time0
/ _timeDelta
) * _timeDelta
;
310 int y
= _rect0
.y
+ _rect0
.height
;
312 if (_timeProvider
!= null && _timeProvider
.getTimeFormat().equals(TimeFormat
.CALENDAR
)) {
313 timeDraw
.drawAbsHeader(gc
, time
, absHeaderRect
);
317 x
= rect
.x
+ leftSpace
+ (int) (Math
.floor((time
- time0
) * pixelsPerNanoSec
));
318 if (x
>= rect
.x
+ leftSpace
+ rect
.width
- _rect0
.width
) {
321 if (x
>= rect
.x
+ leftSpace
) {
322 gc
.drawLine(x
, y
, x
, y
+ 4);
324 if (x
+ _rect0
.width
<= rect
.x
+ rect
.width
) {
325 timeDraw
.draw(gc
, time
, _rect0
);
328 if (pixelsPerNanoSec
== 0 || time
> Long
.MAX_VALUE
- _timeDelta
|| _timeDelta
== 0) {
331 if (_timeProvider
!= null && _timeProvider
.getTimeFormat().equals(TimeFormat
.CALENDAR
)) {
332 if (_timeDelta
>= YEAR_IN_NS
) {
333 long millis
= time
/ 1000000L;
334 GREGORIAN_CALENDAR
.setTime(new Date(millis
));
335 GREGORIAN_CALENDAR
.add(Calendar
.YEAR
, (int) (_timeDelta
/ YEAR_IN_NS
));
336 millis
= GREGORIAN_CALENDAR
.getTimeInMillis();
337 time
= millis
* 1000000L;
338 } else if (_timeDelta
>= MONTH_IN_NS
) {
339 long millis
= time
/ 1000000L;
340 GREGORIAN_CALENDAR
.setTime(new Date(millis
));
341 GREGORIAN_CALENDAR
.add(Calendar
.MONTH
, (int) (_timeDelta
/ MONTH_IN_NS
));
342 millis
= GREGORIAN_CALENDAR
.getTimeInMillis();
343 time
= millis
* 1000000L;
344 } else if (_timeDelta
>= DAY_IN_NS
) {
345 long millis
= time
/ 1000000L;
346 GREGORIAN_CALENDAR
.setTime(new Date(millis
));
347 GREGORIAN_CALENDAR
.add(Calendar
.DAY_OF_MONTH
, (int) (_timeDelta
/ DAY_IN_NS
));
348 millis
= GREGORIAN_CALENDAR
.getTimeInMillis();
349 time
= millis
* 1000000L;
359 private long floorToCalendar(long time
, long timeDelta
) {
362 if (_timeDelta
>= YEAR_IN_NS
) {
363 GREGORIAN_CALENDAR
.setTime(new Date(ret
/ 1000000));
364 int year
= GREGORIAN_CALENDAR
.get(Calendar
.YEAR
);
365 int yearDelta
= (int) (timeDelta
/ YEAR_IN_NS
);
366 year
= (year
/ yearDelta
) * yearDelta
;
367 GREGORIAN_CALENDAR
.set(Calendar
.YEAR
, year
);
368 GREGORIAN_CALENDAR
.set(Calendar
.MONTH
, 0); // January 1st of year
369 GREGORIAN_CALENDAR
.set(Calendar
.DAY_OF_MONTH
, 1);
370 GREGORIAN_CALENDAR
.set(Calendar
.HOUR_OF_DAY
, 0);
371 GREGORIAN_CALENDAR
.set(Calendar
.MINUTE
, 0);
372 GREGORIAN_CALENDAR
.set(Calendar
.SECOND
, 0);
373 GREGORIAN_CALENDAR
.set(Calendar
.MILLISECOND
, 0);
374 ret
= GREGORIAN_CALENDAR
.getTimeInMillis() * 1000000;
375 } else if (_timeDelta
>= MONTH_IN_NS
) {
376 GREGORIAN_CALENDAR
.setTime(new Date(ret
/ 1000000));
377 int month
= GREGORIAN_CALENDAR
.get(Calendar
.MONTH
);
378 int monthDelta
= (int) (timeDelta
/ MONTH_IN_NS
);
379 month
= (month
/ monthDelta
) * monthDelta
;
380 GREGORIAN_CALENDAR
.set(Calendar
.MONTH
, month
);
381 GREGORIAN_CALENDAR
.set(Calendar
.DAY_OF_MONTH
, 1); // 1st of month
382 GREGORIAN_CALENDAR
.set(Calendar
.HOUR_OF_DAY
, 0);
383 GREGORIAN_CALENDAR
.set(Calendar
.MINUTE
, 0);
384 GREGORIAN_CALENDAR
.set(Calendar
.SECOND
, 0);
385 GREGORIAN_CALENDAR
.set(Calendar
.MILLISECOND
, 0);
386 ret
= GREGORIAN_CALENDAR
.getTimeInMillis() * 1000000;
388 long offset
= GREGORIAN_CALENDAR
.getTimeZone().getOffset(ret
/ 1000000L) * 1000000L;
390 ret
= (ret
/ timeDelta
) * timeDelta
;
396 private int calculateDigits(long time0
, long time1
) {
398 long timeRange
= time1
- time0
;
400 if (_timeProvider
.getTimeFormat().equals(TimeFormat
.CALENDAR
)) {
401 // Calculate the number of digits to represent the minutes provided
405 if (timeRange
< 10000) {
406 // HH:11:222:333:444__
408 } else if (timeRange
< 10000000) {
413 long sec
= time1
/ 1000000000;
414 numDigits
= Long
.toString(sec
).length();
415 int thousandGroups
= (numDigits
- 1) / 3;
416 numDigits
+= thousandGroups
;
417 numDigits
+= 12; // .000 000 000
424 public void mouseDown(MouseEvent e
) {
425 getParent().setFocus();
426 if (_dragState
== 0 && null != _timeProvider
) {
427 int x
= e
.x
- _timeProvider
.getNameSpace();
428 if (1 == e
.button
&& x
> 0) {
431 } else if (3 == e
.button
) {
436 } else if (x
> getSize().x
- _timeProvider
.getNameSpace()) {
437 x
= getSize().x
- _timeProvider
.getNameSpace();
439 _dragX
= _dragX0
= x
;
440 _time0bak
= _timeProvider
.getTime0();
441 _time1bak
= _timeProvider
.getTime1();
446 public void mouseUp(MouseEvent e
) {
447 if (e
.button
== 1 && _dragState
== 1) {
451 // Notify time provider to check the need for listener notification
452 if (_dragX
!= _dragX0
&& _timeProvider
.getTime0() != _timeProvider
.getTime1()) {
453 _timeProvider
.setStartFinishTimeNotify(_timeProvider
.getTime0(), _timeProvider
.getTime1());
455 } else if (e
.button
== 3 && _dragState
== 3 && null != _timeProvider
) {
457 if (_dragX0
== _dragX
|| _timeProvider
.getTime0() == _timeProvider
.getTime1()) {
461 int timeSpace
= _timeProvider
.getTimeSpace();
462 int leftSpace
= _timeProvider
.getNameSpace();
463 int x
= Math
.max(0, e
.x
- leftSpace
);
466 if (_dragX0
> _dragX
) { // drag right to left
470 long time0
= _time0bak
+ (long) ((_time1bak
- _time0bak
) * ((double) _dragX0
/ timeSpace
));
471 long time1
= _time0bak
+ (long) ((_time1bak
- _time0bak
) * ((double) _dragX
/ timeSpace
));
473 _timeProvider
.setStartFinishTimeNotify(time0
, time1
);
474 _time0bak
= _timeProvider
.getTime0();
475 _time1bak
= _timeProvider
.getTime1();
481 public void mouseMove(MouseEvent e
) {
482 if (_dragX0
< 0 || _dragState
== 0 || _timeProvider
== null) {
485 Point size
= getSize();
486 int leftSpace
= _timeProvider
.getNameSpace();
487 int timeSpace
= _timeProvider
.getTimeSpace();
488 int x
= e
.x
- leftSpace
;
489 if (1 == _dragState
) {
490 if (x
> 0 && size
.x
> leftSpace
&& _dragX
!= x
) {
492 if (_timeProvider
.getTime0() == _timeProvider
.getTime1()) {
495 long interval
= (long) ((_time1bak
- _time0bak
) * ((double) _dragX0
/ _dragX
));
496 if (interval
== Long
.MAX_VALUE
) {
497 _timeProvider
.setStartFinishTime(_time0bak
, Long
.MAX_VALUE
);
499 long time1
= _time0bak
+ (long) ((_time1bak
- _time0bak
) * ((double) _dragX0
/ _dragX
));
500 _timeProvider
.setStartFinishTime(_time0bak
, time1
);
503 } else if (3 == _dragState
) {
506 } else if (x
> timeSpace
) {
516 public void mouseDoubleClick(MouseEvent e
) {
517 if (e
.button
== 1 && null != _timeProvider
&& _timeProvider
.getTime0() != _timeProvider
.getTime1() && (e
.stateMask
& SWT
.BUTTON_MASK
) == 0) {
518 _timeProvider
.resetStartFinishTime();
519 _timeProvider
.notifyStartFinishTime();
520 _time0bak
= _timeProvider
.getTime0();
521 _time1bak
= _timeProvider
.getTime1();
526 abstract class TimeDraw
{
527 static String S
= "" ; //$NON-NLS-1$
528 static String S0
= "0" ; //$NON-NLS-1$
529 static String S00
= "00"; //$NON-NLS-1$
530 protected static final SimpleDateFormat stimeformat
= new SimpleDateFormat("HH:mm:ss"); //$NON-NLS-1$
531 protected static final SimpleDateFormat stimeformatheader
= new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$
532 protected static final SimpleDateFormat sminformat
= new SimpleDateFormat("HH:mm"); //$NON-NLS-1$
533 protected static final SimpleDateFormat sminformatheader
= new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$
534 protected static final SimpleDateFormat shrsformat
= new SimpleDateFormat("MMM dd HH:mm"); //$NON-NLS-1$
535 protected static final SimpleDateFormat shrsformatheader
= new SimpleDateFormat("yyyy"); //$NON-NLS-1$
536 protected static final SimpleDateFormat sdayformat
= new SimpleDateFormat("MMM dd"); //$NON-NLS-1$
537 protected static final SimpleDateFormat sdayformatheader
= new SimpleDateFormat("yyyy"); //$NON-NLS-1$
538 protected static final SimpleDateFormat smonthformat
= new SimpleDateFormat("yyyy MMM"); //$NON-NLS-1$
539 protected static final SimpleDateFormat syearformat
= new SimpleDateFormat("yyyy"); //$NON-NLS-1$
541 static String
sep(long n
) {
542 StringBuilder retVal
= new StringBuilder();
543 String s
= Long
.toString(n
);
544 for (int i
= 0; i
< s
.length(); i
++) {
545 int pos
= s
.length() - i
- 1;
546 retVal
.append(s
.charAt(i
));
547 if (pos
% 3 == 0 && pos
!= 0) {
551 return retVal
.toString();
554 static String
pad(long n
) {
558 } else if (n
< 100) {
566 public abstract void draw(GC gc
, long time
, Rectangle rect
);
569 * Override to draw absolute time header This is for the time information
570 * not shown in the draw of each tick
576 * @param absHeaderRect
579 public void drawAbsHeader(GC gc
, long time
, Rectangle absHeaderRect
) {
582 public abstract String
hint();
585 class TimeDrawSec
extends TimeDraw
{
586 static String _hint
= "sec"; //$NON-NLS-1$
589 public void draw(GC gc
, long time
, Rectangle rect
) {
590 long correctTime
= time
/ 1000000000;
591 Utils
.drawText(gc
, sep(correctTime
), rect
, true);
595 public String
hint() {
600 class TimeDrawMillisec
extends TimeDraw
{
601 static String _hint
= "0.000"; //$NON-NLS-1$
604 public void draw(GC gc
, long time
, Rectangle rect
) {
605 long correctTime
= time
/ 1000000;
606 long ms
= correctTime
% 1000;
608 Utils
.drawText(gc
, sep(correctTime
) + "." + pad(ms
), rect
, true); //$NON-NLS-1$
612 public String
hint() {
617 class TimeDrawMicrosec
extends TimeDraw
{
618 static String _hint
= "0.000 000"; //$NON-NLS-1$
621 public void draw(GC gc
, long time
, Rectangle rect
) {
622 long correctTime
= time
/ 1000;
623 long mcs
= correctTime
% 1000;
625 long ms
= correctTime
% 1000;
627 Utils
.drawText(gc
, sep(correctTime
) + "." + pad(ms
) + " " + pad(mcs
), rect
, true); //$NON-NLS-1$ //$NON-NLS-2$
631 public String
hint() {
636 class TimeDrawNanosec
extends TimeDraw
{
637 static String _hint
= "0.000 000 000"; //$NON-NLS-1$
640 public void draw(GC gc
, long time
, Rectangle rect
) {
641 long ns
= time
% 1000;
642 long correctTime
= time
/ 1000;
643 long mcs
= correctTime
% 1000;
645 long ms
= correctTime
% 1000;
647 Utils
.drawText(gc
, sep(correctTime
) + "." + pad(ms
) + " " + pad(mcs
) + " " + pad(ns
), rect
, true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
651 public String
hint() {
656 class TimeDrawAbsYear
extends TimeDraw
{
657 static String _hint
= "YYYY"; //$NON-NLS-1$
660 public void draw(GC gc
, long time
, Rectangle rect
) {
661 String stime
= syearformat
.format(new Date(time
/ 1000000));
662 Utils
.drawText(gc
, stime
, rect
, true);
666 public String
hint() {
671 class TimeDrawAbsMonth
extends TimeDraw
{
672 static String _hint
= "YYYY Mmm"; //$NON-NLS-1$
675 public void draw(GC gc
, long time
, Rectangle rect
) {
676 String stime
= smonthformat
.format(new Date(time
/ 1000000));
677 Utils
.drawText(gc
, stime
, rect
, true);
681 public String
hint() {
686 class TimeDrawAbsDay
extends TimeDraw
{
687 static String _hint
= "Mmm dd"; //$NON-NLS-1$
690 public void draw(GC gc
, long time
, Rectangle rect
) {
691 String stime
= sdayformat
.format(new Date(time
/ 1000000));
692 Utils
.drawText(gc
, stime
, rect
, true);
696 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
697 String header
= sdayformatheader
.format(new Date(time
/ 1000000));
698 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
699 if (headerwidth
<= rect
.width
) {
700 rect
.x
+= (rect
.width
- headerwidth
);
701 Utils
.drawText(gc
, header
, rect
, true);
706 public String
hint() {
711 class TimeDrawAbsHrs
extends TimeDraw
{
712 static String _hint
= "Mmm dd HH:mm"; //$NON-NLS-1$
715 public void draw(GC gc
, long time
, Rectangle rect
) {
716 String stime
= shrsformat
.format(new Date(time
/ 1000000));
717 Utils
.drawText(gc
, stime
, rect
, true);
721 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
722 String header
= shrsformatheader
.format(new Date(time
/ 1000000));
723 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
724 if (headerwidth
<= rect
.width
) {
725 rect
.x
+= (rect
.width
- headerwidth
);
726 Utils
.drawText(gc
, header
, rect
, true);
731 public String
hint() {
736 class TimeDrawAbsMin
extends TimeDraw
{
737 static String _hint
= "HH:mm"; //$NON-NLS-1$
740 public void draw(GC gc
, long time
, Rectangle rect
) {
741 String stime
= sminformat
.format(new Date(time
/ 1000000));
742 Utils
.drawText(gc
, stime
, rect
, true);
746 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
747 String header
= sminformatheader
.format(new Date(time
/ 1000000));
748 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
749 if (headerwidth
<= rect
.width
) {
750 rect
.x
+= (rect
.width
- headerwidth
);
751 Utils
.drawText(gc
, header
, rect
, true);
757 public String
hint() {
762 class TimeDrawAbsSec
extends TimeDraw
{
763 static String _hint
= "HH:mm:ss"; //$NON-NLS-1$
766 public void draw(GC gc
, long time
, Rectangle rect
) {
767 String stime
= stimeformat
.format(new Date(time
/ 1000000));
768 Utils
.drawText(gc
, stime
, rect
, true);
772 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
773 String header
= stimeformatheader
.format(new Date(time
/ 1000000));
774 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
775 if (headerwidth
<= rect
.width
) {
776 rect
.x
+= (rect
.width
- headerwidth
);
777 Utils
.drawText(gc
, header
, rect
, true);
782 public String
hint() {
787 class TimeDrawAbsMillisec
extends TimeDraw
{
788 static String _hint
= "HH:ss:ms"; //$NON-NLS-1$
791 public void draw(GC gc
, long time
, Rectangle rect
) {
792 String stime
= stimeformat
.format(new Date(time
/ 1000000));
793 String ns
= Utils
.formatNs(time
, Resolution
.MILLISEC
);
795 Utils
.drawText(gc
, stime
+ "." + ns
, rect
, true); //$NON-NLS-1$
799 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
800 String header
= stimeformatheader
.format(new Date(time
/ 1000000));
801 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
802 if (headerwidth
<= rect
.width
) {
803 rect
.x
+= (rect
.width
- headerwidth
);
804 Utils
.drawText(gc
, header
, rect
, true);
809 public String
hint() {
814 class TimeDrawAbsMicroSec
extends TimeDraw
{
815 static String _hint
= "HH:ss:ms:mcs"; //$NON-NLS-1$
818 public void draw(GC gc
, long time
, Rectangle rect
) {
819 String stime
= stimeformat
.format(new Date(time
/ 1000000));
820 String micr
= Utils
.formatNs(time
, Resolution
.MICROSEC
);
821 Utils
.drawText(gc
, stime
+ "." + micr
, rect
, true); //$NON-NLS-1$
825 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
826 String header
= stimeformatheader
.format(new Date(time
/ 1000000));
827 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
828 if (headerwidth
<= rect
.width
) {
829 rect
.x
+= (rect
.width
- headerwidth
);
830 Utils
.drawText(gc
, header
, rect
, true);
835 public String
hint() {
840 class TimeDrawAbsNanoSec
extends TimeDraw
{
841 static String _hint
= "HH:ss:ms:mcs:ns"; //$NON-NLS-1$
844 public void draw(GC gc
, long time
, Rectangle rect
) {
845 String stime
= stimeformat
.format(new Date(time
/ 1000000));
846 String ns
= Utils
.formatNs(time
, Resolution
.NANOSEC
);
847 Utils
.drawText(gc
, stime
+ "." + ns
, rect
, true); //$NON-NLS-1$
851 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
852 String header
= stimeformatheader
.format(new Date(time
/ 1000000));
853 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
854 if (headerwidth
<= rect
.width
) {
855 rect
.x
+= (rect
.width
- headerwidth
);
856 Utils
.drawText(gc
, header
, rect
, true);
861 public String
hint() {
867 class TimeDrawNumber
extends TimeDraw
{
870 public void draw(GC gc
, long time
, Rectangle rect
) {
871 String stime
= NumberFormat
.getInstance().format(time
);
872 Utils
.drawText(gc
, stime
, rect
, true);
876 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
877 String header
= NumberFormat
.getInstance().format(time
);
878 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
879 if (headerwidth
<= rect
.width
) {
880 rect
.x
+= (rect
.width
- headerwidth
);
881 Utils
.drawText(gc
, header
, rect
, true);
886 public String
hint() {
887 return "cycle"; //$NON-NLS-1$