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