Commit | Line | Data |
---|---|---|
fb5cad3d PT |
1 | /*****************************************************************************\r |
2 | * Copyright (c) 2007 Intel Corporation, 2009, 2012 Ericsson.\r | |
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 | * Vitaly A. Provodin, Intel - Initial API and implementation\r | |
11 | * Alvaro Sanchez-Leon - Updated for TMF\r | |
12 | * Patrick Tasse - Refactoring\r | |
13 | *\r | |
14 | *****************************************************************************/\r | |
15 | package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets;\r | |
16 | \r | |
17 | import java.util.Iterator;\r | |
18 | import java.util.Map;\r | |
19 | \r | |
20 | import org.eclipse.linuxtools.internal.tmf.ui.Messages;\r | |
b83af2c3 | 21 | import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider;\r |
fb5cad3d PT |
22 | import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;\r |
23 | import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;\r | |
24 | import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;\r | |
25 | import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;\r | |
26 | import org.eclipse.swt.SWT;\r | |
27 | import org.eclipse.swt.events.MouseAdapter;\r | |
28 | import org.eclipse.swt.events.MouseEvent;\r | |
b83af2c3 | 29 | import org.eclipse.swt.events.MouseMoveListener;\r |
fb5cad3d PT |
30 | import org.eclipse.swt.events.MouseTrackAdapter;\r |
31 | import org.eclipse.swt.graphics.Point;\r | |
32 | import org.eclipse.swt.graphics.Rectangle;\r | |
33 | import org.eclipse.swt.layout.GridData;\r | |
34 | import org.eclipse.swt.layout.GridLayout;\r | |
35 | import org.eclipse.swt.widgets.Control;\r | |
36 | import org.eclipse.swt.widgets.Display;\r | |
37 | import org.eclipse.swt.widgets.Shell;\r | |
38 | import org.eclipse.swt.widgets.Table;\r | |
39 | import org.eclipse.swt.widgets.TableColumn;\r | |
40 | import org.eclipse.swt.widgets.TableItem;\r | |
fb5cad3d PT |
41 | \r |
42 | \r | |
43 | public class TimeGraphTooltipHandler {\r | |
44 | \r | |
45 | private Shell _tipShell;\r | |
46 | private Table _tipTable;\r | |
47 | private TimeGraphItem _tipItem;\r | |
48 | private Point _tipPosition;\r | |
49 | private ITimeDataProvider _timeDataProvider;\r | |
b83af2c3 | 50 | ITimeGraphPresentationProvider _utilImp = null;\r |
fb5cad3d | 51 | \r |
b83af2c3 | 52 | public TimeGraphTooltipHandler(Shell parent, ITimeGraphPresentationProvider rUtilImpl,\r |
fb5cad3d PT |
53 | ITimeDataProvider timeProv) {\r |
54 | final Display display = parent.getDisplay();\r | |
55 | \r | |
56 | this._utilImp = rUtilImpl;\r | |
57 | this._timeDataProvider = timeProv;\r | |
58 | _tipShell = new Shell(parent, SWT.ON_TOP | SWT.TOOL);\r | |
59 | GridLayout gridLayout = new GridLayout();\r | |
60 | gridLayout.numColumns = 2;\r | |
61 | gridLayout.marginWidth = 2;\r | |
62 | gridLayout.marginHeight = 2;\r | |
63 | _tipShell.setLayout(gridLayout);\r | |
64 | GridData data = new GridData(GridData.BEGINNING, GridData.BEGINNING,\r | |
65 | true, true);\r | |
66 | _tipShell.setLayoutData(data);\r | |
67 | _tipShell.setBackground(display\r | |
68 | .getSystemColor(SWT.COLOR_INFO_BACKGROUND));\r | |
69 | \r | |
70 | _tipTable = new Table(_tipShell, SWT.NONE);\r | |
b83af2c3 PT |
71 | new TableColumn(_tipTable, SWT.NONE);\r |
72 | new TableColumn(_tipTable, SWT.NONE);\r | |
fb5cad3d PT |
73 | _tipTable.setForeground(display\r |
74 | .getSystemColor(SWT.COLOR_INFO_FOREGROUND));\r | |
75 | _tipTable.setBackground(display\r | |
76 | .getSystemColor(SWT.COLOR_INFO_BACKGROUND));\r | |
77 | _tipTable.setHeaderVisible(false);\r | |
78 | _tipTable.setLinesVisible(false);\r | |
79 | \r | |
80 | // tipTable.setLayoutData(new GridData(GridData.FILL_HORIZONTAL\r | |
81 | // | GridData.VERTICAL_ALIGN_CENTER));\r | |
82 | }\r | |
83 | \r | |
84 | public void activateHoverHelp(final Control control) {\r | |
85 | //FIXME: remove old listeners\r | |
86 | control.addMouseListener(new MouseAdapter() {\r | |
87 | @Override\r | |
88 | public void mouseDown(MouseEvent e) {\r | |
b83af2c3 | 89 | if (_tipShell.isVisible()) {\r |
fb5cad3d | 90 | _tipShell.setVisible(false);\r |
b83af2c3 PT |
91 | }\r |
92 | }\r | |
93 | });\r | |
94 | \r | |
95 | control.addMouseMoveListener(new MouseMoveListener() {\r | |
96 | @Override\r | |
97 | public void mouseMove(MouseEvent e) {\r | |
98 | if (_tipShell.isVisible()) {\r | |
99 | _tipShell.setVisible(false);\r | |
100 | }\r | |
fb5cad3d PT |
101 | }\r |
102 | });\r | |
103 | \r | |
104 | control.addMouseTrackListener(new MouseTrackAdapter() {\r | |
105 | @Override\r | |
106 | public void mouseExit(MouseEvent e) {\r | |
b83af2c3 | 107 | if (_tipShell.isVisible()) {\r |
fb5cad3d | 108 | _tipShell.setVisible(false);\r |
b83af2c3 | 109 | }\r |
fb5cad3d | 110 | _tipItem = null;\r |
fb5cad3d PT |
111 | }\r |
112 | \r | |
113 | private void addItem(String name, String value) {\r | |
114 | TableItem line = new TableItem(_tipTable, SWT.NONE);\r | |
115 | line.setText(0, name);\r | |
116 | line.setText(1, value);\r | |
117 | }\r | |
118 | \r | |
119 | private void fillValues(Point pt, TimeGraphControl threadStates, TimeGraphItem item) {\r | |
120 | if (item == null) {\r | |
121 | return;\r | |
122 | }\r | |
123 | if (item._trace.getTimeEventsIterator() == null) {\r | |
124 | addItem(Messages.TmfTimeTipHandler_TRACE_GROUP_NAME, item.toString());\r | |
125 | addItem(Messages.TmfTimeTipHandler_NUMBER_OF_TRACES, "" + item.children.size()); //$NON-NLS-1$\r | |
126 | } else {\r | |
127 | ITimeGraphEntry thrd = item._trace;\r | |
128 | ITimeEvent threadEvent = Utils.findEvent(thrd, threadStates.getTimeAtX(pt.x), 2);\r | |
129 | ITimeEvent nextEvent = Utils.findEvent(thrd, threadStates.getTimeAtX(pt.x), 1);\r | |
130 | // thread name\r | |
3ac6ad1a BH |
131 | // addItem(Messages.TmfTimeTipHandler_TRACE_NAME, thrd.getName());\r |
132 | addItem(_utilImp.getStateTypeName(), thrd.getName());\r | |
fb5cad3d PT |
133 | // class name\r |
134 | String traceClass = _utilImp.getTraceClassName(thrd);\r | |
135 | if (traceClass != null) {\r | |
136 | addItem(Messages.TmfTimeTipHandler_TRACE_CLASS_NAME, traceClass);\r | |
137 | }\r | |
b83af2c3 PT |
138 | if (threadEvent == null) {\r |
139 | return;\r | |
140 | }\r | |
fb5cad3d PT |
141 | // thread state\r |
142 | String state = _utilImp.getEventName(threadEvent);\r | |
143 | if (state != null) {\r | |
144 | addItem(Messages.TmfTimeTipHandler_TRACE_STATE, state);\r | |
145 | }\r | |
146 | \r | |
147 | // This block receives a\r | |
148 | // list of <String, String> values to be added to the tip\r | |
149 | // table\r | |
150 | Map<String, String> eventAddOns = _utilImp.getEventHoverToolTipInfo(threadEvent);\r | |
151 | if (eventAddOns != null) {\r | |
152 | for (Iterator<String> iter = eventAddOns.keySet().iterator(); iter.hasNext();) {\r | |
153 | String message = (String) iter.next();\r | |
154 | addItem(message, eventAddOns.get(message));\r | |
155 | }\r | |
156 | }\r | |
157 | \r | |
158 | long eventStartTime = -1;\r | |
159 | long eventDuration = -1;\r | |
160 | long eventEndTime = -1;\r | |
161 | \r | |
162 | if (threadEvent != null) {\r | |
163 | eventStartTime = threadEvent.getTime();\r | |
164 | eventDuration = threadEvent.getDuration();\r | |
165 | if (eventDuration < 0 && nextEvent != null) {\r | |
166 | eventEndTime = nextEvent.getTime();\r | |
167 | eventDuration = eventEndTime - eventStartTime;\r | |
168 | } else {\r | |
169 | eventEndTime = eventStartTime + eventDuration;\r | |
170 | }\r | |
171 | }\r | |
172 | \r | |
173 | // TODO: Check if we need "format" \r | |
174 | // TimeFormat format = TimeFormat.RELATIVE;\r | |
175 | Resolution res = Resolution.NANOSEC;\r | |
176 | if (_timeDataProvider.isCalendarFormat()) {\r | |
177 | // format = TimeFormat.ABSOLUTE; // Absolute format\r | |
178 | // // (calendar)\r | |
179 | // Add Date\r | |
180 | addItem(Messages.TmfTimeTipHandler_TRACE_DATE, eventStartTime > -1 ?\r | |
181 | Utils.formatDate(eventStartTime)\r | |
182 | : "?"); //$NON-NLS-1$\r | |
183 | if (eventDuration > 0) {\r | |
184 | addItem(Messages.TmfTimeTipHandler_TRACE_START_TIME, eventStartTime > -1 ?\r | |
185 | Utils.formatTime(eventStartTime, TimeFormat.ABSOLUTE, res)\r | |
186 | : "?"); //$NON-NLS-1$\r | |
187 | \r | |
188 | addItem(Messages.TmfTimeTipHandler_TRACE_STOP_TIME, eventEndTime > -1 ?\r | |
189 | Utils.formatTime(eventEndTime, TimeFormat.ABSOLUTE, res)\r | |
190 | : "?"); //$NON-NLS-1$\r | |
191 | } else {\r | |
192 | addItem(Messages.TmfTimeTipHandler_TRACE_EVENT_TIME, eventStartTime > -1 ?\r | |
193 | Utils.formatTime(eventStartTime, TimeFormat.ABSOLUTE, res)\r | |
194 | : "?"); //$NON-NLS-1$\r | |
195 | }\r | |
196 | } else {\r | |
197 | if (eventDuration > 0) {\r | |
198 | addItem(Messages.TmfTimeTipHandler_TRACE_START_TIME, eventStartTime > -1 ?\r | |
199 | Utils.formatTime(eventStartTime, TimeFormat.RELATIVE, res)\r | |
200 | : "?"); //$NON-NLS-1$\r | |
201 | \r | |
202 | addItem(Messages.TmfTimeTipHandler_TRACE_STOP_TIME, eventEndTime > -1 ?\r | |
203 | Utils.formatTime(eventEndTime, TimeFormat.RELATIVE, res)\r | |
204 | : "?"); //$NON-NLS-1$\r | |
205 | } else {\r | |
206 | addItem(Messages.TmfTimeTipHandler_TRACE_EVENT_TIME, eventStartTime > -1 ?\r | |
207 | Utils.formatTime(eventStartTime, TimeFormat.RELATIVE, res)\r | |
208 | : "?"); //$NON-NLS-1$\r | |
209 | }\r | |
210 | }\r | |
211 | \r | |
212 | if (eventDuration > 0) {\r | |
213 | // Duration in relative format in any case\r | |
214 | addItem(Messages.TmfTimeTipHandler_DURATION, eventDuration > -1 ?\r | |
215 | Utils.formatTime(eventDuration, TimeFormat.RELATIVE, res)\r | |
216 | : "?"); //$NON-NLS-1$\r | |
217 | }\r | |
218 | }\r | |
219 | }\r | |
220 | \r | |
221 | @Override\r | |
222 | public void mouseHover(MouseEvent event) {\r | |
223 | Point pt = new Point(event.x, event.y);\r | |
b83af2c3 PT |
224 | TimeGraphControl threadStates = (TimeGraphControl) event.widget;\r |
225 | TimeGraphItem item = threadStates.getItem(pt);\r | |
226 | _tipTable.remove(0, _tipTable.getItemCount() - 1);\r | |
227 | fillValues(pt, threadStates, item);\r | |
228 | _tipTable.getColumn(0).setWidth(200);\r | |
229 | _tipTable.getColumn(1).pack();\r | |
230 | _tipTable.setSize(_tipTable.computeSize(SWT.DEFAULT, 200));\r | |
231 | _tipShell.pack();\r | |
fb5cad3d PT |
232 | _tipItem = item;\r |
233 | _tipPosition = control.toDisplay(pt);\r | |
234 | _tipShell.pack();\r | |
235 | setHoverLocation(_tipShell, _tipPosition);\r | |
236 | _tipShell.setVisible(true);\r | |
237 | }\r | |
238 | });\r | |
239 | }\r | |
240 | \r | |
241 | private void setHoverLocation(Shell shell, Point position) {\r | |
242 | Rectangle displayBounds = shell.getDisplay().getBounds();\r | |
243 | Rectangle shellBounds = shell.getBounds();\r | |
244 | shellBounds.x = Math.max(Math.min(position.x, displayBounds.width\r | |
245 | - shellBounds.width), 0);\r | |
246 | shellBounds.y = Math.max(Math.min(position.y + 16, displayBounds.height\r | |
247 | - shellBounds.height), 0);\r | |
248 | shell.setBounds(shellBounds);\r | |
249 | }\r | |
250 | \r | |
251 | } |