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
.SimpleDateFormat
;
19 import java
.util
.Calendar
;
20 import java
.util
.Date
;
21 import java
.util
.GregorianCalendar
;
23 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.Resolution
;
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 MouseListener
, MouseMoveListener
{
45 public TimeGraphScale(Composite parent
, TimeGraphColorScheme colors
) {
46 super(parent
, colors
, SWT
.NO_BACKGROUND
| SWT
.NO_FOCUS
| SWT
.DOUBLE_BUFFERED
);
47 addMouseListener(this);
48 addMouseMoveListener(this);
51 private static final long SEC_IN_NS
= 1000000000;
52 private static final long MIN_IN_NS
= 60 * SEC_IN_NS
;
53 private static final long HOUR_IN_NS
= 60 * MIN_IN_NS
;
54 private static final long DAY_IN_NS
= 24 * HOUR_IN_NS
;
55 private static final long MONTH_IN_NS
= 31 * DAY_IN_NS
; // upper limit
56 private static final long YEAR_IN_NS
= 366 * DAY_IN_NS
; // upper limit
58 private static final double LOG10_1
= Math
.log10(1);
59 private static final double LOG10_2
= Math
.log10(2);
60 private static final double LOG10_3
= Math
.log10(3);
61 private static final double LOG10_5
= Math
.log10(5);
63 private static final Calendar GREGORIAN_CALENDAR
= GregorianCalendar
.getInstance();
65 private ITimeDataProvider _timeProvider
;
66 private int _dragState
= 0;
67 private int _dragX0
= 0;
68 private int _dragX
= 0;
69 private long _time0bak
;
70 private long _time1bak
;
71 private boolean _isInUpdate
;
72 private final Rectangle _rect0
= new Rectangle(0, 0, 0, 0);
75 public void setTimeProvider(ITimeDataProvider timeProvider
) {
76 _timeProvider
= timeProvider
;
79 private long _timeDelta
;
82 public Point
computeSize(int wHint
, int hHint
, boolean changed
) {
83 return super.computeSize(wHint
, _height
, changed
);
86 public void setHeight(int height
) {
87 this._height
= height
;
90 private void calcTimeDelta(int width
, double pixelsPerNanoSec
) {
91 double minDelta
= (double) ((pixelsPerNanoSec
== 0) ? YEAR_IN_NS
: width
/ pixelsPerNanoSec
);
93 if (_timeProvider
!= null && _timeProvider
.isCalendarFormat()) {
94 if (minDelta
> 6 * MONTH_IN_NS
) {
96 } else if (minDelta
> 3 * MONTH_IN_NS
) {
97 unit
= 6 * MONTH_IN_NS
;
98 } else if (minDelta
> 10 * DAY_IN_NS
) {
100 } else if (minDelta
> 12 * HOUR_IN_NS
) {
102 } else if (minDelta
> 3 * HOUR_IN_NS
) {
103 unit
= 6 * HOUR_IN_NS
;
104 } else if (minDelta
> 30 * MIN_IN_NS
) {
106 } else if (minDelta
> 10 * MIN_IN_NS
) {
107 unit
= 15 * MIN_IN_NS
;
108 } else if (minDelta
> 30 * SEC_IN_NS
) {
110 } else if (minDelta
> 20 * SEC_IN_NS
) {
111 unit
= 30 * SEC_IN_NS
;
112 } else if (minDelta
<= 1) {
117 double log
= Math
.log10((double) minDelta
/ unit
);
118 long pow10
= (long) log
;
119 double remainder
= log
- pow10
;
120 if (remainder
< LOG10_1
) {
121 _timeDelta
= (long) Math
.pow(10, pow10
) * unit
;
122 } else if (remainder
< LOG10_2
) {
123 _timeDelta
= 2 * (long) Math
.pow(10, pow10
) * unit
;
124 } else if (remainder
< LOG10_3
&& unit
>= HOUR_IN_NS
&& unit
< YEAR_IN_NS
) {
125 _timeDelta
= 3 * (long) Math
.pow(10, pow10
) * unit
;
126 } else if (remainder
< LOG10_5
) {
127 _timeDelta
= 5 * (long) Math
.pow(10, pow10
) * unit
;
129 _timeDelta
= 10 * (long) Math
.pow(10, pow10
) * unit
;
133 private static TimeDraw TIMEDRAW_NANOSEC
= new TimeDrawNanosec();
134 private static TimeDraw TIMEDRAW_MICROSEC
= new TimeDrawMicrosec();
135 private static TimeDraw TIMEDRAW_MILLISEC
= new TimeDrawMillisec();
136 private static TimeDraw TIMEDRAW_SEC
= new TimeDrawSec();
137 private static TimeDraw TIMEDRAW_ABS_NANOSEC
= new TimeDrawAbsNanoSec();
138 private static TimeDraw TIMEDRAW_ABS_MICROSEC
= new TimeDrawAbsMicroSec();
139 private static TimeDraw TIMEDRAW_ABS_MILLISEC
= new TimeDrawAbsMillisec();
140 private static TimeDraw TIMEDRAW_ABS_SEC
= new TimeDrawAbsSec();
141 private static TimeDraw TIMEDRAW_ABS_MIN
= new TimeDrawAbsMin();
142 private static TimeDraw TIMEDRAW_ABS_HRS
= new TimeDrawAbsHrs();
143 private static TimeDraw TIMEDRAW_ABS_DAY
= new TimeDrawAbsDay();
144 private static TimeDraw TIMEDRAW_ABS_MONTH
= new TimeDrawAbsMonth();
145 private static TimeDraw TIMEDRAW_ABS_YEAR
= new TimeDrawAbsYear();
147 TimeDraw
getTimeDraw(long timeDelta
) {
149 if (_timeProvider
!= null && _timeProvider
.isCalendarFormat()) {
150 if (timeDelta
>= YEAR_IN_NS
) {
151 timeDraw
= TIMEDRAW_ABS_YEAR
;
152 } else if (timeDelta
>= MONTH_IN_NS
) {
153 timeDraw
= TIMEDRAW_ABS_MONTH
;
154 } else if (timeDelta
>= DAY_IN_NS
) {
155 timeDraw
= TIMEDRAW_ABS_DAY
;
156 } else if (timeDelta
>= HOUR_IN_NS
) {
157 timeDraw
= TIMEDRAW_ABS_HRS
;
158 } else if (timeDelta
>= MIN_IN_NS
) {
159 timeDraw
= TIMEDRAW_ABS_MIN
;
160 } else if (timeDelta
>= SEC_IN_NS
) {
161 timeDraw
= TIMEDRAW_ABS_SEC
;
162 } else if (timeDelta
>= 1000000) {
163 timeDraw
= TIMEDRAW_ABS_MILLISEC
;
164 } else if (timeDelta
>= 1000) {
165 timeDraw
= TIMEDRAW_ABS_MICROSEC
;
167 timeDraw
= TIMEDRAW_ABS_NANOSEC
;
171 if (timeDelta
>= 1000000000) {
172 timeDraw
= TIMEDRAW_SEC
;
173 } else if (timeDelta
>= 1000000) {
174 timeDraw
= TIMEDRAW_MILLISEC
;
175 } else if (timeDelta
>= 1000) {
176 timeDraw
= TIMEDRAW_MICROSEC
;
178 timeDraw
= TIMEDRAW_NANOSEC
;
184 void paint(Rectangle rect
, PaintEvent e
) {
186 if (_isInUpdate
|| null == _timeProvider
) {
191 gc
.fillRectangle(rect
);
193 long time0
= _timeProvider
.getTime0();
194 long time1
= _timeProvider
.getTime1();
195 long selectedTime
= _timeProvider
.getSelectedTime();
196 int leftSpace
= _timeProvider
.getNameSpace();
197 int timeSpace
= _timeProvider
.getTimeSpace();
199 gc
.setBackground(_colors
.getColor(TimeGraphColorScheme
.TOOL_BACKGROUND
));
200 gc
.setForeground(_colors
.getColor(TimeGraphColorScheme
.TOOL_FOREGROUND
));
201 Utils
.init(_rect0
, rect
);
203 // draw top left area
204 _rect0
.width
= leftSpace
;
207 Rectangle absHeaderRect
= new Rectangle(_rect0
.x
, _rect0
.y
, _rect0
.width
, _rect0
.height
);
211 // prepare and draw right rect of the timescale
212 _rect0
.x
+= leftSpace
;
213 _rect0
.width
= rect
.width
- leftSpace
;
215 // draw bottom border and erase all other area
216 gc
.drawLine(rect
.x
, rect
.y
+ rect
.height
- 1, rect
.x
+ rect
.width
- 1,
217 rect
.y
+ rect
.height
- 1);
219 gc
.fillRectangle(_rect0
);
221 if (time1
<= time0
|| timeSpace
< 2) {
225 int numDigits
= calculateDigits(time0
, time1
);
227 int labelWidth
= gc
.getCharWidth('0') * numDigits
;
228 double pixelsPerNanoSec
= (timeSpace
<= RIGHT_MARGIN
) ?
0 :
229 (double) (timeSpace
- RIGHT_MARGIN
) / (time1
- time0
);
230 calcTimeDelta(labelWidth
, pixelsPerNanoSec
);
232 TimeDraw timeDraw
= getTimeDraw(_timeDelta
);
234 // draw zoom rectangle
235 if (3 == _dragState
&& null != _timeProvider
) {
236 if (_dragX0
< _dragX
) {
237 gc
.drawRectangle(leftSpace
+ _dragX0
, rect
.y
, _dragX
- _dragX0
- 1, rect
.height
- 8);
238 } else if (_dragX0
> _dragX
) {
239 gc
.drawRectangle(leftSpace
+ _dragX
, rect
.y
, _dragX0
- _dragX
- 1, rect
.height
- 8);
243 if (_rect0
.isEmpty()) {
247 // draw selected time
248 int x
= _rect0
.x
+ (int) ((double)(selectedTime
- time0
) * pixelsPerNanoSec
);
249 if (x
>= _rect0
.x
&& x
< _rect0
.x
+ _rect0
.width
) {
250 gc
.setForeground(_colors
.getColor(TimeGraphColorScheme
.SELECTED_TIME
));
251 gc
.drawLine(x
, _rect0
.y
+ _rect0
.height
- 6, x
, _rect0
.y
253 gc
.setForeground(_colors
.getColor(TimeGraphColorScheme
.TOOL_FOREGROUND
));
256 // draw time scale ticks
258 _rect0
.height
= rect
.height
- 4;
259 _rect0
.width
= labelWidth
;
262 if (_timeProvider
!= null && _timeProvider
.isCalendarFormat()) {
263 time
= floorToCalendar(time0
, _timeDelta
);
265 time
= (long) (Math
.ceil((double) time0
/ _timeDelta
) * _timeDelta
);
268 int y
= _rect0
.y
+ _rect0
.height
;
270 if (_timeProvider
!= null && _timeProvider
.isCalendarFormat()) {
271 timeDraw
.drawAbsHeader(gc
, time
, absHeaderRect
);
275 x
= rect
.x
+ leftSpace
+ (int) (Math
.floor((time
- time0
) * pixelsPerNanoSec
));
276 if (x
>= rect
.x
+ leftSpace
+ rect
.width
- _rect0
.width
) {
279 if (x
>= rect
.x
+ leftSpace
) {
280 gc
.drawLine(x
, y
, x
, y
+ 4);
282 if (x
+ _rect0
.width
<= rect
.x
+ rect
.width
) {
283 timeDraw
.draw(gc
, time
, _rect0
);
286 if (pixelsPerNanoSec
== 0 || time
> Long
.MAX_VALUE
- _timeDelta
|| _timeDelta
== 0) {
289 if (_timeProvider
!= null && _timeProvider
.isCalendarFormat()) {
290 if (_timeDelta
>= YEAR_IN_NS
) {
291 long millis
= time
/ 1000000L;
292 GREGORIAN_CALENDAR
.setTime(new Date(millis
));
293 GREGORIAN_CALENDAR
.add(Calendar
.YEAR
, (int) (_timeDelta
/ YEAR_IN_NS
));
294 millis
= GREGORIAN_CALENDAR
.getTimeInMillis();
295 time
= millis
* 1000000L;
296 } else if (_timeDelta
>= MONTH_IN_NS
) {
297 long millis
= time
/ 1000000L;
298 GREGORIAN_CALENDAR
.setTime(new Date(millis
));
299 GREGORIAN_CALENDAR
.add(Calendar
.MONTH
, (int) (_timeDelta
/ MONTH_IN_NS
));
300 millis
= GREGORIAN_CALENDAR
.getTimeInMillis();
301 time
= millis
* 1000000L;
302 } else if (_timeDelta
>= DAY_IN_NS
) {
303 long millis
= time
/ 1000000L;
304 GREGORIAN_CALENDAR
.setTime(new Date(millis
));
305 GREGORIAN_CALENDAR
.add(Calendar
.DAY_OF_MONTH
, (int) (_timeDelta
/ DAY_IN_NS
));
306 millis
= GREGORIAN_CALENDAR
.getTimeInMillis();
307 time
= millis
* 1000000L;
317 private long floorToCalendar(long time
, long timeDelta
) {
318 if (_timeDelta
>= YEAR_IN_NS
) {
319 GREGORIAN_CALENDAR
.setTime(new Date(time
/ 1000000));
320 int year
= GREGORIAN_CALENDAR
.get(Calendar
.YEAR
);
321 int yearDelta
= (int) (timeDelta
/ YEAR_IN_NS
);
322 year
= (year
/ yearDelta
) * yearDelta
;
323 GREGORIAN_CALENDAR
.set(Calendar
.YEAR
, year
);
324 GREGORIAN_CALENDAR
.set(Calendar
.MONTH
, 0); // January 1st of year
325 GREGORIAN_CALENDAR
.set(Calendar
.DAY_OF_MONTH
, 1);
326 GREGORIAN_CALENDAR
.set(Calendar
.HOUR_OF_DAY
, 0);
327 GREGORIAN_CALENDAR
.set(Calendar
.MINUTE
, 0);
328 GREGORIAN_CALENDAR
.set(Calendar
.SECOND
, 0);
329 GREGORIAN_CALENDAR
.set(Calendar
.MILLISECOND
, 0);
330 time
= GREGORIAN_CALENDAR
.getTimeInMillis() * 1000000;
331 } else if (_timeDelta
>= MONTH_IN_NS
) {
332 GREGORIAN_CALENDAR
.setTime(new Date(time
/ 1000000));
333 int month
= GREGORIAN_CALENDAR
.get(Calendar
.MONTH
);
334 int monthDelta
= (int) (timeDelta
/ MONTH_IN_NS
);
335 month
= (month
/ monthDelta
) * monthDelta
;
336 GREGORIAN_CALENDAR
.set(Calendar
.MONTH
, month
);
337 GREGORIAN_CALENDAR
.set(Calendar
.DAY_OF_MONTH
, 1); // 1st of month
338 GREGORIAN_CALENDAR
.set(Calendar
.HOUR_OF_DAY
, 0);
339 GREGORIAN_CALENDAR
.set(Calendar
.MINUTE
, 0);
340 GREGORIAN_CALENDAR
.set(Calendar
.SECOND
, 0);
341 GREGORIAN_CALENDAR
.set(Calendar
.MILLISECOND
, 0);
342 time
= GREGORIAN_CALENDAR
.getTimeInMillis() * 1000000;
344 long offset
= GREGORIAN_CALENDAR
.getTimeZone().getOffset(time
/ 1000000L) * 1000000L;
346 time
= (time
/ timeDelta
) * timeDelta
;
352 private int calculateDigits(long time0
, long time1
) {
354 long timeRange
= time1
- time0
;
356 if (_timeProvider
.isCalendarFormat()) {
357 // Calculate the number of digits to represent the minutes provided
361 if (timeRange
< 10000) {
362 // HH:11:222:333:444__
364 } else if (timeRange
< 10000000) {
369 // Calculate the number of digits to represent the minutes provided
370 long min
= (long) ((time1
* 1E-9) / 60); // to sec then to minutes
371 String strMinutes
= String
.valueOf(min
);
373 if (strMinutes
!= null) {
374 numDigits
+= strMinutes
.length();
378 if (timeRange
< 10000) {
381 } else if (timeRange
< 10000000) {
391 public void mouseDown(MouseEvent e
) {
392 getParent().setFocus();
393 if (_dragState
== 0 && null != _timeProvider
) {
394 int x
= e
.x
- _timeProvider
.getNameSpace();
395 if (1 == e
.button
&& x
> 0) {
398 } else if (3 == e
.button
) {
403 } else if (x
> getSize().x
- _timeProvider
.getNameSpace()) {
404 x
= getSize().x
- _timeProvider
.getNameSpace();
406 _dragX
= _dragX0
= x
;
407 _time0bak
= _timeProvider
.getTime0();
408 _time1bak
= _timeProvider
.getTime1();
413 public void mouseUp(MouseEvent e
) {
414 if (e
.button
== 1 && _dragState
== 1) {
418 // Notify time provider to check the need for listener notification
419 if (_dragX
!= _dragX0
&& _timeProvider
.getTime0() != _timeProvider
.getTime1()) {
420 _timeProvider
.setStartFinishTimeNotify(_timeProvider
.getTime0(), _timeProvider
.getTime1());
422 } else if (e
.button
== 3 && _dragState
== 3 && null != _timeProvider
) {
424 if (_dragX0
== _dragX
|| _timeProvider
.getTime0() == _timeProvider
.getTime1()) {
427 int timeSpace
= _timeProvider
.getTimeSpace();
428 int leftSpace
= _timeProvider
.getNameSpace();
429 int x
= Math
.max(0, e
.x
- leftSpace
);
432 if (_dragX0
> _dragX
) { // drag right to left
436 long time0
= _time0bak
+ (long) ((_time1bak
- _time0bak
) * ((double) _dragX0
/ timeSpace
));
437 long time1
= _time0bak
+ (long) ((_time1bak
- _time0bak
) * ((double) _dragX
/ timeSpace
));
439 _timeProvider
.setStartFinishTimeNotify(time0
, time1
);
440 _time0bak
= _timeProvider
.getTime0();
441 _time1bak
= _timeProvider
.getTime1();
447 public void mouseMove(MouseEvent e
) {
448 if (_dragX0
< 0 || _dragState
== 0 || _timeProvider
== null) {
451 Point size
= getSize();
452 int leftSpace
= _timeProvider
.getNameSpace();
453 int timeSpace
= _timeProvider
.getTimeSpace();
454 int x
= e
.x
- leftSpace
;
455 if (1 == _dragState
) {
456 if (x
> 0 && size
.x
> leftSpace
&& _dragX
!= x
) {
458 if (_timeProvider
.getTime0() == _timeProvider
.getTime1()) {
461 long interval
= (long) ((_time1bak
- _time0bak
) * ((double) _dragX0
/ _dragX
));
462 if (interval
== Long
.MAX_VALUE
) {
463 _timeProvider
.setStartFinishTime(_time0bak
, Long
.MAX_VALUE
);
465 long time1
= _time0bak
+ (long) ((_time1bak
- _time0bak
) * ((double) _dragX0
/ _dragX
));
466 _timeProvider
.setStartFinishTime(_time0bak
, time1
);
469 } else if (3 == _dragState
) {
472 } else if (x
> timeSpace
) {
482 public void mouseDoubleClick(MouseEvent e
) {
483 if (null != _timeProvider
&& _timeProvider
.getTime0() != _timeProvider
.getTime1()) {
484 _timeProvider
.resetStartFinishTime();
485 _time0bak
= _timeProvider
.getTime0();
486 _time1bak
= _timeProvider
.getTime1();
491 abstract class TimeDraw
{
492 static String S
= ":" ; //$NON-NLS-1$
493 static String S0
= ":0" ; //$NON-NLS-1$
494 static String S00
= ":00"; //$NON-NLS-1$
495 protected static final SimpleDateFormat stimeformat
= new SimpleDateFormat("HH:mm:ss"); //$NON-NLS-1$
496 protected static final SimpleDateFormat stimeformatheader
= new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$
497 protected static final SimpleDateFormat sminformat
= new SimpleDateFormat("HH:mm"); //$NON-NLS-1$
498 protected static final SimpleDateFormat sminformatheader
= new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$
499 protected static final SimpleDateFormat shrsformat
= new SimpleDateFormat("MMM dd HH:mm"); //$NON-NLS-1$
500 protected static final SimpleDateFormat shrsformatheader
= new SimpleDateFormat("yyyy"); //$NON-NLS-1$
501 protected static final SimpleDateFormat sdayformat
= new SimpleDateFormat("MMM dd"); //$NON-NLS-1$
502 protected static final SimpleDateFormat sdayformatheader
= new SimpleDateFormat("yyyy"); //$NON-NLS-1$
503 protected static final SimpleDateFormat smonthformat
= new SimpleDateFormat("yyyy MMM"); //$NON-NLS-1$
504 protected static final SimpleDateFormat syearformat
= new SimpleDateFormat("yyyy"); //$NON-NLS-1$
506 static String
pad(long n
) {
510 } else if (n
< 100) {
516 public abstract void draw(GC gc
, long time
, Rectangle rect
);
518 public void drawAbsHeader(GC gc
, long time
, Rectangle absHeaderRect
) {
519 // Override to draw absolute time header
520 // This is for the time information not shown in the draw of each tick
523 public abstract String
hint();
526 class TimeDrawSec
extends TimeDraw
{
527 static String _hint
= "sec"; //$NON-NLS-1$
530 public void draw(GC gc
, long time
, Rectangle rect
) {
532 Utils
.drawText(gc
, time
+ "", rect
, true); //$NON-NLS-1$
536 public String
hint() {
541 class TimeDrawMillisec
extends TimeDraw
{
542 static String _hint
= "s:ms"; //$NON-NLS-1$
545 public void draw(GC gc
, long time
, Rectangle rect
) {
547 long ms
= time
% 1000;
549 Utils
.drawText(gc
, time
+ pad(ms
), rect
, true);
553 public String
hint() {
558 class TimeDrawMicrosec
extends TimeDraw
{
559 static String _hint
= "s:ms:mcs"; //$NON-NLS-1$
562 public void draw(GC gc
, long time
, Rectangle rect
) {
564 long mcs
= time
% 1000;
566 long ms
= time
% 1000;
568 Utils
.drawText(gc
, time
+ pad(ms
) + pad(mcs
), rect
, true);
572 public String
hint() {
577 class TimeDrawNanosec
extends TimeDraw
{
578 static String _hint
= "s:ms:mcs:ns"; //$NON-NLS-1$
581 public void draw(GC gc
, long time
, Rectangle rect
) {
582 long ns
= time
% 1000;
584 long mcs
= time
% 1000;
586 long ms
= time
% 1000;
588 Utils
.drawText(gc
, time
+ pad(ms
) + pad(mcs
) + pad(ns
), rect
, true);
592 public String
hint() {
597 class TimeDrawAbsYear
extends TimeDraw
{
598 static String _hint
= "YYYY"; //$NON-NLS-1$
601 public void draw(GC gc
, long time
, Rectangle rect
) {
602 String stime
= syearformat
.format(new Date((long) (time
/ 1000000)));
603 Utils
.drawText(gc
, stime
, rect
, true);
607 public String
hint() {
612 class TimeDrawAbsMonth
extends TimeDraw
{
613 static String _hint
= "YYYY Mmm"; //$NON-NLS-1$
616 public void draw(GC gc
, long time
, Rectangle rect
) {
617 String stime
= smonthformat
.format(new Date((long) (time
/ 1000000)));
618 Utils
.drawText(gc
, stime
, rect
, true);
622 public String
hint() {
627 class TimeDrawAbsDay
extends TimeDraw
{
628 static String _hint
= "Mmm dd"; //$NON-NLS-1$
631 public void draw(GC gc
, long time
, Rectangle rect
) {
632 String stime
= sdayformat
.format(new Date((long) (time
/ 1000000)));
633 Utils
.drawText(gc
, stime
, rect
, true);
637 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
638 String header
= sdayformatheader
.format(new Date((long) (time
/ 1000000)));
639 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
640 if (headerwidth
<= rect
.width
) {
641 rect
.x
+= (rect
.width
- headerwidth
);
642 Utils
.drawText(gc
, header
, rect
, true);
647 public String
hint() {
652 class TimeDrawAbsHrs
extends TimeDraw
{
653 static String _hint
= "Mmm dd HH:mm"; //$NON-NLS-1$
656 public void draw(GC gc
, long time
, Rectangle rect
) {
657 String stime
= shrsformat
.format(new Date((long) (time
/ 1000000)));
658 Utils
.drawText(gc
, stime
, rect
, true);
662 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
663 String header
= shrsformatheader
.format(new Date((long) (time
/ 1000000)));
664 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
665 if (headerwidth
<= rect
.width
) {
666 rect
.x
+= (rect
.width
- headerwidth
);
667 Utils
.drawText(gc
, header
, rect
, true);
672 public String
hint() {
677 class TimeDrawAbsMin
extends TimeDraw
{
678 static String _hint
= "HH:mm"; //$NON-NLS-1$
681 public void draw(GC gc
, long time
, Rectangle rect
) {
682 String stime
= sminformat
.format(new Date((long) (time
/ 1000000)));
683 Utils
.drawText(gc
, stime
, rect
, true);
687 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
688 String header
= sminformatheader
.format(new Date((long) (time
/ 1000000)));
689 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
690 if (headerwidth
<= rect
.width
) {
691 rect
.x
+= (rect
.width
- headerwidth
);
692 Utils
.drawText(gc
, header
, rect
, true);
698 public String
hint() {
703 class TimeDrawAbsSec
extends TimeDraw
{
704 static String _hint
= "HH:mm:ss"; //$NON-NLS-1$
707 public void draw(GC gc
, long time
, Rectangle rect
) {
708 String stime
= stimeformat
.format(new Date((long) (time
/ 1000000)));
709 Utils
.drawText(gc
, stime
, rect
, true);
713 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
714 String header
= stimeformatheader
.format(new Date((long) (time
/ 1000000)));
715 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
716 if (headerwidth
<= rect
.width
) {
717 rect
.x
+= (rect
.width
- headerwidth
);
718 Utils
.drawText(gc
, header
, rect
, true);
723 public String
hint() {
728 class TimeDrawAbsMillisec
extends TimeDraw
{
729 static String _hint
= "HH:ss:ms"; //$NON-NLS-1$
732 public void draw(GC gc
, long time
, Rectangle rect
) {
733 String stime
= stimeformat
.format(new Date((long) (time
/ 1000000)));
734 String ns
= Utils
.formatNs(time
, Resolution
.MILLISEC
);
736 Utils
.drawText(gc
, stime
+ "." + ns
, rect
, true); //$NON-NLS-1$
740 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
741 String header
= stimeformatheader
.format(new Date((long) (time
/ 1000000)));
742 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
743 if (headerwidth
<= rect
.width
) {
744 rect
.x
+= (rect
.width
- headerwidth
);
745 Utils
.drawText(gc
, header
, rect
, true);
750 public String
hint() {
755 class TimeDrawAbsMicroSec
extends TimeDraw
{
756 static String _hint
= "HH:ss:ms:mcs"; //$NON-NLS-1$
759 public void draw(GC gc
, long time
, Rectangle rect
) {
760 String stime
= stimeformat
.format(new Date((long) (time
/ 1000000)));
761 String micr
= Utils
.formatNs(time
, Resolution
.MICROSEC
);
762 Utils
.drawText(gc
, stime
+ "." + micr
, rect
, true); //$NON-NLS-1$
766 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
767 String header
= stimeformatheader
.format(new Date((long) (time
/ 1000000)));
768 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
769 if (headerwidth
<= rect
.width
) {
770 rect
.x
+= (rect
.width
- headerwidth
);
771 Utils
.drawText(gc
, header
, rect
, true);
776 public String
hint() {
781 class TimeDrawAbsNanoSec
extends TimeDraw
{
782 static String _hint
= "HH:ss:ms:mcs:ns"; //$NON-NLS-1$
785 public void draw(GC gc
, long time
, Rectangle rect
) {
786 String stime
= stimeformat
.format(new Date((long) (time
/ 1000000)));
787 String ns
= Utils
.formatNs(time
, Resolution
.NANOSEC
);
788 Utils
.drawText(gc
, stime
+ "." + ns
, rect
, true); //$NON-NLS-1$
792 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
793 String header
= stimeformatheader
.format(new Date((long) (time
/ 1000000)));
794 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
795 if (headerwidth
<= rect
.width
) {
796 rect
.x
+= (rect
.width
- headerwidth
);
797 Utils
.drawText(gc
, header
, rect
, true);
802 public String
hint() {