1 /*****************************************************************************
2 * Copyright (c) 2007 Intel Corporation, 2009, 2012 Ericsson.
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
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
14 *****************************************************************************/
15 package org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
;
17 import java
.util
.Iterator
;
20 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Messages
;
21 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.ITimeGraphPresentationProvider
;
22 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
23 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
24 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.Resolution
;
25 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
26 import org
.eclipse
.swt
.SWT
;
27 import org
.eclipse
.swt
.events
.MouseAdapter
;
28 import org
.eclipse
.swt
.events
.MouseEvent
;
29 import org
.eclipse
.swt
.events
.MouseMoveListener
;
30 import org
.eclipse
.swt
.events
.MouseTrackAdapter
;
31 import org
.eclipse
.swt
.graphics
.Point
;
32 import org
.eclipse
.swt
.graphics
.Rectangle
;
33 import org
.eclipse
.swt
.layout
.GridData
;
34 import org
.eclipse
.swt
.layout
.GridLayout
;
35 import org
.eclipse
.swt
.widgets
.Control
;
36 import org
.eclipse
.swt
.widgets
.Display
;
37 import org
.eclipse
.swt
.widgets
.Shell
;
38 import org
.eclipse
.swt
.widgets
.Table
;
39 import org
.eclipse
.swt
.widgets
.TableColumn
;
40 import org
.eclipse
.swt
.widgets
.TableItem
;
43 * Handler for the tool tips in the generic time graph view.
46 * @author Alvaro Sanchez-Leon
47 * @author Patrick Tasse
49 public class TimeGraphTooltipHandler
{
51 private final Shell _tipShell
;
52 private final Table _tipTable
;
53 private Point _tipPosition
;
54 private final ITimeDataProvider _timeDataProvider
;
55 ITimeGraphPresentationProvider _utilImp
= null;
58 * Standard constructor
61 * The parent composite object
63 * The presentation provider
67 public TimeGraphTooltipHandler(Shell parent
, ITimeGraphPresentationProvider rUtilImpl
,
68 ITimeDataProvider timeProv
) {
69 final Display display
= parent
.getDisplay();
71 this._utilImp
= rUtilImpl
;
72 this._timeDataProvider
= timeProv
;
73 _tipShell
= new Shell(parent
, SWT
.ON_TOP
| SWT
.TOOL
);
74 GridLayout gridLayout
= new GridLayout();
75 gridLayout
.numColumns
= 2;
76 gridLayout
.marginWidth
= 2;
77 gridLayout
.marginHeight
= 2;
78 _tipShell
.setLayout(gridLayout
);
79 GridData data
= new GridData(GridData
.BEGINNING
, GridData
.BEGINNING
,
81 _tipShell
.setLayoutData(data
);
82 _tipShell
.setBackground(display
83 .getSystemColor(SWT
.COLOR_INFO_BACKGROUND
));
85 _tipTable
= new Table(_tipShell
, SWT
.NONE
);
86 new TableColumn(_tipTable
, SWT
.NONE
);
87 new TableColumn(_tipTable
, SWT
.NONE
);
88 _tipTable
.setForeground(display
89 .getSystemColor(SWT
.COLOR_INFO_FOREGROUND
));
90 _tipTable
.setBackground(display
91 .getSystemColor(SWT
.COLOR_INFO_BACKGROUND
));
92 _tipTable
.setHeaderVisible(false);
93 _tipTable
.setLinesVisible(false);
95 // tipTable.setLayoutData(new GridData(GridData.FILL_HORIZONTAL
96 // | GridData.VERTICAL_ALIGN_CENTER));
100 * Callback for the mouse-over tooltip
103 * The control object to use
105 public void activateHoverHelp(final Control control
) {
106 //FIXME: remove old listeners
107 control
.addMouseListener(new MouseAdapter() {
109 public void mouseDown(MouseEvent e
) {
110 if (_tipShell
.isVisible()) {
111 _tipShell
.setVisible(false);
116 control
.addMouseMoveListener(new MouseMoveListener() {
118 public void mouseMove(MouseEvent e
) {
119 if (_tipShell
.isVisible()) {
120 _tipShell
.setVisible(false);
125 control
.addMouseTrackListener(new MouseTrackAdapter() {
127 public void mouseExit(MouseEvent e
) {
128 if (_tipShell
.isVisible()) {
129 _tipShell
.setVisible(false);
133 private void addItem(String name
, String value
) {
134 TableItem line
= new TableItem(_tipTable
, SWT
.NONE
);
135 line
.setText(0, name
);
136 line
.setText(1, value
);
139 private void fillValues(Point pt
, TimeGraphControl threadStates
, ITimeGraphEntry entry
) {
143 if (entry
.hasTimeEvents()) {
144 ITimeEvent threadEvent
= Utils
.findEvent(entry
, threadStates
.getTimeAtX(pt
.x
), 2);
145 ITimeEvent nextEvent
= Utils
.findEvent(entry
, threadStates
.getTimeAtX(pt
.x
), 1);
147 addItem(_utilImp
.getStateTypeName(), entry
.getName());
148 if (threadEvent
== null) {
152 String state
= _utilImp
.getEventName(threadEvent
);
154 addItem(Messages
.TmfTimeTipHandler_TRACE_STATE
, state
);
157 // This block receives a
158 // list of <String, String> values to be added to the tip
160 Map
<String
, String
> eventAddOns
= _utilImp
.getEventHoverToolTipInfo(threadEvent
);
161 if (eventAddOns
!= null) {
162 for (Iterator
<String
> iter
= eventAddOns
.keySet().iterator(); iter
.hasNext();) {
163 String message
= (String
) iter
.next();
164 addItem(message
, eventAddOns
.get(message
));
168 long eventStartTime
= -1;
169 long eventDuration
= -1;
170 long eventEndTime
= -1;
172 if (threadEvent
!= null) {
173 eventStartTime
= threadEvent
.getTime();
174 eventDuration
= threadEvent
.getDuration();
175 if (eventDuration
< 0 && nextEvent
!= null) {
176 eventEndTime
= nextEvent
.getTime();
177 eventDuration
= eventEndTime
- eventStartTime
;
179 eventEndTime
= eventStartTime
+ eventDuration
;
183 // TODO: Check if we need "format"
184 // TimeFormat format = TimeFormat.RELATIVE;
185 Resolution res
= Resolution
.NANOSEC
;
186 if (_timeDataProvider
.isCalendarFormat()) {
187 // format = TimeFormat.ABSOLUTE; // Absolute format
190 addItem(Messages
.TmfTimeTipHandler_TRACE_DATE
, eventStartTime
> -1 ?
191 Utils
.formatDate(eventStartTime
)
192 : "?"); //$NON-NLS-1$
193 if (eventDuration
> 0) {
194 addItem(Messages
.TmfTimeTipHandler_TRACE_START_TIME
, eventStartTime
> -1 ?
195 Utils
.formatTime(eventStartTime
, TimeFormat
.ABSOLUTE
, res
)
196 : "?"); //$NON-NLS-1$
198 addItem(Messages
.TmfTimeTipHandler_TRACE_STOP_TIME
, eventEndTime
> -1 ?
199 Utils
.formatTime(eventEndTime
, TimeFormat
.ABSOLUTE
, res
)
200 : "?"); //$NON-NLS-1$
202 addItem(Messages
.TmfTimeTipHandler_TRACE_EVENT_TIME
, eventStartTime
> -1 ?
203 Utils
.formatTime(eventStartTime
, TimeFormat
.ABSOLUTE
, res
)
204 : "?"); //$NON-NLS-1$
207 if (eventDuration
> 0) {
208 addItem(Messages
.TmfTimeTipHandler_TRACE_START_TIME
, eventStartTime
> -1 ?
209 Utils
.formatTime(eventStartTime
, TimeFormat
.RELATIVE
, res
)
210 : "?"); //$NON-NLS-1$
212 addItem(Messages
.TmfTimeTipHandler_TRACE_STOP_TIME
, eventEndTime
> -1 ?
213 Utils
.formatTime(eventEndTime
, TimeFormat
.RELATIVE
, res
)
214 : "?"); //$NON-NLS-1$
216 addItem(Messages
.TmfTimeTipHandler_TRACE_EVENT_TIME
, eventStartTime
> -1 ?
217 Utils
.formatTime(eventStartTime
, TimeFormat
.RELATIVE
, res
)
218 : "?"); //$NON-NLS-1$
222 if (eventDuration
> 0) {
223 // Duration in relative format in any case
224 addItem(Messages
.TmfTimeTipHandler_DURATION
, eventDuration
> -1 ?
225 Utils
.formatTime(eventDuration
, TimeFormat
.RELATIVE
, res
)
226 : "?"); //$NON-NLS-1$
232 public void mouseHover(MouseEvent event
) {
233 Point pt
= new Point(event
.x
, event
.y
);
234 TimeGraphControl threadStates
= (TimeGraphControl
) event
.widget
;
235 ITimeGraphEntry entry
= threadStates
.getEntry(pt
);
236 _tipTable
.remove(0, _tipTable
.getItemCount() - 1);
237 fillValues(pt
, threadStates
, entry
);
238 if (_tipTable
.getItemCount() == 0) {
241 _tipTable
.getColumn(0).pack();
242 _tipTable
.getColumn(1).pack();
244 _tipPosition
= control
.toDisplay(pt
);
246 setHoverLocation(_tipShell
, _tipPosition
);
247 _tipShell
.setVisible(true);
252 private void setHoverLocation(Shell shell
, Point position
) {
253 Rectangle displayBounds
= shell
.getDisplay().getBounds();
254 Rectangle shellBounds
= shell
.getBounds();
255 shellBounds
.x
= Math
.max(Math
.min(position
.x
, displayBounds
.width
256 - shellBounds
.width
), 0);
257 shellBounds
.y
= Math
.max(Math
.min(position
.y
+ 16, displayBounds
.height
258 - shellBounds
.height
), 0);
259 shell
.setBounds(shellBounds
);