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