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