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