Move alltests plugin to the Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / widgets / timegraph / widgets / TimeGraphTooltipHandler.java
CommitLineData
34313553 1/*****************************************************************************
0fab12b0 2 * Copyright (c) 2007, 2014 Intel Corporation, Ericsson
34313553
PT
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 *
8 * Contributors:
9 * Intel Corporation - Initial API and implementation
10 * Vitaly A. Provodin, Intel - Initial API and implementation
11 * Alvaro Sanchez-Leon - Updated for TMF
12 * Patrick Tasse - Refactoring
34313553 13 *****************************************************************************/
c8422608 14
34313553
PT
15package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets;
16
17import java.util.Iterator;
18import java.util.Map;
19
20import org.eclipse.linuxtools.internal.tmf.ui.Messages;
21import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider;
1053eaa6 22import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent;
34313553
PT
23import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;
24import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
3e9a3685 25import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.NullTimeEvent;
34313553
PT
26import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;
27import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
28import org.eclipse.swt.SWT;
29import org.eclipse.swt.events.MouseAdapter;
30import org.eclipse.swt.events.MouseEvent;
31import org.eclipse.swt.events.MouseMoveListener;
32import org.eclipse.swt.events.MouseTrackAdapter;
33import org.eclipse.swt.graphics.Point;
34import org.eclipse.swt.graphics.Rectangle;
35import org.eclipse.swt.layout.GridData;
36import org.eclipse.swt.layout.GridLayout;
37import org.eclipse.swt.widgets.Composite;
38import org.eclipse.swt.widgets.Control;
39import org.eclipse.swt.widgets.Display;
40import org.eclipse.swt.widgets.Label;
41import org.eclipse.swt.widgets.Shell;
42
43/**
44 * Handler for the tool tips in the generic time graph view.
45 *
46 * @version 1.0
47 * @author Alvaro Sanchez-Leon
48 * @author Patrick Tasse
49 */
50public class TimeGraphTooltipHandler {
51
f1fae91f
PT
52 private static final int OFFSET = 16;
53
54 private Shell fTipShell;
55 private Composite fTipComposite;
0fab12b0 56 private ITimeDataProvider fTimeDataProvider;
f1fae91f 57 private ITimeGraphPresentationProvider fTimeGraphProvider = null;
34313553
PT
58
59 /**
60 * Standard constructor
61 *
f1fae91f 62 * @param graphProv
34313553
PT
63 * The presentation provider
64 * @param timeProv
65 * The time provider
f1fae91f
PT
66 *
67 * @since 2.0
34313553 68 */
f1fae91f 69 public TimeGraphTooltipHandler(ITimeGraphPresentationProvider graphProv,
34313553
PT
70 ITimeDataProvider timeProv) {
71
f1fae91f
PT
72 this.fTimeGraphProvider = graphProv;
73 this.fTimeDataProvider = timeProv;
34313553
PT
74 }
75
0fab12b0
PT
76 /**
77 * Set the time data provider
78 *
79 * @param timeDataProvider
80 * The time data provider
81 *
a465519a 82 * @since 3.2
0fab12b0
PT
83 */
84 public void setTimeProvider(ITimeDataProvider timeDataProvider) {
85 fTimeDataProvider = timeDataProvider;
86 }
87
34313553
PT
88 private void createTooltipShell(Shell parent) {
89 final Display display = parent.getDisplay();
f1fae91f
PT
90 if (fTipShell != null && ! fTipShell.isDisposed()) {
91 fTipShell.dispose();
34313553 92 }
f1fae91f 93 fTipShell = new Shell(parent, SWT.ON_TOP | SWT.TOOL);
34313553
PT
94 GridLayout gridLayout = new GridLayout();
95 gridLayout.numColumns = 2;
96 gridLayout.marginWidth = 2;
97 gridLayout.marginHeight = 2;
f1fae91f
PT
98 fTipShell.setLayout(gridLayout);
99 fTipShell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
34313553 100
f1fae91f
PT
101 fTipComposite = new Composite(fTipShell, SWT.NONE);
102 fTipComposite.setLayout(new GridLayout(3, false));
103 setupControl(fTipComposite);
34313553
PT
104
105 }
106
107 /**
108 * Callback for the mouse-over tooltip
109 *
110 * @param control
111 * The control object to use
112 */
113 public void activateHoverHelp(final Control control) {
114 control.addMouseListener(new MouseAdapter() {
115 @Override
116 public void mouseDown(MouseEvent e) {
f1fae91f
PT
117 if (fTipShell != null && ! fTipShell.isDisposed()) {
118 fTipShell.dispose();
34313553
PT
119 }
120 }
121 });
122
123 control.addMouseMoveListener(new MouseMoveListener() {
124 @Override
125 public void mouseMove(MouseEvent e) {
f1fae91f
PT
126 if (fTipShell != null && ! fTipShell.isDisposed()) {
127 fTipShell.dispose();
34313553
PT
128 }
129 }
130 });
131
132 control.addMouseTrackListener(new MouseTrackAdapter() {
133 @Override
134 public void mouseExit(MouseEvent e) {
f1fae91f 135 if (fTipShell != null && ! fTipShell.isDisposed()) {
34313553 136 Point pt = control.toDisplay(e.x, e.y);
f1fae91f
PT
137 if (! fTipShell.getBounds().contains(pt)) {
138 fTipShell.dispose();
34313553
PT
139 }
140 }
141 }
142
143 private void addItem(String name, String value) {
f1fae91f 144 Label nameLabel = new Label(fTipComposite, SWT.NO_FOCUS);
34313553
PT
145 nameLabel.setText(name);
146 setupControl(nameLabel);
f1fae91f 147 Label separator = new Label(fTipComposite, SWT.NO_FOCUS | SWT.SEPARATOR | SWT.VERTICAL);
34313553
PT
148 GridData gd = new GridData(SWT.CENTER, SWT.CENTER, false, false);
149 gd.heightHint = nameLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
150 separator.setLayoutData(gd);
151 setupControl(separator);
f1fae91f 152 Label valueLabel = new Label(fTipComposite, SWT.NO_FOCUS);
34313553
PT
153 valueLabel.setText(value);
154 setupControl(valueLabel);
155 }
156
157 private void fillValues(Point pt, TimeGraphControl timeGraphControl, ITimeGraphEntry entry) {
158 if (entry == null) {
159 return;
160 }
161 if (entry.hasTimeEvents()) {
162 long currPixelTime = timeGraphControl.getTimeAtX(pt.x);
163 long nextPixelTime = timeGraphControl.getTimeAtX(pt.x + 1);
164 if (nextPixelTime == currPixelTime) {
165 nextPixelTime++;
166 }
167 ITimeEvent currEvent = Utils.findEvent(entry, currPixelTime, 0);
168 ITimeEvent nextEvent = Utils.findEvent(entry, currPixelTime, 1);
169
170 // if there is no current event at the start of the current pixel range,
171 // or if the current event starts before the current pixel range,
172 // use the next event as long as it starts within the current pixel range
f1fae91f
PT
173 if ((currEvent == null || currEvent.getTime() < currPixelTime) &&
174 (nextEvent != null && nextEvent.getTime() < nextPixelTime)) {
175 currEvent = nextEvent;
176 currPixelTime = nextEvent.getTime();
34313553
PT
177 }
178
179 // state name
f1fae91f 180 String stateTypeName = fTimeGraphProvider.getStateTypeName(entry);
34313553
PT
181 String entryName = entry.getName();
182 if (stateTypeName == null) {
f1fae91f 183 stateTypeName = fTimeGraphProvider.getStateTypeName();
34313553
PT
184 }
185
186 if (!entryName.isEmpty()) {
187 addItem(stateTypeName, entry.getName());
188 }
189
3e9a3685 190 if (currEvent == null || currEvent instanceof NullTimeEvent) {
34313553
PT
191 return;
192 }
193
194 // state
f1fae91f 195 String state = fTimeGraphProvider.getEventName(currEvent);
34313553
PT
196 if (state != null) {
197 addItem(Messages.TmfTimeTipHandler_TRACE_STATE, state);
198 }
199
200 // This block receives a list of <String, String> values to be added to the tip table
f1fae91f 201 Map<String, String> eventAddOns = fTimeGraphProvider.getEventHoverToolTipInfo(currEvent, currPixelTime);
34313553
PT
202 if (eventAddOns != null) {
203 for (Iterator<String> iter = eventAddOns.keySet().iterator(); iter.hasNext();) {
204 String message = iter.next();
205 addItem(message, eventAddOns.get(message));
206 }
207 }
1e9f8bef
XR
208 if (fTimeGraphProvider.displayTimesInTooltip()) {
209 long eventStartTime = -1;
210 long eventDuration = -1;
211 long eventEndTime = -1;
34313553 212
1e9f8bef
XR
213 eventStartTime = currEvent.getTime();
214 eventDuration = currEvent.getDuration();
215 if (eventDuration < 0 && nextEvent != null) {
216 eventEndTime = nextEvent.getTime();
217 eventDuration = eventEndTime - eventStartTime;
218 } else {
219 eventEndTime = eventStartTime + eventDuration;
220 }
34313553 221
1e9f8bef
XR
222 Resolution res = Resolution.NANOSEC;
223 TimeFormat tf = fTimeDataProvider.getTimeFormat();
0fab12b0
PT
224 String startTime = "?"; //$NON-NLS-1$
225 String duration = "?"; //$NON-NLS-1$
226 String endTime = "?"; //$NON-NLS-1$
227 if (fTimeDataProvider instanceof ITimeDataProviderConverter) {
228 ITimeDataProviderConverter tdp = (ITimeDataProviderConverter) fTimeDataProvider;
229 if (eventStartTime > -1) {
230 eventStartTime = tdp.convertTime(eventStartTime);
231 startTime = Utils.formatTime(eventStartTime, tf, res);
232 }
233 if (eventEndTime > -1) {
234 eventEndTime = tdp.convertTime(eventEndTime);
235 endTime = Utils.formatTime(eventEndTime, tf, res);
236 }
237 if (eventDuration > -1) {
238 duration = Utils.formatDelta(eventEndTime - eventStartTime, tf, res);
239 }
240 } else {
241 if (eventStartTime > -1) {
242 startTime = Utils.formatTime(eventStartTime, tf, res);
243 }
244 if (eventEndTime > -1) {
245 endTime = Utils.formatTime(eventEndTime, tf, res);
246 }
247 if (eventDuration > -1) {
248 duration = Utils.formatDelta(eventDuration, tf, res);
249 }
250 }
1e9f8bef 251 if (tf == TimeFormat.CALENDAR) {
0fab12b0
PT
252 addItem(Messages.TmfTimeTipHandler_TRACE_DATE,
253 eventStartTime > -1 ? Utils.formatDate(eventStartTime) : "?"); //$NON-NLS-1$
1e9f8bef
XR
254 }
255 if (eventDuration > 0) {
0fab12b0
PT
256 addItem(Messages.TmfTimeTipHandler_TRACE_START_TIME, startTime);
257 addItem(Messages.TmfTimeTipHandler_TRACE_STOP_TIME, endTime);
1e9f8bef 258 } else {
0fab12b0 259 addItem(Messages.TmfTimeTipHandler_TRACE_EVENT_TIME, startTime);
1e9f8bef 260 }
34313553 261
1e9f8bef 262 if (eventDuration > 0) {
0fab12b0 263 addItem(Messages.TmfTimeTipHandler_DURATION, duration);
026664b7 264 }
34313553
PT
265 }
266 }
267 }
268
1053eaa6
PT
269 private void fillValues(ILinkEvent linkEvent) {
270 addItem(Messages.TmfTimeTipHandler_LINK_SOURCE, linkEvent.getEntry().getName());
271 addItem(Messages.TmfTimeTipHandler_LINK_TARGET, linkEvent.getDestinationEntry().getName());
272
273 // This block receives a list of <String, String> values to be added to the tip table
274 Map<String, String> eventAddOns = fTimeGraphProvider.getEventHoverToolTipInfo(linkEvent);
275 if (eventAddOns != null) {
276 for (Iterator<String> iter = eventAddOns.keySet().iterator(); iter.hasNext();) {
277 String message = iter.next();
278 addItem(message, eventAddOns.get(message));
279 }
280 }
281 if (fTimeGraphProvider.displayTimesInTooltip()) {
282 long sourceTime = linkEvent.getTime();
283 long duration = linkEvent.getDuration();
284 long targetTime = sourceTime + duration;
0fab12b0
PT
285 if (fTimeDataProvider instanceof ITimeDataProviderConverter) {
286 ITimeDataProviderConverter tdp = (ITimeDataProviderConverter) fTimeDataProvider;
287 sourceTime = tdp.convertTime(sourceTime);
288 targetTime = tdp.convertTime(targetTime);
289 duration = targetTime - sourceTime;
290 }
1053eaa6
PT
291 Resolution res = Resolution.NANOSEC;
292 TimeFormat tf = fTimeDataProvider.getTimeFormat();
293 if (tf == TimeFormat.CALENDAR) {
294 addItem(Messages.TmfTimeTipHandler_TRACE_DATE, Utils.formatDate(sourceTime));
295 }
296 if (duration > 0) {
297 addItem(Messages.TmfTimeTipHandler_LINK_SOURCE_TIME, Utils.formatTime(sourceTime, tf, res));
298 addItem(Messages.TmfTimeTipHandler_LINK_TARGET_TIME, Utils.formatTime(targetTime, tf, res));
0fab12b0 299 addItem(Messages.TmfTimeTipHandler_DURATION, Utils.formatDelta(duration, tf, res));
1053eaa6
PT
300 } else {
301 addItem(Messages.TmfTimeTipHandler_LINK_TIME, Utils.formatTime(sourceTime, tf, res));
302 }
303 }
304 }
305
34313553
PT
306 @Override
307 public void mouseHover(MouseEvent event) {
5b2b9bd7
PT
308 if ((event.stateMask & SWT.BUTTON_MASK) != 0) {
309 return;
310 }
34313553
PT
311 Point pt = new Point(event.x, event.y);
312 TimeGraphControl timeGraphControl = (TimeGraphControl) event.widget;
313 createTooltipShell(timeGraphControl.getShell());
f1fae91f 314 for (Control child : fTipComposite.getChildren()) {
34313553
PT
315 child.dispose();
316 }
1053eaa6
PT
317 if ((event.stateMask & SWT.MODIFIER_MASK) != SWT.SHIFT) {
318 ILinkEvent linkEvent = timeGraphControl.getArrow(pt);
319 if (linkEvent != null) {
320 fillValues(linkEvent);
321 }
322 }
323 if (fTipComposite.getChildren().length == 0) {
324 ITimeGraphEntry entry = timeGraphControl.getEntry(pt);
325 fillValues(pt, timeGraphControl, entry);
326 }
f1fae91f 327 if (fTipComposite.getChildren().length == 0) {
34313553
PT
328 return;
329 }
f1fae91f
PT
330 fTipShell.pack();
331 Point tipPosition = control.toDisplay(pt);
332 fTipShell.pack();
333 setHoverLocation(fTipShell, tipPosition);
334 fTipShell.setVisible(true);
34313553
PT
335 }
336 });
337 }
338
339 private static void setHoverLocation(Shell shell, Point position) {
340 Rectangle displayBounds = shell.getDisplay().getBounds();
341 Rectangle shellBounds = shell.getBounds();
f1fae91f
PT
342 if (position.x + shellBounds.width + OFFSET > displayBounds.width && position.x - shellBounds.width - OFFSET >= 0) {
343 shellBounds.x = position.x - shellBounds.width - OFFSET;
34313553 344 } else {
f1fae91f 345 shellBounds.x = Math.max(Math.min(position.x + OFFSET, displayBounds.width - shellBounds.width), 0);
34313553 346 }
f1fae91f
PT
347 if (position.y + shellBounds.height + OFFSET > displayBounds.height && position.y - shellBounds.height - OFFSET >= 0) {
348 shellBounds.y = position.y - shellBounds.height - OFFSET;
34313553 349 } else {
f1fae91f 350 shellBounds.y = Math.max(Math.min(position.y + OFFSET, displayBounds.height - shellBounds.height), 0);
34313553
PT
351 }
352 shell.setBounds(shellBounds);
353 }
354
355 private void setupControl(Control control) {
f1fae91f
PT
356 control.setForeground(fTipShell.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
357 control.setBackground(fTipShell.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
34313553
PT
358
359 control.addMouseListener(new MouseAdapter() {
360 @Override
361 public void mouseDown(MouseEvent e) {
f1fae91f 362 fTipShell.dispose();
34313553
PT
363 }
364 });
365
366 control.addMouseTrackListener(new MouseTrackAdapter() {
367 @Override
368 public void mouseExit(MouseEvent e) {
f1fae91f 369 fTipShell.dispose();
34313553
PT
370 }
371 });
372
373 control.addMouseMoveListener(new MouseMoveListener() {
374 @Override
375 public void mouseMove(MouseEvent e) {
f1fae91f 376 fTipShell.dispose();
34313553
PT
377 }
378 });
379 }
549f3c43 380}
This page took 0.071712 seconds and 5 git commands to generate.