Fix for bug289620
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / viewers / timeAnalysis / widgets / TimeScaleCtrl.java
CommitLineData
b0d3496e 1/*****************************************************************************\r
79a3a76e 2 * Copyright (c) 2007, 2008 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
b0d3496e 19import java.util.Date;\r
b0d3496e
ASL
20\r
21import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.Messages;\r
22import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.widgets.Utils.Resolution;\r
23import org.eclipse.swt.SWT;\r
24import org.eclipse.swt.events.MouseEvent;\r
25import org.eclipse.swt.events.MouseListener;\r
26import org.eclipse.swt.events.MouseMoveListener;\r
27import org.eclipse.swt.events.PaintEvent;\r
28import org.eclipse.swt.graphics.GC;\r
29import org.eclipse.swt.graphics.Point;\r
30import org.eclipse.swt.graphics.Rectangle;\r
31import org.eclipse.swt.widgets.Composite;\r
32\r
33public class TimeScaleCtrl extends TraceCtrl implements MouseListener,\r
34 MouseMoveListener {\r
35\r
36 public TimeScaleCtrl(Composite parent, TraceColorScheme colors) {\r
37 super(parent, colors, SWT.NO_BACKGROUND | SWT.NO_FOCUS\r
38 | SWT.DOUBLE_BUFFERED);\r
39 addMouseListener(this);\r
40 addMouseMoveListener(this);\r
41 }\r
42\r
b0d3496e
ASL
43 private ITimeDataProvider _timeProvider;\r
44 private int _dragState = 0;\r
45 private int _dragX0 = 0;\r
46 private int _dragX = 0;\r
47 private long _time0bak;\r
48 private long _time1bak;\r
49 private boolean _isInUpdate;\r
50 private Rectangle _rect0 = new Rectangle(0, 0, 0, 0);\r
b0d3496e
ASL
51\r
52 public void setTimeProvider(ITimeDataProvider timeProvider) {\r
53 _timeProvider = timeProvider;\r
54 }\r
55\r
79a3a76e 56 private double _timeDeltaD;\r
b0d3496e
ASL
57 private long _timeDelta;\r
58\r
79a3a76e
FC
59 private void calcTimeDelta(int width, double K) {\r
60 long D[] = { 1, 2, 5, };\r
61 long pow = 1;\r
62 double powD = 1;\r
63 long td = pow;\r
64 double tdD = powD;\r
65 double dx = tdD * K;\r
66 int i = 0;\r
67 while (dx < width) {\r
68 td = D[i] * pow;\r
69 tdD = D[i] * powD;\r
70 dx = tdD * K;\r
71 i++;\r
72 if (i == 3) {\r
73 i = 0;\r
74 pow *= 10;\r
75 powD *= 10;\r
76 }\r
77 }\r
78 _timeDeltaD = tdD;\r
79 _timeDelta = td;\r
80// Trace.debug("Width: " + width + " K: " + K + " Time Delta: "\r
81// + _timeDelta);\r
82 }\r
83\r
84 static private TimeDraw _tds[] = new TimeDraw[] { new TimeDrawSec(),\r
85 new TimeDrawMillisec(), new TimeDrawMicrosec(),\r
86 new TimeDrawNanosec(), new TimeDrawAbsSec(),\r
87 new TimeDrawAbsMillisec(), new TimeDrawAbsMicroSec(),\r
88 new TimeDrawAbsNanoSec() };\r
b0d3496e
ASL
89\r
90 TimeDraw getTimeDraw(long timeDelta) {\r
91 TimeDraw timeDraw;\r
79a3a76e
FC
92 if (_timeProvider != null) {\r
93 if (_timeProvider.isCalendarFormat()) {\r
94 if (timeDelta >= 1000000000)\r
95 timeDraw = _tds[4];\r
96 else if (timeDelta >= 1000000)\r
97 timeDraw = _tds[5];\r
98 else if (timeDelta >= 1000)\r
99 timeDraw = _tds[6];\r
100 else\r
101 timeDraw = _tds[7];\r
102 return timeDraw;\r
103 }\r
b0d3496e
ASL
104 }\r
105 if (timeDelta >= 1000000000)\r
79a3a76e 106 timeDraw = _tds[0];\r
b0d3496e 107 else if (timeDelta >= 1000000)\r
79a3a76e 108 timeDraw = _tds[1];\r
b0d3496e 109 else if (timeDelta >= 1000)\r
79a3a76e 110 timeDraw = _tds[2];\r
b0d3496e 111 else\r
79a3a76e 112 timeDraw = _tds[3];\r
b0d3496e
ASL
113 return timeDraw;\r
114 }\r
115\r
b0d3496e
ASL
116 void paint(Rectangle rect, PaintEvent e) {\r
117\r
118 if (_isInUpdate || null == _timeProvider)\r
119 return;\r
120\r
121 GC gc = e.gc;\r
b0d3496e 122 if (null == _timeProvider) {\r
79a3a76e 123 gc.fillRectangle(rect);\r
b0d3496e
ASL
124 return;\r
125 }\r
126\r
79a3a76e
FC
127 gc.setBackground(_colors.getColor(TraceColorScheme.TOOL_BACKGROUND));\r
128 gc.setForeground(_colors.getColor(TraceColorScheme.TOOL_FOREGROUND));\r
b0d3496e
ASL
129 long time0 = _timeProvider.getTime0();\r
130 long time1 = _timeProvider.getTime1();\r
131 long selectedTime = _timeProvider.getSelectedTime();\r
132 int leftSpace = _timeProvider.getNameSpace();\r
133 int timeSpace = _timeProvider.getTimeSpace();\r
79a3a76e
FC
134\r
135 if (time1 <= time0 || timeSpace < 2) {\r
136 gc.fillRectangle(rect);\r
137 return;\r
138 }\r
139\r
140 int numDigits = calculateDigits(time0, time1);\r
141\r
b0d3496e 142 Utils.init(_rect0, rect);\r
79a3a76e
FC
143 int labelWidth = gc.getCharWidth('0') * numDigits;\r
144 double K = 1;\r
145 if (rect.width - leftSpace > 0) {\r
146 K = (double) timeSpace / (time1 - time0);\r
147 calcTimeDelta(labelWidth, K);\r
148 }\r
b0d3496e 149 \r
79a3a76e
FC
150 TimeDraw timeDraw = getTimeDraw(_timeDelta);\r
151\r
b0d3496e
ASL
152 // draw top left area\r
153 _rect0.width = leftSpace;\r
79a3a76e 154 gc.fillRectangle(_rect0);\r
b0d3496e
ASL
155 _rect0.x += 4;\r
156 _rect0.width -= 4;\r
157 if (_rect0.width > 0) {\r
79a3a76e
FC
158// TODO: Check if we really need that piece of code... \r
159// if (false && rect.width - leftSpace > 0)\r
160// Utils.drawText(gc, Messages._Timescale + ": "\r
161// + timeDraw.hint(), _rect0, true);\r
162// else\r
163 Utils.drawText(gc, Messages._Timescale + ":", _rect0, true);\r
b0d3496e 164 }\r
b0d3496e
ASL
165 _rect0.x -= 4;\r
166 _rect0.width += 4;\r
79a3a76e 167\r
b0d3496e
ASL
168 // prepare and draw right rect of the timescale\r
169 _rect0.x += leftSpace;\r
170 _rect0.width = rect.width - leftSpace;\r
79a3a76e 171\r
b0d3496e
ASL
172 // draw bottom border and erase all other area\r
173 gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width - 1,\r
79a3a76e 174 rect.y + rect.height - 1);\r
b0d3496e
ASL
175 _rect0.height--;\r
176 gc.fillRectangle(_rect0);\r
b0d3496e
ASL
177\r
178 if (_rect0.isEmpty())\r
179 return;\r
180\r
181 // draw selected time\r
79a3a76e 182 int x = _rect0.x + (int) ((selectedTime - time0) * K);\r
b0d3496e
ASL
183 if (x >= _rect0.x && x < _rect0.x + _rect0.width) {\r
184 gc.setForeground(_colors.getColor(TraceColorScheme.SELECTED_TIME));\r
185 gc.drawLine(x, _rect0.y + _rect0.height - 6, x, _rect0.y\r
186 + _rect0.height);\r
187 gc\r
188 .setForeground(_colors\r
189 .getColor(TraceColorScheme.TOOL_FOREGROUND));\r
190 }\r
191\r
192 // draw time scale ticks\r
193 _rect0.y = rect.y;\r
194 _rect0.height = rect.height - 4;\r
195 _rect0.width = labelWidth;\r
79a3a76e 196 long time = (long) (Math.floor(time0 / _timeDeltaD) * _timeDeltaD);\r
b0d3496e 197 // long t = (long) (time * 1000000000);\r
79a3a76e 198 long t = time;\r
b0d3496e 199 int y = _rect0.y + _rect0.height;\r
b0d3496e 200 while (true) {\r
79a3a76e 201 x = rect.x + leftSpace + (int) ((time - time0) * K);\r
b0d3496e
ASL
202 if (x >= rect.x + leftSpace + rect.width - _rect0.width) {\r
203 break;\r
204 }\r
205 if (x >= rect.x + leftSpace) {\r
206 gc.drawLine(x, y, x, y + 4);\r
207 _rect0.x = x;\r
208 if (x + _rect0.width <= rect.x + rect.width)\r
79a3a76e 209 timeDraw.draw(gc, t, _rect0);\r
b0d3496e 210 }\r
79a3a76e
FC
211 time += _timeDeltaD;\r
212 t += _timeDelta;\r
b0d3496e
ASL
213 }\r
214 }\r
215\r
b0d3496e
ASL
216 private int calculateDigits(long time0, long time1) {\r
217 int numDigits = 5;\r
218 long timeRange = time1 - time0;\r
219\r
220 if (_timeProvider.isCalendarFormat()) {\r
221 // Calculate the number of digits to represent the minutes provided\r
222 // 11:222\r
223 // HH:mm:ss\r
79a3a76e 224 numDigits += 5;\r
b0d3496e
ASL
225 if (timeRange < 10000) {\r
226 // HH:11:222:333:444__\r
227 numDigits += 10;\r
228 } else if (timeRange < 10000000) {\r
229 // HH:11:222:333__\r
230 numDigits += 6;\r
231 }\r
232 } else {\r
233 // Calculate the number of digits to represent the minutes provided\r
234 long min = (long) ((time1 * 1E-9) / 60); // to sec then to minutes\r
235 String strMinutes = String.valueOf(min);\r
236 // 11:222\r
237 if (strMinutes != null) {\r
238 numDigits += strMinutes.length();\r
239 } else {\r
240 numDigits += 2;\r
241 }\r
242 if (timeRange < 10000) {\r
243 // 11:222:333:444__\r
244 numDigits += 8;\r
245 } else if (timeRange < 10000000) {\r
246 // 11:222:333__\r
247 numDigits += 4;\r
248 }\r
249 }\r
250\r
251// Trace.debug("timeRange: " + timeRange + " numDigits: " + numDigits);\r
252 return numDigits;\r
253 }\r
254\r
255 public void mouseDown(MouseEvent e) {\r
79a3a76e
FC
256 if (1 == e.button && null != _timeProvider) {\r
257 setCapture(true);\r
258 _dragState = 1;\r
259 }\r
260 // Window adjustment allowed using mouse button three.\r
261 _dragX = _dragX0 = e.x - _timeProvider.getNameSpace();\r
262 _time0bak = _timeProvider.getTime0();\r
263 _time1bak = _timeProvider.getTime1();\r
b0d3496e
ASL
264 }\r
265\r
266 public void mouseUp(MouseEvent e) {\r
79a3a76e 267 if (1 == _dragState) {\r
b0d3496e
ASL
268 setCapture(false);\r
269 _dragState = 0;\r
79a3a76e
FC
270 }\r
271\r
272 if (3 == e.button && null != _timeProvider) {\r
273 if (_dragX0 < 0) {\r
b0d3496e
ASL
274 return;\r
275 }\r
79a3a76e
FC
276 Point size = getSize();\r
277\r
b0d3496e
ASL
278 int leftSpace = _timeProvider.getNameSpace();\r
279 int x = e.x - leftSpace;\r
79a3a76e 280 if (x > 0 && size.x > leftSpace && _dragX != x) {\r
b0d3496e 281 _dragX = x;\r
79a3a76e
FC
282 long time0 = _time0bak + ((_time1bak - _time0bak) * _dragX0)\r
283 / (size.x - leftSpace);\r
284 long time1 = _time0bak + ((_time1bak - _time0bak) * _dragX)\r
285 / (size.x - leftSpace);\r
286\r
287 _timeProvider.setStartFinishTime(time0, time1);\r
b0d3496e
ASL
288 }\r
289 }\r
290 }\r
291\r
292 public void mouseMove(MouseEvent e) {\r
79a3a76e 293 if (_dragX0 < 0) {\r
b0d3496e
ASL
294 return;\r
295 }\r
296 Point size = getSize();\r
b0d3496e 297 if (1 == _dragState && null != _timeProvider) {\r
79a3a76e
FC
298 int leftSpace = _timeProvider.getNameSpace();\r
299 int x = e.x - leftSpace;\r
b0d3496e
ASL
300 if (x > 0 && size.x > leftSpace && _dragX != x) {\r
301 _dragX = x;\r
79a3a76e
FC
302 long time1 = _time0bak + ((_time1bak - _time0bak) * _dragX0)\r
303 / _dragX;\r
b0d3496e
ASL
304 _timeProvider.setStartFinishTime(_time0bak, time1);\r
305 }\r
b0d3496e
ASL
306 }\r
307 }\r
308\r
309 public void mouseDoubleClick(MouseEvent e) {\r
310 if (null != _timeProvider) {\r
311 _timeProvider.resetStartFinishTime();\r
b0d3496e
ASL
312 }\r
313 }\r
314}\r
315\r
316abstract class TimeDraw {\r
317 static String S = ":";\r
318 static String S0 = ":0";\r
319 static String S00 = ":00";\r
79a3a76e 320 protected SimpleDateFormat stimeformat = new SimpleDateFormat("HH:mm:ss");\r
b0d3496e
ASL
321 \r
322 static String pad(long n) {\r
323 String s = S;\r
324 if (n < 10)\r
325 s = S00;\r
326 else if (n < 100)\r
327 s = S0;\r
328 return s + n;\r
329 }\r
330\r
79a3a76e 331 public abstract void draw(GC gc, long time, Rectangle rect);\r
b0d3496e 332\r
b0d3496e
ASL
333 public abstract String hint();\r
334}\r
335\r
336class TimeDrawSec extends TimeDraw {\r
337 static String _hint = "sec";\r
338\r
b0d3496e
ASL
339 public void draw(GC gc, long time, Rectangle rect) {\r
340 time /= 1000000000;\r
341 Utils.drawText(gc, time + "", rect, true);\r
342 }\r
343\r
b0d3496e
ASL
344 public String hint() {\r
345 return _hint;\r
346 }\r
347}\r
348\r
349class TimeDrawMillisec extends TimeDraw {\r
350 static String _hint = "s:ms";\r
351\r
b0d3496e
ASL
352 public void draw(GC gc, long time, Rectangle rect) {\r
353 time /= 1000000;\r
354 long ms = time % 1000;\r
355 time /= 1000;\r
356 Utils.drawText(gc, time + pad(ms), rect, true);\r
357 }\r
358\r
b0d3496e
ASL
359 public String hint() {\r
360 return _hint;\r
361 }\r
362}\r
363\r
364class TimeDrawMicrosec extends TimeDraw {\r
365 static String _hint = "s:ms:mcs";\r
366\r
b0d3496e
ASL
367 public void draw(GC gc, long time, Rectangle rect) {\r
368 time /= 1000;\r
369 long mcs = time % 1000;\r
370 time /= 1000;\r
371 long ms = time % 1000;\r
372 time /= 1000;\r
373 Utils.drawText(gc, time + pad(ms) + pad(mcs), rect, true);\r
374 }\r
375\r
b0d3496e
ASL
376 public String hint() {\r
377 return _hint;\r
378 }\r
379}\r
380\r
381class TimeDrawNanosec extends TimeDraw {\r
382 static String _hint = "s:ms:mcs:ns";\r
383\r
b0d3496e
ASL
384 public void draw(GC gc, long time, Rectangle rect) {\r
385 long ns = time % 1000;\r
386 time /= 1000;\r
387 long mcs = time % 1000;\r
388 time /= 1000;\r
389 long ms = time % 1000;\r
390 time /= 1000;\r
391 Utils.drawText(gc, time + pad(ms) + pad(mcs) + pad(ns), rect, true);\r
392 }\r
393\r
b0d3496e
ASL
394 public String hint() {\r
395 return _hint;\r
396 }\r
397}\r
398\r
79a3a76e
FC
399class TimeDrawAbsSec extends TimeDraw {\r
400 static String _hint = "HH:mm:ss";\r
b0d3496e 401\r
79a3a76e
FC
402 public void draw(GC gc, long time, Rectangle rect) {\r
403 String stime = stimeformat.format(new Date((long) (time * 1E-6)));\r
404 Utils.drawText(gc, stime, rect, true);\r
405 }\r
b0d3496e 406\r
79a3a76e
FC
407 public String hint() {\r
408 return _hint;\r
409 }\r
b0d3496e
ASL
410}\r
411\r
412class TimeDrawAbsMillisec extends TimeDraw {\r
413 static String _hint = "HH:ss:ms";\r
414\r
b0d3496e 415 public void draw(GC gc, long time, Rectangle rect) {\r
79a3a76e 416 String stime = stimeformat.format(new Date((long) (time * 1E-6)));\r
b0d3496e
ASL
417 String ns = Utils.formatNs(time, Resolution.MILLISEC);\r
418\r
419 Utils.drawText(gc, stime + " " + ns, rect, true);\r
420 }\r
421\r
b0d3496e
ASL
422 public String hint() {\r
423 return _hint;\r
424 }\r
425}\r
426\r
427class TimeDrawAbsMicroSec extends TimeDraw {\r
428 static String _hint = "HH:ss:ms:mcs";\r
429\r
b0d3496e 430 public void draw(GC gc, long time, Rectangle rect) {\r
79a3a76e 431 String stime = stimeformat.format(new Date((long) (time * 1E-6)));\r
b0d3496e
ASL
432 String micr = Utils.formatNs(time, Resolution.MICROSEC);\r
433 Utils.drawText(gc, stime + " " + micr, rect, true);\r
434 }\r
435\r
b0d3496e
ASL
436 public String hint() {\r
437 return _hint;\r
438 }\r
439}\r
440\r
441class TimeDrawAbsNanoSec extends TimeDraw {\r
442 static String _hint = "HH:ss:ms:mcs:ns";\r
443\r
b0d3496e 444 public void draw(GC gc, long time, Rectangle rect) {\r
79a3a76e 445 String stime = stimeformat.format(new Date((long) (time * 1E-6)));\r
b0d3496e
ASL
446 String ns = Utils.formatNs(time, Resolution.NANOSEC);\r
447 Utils.drawText(gc, stime + " " + ns, rect, true);\r
448 }\r
449\r
b0d3496e
ASL
450 public String hint() {\r
451 return _hint;\r
452 }\r
453}\r
This page took 0.046946 seconds and 5 git commands to generate.