Commit | Line | Data |
---|---|---|
73005152 BH |
1 | /********************************************************************** |
2 | * Copyright (c) 2005, 2008, 2011 IBM Corporation and others. | |
3 | * All rights reserved. This program and the accompanying materials | |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | * $Id: TimeCompressionBar.java,v 1.3 2008/01/24 02:29:01 apnan Exp $ | |
8 | * | |
9 | * Contributors: | |
10 | * IBM - Initial API and implementation | |
11 | * Bernd Hufmann - Updated for TMF | |
12 | * | |
13 | **********************************************************************/ | |
14 | package org.eclipse.linuxtools.tmf.ui.views.uml2sd; | |
15 | ||
16 | import java.util.ArrayList; | |
17 | import java.util.Arrays; | |
18 | import java.util.List; | |
19 | ||
4df4581d | 20 | import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp; |
6c13869b | 21 | import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp; |
73005152 BH |
22 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.AsyncMessage; |
23 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.AsyncMessageReturn; | |
24 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.BaseMessage; | |
25 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.ExecutionOccurrence; | |
26 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Frame; | |
27 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode; | |
28 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.ITimeRange; | |
29 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline; | |
30 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Metrics; | |
31 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SDTimeEvent; | |
32 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.SyncMessage; | |
33 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; | |
34 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.impl.ColorImpl; | |
35 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; | |
36 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.TimeEventComparator; | |
37 | import org.eclipse.swt.SWT; | |
38 | import org.eclipse.swt.accessibility.ACC; | |
39 | import org.eclipse.swt.accessibility.Accessible; | |
40 | import org.eclipse.swt.accessibility.AccessibleAdapter; | |
41 | import org.eclipse.swt.accessibility.AccessibleControlAdapter; | |
42 | import org.eclipse.swt.accessibility.AccessibleControlEvent; | |
43 | import org.eclipse.swt.accessibility.AccessibleEvent; | |
44 | import org.eclipse.swt.events.DisposeEvent; | |
45 | import org.eclipse.swt.events.DisposeListener; | |
46 | import org.eclipse.swt.events.FocusEvent; | |
47 | import org.eclipse.swt.events.FocusListener; | |
48 | import org.eclipse.swt.events.KeyEvent; | |
49 | import org.eclipse.swt.events.MouseEvent; | |
50 | import org.eclipse.swt.events.TraverseEvent; | |
51 | import org.eclipse.swt.events.TraverseListener; | |
52 | import org.eclipse.swt.graphics.Color; | |
53 | import org.eclipse.swt.graphics.GC; | |
54 | import org.eclipse.swt.graphics.Image; | |
55 | import org.eclipse.swt.widgets.Composite; | |
56 | import org.eclipse.swt.widgets.Control; | |
57 | import org.eclipse.swt.widgets.Display; | |
58 | ||
59 | /** | |
60 | * @author sveyrier | |
61 | * | |
62 | */ | |
63 | public class TimeCompressionBar extends ScrollView implements DisposeListener { | |
64 | ||
65 | /** | |
66 | * The listener list | |
67 | */ | |
68 | protected ArrayList<ITimeCompressionListener> listenerList = null; | |
69 | ||
70 | protected Frame frame = null; | |
71 | protected List<SDTimeEvent> nodeList = null; | |
4df4581d | 72 | protected ITmfTimestamp min = new TmfTimestamp(); |
73 | protected ITmfTimestamp max = new TmfTimestamp(); | |
73005152 BH |
74 | protected float zoomValue = 1; |
75 | protected DrawableToolTip tooltip = null; | |
76 | ||
77 | protected ColorImpl[] col; | |
78 | ||
79 | protected Accessible accessible = null; | |
80 | ||
81 | protected int focusedWidget = -1; | |
82 | ||
83 | protected SDView view = null; | |
84 | ||
85 | protected Lifeline ll = null; | |
86 | protected int ls = 0; | |
87 | protected int ln = 0; | |
88 | protected IColor lc = null; | |
89 | ||
90 | protected int nextNodeY = 0; | |
91 | protected int prevNodeY = 0; | |
92 | ||
93 | public TimeCompressionBar(Composite parent, int s) { | |
94 | super(parent, s | SWT.NO_BACKGROUND, false); | |
95 | setVScrollBarMode(ScrollView.ALWAYS_OFF); | |
96 | setHScrollBarMode(ScrollView.ALWAYS_OFF); | |
97 | listenerList = new ArrayList<ITimeCompressionListener>(); | |
98 | col = new ColorImpl[10]; | |
99 | col[0] = new ColorImpl(Display.getDefault(), 255, 229, 229); | |
100 | col[1] = new ColorImpl(Display.getDefault(), 255, 204, 204); | |
101 | col[2] = new ColorImpl(Display.getDefault(), 255, 178, 178); | |
102 | col[3] = new ColorImpl(Display.getDefault(), 255, 153, 153); | |
103 | col[4] = new ColorImpl(Display.getDefault(), 255, 127, 127); | |
104 | col[5] = new ColorImpl(Display.getDefault(), 255, 102, 102); | |
105 | col[6] = new ColorImpl(Display.getDefault(), 255, 76, 76); | |
106 | col[7] = new ColorImpl(Display.getDefault(), 255, 51, 51); | |
107 | col[8] = new ColorImpl(Display.getDefault(), 255, 25, 25); | |
108 | col[9] = new ColorImpl(Display.getDefault(), 255, 0, 0); | |
109 | super.addDisposeListener(this); | |
110 | ||
111 | accessible = getViewControl().getAccessible(); | |
112 | ||
113 | accessible.addAccessibleListener(new AccessibleAdapter() { | |
114 | @Override | |
115 | public void getName(AccessibleEvent e) { | |
116 | if (e.childID == ACC.CHILDID_SELF) { | |
117 | // e.result = "Sequence Diagram"; | |
118 | } | |
119 | // Case toolTip | |
120 | else if (e.childID == 0) { | |
121 | if (tooltip != null) | |
122 | e.result = tooltip.getAccessibleText(); | |
123 | } else if (e.childID == 1) { | |
124 | createFakeTooltip(); | |
125 | e.result = tooltip.getAccessibleText(); | |
126 | } | |
127 | } | |
128 | }); | |
129 | ||
130 | accessible.addAccessibleControlListener(new AccessibleControlAdapter() { | |
131 | @Override | |
132 | public void getFocus(AccessibleControlEvent e) { | |
133 | if (focusedWidget == -1) | |
134 | e.childID = ACC.CHILDID_SELF; | |
135 | else | |
136 | e.childID = focusedWidget; | |
137 | } | |
138 | ||
139 | @Override | |
140 | public void getRole(AccessibleControlEvent e) { | |
141 | switch (e.childID) { | |
142 | case ACC.CHILDID_SELF: | |
143 | e.detail = ACC.ROLE_CLIENT_AREA; | |
144 | break; | |
145 | case 0: | |
146 | e.detail = ACC.ROLE_TOOLTIP; | |
147 | break; | |
148 | case 1: | |
149 | e.detail = ACC.ROLE_LABEL; | |
150 | break; | |
151 | } | |
152 | } | |
153 | ||
154 | @Override | |
155 | public void getState(AccessibleControlEvent e) { | |
156 | e.detail = ACC.STATE_FOCUSABLE; | |
157 | if (e.childID == ACC.CHILDID_SELF) { | |
158 | e.detail |= ACC.STATE_FOCUSED; | |
159 | } else { | |
160 | e.detail |= ACC.STATE_SELECTABLE; | |
161 | if (e.childID == focusedWidget) | |
162 | e.detail |= ACC.STATE_FOCUSED | ACC.STATE_SELECTED | ACC.STATE_CHECKED; | |
163 | } | |
164 | } | |
165 | }); | |
166 | ||
167 | getViewControl().addTraverseListener(new TraverseListener() { | |
168 | ||
169 | @Override | |
170 | public void keyTraversed(TraverseEvent e) { | |
171 | if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) | |
172 | e.doit = true; | |
173 | ||
174 | } | |
175 | ||
176 | }); | |
177 | ||
178 | addTraverseListener(new TraverseListener() { | |
179 | ||
180 | @Override | |
181 | public void keyTraversed(TraverseEvent e) { | |
182 | if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) | |
183 | e.doit = true; | |
184 | ||
185 | } | |
186 | ||
187 | }); | |
188 | ||
189 | getViewControl().addFocusListener(new FocusListener() { | |
190 | ||
191 | @Override | |
192 | public void focusGained(FocusEvent e) { | |
193 | ||
194 | redraw(); | |
195 | } | |
196 | ||
197 | @Override | |
198 | public void focusLost(FocusEvent e) { | |
199 | redraw(); | |
200 | } | |
201 | }); | |
202 | } | |
203 | ||
204 | void setFocus(int newFocusShape) { | |
205 | focusedWidget = newFocusShape; | |
206 | if (focusedWidget == -1) { | |
207 | getViewControl().getAccessible().setFocus(ACC.CHILDID_SELF); | |
208 | } else { | |
209 | getViewControl().getAccessible().setFocus(focusedWidget); | |
210 | } | |
211 | } | |
212 | ||
213 | public void setFrame(Frame theFrame) { | |
214 | frame = theFrame; | |
215 | min = frame.getMinTime(); | |
216 | max = frame.getMaxTime(); | |
217 | } | |
218 | ||
219 | @Override | |
220 | protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) { | |
221 | if (frame == null) | |
222 | return; | |
223 | nodeList = new ArrayList<SDTimeEvent>(); | |
224 | int messageArraysStep = 1; | |
225 | ||
226 | if ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * zoomValue < Metrics.MESSAGE_SIGNIFICANT_VSPACING + 1) | |
227 | messageArraysStep = Math.round(Metrics.MESSAGE_SIGNIFICANT_VSPACING + 1 / ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * zoomValue)); | |
228 | ||
229 | int firstVisible = frame.getFirstVisibleSyncMessage(); | |
230 | if (firstVisible > 0) | |
231 | firstVisible = firstVisible - 1; | |
232 | for (int i = firstVisible; i < frame.syncMessageCount(); i = i + messageArraysStep) { | |
233 | SyncMessage m = frame.getSyncMessage(i); | |
234 | if (m.hasTimeInfo()) { | |
235 | SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getEventOccurrence(), (ITimeRange) m); | |
236 | nodeList.add(t); | |
237 | if (m.getY() * zoomValue > getContentsY() + getVisibleHeight()) | |
238 | break; | |
239 | } | |
240 | } | |
241 | ||
242 | firstVisible = frame.getFirstVisibleSyncMessageReturn(); | |
243 | if (firstVisible > 0) | |
244 | firstVisible = firstVisible - 1; | |
245 | for (int i = firstVisible; i < frame.syncMessageReturnCount(); i = i + messageArraysStep) { | |
246 | SyncMessage m = frame.getSyncMessageReturn(i); | |
247 | if (m.hasTimeInfo()) { | |
248 | SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getEventOccurrence(), (ITimeRange) m); | |
249 | nodeList.add(t); | |
250 | if (m.getY() * zoomValue > getContentsY() + getVisibleHeight()) | |
251 | break; | |
252 | } | |
253 | } | |
254 | ||
255 | firstVisible = frame.getFirstVisibleAsyncMessage(); | |
256 | if (firstVisible > 0) | |
257 | firstVisible = firstVisible - 1; | |
258 | for (int i = firstVisible; i < frame.asyncMessageCount(); i = i + messageArraysStep) { | |
259 | AsyncMessage m = frame.getAsyncMessage(i); | |
260 | if (m.hasTimeInfo()) { | |
261 | SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getStartOccurrence(), (ITimeRange) m); | |
262 | nodeList.add(t); | |
263 | t = new SDTimeEvent(m.getEndTime(), m.getEndOccurrence(), (ITimeRange) m); | |
264 | nodeList.add(t); | |
265 | if (m.getY() * zoomValue > getContentsY() + getVisibleHeight()) | |
266 | break; | |
267 | } | |
268 | } | |
269 | ||
270 | firstVisible = frame.getFirstVisibleAsyncMessageReturn(); | |
271 | if (firstVisible > 0) | |
272 | firstVisible = firstVisible - 1; | |
273 | for (int i = firstVisible; i < frame.asyncMessageReturnCount(); i = i + messageArraysStep) { | |
274 | AsyncMessageReturn m = frame.getAsyncMessageReturn(i); | |
275 | if (m.hasTimeInfo()) { | |
276 | SDTimeEvent t = new SDTimeEvent(m.getStartTime(), m.getStartOccurrence(), (ITimeRange) m); | |
277 | nodeList.add(t); | |
278 | t = new SDTimeEvent(m.getEndTime(), m.getEndOccurrence(), (ITimeRange) m); | |
279 | nodeList.add(t); | |
280 | if (m.getY() * zoomValue > getContentsY() + getVisibleHeight()) | |
281 | break; | |
282 | } | |
283 | } | |
284 | ||
285 | /* | |
286 | * for (int i=0; i<frame.lifeLinesCount();i++) { | |
287 | * Lifeline lifeline = frame.getLifeline(i); | |
288 | * if (lifeline.getExecutions()!=null) | |
289 | * for (int j=lifeline.getExecOccurrenceDrawIndex(); j<lifeline.getExecutions().size(); j++) { | |
290 | * ExecutionOccurrence exec = (ExecutionOccurrence)lifeline.getExecutions().get(j); | |
291 | * if (exec.hasTimeInfo()) { | |
292 | * TimeEvent t = new TimeEvent(exec.getFirstTime(), exec.getStartOccurrence(),(ITimeRange)exec); | |
293 | * nodeList.add(t); | |
294 | * t = new TimeEvent(exec.getLastTime(),exec.getEndOccurrence(),(ITimeRange)exec); nodeList.add(t); | |
295 | * } | |
296 | * if (exec.getY()*zoomValue>getContentsY()+getVisibleHeight()) break; | |
297 | * } | |
298 | * float g= lifeline.getX()*zoomValue; | |
299 | * int h=frame.getContentX(); int r=frame.getVisibleWidth(); | |
300 | * } | |
301 | */ | |
302 | List<SDTimeEvent> executionOccurrencesWithTime = frame.getExecutionOccurrencesWithTime(); | |
303 | if (executionOccurrencesWithTime != null) { | |
304 | nodeList.addAll(executionOccurrencesWithTime); | |
305 | } | |
306 | ||
307 | SDTimeEvent[] temp = nodeList.toArray(new SDTimeEvent[0]); | |
308 | Arrays.sort(temp, new TimeEventComparator()); | |
309 | nodeList = Arrays.asList(temp); | |
310 | ||
311 | Image dbuffer = null; | |
312 | GC gcim = null; | |
313 | try { | |
314 | dbuffer = new Image(getDisplay(), getClientArea().width, getClientArea().height); | |
315 | } catch (Exception e) { | |
316 | System.out.println(e.toString()); | |
317 | } | |
318 | gcim = new GC(dbuffer); | |
319 | for (int i = 0; i < nodeList.size() - 1; i++) { | |
320 | SDTimeEvent m1 = (SDTimeEvent) nodeList.get(i); | |
321 | SDTimeEvent m2 = (SDTimeEvent) nodeList.get(i + 1); | |
322 | ||
323 | if (SDViewPref.getInstance().excludeExternalTime()) { | |
324 | if ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage)) { | |
325 | BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); | |
326 | BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); | |
327 | if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) | |
328 | continue; | |
329 | } | |
330 | } | |
331 | ||
332 | min = frame.getMinTime(); | |
333 | max = frame.getMaxTime(); | |
d7dbf09a | 334 | ITmfTimestamp minMaxdelta = (TmfTimestamp) max.getDelta(min); |
73005152 BH |
335 | double gr = (minMaxdelta.getValue()) / (double) 10; |
336 | ||
d7dbf09a | 337 | ITmfTimestamp delta = (TmfTimestamp) m2.getTime().getDelta(m1.getTime()).getDelta(min); |
73005152 BH |
338 | long absDelta = Math.abs(delta.getValue()); |
339 | ||
340 | ColorImpl color; | |
341 | if (gr != 0) { | |
342 | int colIndex = Math.round((float) (absDelta / gr)); | |
343 | if (colIndex < col.length && colIndex > 0) | |
344 | color = col[colIndex - 1]; | |
345 | else if (colIndex <= 0) | |
346 | color = col[0]; | |
347 | else | |
348 | color = col[col.length - 1]; | |
349 | } else | |
350 | color = col[0]; | |
351 | ||
352 | if (color.getColor() instanceof Color) | |
353 | gcim.setBackground((Color) color.getColor()); | |
354 | int y1 = ((GraphNode) m1.getGraphNode()).getY(); | |
355 | int y2 = ((GraphNode) m2.getGraphNode()).getY(); | |
356 | if (m1.getGraphNode() instanceof AsyncMessage) { | |
357 | AsyncMessage as = (AsyncMessage) m1.getGraphNode(); | |
358 | if (as.getEndTime() == m1.getTime()) | |
359 | y1 += as.getHeight(); | |
360 | } | |
361 | if (m2.getGraphNode() instanceof AsyncMessage) { | |
362 | AsyncMessage as = (AsyncMessage) m2.getGraphNode(); | |
363 | if (as.getEndTime() == m2.getTime()) | |
364 | y2 += as.getHeight(); | |
365 | } | |
366 | if (m1.getGraphNode() instanceof ExecutionOccurrence) { | |
367 | ||
368 | ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); | |
369 | if (m1.getEvent() == eo.getEndOccurrence()) | |
370 | y1 += eo.getHeight(); | |
371 | ||
372 | if (m2.getGraphNode() instanceof ExecutionOccurrence) { | |
373 | ||
374 | ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); | |
375 | if (m2.getEvent() == eo2.getEndOccurrence()) | |
376 | y2 += eo2.getHeight(); | |
377 | ||
378 | } | |
379 | } | |
380 | gcim.fillRectangle(contentsToViewX(0), contentsToViewY(Math.round(y1 * zoomValue)), 10, Math.round((y2 - y1) * zoomValue) + 1); | |
381 | if (messageArraysStep == 1) { | |
382 | Color backupColor = gcim.getForeground(); | |
383 | gcim.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); | |
384 | gcim.drawRectangle(contentsToViewX(0), contentsToViewY(Math.round(y1 * zoomValue)), 9, Math.round((y2 - y1) * zoomValue)); | |
385 | gcim.setForeground(backupColor); | |
386 | } | |
387 | } | |
388 | if (getViewControl().isFocusControl() || isFocusControl()) { | |
389 | gcim.drawFocus(contentsToViewX(0), contentsToViewY(Math.round(prevNodeY * zoomValue)), contentsToViewX(10), Math.round((nextNodeY - prevNodeY) * zoomValue)); | |
390 | } | |
391 | try { | |
392 | gc.drawImage(dbuffer, 0, 0, getClientArea().width, getClientArea().height, 0, 0, getClientArea().width, getClientArea().height); | |
393 | } catch (Exception e) { | |
394 | System.out.println(e.getMessage()); | |
395 | } | |
396 | gcim.dispose(); | |
397 | if (dbuffer != null) { | |
398 | dbuffer.dispose(); | |
399 | } | |
400 | gc.dispose(); | |
401 | } | |
402 | ||
403 | protected boolean checkFocusOnChilds(Control childs) { | |
404 | if (childs instanceof Composite) { | |
405 | Control[] child = ((Composite) childs).getChildren(); | |
406 | for (int i = 0; i < child.length; i++) { | |
407 | if (child[i].isFocusControl()) { | |
408 | return true; | |
409 | } else | |
410 | checkFocusOnChilds(child[i]); | |
411 | } | |
412 | } | |
413 | return false; | |
414 | } | |
415 | ||
416 | @Override | |
417 | public boolean isFocusControl() { | |
418 | Control[] child = getChildren(); | |
419 | for (int i = 0; i < child.length; i++) { | |
420 | if (child[i].isFocusControl()) { | |
421 | return true; | |
422 | } else | |
423 | checkFocusOnChilds(child[i]); | |
424 | } | |
425 | return false; | |
426 | } | |
427 | ||
428 | @Override | |
429 | protected void contentsMouseMoveEvent(MouseEvent event) { | |
430 | if (tooltip != null) | |
431 | tooltip.hideToolTip(); | |
432 | super.contentsMouseMoveEvent(event); | |
433 | if (!isFocusControl() || getViewControl().isFocusControl()) { | |
434 | Control[] child = getParent().getChildren(); | |
435 | for (int i = 0; i < child.length; i++) { | |
436 | if (child[i].isFocusControl()) { | |
437 | // getViewControl().setFocus(); | |
438 | break; | |
439 | } | |
440 | } | |
441 | } | |
442 | setFocus(-1); | |
443 | } | |
444 | ||
445 | @Override | |
446 | protected void contentsMouseHover(MouseEvent e) { | |
447 | if (tooltip == null) { | |
448 | tooltip = new DrawableToolTip(this); | |
449 | } | |
450 | if (frame != null) { | |
451 | setFocus(0); | |
452 | for (int i = 0; i < nodeList.size() - 1; i++) { | |
453 | SDTimeEvent m1 = (SDTimeEvent) nodeList.get(i); | |
454 | SDTimeEvent m2 = (SDTimeEvent) nodeList.get(i + 1); | |
455 | ||
456 | if (SDViewPref.getInstance().excludeExternalTime()) { | |
457 | if ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage)) { | |
458 | BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); | |
459 | BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); | |
460 | if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) | |
461 | continue; | |
462 | } | |
463 | } | |
464 | ||
465 | int y1 = ((GraphNode) m1.getGraphNode()).getY(); | |
466 | int y2 = ((GraphNode) m2.getGraphNode()).getY(); | |
467 | ||
468 | if (m1.getGraphNode() instanceof AsyncMessage) { | |
469 | AsyncMessage as = (AsyncMessage) m1.getGraphNode(); | |
470 | if (as.getEndTime() == m1.getTime()) | |
471 | y1 += as.getHeight(); | |
472 | } | |
473 | if (m2.getGraphNode() instanceof AsyncMessage) { | |
474 | AsyncMessage as = (AsyncMessage) m2.getGraphNode(); | |
475 | if (as.getEndTime() == m2.getTime()) | |
476 | y2 += as.getHeight(); | |
477 | } | |
478 | if (m1.getGraphNode() instanceof ExecutionOccurrence) { | |
479 | ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); | |
480 | if (m1.getEvent() == eo.getEndOccurrence()) | |
481 | y1 += eo.getHeight(); | |
482 | ||
483 | if (m2.getGraphNode() instanceof ExecutionOccurrence) { | |
484 | ||
485 | ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); | |
486 | if (m2.getEvent() == eo2.getEndOccurrence()) | |
487 | y2 += eo2.getHeight(); | |
488 | ||
489 | } | |
490 | } | |
491 | int m1Y = Math.round(y1 * zoomValue); | |
492 | int m2Y = Math.round(y2 * zoomValue); | |
493 | if ((m1Y < e.y) && (m2Y >= e.y)) { | |
5179fc01 | 494 | TmfTimestamp delta = (TmfTimestamp) m2.getTime().getDelta(m1.getTime()); |
73005152 BH |
495 | tooltip.showToolTip(delta, min, max); |
496 | } | |
497 | } | |
498 | } | |
499 | setFocus(0); | |
500 | } | |
501 | ||
502 | @Override | |
503 | protected void contentsMouseExit(MouseEvent e) { | |
504 | if (tooltip != null) | |
505 | tooltip.hideToolTip(); | |
506 | } | |
507 | ||
508 | @Override | |
509 | protected void contentsMouseUpEvent(MouseEvent event) { | |
510 | selectTimeDelta(event.y, 0); | |
511 | setFocus(); | |
512 | super.contentsMouseUpEvent(event); | |
513 | } | |
514 | ||
515 | /** | |
516 | * Force the time compression bar to highlight the event occurrences between the two given messages. The event | |
517 | * occurrences are highlighted on the first message's end lifeline | |
518 | * | |
519 | * @param mes1 the first message | |
520 | * @param mes2 | |
521 | */ | |
522 | public void highlightRegion(BaseMessage mes1, BaseMessage mes2) { | |
523 | if (frame == null) | |
524 | return; | |
525 | if (!(mes1 instanceof ITimeRange)) | |
526 | return; | |
527 | if (!(mes2 instanceof ITimeRange)) | |
528 | return; | |
529 | ITimeRange t1 = (ITimeRange) mes1; | |
530 | ITimeRange t2 = (ITimeRange) mes2; | |
531 | ||
4df4581d | 532 | ITmfTimestamp time1 = t1.getStartTime(); |
533 | ITmfTimestamp time2 = t2.getStartTime(); | |
73005152 BH |
534 | int event1 = mes1.getEventOccurrence(); |
535 | int event2 = mes2.getEventOccurrence(); | |
536 | ||
537 | if (mes1 instanceof AsyncMessage) { | |
538 | AsyncMessage as = (AsyncMessage) mes2; | |
539 | time1 = as.getEndTime(); | |
540 | event1 = as.getEndOccurrence(); | |
541 | } | |
542 | if (mes2 instanceof AsyncMessage) { | |
543 | AsyncMessage as = (AsyncMessage) mes2; | |
544 | if (as.getEndOccurrence() > as.getStartOccurrence()) { | |
545 | time1 = as.getEndTime(); | |
546 | event1 = as.getEndOccurrence(); | |
547 | } else { | |
548 | time1 = as.getStartTime(); | |
549 | event1 = as.getStartOccurrence(); | |
550 | } | |
551 | } | |
552 | ||
553 | if (event1 > event2) { | |
554 | BaseMessage tempMes = mes2; | |
555 | mes2 = mes1; | |
556 | mes1 = tempMes; | |
557 | ||
558 | t1 = (ITimeRange) mes1; | |
559 | t2 = (ITimeRange) mes2; | |
560 | ||
561 | time1 = t1.getStartTime(); | |
562 | time2 = t2.getStartTime(); | |
563 | event1 = mes1.getEventOccurrence(); | |
564 | event2 = mes2.getEventOccurrence(); | |
565 | ||
566 | if (mes1 instanceof AsyncMessage) { | |
567 | AsyncMessage as = (AsyncMessage) mes2; | |
568 | time1 = as.getEndTime(); | |
569 | event1 = as.getEndOccurrence(); | |
570 | } | |
571 | if (mes2 instanceof AsyncMessage) { | |
572 | AsyncMessage as = (AsyncMessage) mes2; | |
573 | if (as.getEndOccurrence() > as.getStartOccurrence()) { | |
574 | time1 = as.getEndTime(); | |
575 | event1 = as.getEndOccurrence(); | |
576 | } else { | |
577 | time1 = as.getStartTime(); | |
578 | event1 = as.getStartOccurrence(); | |
579 | } | |
580 | } | |
581 | } | |
582 | ||
5179fc01 | 583 | TmfTimestamp minMaxdelta = (TmfTimestamp) max.getDelta(min); |
73005152 BH |
584 | double gr = (minMaxdelta.getValue()) / (double) 10; |
585 | ||
5179fc01 | 586 | TmfTimestamp delta = (TmfTimestamp) time2.getDelta(time1).getDelta(min); |
73005152 BH |
587 | long absDelta = Math.abs(delta.getValue()); |
588 | ||
589 | int colIndex = 0; | |
590 | if (gr != 0) { | |
591 | colIndex = Math.round((float) (absDelta / gr)); | |
592 | if (colIndex >= col.length) | |
593 | colIndex = col.length - 1; | |
594 | else if (colIndex < 0) | |
595 | colIndex = 0; | |
596 | } else | |
597 | colIndex = 0; | |
598 | for (int j = 0; j < listenerList.size(); j++) { | |
599 | ITimeCompressionListener list = (ITimeCompressionListener) listenerList.get(j); | |
600 | if (mes1.getEndLifeline() != null) { | |
601 | list.deltaSelected(mes1.getEndLifeline(), event1, event2 - event1, col[colIndex]); | |
602 | } else if (mes2.getStartLifeline() != null) { | |
603 | list.deltaSelected(mes2.getStartLifeline(), event1, event2 - event1, col[colIndex]); | |
604 | } else | |
605 | list.deltaSelected(mes1.getStartLifeline(), event1, event2 - event1, col[colIndex]); | |
606 | } | |
607 | } | |
608 | ||
609 | /** | |
610 | * Force the time compression bar to highlight the event occurrences between the two given messages. The event | |
611 | * occurrences are highlighted on the first message's end lifeline | |
612 | * | |
613 | * @param mes1 the first message | |
614 | * @param mes2 | |
615 | */ | |
616 | public void highlightRegionSync(final BaseMessage mes1, final BaseMessage mes2) { | |
617 | getDisplay().syncExec(new Runnable() { | |
618 | @Override | |
619 | public void run() { | |
620 | highlightRegion(mes1, mes2); | |
621 | } | |
622 | }); | |
623 | } | |
624 | ||
625 | @Override | |
626 | public void scrollBy(int x, int y) { | |
627 | } | |
628 | ||
629 | public void setZoom(float value) { | |
630 | zoomValue = value; | |
631 | redraw(); | |
632 | } | |
633 | ||
634 | public void addTimeCompressionListener(ITimeCompressionListener listener) { | |
635 | if (!listenerList.contains(listener)) | |
636 | listenerList.add(listener); | |
637 | } | |
638 | ||
639 | public void removeSelectionChangedListener(ITimeCompressionListener listener) { | |
640 | listenerList.remove(listener); | |
641 | } | |
642 | ||
643 | @Override | |
644 | public void widgetDisposed(DisposeEvent e) { | |
645 | if (tooltip != null) | |
646 | tooltip.dispose(); | |
647 | super.removeDisposeListener(this); | |
648 | for (int i = 0; i < col.length; i++) | |
649 | col[i].dispose(); | |
650 | } | |
651 | ||
652 | @Override | |
653 | protected void keyPressedEvent(KeyEvent _e) { | |
654 | if (tooltip != null) | |
655 | tooltip.hideToolTip(); | |
656 | if (!isFocusControl() || getViewControl().isFocusControl()) { | |
657 | Control[] child = getParent().getChildren(); | |
658 | for (int i = 0; i < child.length; i++) { | |
659 | if (child[i].isFocusControl()) { | |
660 | // getViewControl().setFocus(); | |
661 | break; | |
662 | } | |
663 | } | |
664 | } | |
665 | setFocus(-1); | |
666 | ||
667 | boolean top = false; | |
668 | if (nextNodeY == 0) | |
669 | top = true; | |
670 | if ((frame != null) && (nextNodeY == 0)) { | |
671 | for (int i = 0; i < nodeList.size() - 1 && i < 1; i++) { | |
672 | SDTimeEvent m1 = (SDTimeEvent) nodeList.get(i); | |
673 | SDTimeEvent m2 = (SDTimeEvent) nodeList.get(i + 1); | |
674 | if (SDViewPref.getInstance().excludeExternalTime()) { | |
675 | if ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage)) { | |
676 | BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); | |
677 | BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); | |
678 | if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) | |
679 | continue; | |
680 | } | |
681 | } | |
682 | ||
683 | int y1 = ((GraphNode) m1.getGraphNode()).getY(); | |
684 | int y2 = ((GraphNode) m2.getGraphNode()).getY(); | |
685 | if (m1.getGraphNode() instanceof AsyncMessage) { | |
686 | AsyncMessage as = (AsyncMessage) m1.getGraphNode(); | |
687 | if (as.getEndTime() == m1.getTime()) | |
688 | y1 += as.getHeight(); | |
689 | } | |
690 | if (m2.getGraphNode() instanceof AsyncMessage) { | |
691 | AsyncMessage as = (AsyncMessage) m2.getGraphNode(); | |
692 | if (as.getEndTime() == m2.getTime()) | |
693 | y2 += as.getHeight(); | |
694 | } | |
695 | if (m1.getGraphNode() instanceof ExecutionOccurrence) { | |
696 | ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); | |
697 | if (m1.getEvent() == eo.getEndOccurrence()) | |
698 | y1 += eo.getHeight(); | |
699 | ||
700 | if (m2.getGraphNode() instanceof ExecutionOccurrence) { | |
701 | ||
702 | ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); | |
703 | if (m2.getEvent() == eo2.getEndOccurrence()) | |
704 | y2 += eo2.getHeight(); | |
705 | ||
706 | } | |
707 | } | |
708 | prevNodeY = Math.round(y1 * zoomValue); | |
709 | nextNodeY = Math.round(y2 * zoomValue); | |
710 | } | |
711 | } | |
712 | ||
713 | if (ll != null) | |
714 | for (int j = 0; j < listenerList.size(); j++) { | |
715 | ITimeCompressionListener list = (ITimeCompressionListener) listenerList.get(j); | |
716 | list.deltaSelected(ll, ls, ln, lc); | |
717 | } | |
718 | ||
719 | if (_e.keyCode == SWT.ARROW_DOWN) { | |
720 | if (!top) | |
721 | selectTimeDelta(nextNodeY + 1, 1); | |
722 | else | |
723 | selectTimeDelta(prevNodeY + 1, 1); | |
724 | setFocus(1); | |
725 | } else if (_e.keyCode == SWT.ARROW_UP) { | |
726 | selectTimeDelta(prevNodeY - 1, 2); | |
727 | setFocus(1); | |
728 | } else if (_e.keyCode == SWT.ARROW_RIGHT) { | |
729 | selectTimeDelta(prevNodeY, 1); | |
730 | setFocus(1); | |
731 | } | |
732 | super.keyPressedEvent(_e); | |
733 | } | |
734 | ||
735 | @Override | |
736 | protected void keyReleasedEvent(KeyEvent _e) { | |
737 | super.keyReleasedEvent(_e); | |
738 | } | |
739 | ||
740 | /** | |
741 | * 0 no direction, 1 = down, 2 = up | |
742 | * | |
743 | * @param dy | |
744 | * @param direction | |
745 | */ | |
746 | protected void selectTimeDelta(int dy, int direction) { | |
747 | SDTimeEvent lastM1 = null; | |
748 | SDTimeEvent lastM2 = null; | |
749 | int lastY1 = 0; | |
750 | int lastY2 = 0; | |
751 | boolean done = false; | |
752 | if (frame != null) { | |
753 | for (int i = 0; i < nodeList.size() - 1; i++) { | |
754 | SDTimeEvent m1 = (SDTimeEvent) nodeList.get(i); | |
755 | SDTimeEvent m2 = (SDTimeEvent) nodeList.get(i + 1); | |
756 | if (SDViewPref.getInstance().excludeExternalTime()) { | |
757 | if ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage)) { | |
758 | BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); | |
759 | BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); | |
760 | if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) | |
761 | continue; | |
762 | } | |
763 | } | |
764 | ||
765 | int y1 = ((GraphNode) m1.getGraphNode()).getY(); | |
766 | int y2 = ((GraphNode) m2.getGraphNode()).getY(); | |
767 | if (m1.getGraphNode() instanceof AsyncMessage) { | |
768 | AsyncMessage as = (AsyncMessage) m1.getGraphNode(); | |
769 | if (as.getEndTime() == m1.getTime()) | |
770 | y1 += as.getHeight(); | |
771 | } | |
772 | if (m2.getGraphNode() instanceof AsyncMessage) { | |
773 | AsyncMessage as = (AsyncMessage) m2.getGraphNode(); | |
774 | if (as.getEndTime() == m2.getTime()) | |
775 | y2 += as.getHeight(); | |
776 | } | |
777 | if (m1.getGraphNode() instanceof ExecutionOccurrence) { | |
778 | ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); | |
779 | if (m1.getEvent() == eo.getEndOccurrence()) | |
780 | y1 += eo.getHeight(); | |
781 | ||
782 | if (m2.getGraphNode() instanceof ExecutionOccurrence) { | |
783 | ||
784 | ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); | |
785 | if (m2.getEvent() == eo2.getEndOccurrence()) | |
786 | y2 += eo2.getHeight(); | |
787 | ||
788 | } | |
789 | } | |
790 | int m1Y = Math.round(y1 * zoomValue); | |
791 | int m2Y = Math.round(y2 * zoomValue); | |
792 | ||
793 | if ((m1Y < dy) && (m2Y > dy) || (!done && m2Y > dy && direction == 1 && lastM1 != null) || (!done && m1Y > dy && direction == 2 && lastM1 != null)) { | |
794 | if (m1Y > dy && direction == 2) { | |
795 | m1 = lastM1; | |
796 | m2 = lastM2; | |
797 | m1Y = lastY1; | |
798 | m2Y = lastY2; | |
799 | } | |
800 | done = true; | |
801 | prevNodeY = m1Y; | |
802 | nextNodeY = m2Y; | |
5179fc01 | 803 | TmfTimestamp minMaxdelta = (TmfTimestamp) max.getDelta(min); |
73005152 BH |
804 | double gr = (minMaxdelta.getValue()) / (double) 10; |
805 | ||
5179fc01 | 806 | TmfTimestamp delta = (TmfTimestamp) m2.getTime().getDelta(m1.getTime()).getDelta(min); |
73005152 BH |
807 | long absDelta = Math.abs(delta.getValue()); |
808 | ||
809 | int colIndex = 0; | |
810 | if (gr != 0) { | |
811 | colIndex = Math.round((float) (absDelta / gr)); | |
812 | if (colIndex >= col.length) | |
813 | colIndex = col.length - 1; | |
814 | else if (colIndex < 0) | |
815 | colIndex = 0; | |
816 | } else | |
817 | colIndex = 0; | |
818 | if (m1.getGraphNode() instanceof BaseMessage) { | |
819 | BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); | |
820 | if (mes1.getEndLifeline() != null) { | |
821 | ll = mes1.getEndLifeline(); | |
822 | ls = m1.getEvent(); | |
823 | ln = m2.getEvent() - m1.getEvent(); | |
824 | lc = col[colIndex]; | |
825 | } else if (m2.getGraphNode() instanceof BaseMessage && ((BaseMessage) m2.getGraphNode()).getStartLifeline() != null) { | |
826 | ll = ((BaseMessage) m2.getGraphNode()).getStartLifeline(); | |
827 | ls = m1.getEvent(); | |
828 | ln = m2.getEvent() - m1.getEvent(); | |
829 | lc = col[colIndex]; | |
830 | } else { | |
831 | ll = mes1.getStartLifeline(); | |
832 | ls = m1.getEvent(); | |
833 | ln = m2.getEvent() - m1.getEvent(); | |
834 | lc = col[colIndex]; | |
835 | } | |
836 | } else if (m1.getGraphNode() instanceof ExecutionOccurrence) { | |
837 | if (m2.getGraphNode() instanceof ExecutionOccurrence) { | |
838 | ExecutionOccurrence eo = (ExecutionOccurrence) m2.getGraphNode(); | |
839 | ll = eo.getLifeline(); | |
840 | ls = m1.getEvent(); | |
841 | ln = m2.getEvent() - m1.getEvent(); | |
842 | lc = col[colIndex]; | |
843 | } else { | |
844 | ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); | |
845 | ll = eo.getLifeline(); | |
846 | ls = m1.getEvent(); | |
847 | ln = m2.getEvent() - m1.getEvent(); | |
848 | lc = col[colIndex]; | |
849 | } | |
850 | } | |
851 | for (int j = 0; j < listenerList.size(); j++) { | |
852 | ITimeCompressionListener list = (ITimeCompressionListener) listenerList.get(j); | |
853 | list.deltaSelected(ll, ls, ln, lc); | |
854 | } | |
855 | break; | |
856 | } else { | |
857 | lastM1 = m1; | |
858 | lastM2 = m2; | |
859 | lastY1 = m1Y; | |
860 | lastY2 = m2Y; | |
861 | } | |
862 | } | |
863 | } | |
864 | } | |
865 | ||
866 | protected void createFakeTooltip() { | |
867 | if (tooltip == null) { | |
868 | tooltip = new DrawableToolTip(this); | |
869 | } | |
870 | if (frame != null) { | |
871 | setFocus(0); | |
872 | for (int i = 0; i < nodeList.size() - 1; i++) { | |
873 | SDTimeEvent m1 = (SDTimeEvent) nodeList.get(i); | |
874 | SDTimeEvent m2 = (SDTimeEvent) nodeList.get(i + 1); | |
875 | ||
876 | if (SDViewPref.getInstance().excludeExternalTime()) { | |
877 | if ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage)) { | |
878 | BaseMessage mes1 = (BaseMessage) m1.getGraphNode(); | |
879 | BaseMessage mes2 = (BaseMessage) m2.getGraphNode(); | |
880 | if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) | |
881 | continue; | |
882 | } | |
883 | } | |
884 | ||
885 | int y1 = ((GraphNode) m1.getGraphNode()).getY(); | |
886 | int y2 = ((GraphNode) m2.getGraphNode()).getY(); | |
887 | ||
888 | if (m1.getGraphNode() instanceof AsyncMessage) { | |
889 | AsyncMessage as = (AsyncMessage) m1.getGraphNode(); | |
890 | if (as.getEndTime() == m1.getTime()) | |
891 | y1 += as.getHeight(); | |
892 | } | |
893 | if (m2.getGraphNode() instanceof AsyncMessage) { | |
894 | AsyncMessage as = (AsyncMessage) m2.getGraphNode(); | |
895 | if (as.getEndTime() == m2.getTime()) | |
896 | y2 += as.getHeight(); | |
897 | } | |
898 | if (m1.getGraphNode() instanceof ExecutionOccurrence) { | |
899 | ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode(); | |
900 | if (m1.getEvent() == eo.getEndOccurrence()) | |
901 | y1 += eo.getHeight(); | |
902 | ||
903 | if (m2.getGraphNode() instanceof ExecutionOccurrence) { | |
904 | ||
905 | ExecutionOccurrence eo2 = (ExecutionOccurrence) m2.getGraphNode(); | |
906 | if (m2.getEvent() == eo2.getEndOccurrence()) | |
907 | y2 += eo2.getHeight(); | |
908 | ||
909 | } | |
910 | } | |
911 | int m1Y = Math.round(y1 * zoomValue); | |
912 | int m2Y = Math.round(y2 * zoomValue); | |
913 | if ((m1Y < prevNodeY + 1) && (m2Y >= prevNodeY + 1)) { | |
5179fc01 | 914 | TmfTimestamp delta = (TmfTimestamp) m2.getTime().getDelta(m1.getTime()); |
73005152 BH |
915 | tooltip.showToolTip(delta, min, max); |
916 | tooltip.hideToolTip(); | |
917 | } | |
918 | } | |
919 | } | |
920 | } | |
921 | } |