Commit | Line | Data |
---|---|---|
6e512b93 ASL |
1 | /******************************************************************************* |
2 | * Copyright (c) 2009 Ericsson | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
b59134e1 | 10 | * William Bourque - Initial API and implementation |
6e512b93 ASL |
11 | *******************************************************************************/ |
12 | package org.eclipse.linuxtools.lttng.ui.views.histogram; | |
13 | ||
b59134e1 WB |
14 | import org.eclipse.linuxtools.lttng.event.LttngEvent; |
15 | import org.eclipse.linuxtools.lttng.event.LttngTimestamp; | |
16 | import org.eclipse.linuxtools.tmf.event.TmfTimeRange; | |
833a21aa | 17 | import org.eclipse.linuxtools.tmf.event.TmfTimestamp; |
b59134e1 | 18 | import org.eclipse.linuxtools.tmf.experiment.TmfExperiment; |
ff4ed569 FC |
19 | import org.eclipse.linuxtools.tmf.signal.TmfExperimentSelectedSignal; |
20 | import org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal; | |
ed4b3b9f | 21 | import org.eclipse.linuxtools.tmf.signal.TmfRangeSynchSignal; |
b59134e1 WB |
22 | import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler; |
23 | import org.eclipse.linuxtools.tmf.signal.TmfTimeSynchSignal; | |
24 | import org.eclipse.linuxtools.tmf.ui.views.TmfView; | |
25 | import org.eclipse.swt.SWT; | |
7ef9ae3f WB |
26 | import org.eclipse.swt.events.ControlEvent; |
27 | import org.eclipse.swt.events.ControlListener; | |
6cf16d22 | 28 | import org.eclipse.swt.graphics.Font; |
833a21aa | 29 | import org.eclipse.swt.graphics.FontData; |
b59134e1 | 30 | import org.eclipse.swt.layout.GridData; |
252ae4bd | 31 | import org.eclipse.swt.layout.GridLayout; |
6e512b93 | 32 | import org.eclipse.swt.widgets.Composite; |
833a21aa | 33 | import org.eclipse.swt.widgets.Text; |
6e512b93 | 34 | |
544fe9b7 WB |
35 | /** |
36 | * <b><u>HistogramView</u></b> | |
37 | * <p> | |
38 | * View that contain an visual approach to the window that control the request. | |
39 | * This is intended to replace the TimeFrameView | |
40 | * <p> | |
41 | * This view is composed of 2 canvas, one for the whole experiment and one for the selectionned window in the experiment. | |
42 | * It also contain a certain number of controls to print or change informations about the experiment. | |
43 | */ | |
7ef9ae3f | 44 | public class HistogramView extends TmfView implements ControlListener { |
544fe9b7 WB |
45 | |
46 | // *** TODO *** | |
47 | // Here is what's left to do in this view | |
48 | // | |
7c1540ab | 49 | // 1- Make sure all control are thread safe (bug 309348) |
544fe9b7 WB |
50 | // Right now, all the basic controls (i.e. Text and Label) are sensible to "Thread Access Exception" if |
51 | // updated from different threads; we need to carefully decide when/where to redraw them. | |
52 | // This is a real problem since there is a lot of thread going on in this view. | |
53 | // All basic control should be subclassed to offer "Asynchronous" functions. | |
544fe9b7 | 54 | |
62d1696a | 55 | public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.histogram"; |
b59134e1 | 56 | |
7c1540ab WB |
57 | // "Minimum" screen width size. On smaller screen, we will apply several space saving technique |
58 | private static final int SCREEN_SMALL_IF_SMALLER_THAN = 1600; | |
59 | ||
544fe9b7 | 60 | // Size of the "fulll trace" canvas |
833a21aa WB |
61 | private static final int FULL_TRACE_CANVAS_HEIGHT = 25; |
62 | private static final int FULL_TRACE_BAR_WIDTH = 1; | |
7ef9ae3f | 63 | private static final double FULL_TRACE_DIFFERENCE_TO_AVERAGE = 1.5; |
833a21aa | 64 | |
544fe9b7 WB |
65 | // Size of the "Selected Window" canvas |
66 | private static final int SELECTED_WINDOW_CANVAS_WIDTH = 300; | |
7ef9ae3f | 67 | private static final int SMALL_SELECTED_WINDOW_CANVAS_WIDTH = 200; |
544fe9b7 | 68 | private static final int SELECTED_WINDOW_CANVAS_HEIGHT = 60; |
833a21aa WB |
69 | private static final int SELECTED_WINDOW_BAR_WIDTH = 1; |
70 | private static final double SELECTED_WINDOW_DIFFERENCE_TO_AVERAGE = 10.0; | |
71 | ||
72 | // For the two "events" label (Max and min number of events in the selection), we force a width | |
73 | // This will prevent the control from moving horizontally if the number of events in the selection varies | |
3fda53ab | 74 | private static final int NB_EVENTS_FIXED_WIDTH = 50; |
833a21aa WB |
75 | |
76 | ||
77 | // The "small font" height used to display time will be "default font" minus this constant | |
78 | private static final int SMALL_FONT_MODIFIER = 2; | |
7c1540ab | 79 | private static final int VERY_SMALL_FONT_MODIFIER = 4; |
ecfd1d41 WB |
80 | |
81 | // *** TODO *** | |
82 | // This need to be changed as soon the framework implement a "window" | |
6cf16d22 | 83 | private static long DEFAULT_WINDOW_SIZE = (1L * 1000000000); |
ecfd1d41 | 84 | |
544fe9b7 | 85 | // The last experiment received/used by the view |
ecfd1d41 | 86 | private TmfExperiment<LttngEvent> lastUsedExperiment = null; |
b59134e1 | 87 | |
7c1540ab WB |
88 | // Parent of the view |
89 | private Composite parent = null; | |
90 | ||
544fe9b7 | 91 | // Request and canvas for the "full trace" part |
b59134e1 | 92 | private HistogramRequest dataBackgroundFullRequest = null; |
544fe9b7 | 93 | private ParentHistogramCanvas fullExperimentCanvas = null; |
b59134e1 | 94 | |
544fe9b7 | 95 | // Request and canvas for the "selected window" |
ecfd1d41 | 96 | private HistogramRequest selectedWindowRequest = null; |
378e7718 | 97 | private ChildrenHistogramCanvas selectedWindowCanvas = null; |
b59134e1 | 98 | |
544fe9b7 WB |
99 | // Content of the timeTextGroup |
100 | // Since the user can modify them with erroneous value, | |
101 | // we will keep track of the value internally | |
102 | private Long selectedWindowTime = 0L; | |
103 | private Long selectedWindowTimerange = 0L; | |
104 | private Long currentEventTime = 0L; | |
7c1540ab | 105 | |
544fe9b7 WB |
106 | // *** All the UI control below |
107 | // | |
108 | // NOTE : All textboxes will be READ_ONLY. | |
109 | // So the user will be able to select/copy the value in them but not to change it | |
833a21aa WB |
110 | private Text txtExperimentStartTime = null; |
111 | private Text txtExperimentStopTime = null; | |
112 | ||
113 | private Text txtWindowStartTime = null; | |
114 | private Text txtWindowStopTime = null; | |
7c1540ab WB |
115 | private Text txtWindowMaxNbEvents = null; |
116 | private Text txtWindowMinNbEvents = null; | |
833a21aa WB |
117 | |
118 | private static final String WINDOW_TIMERANGE_LABEL_TEXT = "Window Timerange "; | |
544fe9b7 WB |
119 | private static final String WINDOW_CURRENT_TIME_LABEL_TEXT = "Cursor Centered on "; |
120 | private static final String EVENT_CURRENT_TIME_LABEL_TEXT = "Current Event Time "; | |
088c1d4e WB |
121 | private TimeTextGroup ntgTimeRangeWindow = null; |
122 | private TimeTextGroup ntgCurrentWindowTime = null; | |
123 | private TimeTextGroup ntgCurrentEventTime = null; | |
124 | ||
544fe9b7 WB |
125 | /** |
126 | * Default contructor of the view | |
127 | */ | |
6e512b93 | 128 | public HistogramView() { |
b59134e1 | 129 | super(ID); |
6e512b93 | 130 | } |
b59134e1 | 131 | |
544fe9b7 WB |
132 | /** |
133 | * Create the UI controls of this view | |
134 | * | |
135 | * @param parent The composite parent of this view | |
136 | */ | |
6e512b93 | 137 | @Override |
7c1540ab WB |
138 | public void createPartControl(Composite newParent) { |
139 | // Save the parent | |
140 | parent = newParent; | |
b59134e1 | 141 | |
833a21aa | 142 | // Default font |
6cf16d22 | 143 | Font font = parent.getFont(); |
833a21aa | 144 | FontData tmpFontData = font.getFontData()[0]; |
833a21aa WB |
145 | |
146 | ||
7c1540ab WB |
147 | Font smallFont = null; |
148 | int nbEventWidth = -1; | |
7ef9ae3f | 149 | int selectedCanvasWidth = -1; |
7c1540ab WB |
150 | boolean doesTimeTextGroupNeedAdjustment = false; |
151 | ||
152 | // Calculate if we need "small screen" fixes | |
153 | if ( parent.getDisplay().getBounds().width < SCREEN_SMALL_IF_SMALLER_THAN ) { | |
154 | // A lot smaller font for timstampe | |
155 | smallFont = new Font(font.getDevice(), tmpFontData.getName(), tmpFontData.getHeight() - VERY_SMALL_FONT_MODIFIER, tmpFontData.getStyle()); | |
156 | ||
7ef9ae3f WB |
157 | // Smaller selection window canvas |
158 | selectedCanvasWidth = SMALL_SELECTED_WINDOW_CANVAS_WIDTH; | |
7c1540ab WB |
159 | // Smaller event number text field |
160 | nbEventWidth = NB_EVENTS_FIXED_WIDTH/2; | |
161 | ||
162 | // Tell the text group to ajust | |
163 | doesTimeTextGroupNeedAdjustment = true; | |
7c1540ab WB |
164 | } |
165 | else { | |
166 | // Slightly smaller font for timestamp | |
167 | smallFont = new Font(font.getDevice(), tmpFontData.getName(), tmpFontData.getHeight() - SMALL_FONT_MODIFIER, tmpFontData.getStyle()); | |
168 | // Usual size for selected window and event number text field | |
169 | nbEventWidth = NB_EVENTS_FIXED_WIDTH; | |
170 | selectedCanvasWidth = SELECTED_WINDOW_CANVAS_WIDTH; | |
171 | // No ajustement needed by the text group | |
172 | doesTimeTextGroupNeedAdjustment = false; | |
173 | } | |
174 | ||
833a21aa WB |
175 | // Layout for the whole view, other elements will be in a child composite of this one |
176 | // Contains : | |
177 | // Composite layoutSelectionWindow | |
178 | // Composite layoutTimesSpinner | |
179 | // Composite layoutExperimentHistogram | |
180 | Composite layoutFullView = new Composite(parent, SWT.NONE); | |
181 | GridLayout gridFullView = new GridLayout(); | |
182 | gridFullView.numColumns = 2; | |
544fe9b7 WB |
183 | gridFullView.horizontalSpacing = 0; |
184 | gridFullView.verticalSpacing = 0; | |
833a21aa WB |
185 | gridFullView.marginHeight = 0; |
186 | gridFullView.marginWidth = 0; | |
187 | layoutFullView.setLayout(gridFullView); | |
833a21aa WB |
188 | |
189 | ||
190 | // Layout that contain the SelectionWindow | |
191 | // Contains : | |
192 | // Label lblWindowStartTime | |
193 | // Label lblWindowStopTime | |
194 | // Label lblWindowMaxNbEvents | |
195 | // Label lblWindowMinNbEvents | |
196 | // ChildrenHistogramCanvas selectedWindowCanvas | |
197 | Composite layoutSelectionWindow = new Composite(layoutFullView, SWT.NONE); | |
198 | GridLayout gridSelectionWindow = new GridLayout(); | |
199 | gridSelectionWindow.numColumns = 3; | |
200 | gridSelectionWindow.marginHeight = 0; | |
201 | gridSelectionWindow.marginWidth = 0; | |
544fe9b7 WB |
202 | gridSelectionWindow.horizontalSpacing = 0; |
203 | gridSelectionWindow.verticalSpacing = 0; | |
833a21aa WB |
204 | layoutSelectionWindow.setLayout(gridSelectionWindow); |
205 | GridData gridDataSelectionWindow = new GridData(SWT.FILL, SWT.TOP, false, false, 1, 1); | |
206 | layoutSelectionWindow.setLayoutData(gridDataSelectionWindow); | |
207 | ||
208 | ||
209 | // Layout that contain the time spinner | |
210 | // Contains : | |
211 | // NanosecTextGroup spTimeRangeWindow | |
212 | // NanosecTextGroup spCurrentWindowTime | |
213 | // NanosecTextGroup spCurrentEventTime | |
214 | Composite layoutTimesSpinner = new Composite(layoutFullView, SWT.NONE); | |
215 | GridLayout gridTimesSpinner = new GridLayout(); | |
544fe9b7 | 216 | gridTimesSpinner.numColumns = 3; |
833a21aa WB |
217 | gridTimesSpinner.marginHeight = 0; |
218 | gridTimesSpinner.marginWidth = 0; | |
544fe9b7 WB |
219 | gridTimesSpinner.horizontalSpacing = 0; |
220 | gridTimesSpinner.verticalSpacing = 0; | |
833a21aa WB |
221 | layoutTimesSpinner.setLayout(gridTimesSpinner); |
222 | GridData gridDataTimesSpinner = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1); | |
223 | layoutTimesSpinner.setLayoutData(gridDataTimesSpinner); | |
224 | ||
225 | ||
226 | // Layout that contain the complete experiment histogram and related controls. | |
227 | // Contains : | |
228 | // Label lblExperimentStartTime | |
229 | // Label lblExperimentStopTime | |
230 | // ParentHistogramCanvas fullTraceCanvas | |
231 | Composite layoutExperimentHistogram = new Composite(layoutFullView, SWT.NONE); | |
232 | GridLayout gridExperimentHistogram = new GridLayout(); | |
233 | gridExperimentHistogram.numColumns = 2; | |
234 | gridExperimentHistogram.marginHeight = 0; | |
235 | gridExperimentHistogram.marginWidth = 0; | |
544fe9b7 WB |
236 | gridExperimentHistogram.horizontalSpacing = 0; |
237 | gridExperimentHistogram.verticalSpacing = 0; | |
833a21aa WB |
238 | layoutExperimentHistogram.setLayout(gridExperimentHistogram); |
239 | GridData gridDataExperimentHistogram = new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1); | |
240 | layoutExperimentHistogram.setLayoutData(gridDataExperimentHistogram); | |
241 | ||
242 | ||
243 | ||
244 | // *** Everything related to the selection window is below | |
7c1540ab | 245 | GridData gridDataSelectionWindowCanvas = new GridData(SWT.LEFT, SWT.TOP, true, false, 2, 2); |
833a21aa WB |
246 | gridDataSelectionWindowCanvas.heightHint = SELECTED_WINDOW_CANVAS_HEIGHT; |
247 | gridDataSelectionWindowCanvas.minimumHeight = SELECTED_WINDOW_CANVAS_HEIGHT; | |
7c1540ab WB |
248 | gridDataSelectionWindowCanvas.widthHint = selectedCanvasWidth; |
249 | gridDataSelectionWindowCanvas.minimumWidth = selectedCanvasWidth; | |
833a21aa WB |
250 | selectedWindowCanvas = new ChildrenHistogramCanvas(this, layoutSelectionWindow, SWT.BORDER); |
251 | selectedWindowCanvas.setLayoutData(gridDataSelectionWindowCanvas); | |
252 | ||
7c1540ab | 253 | GridData gridDataWindowMaxEvents = new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1); |
833a21aa | 254 | // Force a width, to avoid the control to enlarge if the number of events change |
7c1540ab WB |
255 | gridDataWindowMaxEvents.minimumWidth = nbEventWidth; |
256 | txtWindowMaxNbEvents = new Text(layoutSelectionWindow, SWT.READ_ONLY); | |
257 | txtWindowMaxNbEvents.setFont(smallFont); | |
258 | txtWindowMaxNbEvents.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND)); | |
259 | txtWindowMaxNbEvents.setEditable(false); | |
260 | txtWindowMaxNbEvents.setText(""); | |
261 | txtWindowMaxNbEvents.setLayoutData(gridDataWindowMaxEvents); | |
833a21aa WB |
262 | |
263 | GridData gridDataWindowMinEvents = new GridData(SWT.LEFT, SWT.BOTTOM, true, false, 1, 1); | |
264 | // Force a width, to avoid the control to enlarge if the number of events change | |
7c1540ab WB |
265 | gridDataWindowMinEvents.minimumWidth = nbEventWidth; |
266 | txtWindowMinNbEvents = new Text(layoutSelectionWindow, SWT.READ_ONLY); | |
267 | txtWindowMinNbEvents.setFont(smallFont); | |
268 | txtWindowMinNbEvents.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND)); | |
269 | txtWindowMinNbEvents.setEditable(false); | |
270 | txtWindowMinNbEvents.setText(""); | |
271 | txtWindowMinNbEvents.setLayoutData(gridDataWindowMinEvents); | |
833a21aa WB |
272 | |
273 | GridData gridDataWindowStart = new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1); | |
274 | txtWindowStartTime = new Text(layoutSelectionWindow, SWT.READ_ONLY); | |
275 | txtWindowStartTime.setFont(smallFont); | |
276 | txtWindowStartTime.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND)); | |
277 | txtWindowStartTime.setEditable(false); | |
278 | txtWindowStartTime.setText(""); | |
279 | txtWindowStartTime.setLayoutData(gridDataWindowStart); | |
280 | ||
281 | GridData gridDataWindowStop = new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1); | |
282 | txtWindowStopTime = new Text(layoutSelectionWindow, SWT.READ_ONLY); | |
283 | txtWindowStopTime.setFont(smallFont); | |
284 | txtWindowStopTime.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND)); | |
285 | txtWindowStopTime.setEditable(false); | |
286 | txtWindowStopTime.setText(""); | |
287 | txtWindowStopTime.setLayoutData(gridDataWindowStop); | |
288 | ||
7ef9ae3f WB |
289 | GridData gridDataSpacer = new GridData(SWT.FILL, SWT.TOP, true, true, 1, 1); |
290 | gridDataSpacer.minimumWidth = nbEventWidth; | |
291 | // *** HACK *** | |
292 | // To align properly AND to make sure the canvas size is fixed, we NEED to make sure all "section" of the | |
293 | // gridlayout are taken (and if possible of a fixed size). | |
294 | // However, SWT is VERY VERY DUMB and won't consider griddata that contain no control. | |
295 | // Since there will be missing a section, the SelectedWindowCanvas + NbEventsText will take 3 spaces, but | |
296 | // startTimeText + stopTimeText will take only 2 (as if empty the other griddata of 1 will get ignored). | |
297 | // StopTime will then take over the missing space; I want to align "stopTime" right on the end of canvas, so | |
298 | // the added space to stop time would make it being aligned improperly | |
299 | // So I NEED the empty griddata to be considered! | |
300 | // Visually : | |
301 | // |---------------|---------------|-----------| | |
302 | // |SelectionCanvas SelectionCanvas|NbEventText| | |
303 | // |SelectionCanvas SelectionCanvas|NbEventText| | |
304 | // |---------------|---------------|-----------| | |
305 | // |StartTime | StopTime| ??? | | |
306 | // |---------------|---------------|-----------| | |
307 | // | |
308 | // So since SWT will only consider griddata with control, | |
309 | // I need to create a totally useless control in the ??? section. | |
310 | // That's ugly, useless and it generally a bad practice. | |
311 | // | |
312 | // *** SUB-HACK *** | |
313 | // Other interesting fact about SWT : the way it draws (Fill/Expand control in grid) will change if | |
314 | // the control is a Text of a Label. | |
315 | // A Label here will be "pushed" by startTime/stopTime Text and won't fill the full space as NbEventText. | |
316 | // A Text here will NOT be "pushed" and would give a nice visual output. | |
317 | // (NB : No, I am NOT kidding, try it for yourself!) | |
318 | // | |
319 | // Soooooo I guess I will use a Text here. Way to go SWT! | |
320 | // Downside is that disabled textbox has a slightly different color (even if you change it) so if I want | |
321 | // to make the text "invisible", I have to keep it editable, so it can be selected. | |
322 | // | |
323 | // Label uselessControlToByPassSWTStupidBug = new Label(layoutSelectionWindow, SWT.BORDER); // WON'T align correctly!!! | |
324 | Text uselessControlToByPassSWTStupidBug = new Text(layoutSelectionWindow, SWT.READ_ONLY); // WILL align correctly!!! | |
325 | uselessControlToByPassSWTStupidBug.setEditable(false); | |
326 | uselessControlToByPassSWTStupidBug.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND)); | |
327 | uselessControlToByPassSWTStupidBug.setLayoutData(gridDataSpacer); | |
328 | ||
329 | ||
330 | ||
331 | // *** Everything related to the time text group is below | |
3fda53ab | 332 | GridData gridDataCurrentEvent = new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 2); |
7c1540ab | 333 | ntgCurrentEventTime = new TimeTextGroup(this, layoutTimesSpinner, SWT.BORDER, SWT.BORDER, EVENT_CURRENT_TIME_LABEL_TEXT, HistogramConstant.formatNanoSecondsTime( 0L ), doesTimeTextGroupNeedAdjustment); |
3fda53ab | 334 | ntgCurrentEventTime.setLayoutData(gridDataCurrentEvent); |
544fe9b7 WB |
335 | |
336 | GridData gridDataTimeRange = new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 2); | |
7c1540ab | 337 | ntgTimeRangeWindow = new TimeTextGroup(this, layoutTimesSpinner, SWT.BORDER, SWT.BORDER, WINDOW_TIMERANGE_LABEL_TEXT, HistogramConstant.formatNanoSecondsTime( 0L ), doesTimeTextGroupNeedAdjustment); |
544fe9b7 WB |
338 | ntgTimeRangeWindow.setLayoutData(gridDataTimeRange); |
339 | ||
3fda53ab | 340 | GridData gridDataCurrentWindow = new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 2); |
7c1540ab | 341 | ntgCurrentWindowTime = new TimeTextGroup(this, layoutTimesSpinner, SWT.BORDER, SWT.BORDER, WINDOW_CURRENT_TIME_LABEL_TEXT, HistogramConstant.formatNanoSecondsTime( 0L ), doesTimeTextGroupNeedAdjustment); |
3fda53ab | 342 | ntgCurrentWindowTime.setLayoutData(gridDataCurrentWindow); |
544fe9b7 | 343 | |
833a21aa WB |
344 | |
345 | ||
544fe9b7 | 346 | // *** Everything related to the experiment canvas is below |
833a21aa WB |
347 | GridData gridDataExperimentCanvas = new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1); |
348 | gridDataExperimentCanvas.heightHint = FULL_TRACE_CANVAS_HEIGHT; | |
349 | gridDataExperimentCanvas.minimumHeight = FULL_TRACE_CANVAS_HEIGHT; | |
544fe9b7 WB |
350 | fullExperimentCanvas = new ParentHistogramCanvas(this, layoutExperimentHistogram, SWT.BORDER); |
351 | fullExperimentCanvas.setLayoutData(gridDataExperimentCanvas); | |
833a21aa WB |
352 | |
353 | GridData gridDataExperimentStart = new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1); | |
354 | txtExperimentStartTime = new Text(layoutExperimentHistogram, SWT.READ_ONLY); | |
355 | txtExperimentStartTime.setFont(smallFont); | |
356 | txtExperimentStartTime.setText(""); | |
357 | txtExperimentStartTime.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND)); | |
358 | txtExperimentStartTime.setEditable(false); | |
359 | txtExperimentStartTime.setLayoutData(gridDataExperimentStart); | |
360 | ||
361 | GridData gridDataExperimentStop = new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1); | |
362 | txtExperimentStopTime = new Text(layoutExperimentHistogram, SWT.READ_ONLY); | |
363 | txtExperimentStopTime.setFont(smallFont); | |
364 | txtExperimentStopTime.setText(""); | |
365 | txtExperimentStopTime.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND)); | |
366 | txtExperimentStopTime.setEditable(false); | |
367 | txtExperimentStopTime.setLayoutData(gridDataExperimentStop); | |
6e512b93 | 368 | } |
b59134e1 | 369 | |
544fe9b7 WB |
370 | // *** FIXME *** |
371 | // This is mainly used because of a because in the "experimentSelected()" notification, we shouldn't need this | |
372 | /** | |
373 | * Method called when the view receive the focus.<p> | |
374 | * If ExperimentSelected didn't send us a request yet, get the current Experiment and fire requests | |
375 | */ | |
b59134e1 | 376 | @SuppressWarnings("unchecked") |
6e512b93 ASL |
377 | @Override |
378 | public void setFocus() { | |
544fe9b7 | 379 | // WARNING : This does not seem to be thread safe |
b59134e1 WB |
380 | TmfExperiment<LttngEvent> tmpExperiment = (TmfExperiment<LttngEvent>)TmfExperiment.getCurrentExperiment(); |
381 | ||
382 | if ( (dataBackgroundFullRequest == null) && (tmpExperiment != null) ) { | |
ecfd1d41 | 383 | createCanvasAndRequests(tmpExperiment); |
b59134e1 | 384 | } |
7ef9ae3f WB |
385 | |
386 | // Call a redraw for everything | |
387 | parent.redraw(); | |
6e512b93 | 388 | } |
b59134e1 | 389 | |
544fe9b7 WB |
390 | /** |
391 | * Method called when the user select (double-click on) an experiment.<p> | |
392 | * We will create the needed canvas and fire the requests. | |
393 | * | |
394 | * @param signal Signal received from the framework. Contain the experiment. | |
395 | */ | |
b59134e1 WB |
396 | @SuppressWarnings("unchecked") |
397 | @TmfSignalHandler | |
398 | public void experimentSelected(TmfExperimentSelectedSignal<LttngEvent> signal) { | |
ecfd1d41 WB |
399 | TmfExperiment<LttngEvent> tmpExperiment = (TmfExperiment<LttngEvent>)signal.getExperiment(); |
400 | createCanvasAndRequests(tmpExperiment); | |
401 | } | |
402 | ||
088c1d4e WB |
403 | // *** VERIFY *** |
404 | // Not sure what this should do since I don't know when it will be called | |
405 | // Let's do the same thing as experimentSelected for now | |
406 | // | |
544fe9b7 WB |
407 | /** |
408 | * Method called when an experiment is updated (??).<p> | |
7c1540ab | 409 | * ...for now, do nothing, as udating an experiment running in the background might cause crash |
544fe9b7 WB |
410 | * |
411 | * @param signal Signal received from the framework. Contain the experiment. | |
412 | */ | |
c1877796 | 413 | // @SuppressWarnings("unchecked") |
088c1d4e | 414 | @TmfSignalHandler |
833a21aa | 415 | public void experimentUpdated(TmfExperimentUpdatedSignal signal) { |
c1877796 WB |
416 | // |
417 | // TmfExperiment<LttngEvent> tmpExperiment = (TmfExperiment<LttngEvent>)signal.getExperiment(); | |
418 | // | |
419 | // // Make sure the UI object are sane | |
420 | // resetControlsContent(); | |
421 | // | |
422 | // // Redraw the canvas right away to have something "clean" as soon as we can | |
423 | // fullExperimentCanvas.redraw(); | |
424 | // selectedWindowCanvas.redraw(); | |
425 | // | |
426 | // // Recreate the request | |
427 | // createCanvasAndRequests(tmpExperiment); | |
833a21aa WB |
428 | } |
429 | ||
544fe9b7 WB |
430 | /** |
431 | * Method called when synchonization is active and that the user select an event.<p> | |
432 | * We update the current event timeTextGroup and move the selected window if needed. | |
433 | * | |
434 | * @param signal Signal received from the framework. Contain the event. | |
435 | */ | |
833a21aa WB |
436 | @TmfSignalHandler |
437 | public void currentTimeUpdated(TmfTimeSynchSignal signal) { | |
544fe9b7 | 438 | // In case we received our own signal |
833a21aa WB |
439 | if (signal.getSource() != this) { |
440 | TmfTimestamp currentTime = signal.getCurrentTime(); | |
833a21aa | 441 | |
544fe9b7 | 442 | // Update the current event controls |
088c1d4e WB |
443 | currentEventTime = currentTime.getValue(); |
444 | updateSelectedEventTime(); | |
445 | ||
544fe9b7 WB |
446 | // If the given event is outside the selection window, recenter the window |
447 | if ( isGivenTimestampInSelectedWindow( currentEventTime ) == false) { | |
448 | fullExperimentCanvas.centerWindow( fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(currentEventTime) ); | |
449 | // Notify control that the window changed | |
833a21aa WB |
450 | windowChangedNotification(); |
451 | } | |
833a21aa WB |
452 | } |
453 | } | |
454 | ||
544fe9b7 WB |
455 | /* |
456 | * Create the canvas needed and issue the requests | |
457 | * | |
458 | * @param newExperiment Experiment we will use for the request | |
459 | */ | |
460 | private void createCanvasAndRequests(TmfExperiment<LttngEvent> newExperiment) { | |
ecfd1d41 | 461 | lastUsedExperiment = newExperiment; |
6cf16d22 | 462 | |
c1877796 WB |
463 | TmfExperiment<LttngEvent> experimentCopy = newExperiment.createTraceCopy(); |
464 | ||
3fda53ab WB |
465 | // Create the content for the full experiment. |
466 | // This NEED to be created first, as we use it in the selectedWindowCanvas | |
7c1540ab WB |
467 | fullExperimentCanvas.createNewHistogramContent(fullExperimentCanvas.getSize().x, FULL_TRACE_BAR_WIDTH, FULL_TRACE_CANVAS_HEIGHT, FULL_TRACE_DIFFERENCE_TO_AVERAGE); |
468 | fullExperimentCanvas.createNewSelectedWindow(DEFAULT_WINDOW_SIZE); | |
469 | // Set the window of the fullTrace canvas visible. | |
470 | fullExperimentCanvas.getCurrentWindow().setSelectedWindowVisible(true); | |
3fda53ab WB |
471 | fullExperimentCanvas.getHistogramContent().resetTable(newExperiment.getStartTime().getValue(), newExperiment.getEndTime().getValue()); |
472 | ||
7c1540ab | 473 | // Create the content for the selected window. |
7ef9ae3f | 474 | selectedWindowCanvas.createNewHistogramContent(selectedWindowCanvas.getSize().x ,SELECTED_WINDOW_BAR_WIDTH, SELECTED_WINDOW_CANVAS_HEIGHT, SELECTED_WINDOW_DIFFERENCE_TO_AVERAGE); |
3fda53ab | 475 | selectedWindowCanvas.getHistogramContent().resetTable(fullExperimentCanvas.getCurrentWindow().getTimestampLeft(), fullExperimentCanvas.getCurrentWindow().getTimestampRight()); |
6cf16d22 | 476 | |
833a21aa | 477 | // Make sure the UI object are sane |
544fe9b7 | 478 | resetControlsContent(); |
833a21aa | 479 | |
6cf16d22 WB |
480 | // Redraw the canvas right away to have something "clean" as soon as we can |
481 | if ( dataBackgroundFullRequest != null ) { | |
544fe9b7 | 482 | fullExperimentCanvas.redraw(); |
6cf16d22 WB |
483 | selectedWindowCanvas.redraw(); |
484 | } | |
544fe9b7 WB |
485 | // Nullify the (possible) old request to be sure we start we something clean |
486 | // Note : this is very important for the order of the request below, | |
487 | // see "TODO" in performSelectedWindowEventsRequest | |
488 | dataBackgroundFullRequest = null; | |
489 | selectedWindowRequest = null; | |
ecfd1d41 | 490 | |
544fe9b7 WB |
491 | // Perform both request. |
492 | // Order is important here, the small/synchronous request for the selection window should go first | |
ecfd1d41 | 493 | performSelectedWindowEventsRequest(newExperiment); |
c1877796 | 494 | performAllTraceEventsRequest(experimentCopy); |
ecfd1d41 WB |
495 | } |
496 | ||
544fe9b7 WB |
497 | /** |
498 | * Perform a new request for the Selection window.<p> | |
499 | * This assume the full experiment canvas has correct information about the selected window; | |
500 | * we need the fullExperimentCanvas' HistogramContent to be created and a selection window to be set. | |
501 | * | |
502 | * @param experiment The experiment we will select from | |
503 | */ | |
ecfd1d41 | 504 | public void performSelectedWindowEventsRequest(TmfExperiment<LttngEvent> experiment) { |
252ae4bd | 505 | |
544fe9b7 | 506 | HistogramSelectedWindow curSelectedWindow = fullExperimentCanvas.getCurrentWindow(); |
b59134e1 | 507 | |
544fe9b7 WB |
508 | // If no selection window exists, we will try to cerate one; |
509 | // however this will most likely fail as the content is probably not created either | |
ecfd1d41 | 510 | if ( curSelectedWindow == null ) { |
544fe9b7 WB |
511 | fullExperimentCanvas.createNewSelectedWindow( DEFAULT_WINDOW_SIZE ); |
512 | curSelectedWindow = fullExperimentCanvas.getCurrentWindow(); | |
ecfd1d41 WB |
513 | } |
514 | ||
544fe9b7 WB |
515 | // The request will go from the Left timestamp of the window to the Right timestamp |
516 | // This assume that out-of-bound value are handled by the SelectionWindow itself | |
ecfd1d41 WB |
517 | LttngTimestamp ts1 = new LttngTimestamp( curSelectedWindow.getTimestampLeft() ); |
518 | LttngTimestamp ts2 = new LttngTimestamp( curSelectedWindow.getTimestampRight() ); | |
ecfd1d41 WB |
519 | TmfTimeRange tmpRange = new TmfTimeRange(ts1, ts2); |
520 | ||
521 | // Set a (dynamic) time interval | |
522 | long intervalTime = ( (ts2.getValue() - ts1.getValue()) / selectedWindowCanvas.getHistogramContent().getNbElement() ); | |
523 | ||
ecfd1d41 | 524 | selectedWindowRequest = performRequest(experiment, selectedWindowCanvas, tmpRange, intervalTime); |
6cf16d22 | 525 | selectedWindowCanvas.redrawAsynchronously(); |
ecfd1d41 WB |
526 | } |
527 | ||
544fe9b7 WB |
528 | /** |
529 | * Perform a new request for the full experiment.<p> | |
530 | * NOTE : this is very long, we need to implement a way to run this in parallel (see TODO) | |
531 | * | |
532 | * @param experiment The experiment we will select from | |
533 | */ | |
ecfd1d41 | 534 | public void performAllTraceEventsRequest(TmfExperiment<LttngEvent> experiment) { |
b59134e1 WB |
535 | // Create a new time range from "start" to "end" |
536 | // That way, we will get "everything" in the trace | |
ecfd1d41 WB |
537 | LttngTimestamp ts1 = new LttngTimestamp( experiment.getStartTime() ); |
538 | LttngTimestamp ts2 = new LttngTimestamp( experiment.getEndTime() ); | |
b59134e1 WB |
539 | TmfTimeRange tmpRange = new TmfTimeRange(ts1, ts2); |
540 | ||
ecfd1d41 | 541 | // Set a (dynamic) time interval |
544fe9b7 | 542 | long intervalTime = ( (ts2.getValue() - ts1.getValue()) / fullExperimentCanvas.getHistogramContent().getNbElement() ); |
b59134e1 | 543 | |
544fe9b7 WB |
544 | // *** VERIFY *** |
545 | // This would enable "fixed interval" instead of dynamic one. | |
546 | // ... we don't need it, do we? | |
547 | // | |
548 | // long intervalTime = ((long)(0.001 * (double)1000000000)); | |
549 | ||
550 | // *** TODO *** | |
551 | // It would be interesting if there was a way to tell the framework to run the request "in parallel" here. | |
552 | // Mean a completetly independant copy of the Expereiment would be done and we would proceed on that. | |
553 | // | |
554 | dataBackgroundFullRequest = performRequest(experiment, fullExperimentCanvas, tmpRange, intervalTime); | |
555 | fullExperimentCanvas.redrawAsynchronously(); | |
b59134e1 WB |
556 | } |
557 | ||
558 | // *** VERIFY *** | |
544fe9b7 WB |
559 | // This function is synchronized, is it a good idea? |
560 | // Tis is done to make sure requests arrive somewhat in order, | |
561 | // this is especially important when request are issued from different thread. | |
562 | /** | |
563 | * Create a new request from the given data and send it to the framework.<p> | |
564 | * The request will be queued and processed later. | |
565 | * | |
566 | * @param experiment The experiment we will process the request on | |
567 | * @param targetCanvas The canvas that will received the result | |
568 | * @param newRange The range of the request | |
569 | * @param newInterval The interval of time we use to store the result into the HistogramContent | |
570 | */ | |
378e7718 | 571 | public synchronized HistogramRequest performRequest(TmfExperiment<LttngEvent> experiment, HistogramCanvas targetCanvas, TmfTimeRange newRange, long newInterval) { |
b59134e1 WB |
572 | HistogramRequest returnedRequest = null; |
573 | ||
ecfd1d41 WB |
574 | // *** FIXME *** |
575 | // EVIL BUG! | |
576 | // We use integer.MAX_VALUE because we want every events BUT we don't know the number inside the range. | |
577 | // HOWEVER, this would cause the request to run forever (or until it reach the end of trace). | |
578 | // Seeting an EndTime does not seems to stop the request | |
378e7718 | 579 | returnedRequest = new HistogramRequest(newRange, Integer.MAX_VALUE, targetCanvas, newInterval ); |
544fe9b7 WB |
580 | |
581 | // Send the request to the framework : it will be queued and processed later | |
b59134e1 WB |
582 | experiment.sendRequest(returnedRequest); |
583 | ||
584 | return returnedRequest; | |
585 | } | |
088c1d4e | 586 | |
544fe9b7 WB |
587 | /** |
588 | * Function used to warn that the selection window changed.<p> | |
589 | * This might be called because the window moved or because its size changed.<p> | |
590 | * | |
591 | * We will update the different control related to the selection window. | |
592 | */ | |
ecfd1d41 | 593 | public void windowChangedNotification() { |
833a21aa | 594 | |
ecfd1d41 | 595 | if ( lastUsedExperiment != null ) { |
544fe9b7 | 596 | // If a request is ongoing, try to stop it |
6cf16d22 WB |
597 | if ( selectedWindowRequest.isCompleted() == false ) { |
598 | selectedWindowRequest.cancel(); | |
599 | } | |
833a21aa | 600 | |
544fe9b7 WB |
601 | // Get the latest window information |
602 | selectedWindowTime = fullExperimentCanvas.getCurrentWindow().getTimestampCenter(); | |
603 | selectedWindowTimerange = fullExperimentCanvas.getCurrentWindow().getWindowTimeWidth(); | |
088c1d4e | 604 | |
544fe9b7 WB |
605 | // If the current event time is outside the new window, change the current event |
606 | // The new current event will be the one closest to the center of the new window | |
607 | if ( isGivenTimestampInSelectedWindow(currentEventTime) == false ) { | |
088c1d4e WB |
608 | currentEventChangeNotification( selectedWindowTime ); |
609 | } | |
610 | ||
ed4b3b9f WB |
611 | // Tell the framework that the timerange (time window) changed |
612 | currentTimerangeChangeNotification(); | |
613 | ||
544fe9b7 | 614 | // Perform a new request to read data about the new window |
ecfd1d41 WB |
615 | performSelectedWindowEventsRequest(lastUsedExperiment); |
616 | } | |
617 | } | |
618 | ||
544fe9b7 WB |
619 | /** |
620 | * Function used to tell that the current event changed.<p> | |
621 | * This might be called because the user changed the current event or | |
622 | * because the last current event is now outside the selection window.<p> | |
623 | * | |
624 | * We update the related control and send a signal to notify other views of the new current event. | |
625 | * | |
626 | * @param newCurrentEventTime | |
627 | */ | |
088c1d4e WB |
628 | public void currentEventChangeNotification(Long newCurrentEventTime) { |
629 | // Notify other views in the framework | |
630 | if (currentEventTime != newCurrentEventTime) { | |
631 | currentEventTime = newCurrentEventTime; | |
632 | ||
544fe9b7 | 633 | // Update the UI control |
088c1d4e WB |
634 | updateSelectedEventTime(); |
635 | ||
544fe9b7 | 636 | // Send a signal to the framework |
088c1d4e WB |
637 | LttngTimestamp tmpTimestamp = new LttngTimestamp(newCurrentEventTime); |
638 | broadcast(new TmfTimeSynchSignal(this, tmpTimestamp)); | |
639 | } | |
640 | } | |
641 | ||
ed4b3b9f WB |
642 | /** |
643 | * Function used to tell that the timerange (window) changed.<p> | |
644 | * This will most likely be called if the time window is resized. | |
645 | * | |
646 | * We send a signal to notify other views of the new timerange. | |
647 | */ | |
648 | public void currentTimerangeChangeNotification() { | |
649 | LttngTimestamp tmpStartTime = new LttngTimestamp(fullExperimentCanvas.getCurrentWindow().getTimestampLeft()); | |
650 | LttngTimestamp tmpEndTime = new LttngTimestamp(fullExperimentCanvas.getCurrentWindow().getTimestampRight()); | |
651 | TmfTimeRange tmpTimeRange = new TmfTimeRange(tmpStartTime, tmpEndTime); | |
652 | LttngTimestamp tmpEventTime = new LttngTimestamp(currentEventTime); | |
653 | // Send a signal to the framework | |
654 | broadcast(new TmfRangeSynchSignal(this, tmpTimeRange, tmpEventTime)); | |
655 | } | |
656 | ||
544fe9b7 WB |
657 | /** |
658 | * Function that will be called when one of the time text group value is changed.<p> | |
659 | * Since we don't (and can't unless we subclass them) know which one, we check them all. | |
660 | */ | |
088c1d4e WB |
661 | public void timeTextGroupChangeNotification() { |
662 | ||
544fe9b7 | 663 | // Get all the time text group value |
088c1d4e WB |
664 | Long newCurrentTime = ntgCurrentEventTime.getValue(); |
665 | Long newSelectedWindowTime = ntgCurrentWindowTime.getValue(); | |
666 | Long newSelectedWindowTimeRange = ntgTimeRangeWindow.getValue(); | |
667 | ||
544fe9b7 | 668 | // If the user changed the current event time, call the notification |
088c1d4e WB |
669 | if ( newCurrentTime != currentEventTime ) { |
670 | currentEventChangeNotification( newCurrentTime ); | |
671 | } | |
672 | ||
544fe9b7 | 673 | // If the user changed the selected window time, recenter the window and call the notification |
088c1d4e WB |
674 | if ( newSelectedWindowTime != selectedWindowTime ) { |
675 | selectedWindowTime = newSelectedWindowTime; | |
544fe9b7 WB |
676 | fullExperimentCanvas.centerWindow( fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(selectedWindowTime) ); |
677 | windowChangedNotification(); | |
088c1d4e WB |
678 | } |
679 | ||
544fe9b7 | 680 | // If the user changed the selected window size, resize the window and call the notification |
088c1d4e WB |
681 | if ( newSelectedWindowTimeRange != selectedWindowTimerange ) { |
682 | selectedWindowTimerange = newSelectedWindowTimeRange; | |
544fe9b7 WB |
683 | fullExperimentCanvas.resizeWindowByAbsoluteTime(selectedWindowTimerange); |
684 | windowChangedNotification(); | |
088c1d4e WB |
685 | } |
686 | ||
687 | } | |
688 | ||
544fe9b7 WB |
689 | /** |
690 | * Getter for the last used experiment.<p> | |
691 | * This might be different than the current experiment or even null. | |
692 | * | |
693 | * @return the last experiment we used in this view | |
694 | */ | |
ecfd1d41 WB |
695 | public TmfExperiment<LttngEvent> getLastUsedExperiment() { |
696 | return lastUsedExperiment; | |
697 | } | |
698 | ||
544fe9b7 WB |
699 | /** |
700 | * Check if a given timestamp is inside the selection window.<p> | |
701 | * This assume fullExperimentCanvas contain a valid HistogramContent | |
702 | * | |
703 | * @param timestamp the timestamp to check | |
704 | * | |
705 | * @return if the time is inside the selection window or not | |
706 | */ | |
088c1d4e WB |
707 | public boolean isGivenTimestampInSelectedWindow(Long timestamp) { |
708 | boolean returnedValue = true; | |
709 | ||
544fe9b7 WB |
710 | // If the content is not set correctly, this will return weird (or even null) result |
711 | if ( (timestamp < fullExperimentCanvas.getCurrentWindow().getTimestampLeft() ) || | |
712 | (timestamp > fullExperimentCanvas.getCurrentWindow().getTimestampRight() ) ) | |
088c1d4e WB |
713 | { |
714 | returnedValue = false; | |
715 | } | |
716 | ||
717 | return returnedValue; | |
718 | } | |
719 | ||
544fe9b7 WB |
720 | /** |
721 | * Reset the content of all Controls.<p> | |
722 | * WARNING : Calls in there are not thread safe and can't be called from different thread than "main" | |
723 | */ | |
724 | public void resetControlsContent() { | |
833a21aa WB |
725 | |
726 | TmfExperiment<LttngEvent> tmpExperiment = getLastUsedExperiment(); | |
727 | ||
544fe9b7 | 728 | // Use the previous Start and End time, or default if they are not available |
833a21aa WB |
729 | String startTime = null; |
730 | String stopTime = null; | |
731 | if ( tmpExperiment != null ) { | |
732 | startTime = HistogramConstant.formatNanoSecondsTime( tmpExperiment.getStartTime().getValue() ); | |
733 | stopTime = HistogramConstant.formatNanoSecondsTime( tmpExperiment.getEndTime().getValue() ); | |
6cf16d22 | 734 | } |
833a21aa WB |
735 | else { |
736 | startTime = HistogramConstant.formatNanoSecondsTime( 0L ); | |
737 | stopTime = HistogramConstant.formatNanoSecondsTime( 0L ); | |
738 | } | |
739 | ||
740 | txtExperimentStartTime.setText( startTime ); | |
741 | txtExperimentStopTime.setText( stopTime ); | |
742 | txtExperimentStartTime.getParent().layout(); | |
743 | ||
7c1540ab WB |
744 | txtWindowMaxNbEvents.setText("" + 0); |
745 | txtWindowMinNbEvents.setText("" + 0); | |
833a21aa WB |
746 | txtWindowStartTime.setText( HistogramConstant.formatNanoSecondsTime( 0L ) ); |
747 | txtWindowStopTime.setText( HistogramConstant.formatNanoSecondsTime( 0L ) ); | |
748 | txtWindowStartTime.getParent().layout(); | |
378e7718 | 749 | |
833a21aa WB |
750 | ntgCurrentWindowTime.setValue( HistogramConstant.formatNanoSecondsTime( 0L ) ); |
751 | ntgTimeRangeWindow.setValue( HistogramConstant.formatNanoSecondsTime( 0L ) ); | |
752 | ntgCurrentEventTime.setValue( HistogramConstant.formatNanoSecondsTime( 0L ) ); | |
378e7718 WB |
753 | } |
754 | ||
544fe9b7 WB |
755 | /** |
756 | * Update the content of the controls related to the full experiment canvas<p> | |
757 | * WARNING : Calls in there are not thread safe and can't be called from different thread than "main" | |
758 | */ | |
759 | public void updateFullExperimentInformation() { | |
378e7718 | 760 | |
544fe9b7 WB |
761 | String startTime = HistogramConstant.formatNanoSecondsTime( fullExperimentCanvas.getHistogramContent().getStartTime() ); |
762 | String stopTime = HistogramConstant.formatNanoSecondsTime( fullExperimentCanvas.getHistogramContent().getEndTime() ); | |
378e7718 | 763 | |
833a21aa WB |
764 | txtExperimentStartTime.setText( startTime ); |
765 | txtExperimentStopTime.setText( stopTime ); | |
766 | ||
767 | // Take one of the parent and call its layout to update control size | |
768 | // Since both control have the same parent, only one call is needed | |
769 | txtExperimentStartTime.getParent().layout(); | |
770 | ||
771 | // Update the selected window, just in case | |
772 | // This should give a better user experience and it is low cost | |
773 | updateSelectedWindowInformation(); | |
378e7718 WB |
774 | } |
775 | ||
544fe9b7 WB |
776 | /** |
777 | * Update the content of the controls related to the selection window canvas<p> | |
778 | * WARNING : Calls in there are not thread safe and can't be called from different thread than "main" | |
779 | */ | |
378e7718 | 780 | public void updateSelectedWindowInformation() { |
833a21aa WB |
781 | // Update the timestamp as well |
782 | updateSelectedWindowTimestamp(); | |
783 | ||
7c1540ab WB |
784 | txtWindowMaxNbEvents.setText( selectedWindowCanvas.getHistogramContent().getHeighestEventCount().toString() ); |
785 | txtWindowMinNbEvents.setText("0"); | |
833a21aa WB |
786 | |
787 | // Refresh the layout | |
7c1540ab | 788 | txtWindowMaxNbEvents.getParent().layout(); |
ecfd1d41 | 789 | } |
6cf16d22 | 790 | |
544fe9b7 WB |
791 | /** |
792 | * Update the content of the controls related to the timestamp of the selection window<p> | |
793 | * WARNING : Calls in there are not thread safe and can't be called from different thread than "main" | |
794 | */ | |
833a21aa WB |
795 | public void updateSelectedWindowTimestamp() { |
796 | String startTime = HistogramConstant.formatNanoSecondsTime( selectedWindowCanvas.getHistogramContent().getStartTime() ); | |
797 | String stopTime = HistogramConstant.formatNanoSecondsTime( selectedWindowCanvas.getHistogramContent().getEndTime() ); | |
798 | txtWindowStartTime.setText( startTime ); | |
799 | txtWindowStopTime.setText( stopTime ); | |
800 | ||
544fe9b7 WB |
801 | ntgCurrentWindowTime.setValue( fullExperimentCanvas.getCurrentWindow().getTimestampCenter() ); |
802 | ntgTimeRangeWindow.setValue( fullExperimentCanvas.getCurrentWindow().getWindowTimeWidth() ); | |
833a21aa | 803 | |
544fe9b7 | 804 | // If the current event time is outside the selection window, recenter our window |
088c1d4e | 805 | if ( isGivenTimestampInSelectedWindow(ntgCurrentEventTime.getValue()) == false ) { |
544fe9b7 | 806 | currentEventChangeNotification( fullExperimentCanvas.getCurrentWindow().getTimestampCenter() ); |
088c1d4e WB |
807 | } |
808 | ||
833a21aa WB |
809 | // Take one control in each group to call to refresh the layout |
810 | // Since both control have the same parent, only one call is needed | |
811 | txtWindowStartTime.getParent().layout(); | |
812 | ntgCurrentWindowTime.getParent().layout(); | |
813 | } | |
378e7718 | 814 | |
544fe9b7 WB |
815 | /** |
816 | * Update the controls related current event.<p> | |
817 | * The call here SHOULD be thread safe and can be call from any threads. | |
818 | */ | |
088c1d4e WB |
819 | public void updateSelectedEventTime() { |
820 | ntgCurrentEventTime.setValueAsynchronously(currentEventTime); | |
544fe9b7 WB |
821 | // Tell the selection canvas which event is currently selected |
822 | // This give a nice graphic output | |
088c1d4e WB |
823 | selectedWindowCanvas.getHistogramContent().setSelectedEventTimeInWindow(currentEventTime); |
824 | selectedWindowCanvas.redrawAsynchronously(); | |
825 | } | |
826 | ||
7ef9ae3f WB |
827 | /** |
828 | * Method called when the view is moved.<p> | |
829 | * | |
830 | * Just redraw everything... | |
831 | * | |
832 | * @param event The controle event generated by the move. | |
833 | */ | |
834 | public void controlMoved(ControlEvent event) { | |
835 | parent.redraw(); | |
836 | } | |
837 | ||
838 | /** | |
839 | * Method called when the view is resized.<p> | |
840 | * | |
841 | * We will make sure that the size didn't change more than the content size.<p> | |
842 | * Otherwise we need to perform a new request for the full experiment because we are missing data). | |
843 | * | |
844 | * @param event The control event generated by the resize. | |
845 | */ | |
846 | public void controlResized(ControlEvent event) { | |
847 | ||
848 | // Ouch! The screen enlarged (screen resolution changed?) so far that we miss content to fill the space. | |
849 | // Perform a new full request... this is quite heavy. | |
850 | if ( parent.getDisplay().getBounds().width > fullExperimentCanvas.getHistogramContent().getNbElement() ) { | |
851 | if ( lastUsedExperiment != null ) { | |
852 | performAllTraceEventsRequest(lastUsedExperiment); | |
853 | } | |
854 | } | |
855 | ||
856 | } | |
6e512b93 | 857 | } |