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
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
14 *****************************************************************************/
16 package org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
;
18 import java
.text
.NumberFormat
;
19 import java
.text
.SimpleDateFormat
;
20 import java
.util
.Calendar
;
21 import java
.util
.Date
;
23 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.Resolution
;
24 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
25 import org
.eclipse
.swt
.SWT
;
26 import org
.eclipse
.swt
.events
.MouseEvent
;
27 import org
.eclipse
.swt
.events
.MouseListener
;
28 import org
.eclipse
.swt
.events
.MouseMoveListener
;
29 import org
.eclipse
.swt
.events
.PaintEvent
;
30 import org
.eclipse
.swt
.graphics
.GC
;
31 import org
.eclipse
.swt
.graphics
.Point
;
32 import org
.eclipse
.swt
.graphics
.Rectangle
;
33 import org
.eclipse
.swt
.widgets
.Composite
;
36 * Implementation of the scale for the time graph view.
38 * This goes above the "gantt chart" area.
41 * @author Alvaro Sanchez-Leon
42 * @author Patrick Tasse
44 public class TimeGraphScale
extends TimeGraphBaseControl
implements
45 MouseListener
, MouseMoveListener
{
48 * Standard constructor
51 * The parent composite object
53 * The color scheme to use
55 public TimeGraphScale(Composite parent
, TimeGraphColorScheme colors
) {
56 super(parent
, colors
, SWT
.NO_BACKGROUND
| SWT
.NO_FOCUS
| SWT
.DOUBLE_BUFFERED
);
57 addMouseListener(this);
58 addMouseMoveListener(this);
61 private static final long SEC_IN_NS
= 1000000000;
62 private static final long MIN_IN_NS
= 60 * SEC_IN_NS
;
63 private static final long HOUR_IN_NS
= 60 * MIN_IN_NS
;
64 private static final long DAY_IN_NS
= 24 * HOUR_IN_NS
;
65 private static final long MONTH_IN_NS
= 31 * DAY_IN_NS
; // upper limit
66 private static final long YEAR_IN_NS
= 366 * DAY_IN_NS
; // upper limit
68 private static final double LOG10_1
= Math
.log10(1);
69 private static final double LOG10_2
= Math
.log10(2);
70 private static final double LOG10_3
= Math
.log10(3);
71 private static final double LOG10_5
= Math
.log10(5);
73 private static final Calendar GREGORIAN_CALENDAR
= Calendar
.getInstance();
75 private ITimeDataProvider _timeProvider
;
76 private int _dragState
= 0;
77 private int _dragX0
= 0;
78 private int _dragX
= 0;
79 private long _time0bak
;
80 private long _time1bak
;
81 private boolean _isInUpdate
;
82 private final Rectangle _rect0
= new Rectangle(0, 0, 0, 0);
86 * Assign the time provider for this scale
91 public void setTimeProvider(ITimeDataProvider timeProvider
) {
92 _timeProvider
= timeProvider
;
95 private long _timeDelta
;
98 public Point
computeSize(int wHint
, int hHint
, boolean changed
) {
99 return super.computeSize(wHint
, _height
, changed
);
103 * Set the height of the scale
108 public void setHeight(int height
) {
109 this._height
= height
;
112 private void calcTimeDelta(int width
, double pixelsPerNanoSec
) {
113 double minDelta
= (pixelsPerNanoSec
== 0) ? YEAR_IN_NS
: width
/ pixelsPerNanoSec
;
115 if (_timeProvider
!= null && _timeProvider
.getTimeFormat().equals(TimeFormat
.CALENDAR
)) {
116 if (minDelta
> 6 * MONTH_IN_NS
) {
118 } else if (minDelta
> 3 * MONTH_IN_NS
) {
119 unit
= 6 * MONTH_IN_NS
;
120 } else if (minDelta
> 10 * DAY_IN_NS
) {
122 } else if (minDelta
> 12 * HOUR_IN_NS
) {
124 } else if (minDelta
> 3 * HOUR_IN_NS
) {
125 unit
= 6 * HOUR_IN_NS
;
126 } else if (minDelta
> 30 * MIN_IN_NS
) {
128 } else if (minDelta
> 10 * MIN_IN_NS
) {
129 unit
= 15 * MIN_IN_NS
;
130 } else if (minDelta
> 30 * SEC_IN_NS
) {
132 } else if (minDelta
> 20 * SEC_IN_NS
) {
133 unit
= 30 * SEC_IN_NS
;
134 } else if (minDelta
<= 1) {
139 double log
= Math
.log10(minDelta
/ unit
);
140 long pow10
= (long) log
;
141 double remainder
= log
- pow10
;
142 if (remainder
< LOG10_1
) {
143 _timeDelta
= (long) Math
.pow(10, pow10
) * unit
;
144 } else if (remainder
< LOG10_2
) {
145 _timeDelta
= 2 * (long) Math
.pow(10, pow10
) * unit
;
146 } else if (remainder
< LOG10_3
&& unit
>= HOUR_IN_NS
&& unit
< YEAR_IN_NS
) {
147 _timeDelta
= 3 * (long) Math
.pow(10, pow10
) * unit
;
148 } else if (remainder
< LOG10_5
) {
149 _timeDelta
= 5 * (long) Math
.pow(10, pow10
) * unit
;
151 _timeDelta
= 10 * (long) Math
.pow(10, pow10
) * unit
;
158 private static TimeDraw TIMEDRAW_NANOSEC
= new TimeDrawNanosec();
159 private static TimeDraw TIMEDRAW_MICROSEC
= new TimeDrawMicrosec();
160 private static TimeDraw TIMEDRAW_MILLISEC
= new TimeDrawMillisec();
161 private static TimeDraw TIMEDRAW_SEC
= new TimeDrawSec();
162 private static TimeDraw TIMEDRAW_ABS_NANOSEC
= new TimeDrawAbsNanoSec();
163 private static TimeDraw TIMEDRAW_ABS_MICROSEC
= new TimeDrawAbsMicroSec();
164 private static TimeDraw TIMEDRAW_ABS_MILLISEC
= new TimeDrawAbsMillisec();
165 private static TimeDraw TIMEDRAW_ABS_SEC
= new TimeDrawAbsSec();
166 private static TimeDraw TIMEDRAW_ABS_MIN
= new TimeDrawAbsMin();
167 private static TimeDraw TIMEDRAW_ABS_HRS
= new TimeDrawAbsHrs();
168 private static TimeDraw TIMEDRAW_ABS_DAY
= new TimeDrawAbsDay();
169 private static TimeDraw TIMEDRAW_ABS_MONTH
= new TimeDrawAbsMonth();
170 private static TimeDraw TIMEDRAW_ABS_YEAR
= new TimeDrawAbsYear();
171 private static TimeDraw TIMEDRAW_NUMBER
= new TimeDrawNumber();
173 TimeDraw
getTimeDraw(long timeDelta
) {
175 if (_timeProvider
!= null) {
177 if (_timeProvider
.getTimeFormat() == TimeFormat
.CALENDAR
) {
178 if (timeDelta
>= YEAR_IN_NS
) {
179 timeDraw
= TIMEDRAW_ABS_YEAR
;
180 } else if (timeDelta
>= MONTH_IN_NS
) {
181 timeDraw
= TIMEDRAW_ABS_MONTH
;
182 } else if (timeDelta
>= DAY_IN_NS
) {
183 timeDraw
= TIMEDRAW_ABS_DAY
;
184 } else if (timeDelta
>= HOUR_IN_NS
) {
185 timeDraw
= TIMEDRAW_ABS_HRS
;
186 } else if (timeDelta
>= MIN_IN_NS
) {
187 timeDraw
= TIMEDRAW_ABS_MIN
;
188 } else if (timeDelta
>= SEC_IN_NS
) {
189 timeDraw
= TIMEDRAW_ABS_SEC
;
190 } else if (timeDelta
>= 1000000) {
191 timeDraw
= TIMEDRAW_ABS_MILLISEC
;
192 } else if (timeDelta
>= 1000) {
193 timeDraw
= TIMEDRAW_ABS_MICROSEC
;
195 timeDraw
= TIMEDRAW_ABS_NANOSEC
;
198 } else if (_timeProvider
.getTimeFormat() == TimeFormat
.NUMBER
) {
199 timeDraw
= TIMEDRAW_NUMBER
;
204 if (timeDelta
>= 1000000000) {
205 timeDraw
= TIMEDRAW_SEC
;
206 } else if (timeDelta
>= 1000000) {
207 timeDraw
= TIMEDRAW_MILLISEC
;
208 } else if (timeDelta
>= 1000) {
209 timeDraw
= TIMEDRAW_MICROSEC
;
211 timeDraw
= TIMEDRAW_NANOSEC
;
217 void paint(Rectangle rect
, PaintEvent e
) {
219 if (_isInUpdate
|| null == _timeProvider
) {
224 gc
.fillRectangle(rect
);
226 long time0
= _timeProvider
.getTime0();
227 long time1
= _timeProvider
.getTime1();
228 long selectedTime
= _timeProvider
.getSelectedTime();
229 int leftSpace
= _timeProvider
.getNameSpace();
230 int timeSpace
= _timeProvider
.getTimeSpace();
232 gc
.setBackground(_colors
.getColor(TimeGraphColorScheme
.TOOL_BACKGROUND
));
233 gc
.setForeground(_colors
.getColor(TimeGraphColorScheme
.TOOL_FOREGROUND
));
234 Utils
.init(_rect0
, rect
);
236 // draw top left area
237 _rect0
.width
= leftSpace
;
240 Rectangle absHeaderRect
= new Rectangle(_rect0
.x
, _rect0
.y
, _rect0
.width
, _rect0
.height
);
244 // prepare and draw right rect of the timescale
245 _rect0
.x
+= leftSpace
;
246 _rect0
.width
= rect
.width
- leftSpace
;
248 // draw bottom border and erase all other area
249 gc
.drawLine(rect
.x
, rect
.y
+ rect
.height
- 1, rect
.x
+ rect
.width
- 1,
250 rect
.y
+ rect
.height
- 1);
252 gc
.fillRectangle(_rect0
);
254 if (3 == _dragState
&& null != _timeProvider
) {
255 // draw selected zoom region background
256 gc
.setBackground(_colors
.getBkColor(true, false, true));
257 if (_dragX0
< _dragX
) {
258 gc
.fillRectangle(new Rectangle(leftSpace
+ _dragX0
, _rect0
.y
, _dragX
- _dragX0
, _rect0
.height
));
259 } else if (_dragX0
> _dragX
) {
260 gc
.fillRectangle(new Rectangle(leftSpace
+ _dragX
, _rect0
.y
, _dragX0
- _dragX
, _rect0
.height
));
264 if (time1
<= time0
|| timeSpace
< 2) {
268 int numDigits
= calculateDigits(time0
, time1
);
270 int labelWidth
= gc
.getCharWidth('0') * numDigits
;
271 double pixelsPerNanoSec
= (timeSpace
<= RIGHT_MARGIN
) ?
0 :
272 (double) (timeSpace
- RIGHT_MARGIN
) / (time1
- time0
);
273 calcTimeDelta(labelWidth
, pixelsPerNanoSec
);
275 TimeDraw timeDraw
= getTimeDraw(_timeDelta
);
277 // draw selected zoom region lines
278 if (3 == _dragState
&& null != _timeProvider
) {
279 gc
.drawLine(leftSpace
+ _dragX0
, rect
.y
, leftSpace
+ _dragX0
, rect
.y
+ rect
.height
);
280 gc
.drawLine(leftSpace
+ _dragX
, rect
.y
, leftSpace
+ _dragX
, rect
.y
+ rect
.height
);
283 if (_rect0
.isEmpty()) {
287 // draw selected time
288 int x
= _rect0
.x
+ (int) ((selectedTime
- time0
) * pixelsPerNanoSec
);
289 if (x
>= _rect0
.x
&& x
< _rect0
.x
+ _rect0
.width
) {
290 gc
.setForeground(_colors
.getColor(TimeGraphColorScheme
.SELECTED_TIME
));
291 gc
.drawLine(x
, _rect0
.y
+ _rect0
.height
- 6, x
, _rect0
.y
293 gc
.setForeground(_colors
.getColor(TimeGraphColorScheme
.TOOL_FOREGROUND
));
296 // draw time scale ticks
298 _rect0
.height
= rect
.height
- 4;
299 _rect0
.width
= labelWidth
;
302 if (_timeProvider
!= null && _timeProvider
.getTimeFormat().equals(TimeFormat
.CALENDAR
)) {
303 time
= floorToCalendar(time0
, _timeDelta
);
305 time
= (time0
/ _timeDelta
) * _timeDelta
;
311 int y
= _rect0
.y
+ _rect0
.height
;
313 if (_timeProvider
!= null && _timeProvider
.getTimeFormat().equals(TimeFormat
.CALENDAR
)) {
314 timeDraw
.drawAbsHeader(gc
, time
, absHeaderRect
);
318 x
= rect
.x
+ leftSpace
+ (int) (Math
.floor((time
- time0
) * pixelsPerNanoSec
));
319 if (x
>= rect
.x
+ leftSpace
+ rect
.width
- _rect0
.width
) {
322 if (x
>= rect
.x
+ leftSpace
) {
323 gc
.drawLine(x
, y
, x
, y
+ 4);
325 if (x
+ _rect0
.width
<= rect
.x
+ rect
.width
) {
326 timeDraw
.draw(gc
, time
, _rect0
);
329 if (pixelsPerNanoSec
== 0 || time
> Long
.MAX_VALUE
- _timeDelta
|| _timeDelta
== 0) {
332 if (_timeProvider
!= null && _timeProvider
.getTimeFormat().equals(TimeFormat
.CALENDAR
)) {
333 if (_timeDelta
>= YEAR_IN_NS
) {
334 long millis
= time
/ 1000000L;
335 GREGORIAN_CALENDAR
.setTime(new Date(millis
));
336 GREGORIAN_CALENDAR
.add(Calendar
.YEAR
, (int) (_timeDelta
/ YEAR_IN_NS
));
337 millis
= GREGORIAN_CALENDAR
.getTimeInMillis();
338 time
= millis
* 1000000L;
339 } else if (_timeDelta
>= MONTH_IN_NS
) {
340 long millis
= time
/ 1000000L;
341 GREGORIAN_CALENDAR
.setTime(new Date(millis
));
342 GREGORIAN_CALENDAR
.add(Calendar
.MONTH
, (int) (_timeDelta
/ MONTH_IN_NS
));
343 millis
= GREGORIAN_CALENDAR
.getTimeInMillis();
344 time
= millis
* 1000000L;
345 } else if (_timeDelta
>= DAY_IN_NS
) {
346 long millis
= time
/ 1000000L;
347 GREGORIAN_CALENDAR
.setTime(new Date(millis
));
348 GREGORIAN_CALENDAR
.add(Calendar
.DAY_OF_MONTH
, (int) (_timeDelta
/ DAY_IN_NS
));
349 millis
= GREGORIAN_CALENDAR
.getTimeInMillis();
350 time
= millis
* 1000000L;
360 private long floorToCalendar(long time
, long timeDelta
) {
363 if (_timeDelta
>= YEAR_IN_NS
) {
364 GREGORIAN_CALENDAR
.setTime(new Date(ret
/ 1000000));
365 int year
= GREGORIAN_CALENDAR
.get(Calendar
.YEAR
);
366 int yearDelta
= (int) (timeDelta
/ YEAR_IN_NS
);
367 year
= (year
/ yearDelta
) * yearDelta
;
368 GREGORIAN_CALENDAR
.set(Calendar
.YEAR
, year
);
369 GREGORIAN_CALENDAR
.set(Calendar
.MONTH
, 0); // January 1st of year
370 GREGORIAN_CALENDAR
.set(Calendar
.DAY_OF_MONTH
, 1);
371 GREGORIAN_CALENDAR
.set(Calendar
.HOUR_OF_DAY
, 0);
372 GREGORIAN_CALENDAR
.set(Calendar
.MINUTE
, 0);
373 GREGORIAN_CALENDAR
.set(Calendar
.SECOND
, 0);
374 GREGORIAN_CALENDAR
.set(Calendar
.MILLISECOND
, 0);
375 ret
= GREGORIAN_CALENDAR
.getTimeInMillis() * 1000000;
376 } else if (_timeDelta
>= MONTH_IN_NS
) {
377 GREGORIAN_CALENDAR
.setTime(new Date(ret
/ 1000000));
378 int month
= GREGORIAN_CALENDAR
.get(Calendar
.MONTH
);
379 int monthDelta
= (int) (timeDelta
/ MONTH_IN_NS
);
380 month
= (month
/ monthDelta
) * monthDelta
;
381 GREGORIAN_CALENDAR
.set(Calendar
.MONTH
, month
);
382 GREGORIAN_CALENDAR
.set(Calendar
.DAY_OF_MONTH
, 1); // 1st of month
383 GREGORIAN_CALENDAR
.set(Calendar
.HOUR_OF_DAY
, 0);
384 GREGORIAN_CALENDAR
.set(Calendar
.MINUTE
, 0);
385 GREGORIAN_CALENDAR
.set(Calendar
.SECOND
, 0);
386 GREGORIAN_CALENDAR
.set(Calendar
.MILLISECOND
, 0);
387 ret
= GREGORIAN_CALENDAR
.getTimeInMillis() * 1000000;
389 long offset
= GREGORIAN_CALENDAR
.getTimeZone().getOffset(ret
/ 1000000L) * 1000000L;
391 ret
= (ret
/ timeDelta
) * timeDelta
;
397 private int calculateDigits(long time0
, long time1
) {
399 long timeRange
= time1
- time0
;
401 if (_timeProvider
.getTimeFormat().equals(TimeFormat
.CALENDAR
)) {
402 // Calculate the number of digits to represent the minutes provided
406 if (timeRange
< 10000) {
407 // HH:11:222:333:444__
409 } else if (timeRange
< 10000000) {
414 long sec
= time1
/ 1000000000;
415 numDigits
= Long
.toString(sec
).length();
416 int thousandGroups
= (numDigits
- 1) / 3;
417 numDigits
+= thousandGroups
;
418 numDigits
+= 12; // .000 000 000
425 public void mouseDown(MouseEvent e
) {
426 getParent().setFocus();
427 if (_dragState
== 0 && null != _timeProvider
) {
428 int x
= e
.x
- _timeProvider
.getNameSpace();
429 if (1 == e
.button
&& x
> 0) {
432 } else if (3 == e
.button
) {
437 } else if (x
> getSize().x
- _timeProvider
.getNameSpace()) {
438 x
= getSize().x
- _timeProvider
.getNameSpace();
440 _dragX
= _dragX0
= x
;
441 _time0bak
= _timeProvider
.getTime0();
442 _time1bak
= _timeProvider
.getTime1();
447 public void mouseUp(MouseEvent e
) {
448 if (e
.button
== 1 && _dragState
== 1) {
452 // Notify time provider to check the need for listener notification
453 if (_dragX
!= _dragX0
&& _timeProvider
.getTime0() != _timeProvider
.getTime1()) {
454 _timeProvider
.setStartFinishTimeNotify(_timeProvider
.getTime0(), _timeProvider
.getTime1());
456 } else if (e
.button
== 3 && _dragState
== 3 && null != _timeProvider
) {
458 if (_dragX0
== _dragX
|| _timeProvider
.getTime0() == _timeProvider
.getTime1()) {
462 int timeSpace
= _timeProvider
.getTimeSpace();
463 int leftSpace
= _timeProvider
.getNameSpace();
464 int x
= Math
.max(0, e
.x
- leftSpace
);
467 if (_dragX0
> _dragX
) { // drag right to left
471 long time0
= _time0bak
+ (long) ((_time1bak
- _time0bak
) * ((double) _dragX0
/ timeSpace
));
472 long time1
= _time0bak
+ (long) ((_time1bak
- _time0bak
) * ((double) _dragX
/ timeSpace
));
474 _timeProvider
.setStartFinishTimeNotify(time0
, time1
);
475 _time0bak
= _timeProvider
.getTime0();
476 _time1bak
= _timeProvider
.getTime1();
482 public void mouseMove(MouseEvent e
) {
483 if (_dragX0
< 0 || _dragState
== 0 || _timeProvider
== null) {
486 Point size
= getSize();
487 int leftSpace
= _timeProvider
.getNameSpace();
488 int timeSpace
= _timeProvider
.getTimeSpace();
489 int x
= e
.x
- leftSpace
;
490 if (1 == _dragState
) {
491 if (x
> 0 && size
.x
> leftSpace
&& _dragX
!= x
) {
493 if (_timeProvider
.getTime0() == _timeProvider
.getTime1()) {
496 long interval
= (long) ((_time1bak
- _time0bak
) * ((double) _dragX0
/ _dragX
));
497 if (interval
== Long
.MAX_VALUE
) {
498 _timeProvider
.setStartFinishTime(_time0bak
, Long
.MAX_VALUE
);
500 long time1
= _time0bak
+ (long) ((_time1bak
- _time0bak
) * ((double) _dragX0
/ _dragX
));
501 _timeProvider
.setStartFinishTime(_time0bak
, time1
);
504 } else if (3 == _dragState
) {
507 } else if (x
> timeSpace
) {
517 public void mouseDoubleClick(MouseEvent e
) {
518 if (e
.button
== 1 && null != _timeProvider
&& _timeProvider
.getTime0() != _timeProvider
.getTime1() && (e
.stateMask
& SWT
.BUTTON_MASK
) == 0) {
519 _timeProvider
.resetStartFinishTime();
520 _timeProvider
.notifyStartFinishTime();
521 _time0bak
= _timeProvider
.getTime0();
522 _time1bak
= _timeProvider
.getTime1();
527 abstract class TimeDraw
{
528 static String S
= "" ; //$NON-NLS-1$
529 static String S0
= "0" ; //$NON-NLS-1$
530 static String S00
= "00"; //$NON-NLS-1$
531 protected static final SimpleDateFormat stimeformat
= new SimpleDateFormat("HH:mm:ss"); //$NON-NLS-1$
532 protected static final SimpleDateFormat stimeformatheader
= new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$
533 protected static final SimpleDateFormat sminformat
= new SimpleDateFormat("HH:mm"); //$NON-NLS-1$
534 protected static final SimpleDateFormat sminformatheader
= new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$
535 protected static final SimpleDateFormat shrsformat
= new SimpleDateFormat("MMM dd HH:mm"); //$NON-NLS-1$
536 protected static final SimpleDateFormat shrsformatheader
= new SimpleDateFormat("yyyy"); //$NON-NLS-1$
537 protected static final SimpleDateFormat sdayformat
= new SimpleDateFormat("MMM dd"); //$NON-NLS-1$
538 protected static final SimpleDateFormat sdayformatheader
= new SimpleDateFormat("yyyy"); //$NON-NLS-1$
539 protected static final SimpleDateFormat smonthformat
= new SimpleDateFormat("yyyy MMM"); //$NON-NLS-1$
540 protected static final SimpleDateFormat syearformat
= new SimpleDateFormat("yyyy"); //$NON-NLS-1$
542 static String
sep(long n
) {
543 StringBuilder retVal
= new StringBuilder();
544 String s
= Long
.toString(n
);
545 for (int i
= 0; i
< s
.length(); i
++) {
546 int pos
= s
.length() - i
- 1;
547 retVal
.append(s
.charAt(i
));
548 if (pos
% 3 == 0 && pos
!= 0) {
552 return retVal
.toString();
555 static String
pad(long n
) {
559 } else if (n
< 100) {
567 public abstract void draw(GC gc
, long time
, Rectangle rect
);
570 * Override to draw absolute time header This is for the time information
571 * not shown in the draw of each tick
577 * @param absHeaderRect
580 public void drawAbsHeader(GC gc
, long time
, Rectangle absHeaderRect
) {
583 public abstract String
hint();
586 class TimeDrawSec
extends TimeDraw
{
587 static String _hint
= "sec"; //$NON-NLS-1$
590 public void draw(GC gc
, long time
, Rectangle rect
) {
591 long correctTime
= time
/ 1000000000;
592 Utils
.drawText(gc
, sep(correctTime
), rect
, true);
596 public String
hint() {
601 class TimeDrawMillisec
extends TimeDraw
{
602 static String _hint
= "0.000"; //$NON-NLS-1$
605 public void draw(GC gc
, long time
, Rectangle rect
) {
606 long correctTime
= time
/ 1000000;
607 long ms
= correctTime
% 1000;
609 Utils
.drawText(gc
, sep(correctTime
) + "." + pad(ms
), rect
, true); //$NON-NLS-1$
613 public String
hint() {
618 class TimeDrawMicrosec
extends TimeDraw
{
619 static String _hint
= "0.000 000"; //$NON-NLS-1$
622 public void draw(GC gc
, long time
, Rectangle rect
) {
623 long correctTime
= time
/ 1000;
624 long mcs
= correctTime
% 1000;
626 long ms
= correctTime
% 1000;
628 Utils
.drawText(gc
, sep(correctTime
) + "." + pad(ms
) + " " + pad(mcs
), rect
, true); //$NON-NLS-1$ //$NON-NLS-2$
632 public String
hint() {
637 class TimeDrawNanosec
extends TimeDraw
{
638 static String _hint
= "0.000 000 000"; //$NON-NLS-1$
641 public void draw(GC gc
, long time
, Rectangle rect
) {
642 long ns
= time
% 1000;
643 long correctTime
= time
/ 1000;
644 long mcs
= correctTime
% 1000;
646 long ms
= correctTime
% 1000;
648 Utils
.drawText(gc
, sep(correctTime
) + "." + pad(ms
) + " " + pad(mcs
) + " " + pad(ns
), rect
, true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
652 public String
hint() {
657 class TimeDrawAbsYear
extends TimeDraw
{
658 static String _hint
= "YYYY"; //$NON-NLS-1$
661 public void draw(GC gc
, long time
, Rectangle rect
) {
662 String stime
= syearformat
.format(new Date(time
/ 1000000));
663 Utils
.drawText(gc
, stime
, rect
, true);
667 public String
hint() {
672 class TimeDrawAbsMonth
extends TimeDraw
{
673 static String _hint
= "YYYY Mmm"; //$NON-NLS-1$
676 public void draw(GC gc
, long time
, Rectangle rect
) {
677 String stime
= smonthformat
.format(new Date(time
/ 1000000));
678 Utils
.drawText(gc
, stime
, rect
, true);
682 public String
hint() {
687 class TimeDrawAbsDay
extends TimeDraw
{
688 static String _hint
= "Mmm dd"; //$NON-NLS-1$
691 public void draw(GC gc
, long time
, Rectangle rect
) {
692 String stime
= sdayformat
.format(new Date(time
/ 1000000));
693 Utils
.drawText(gc
, stime
, rect
, true);
697 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
698 String header
= sdayformatheader
.format(new Date(time
/ 1000000));
699 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
700 if (headerwidth
<= rect
.width
) {
701 rect
.x
+= (rect
.width
- headerwidth
);
702 Utils
.drawText(gc
, header
, rect
, true);
707 public String
hint() {
712 class TimeDrawAbsHrs
extends TimeDraw
{
713 static String _hint
= "Mmm dd HH:mm"; //$NON-NLS-1$
716 public void draw(GC gc
, long time
, Rectangle rect
) {
717 String stime
= shrsformat
.format(new Date(time
/ 1000000));
718 Utils
.drawText(gc
, stime
, rect
, true);
722 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
723 String header
= shrsformatheader
.format(new Date(time
/ 1000000));
724 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
725 if (headerwidth
<= rect
.width
) {
726 rect
.x
+= (rect
.width
- headerwidth
);
727 Utils
.drawText(gc
, header
, rect
, true);
732 public String
hint() {
737 class TimeDrawAbsMin
extends TimeDraw
{
738 static String _hint
= "HH:mm"; //$NON-NLS-1$
741 public void draw(GC gc
, long time
, Rectangle rect
) {
742 String stime
= sminformat
.format(new Date(time
/ 1000000));
743 Utils
.drawText(gc
, stime
, rect
, true);
747 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
748 String header
= sminformatheader
.format(new Date(time
/ 1000000));
749 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
750 if (headerwidth
<= rect
.width
) {
751 rect
.x
+= (rect
.width
- headerwidth
);
752 Utils
.drawText(gc
, header
, rect
, true);
758 public String
hint() {
763 class TimeDrawAbsSec
extends TimeDraw
{
764 static String _hint
= "HH:mm:ss"; //$NON-NLS-1$
767 public void draw(GC gc
, long time
, Rectangle rect
) {
768 String stime
= stimeformat
.format(new Date(time
/ 1000000));
769 Utils
.drawText(gc
, stime
, rect
, true);
773 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
774 String header
= stimeformatheader
.format(new Date(time
/ 1000000));
775 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
776 if (headerwidth
<= rect
.width
) {
777 rect
.x
+= (rect
.width
- headerwidth
);
778 Utils
.drawText(gc
, header
, rect
, true);
783 public String
hint() {
788 class TimeDrawAbsMillisec
extends TimeDraw
{
789 static String _hint
= "HH:ss:ms"; //$NON-NLS-1$
792 public void draw(GC gc
, long time
, Rectangle rect
) {
793 String stime
= stimeformat
.format(new Date(time
/ 1000000));
794 String ns
= Utils
.formatNs(time
, Resolution
.MILLISEC
);
796 Utils
.drawText(gc
, stime
+ "." + ns
, rect
, true); //$NON-NLS-1$
800 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
801 String header
= stimeformatheader
.format(new Date(time
/ 1000000));
802 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
803 if (headerwidth
<= rect
.width
) {
804 rect
.x
+= (rect
.width
- headerwidth
);
805 Utils
.drawText(gc
, header
, rect
, true);
810 public String
hint() {
815 class TimeDrawAbsMicroSec
extends TimeDraw
{
816 static String _hint
= "HH:ss:ms:mcs"; //$NON-NLS-1$
819 public void draw(GC gc
, long time
, Rectangle rect
) {
820 String stime
= stimeformat
.format(new Date(time
/ 1000000));
821 String micr
= Utils
.formatNs(time
, Resolution
.MICROSEC
);
822 Utils
.drawText(gc
, stime
+ "." + micr
, rect
, true); //$NON-NLS-1$
826 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
827 String header
= stimeformatheader
.format(new Date(time
/ 1000000));
828 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
829 if (headerwidth
<= rect
.width
) {
830 rect
.x
+= (rect
.width
- headerwidth
);
831 Utils
.drawText(gc
, header
, rect
, true);
836 public String
hint() {
841 class TimeDrawAbsNanoSec
extends TimeDraw
{
842 static String _hint
= "HH:ss:ms:mcs:ns"; //$NON-NLS-1$
845 public void draw(GC gc
, long time
, Rectangle rect
) {
846 String stime
= stimeformat
.format(new Date(time
/ 1000000));
847 String ns
= Utils
.formatNs(time
, Resolution
.NANOSEC
);
848 Utils
.drawText(gc
, stime
+ "." + ns
, rect
, true); //$NON-NLS-1$
852 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
853 String header
= stimeformatheader
.format(new Date(time
/ 1000000));
854 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
855 if (headerwidth
<= rect
.width
) {
856 rect
.x
+= (rect
.width
- headerwidth
);
857 Utils
.drawText(gc
, header
, rect
, true);
862 public String
hint() {
868 class TimeDrawNumber
extends TimeDraw
{
871 public void draw(GC gc
, long time
, Rectangle rect
) {
872 String stime
= NumberFormat
.getInstance().format(time
);
873 Utils
.drawText(gc
, stime
, rect
, true);
877 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
878 String header
= NumberFormat
.getInstance().format(time
);
879 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
880 if (headerwidth
<= rect
.width
) {
881 rect
.x
+= (rect
.width
- headerwidth
);
882 Utils
.drawText(gc
, header
, rect
, true);
887 public String
hint() {
888 return "cycle"; //$NON-NLS-1$