tmf: Fix calculation of sash weights in performAlign
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / views / histogram / HistogramView.java
CommitLineData
6e512b93 1/*******************************************************************************
ed902a2b 2 * Copyright (c) 2009, 2015 Ericsson
1b055dfa 3 *
6e512b93
ASL
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
1b055dfa 8 *
6e512b93 9 * Contributors:
b59134e1 10 * William Bourque - Initial API and implementation
c392540b 11 * Yuriy Vashchuk - GUI reorganisation, simplification and some related code improvements.
1b055dfa 12 * Yuriy Vashchuk - Histograms optimisation.
c392540b
FC
13 * Yuriy Vashchuk - Histogram Canvas Heritage correction
14 * Francois Chouinard - Cleanup and refactoring
e0752744 15 * Francois Chouinard - Moved from LTTng to TMF
65cdf787 16 * Patrick Tasse - Update for mouse wheel zoom
2fc582d2 17 * Xavier Raynaud - Support multi-trace coloring
6e512b93 18 *******************************************************************************/
3e9fdb8b 19
2bdf0193 20package org.eclipse.tracecompass.tmf.ui.views.histogram;
6e512b93 21
c14c0757
GB
22import java.util.Collection;
23
dab5f596 24import org.eclipse.jdt.annotation.NonNull;
95aa81ef
JCK
25import org.eclipse.jface.action.Action;
26import org.eclipse.jface.action.IAction;
27import org.eclipse.jface.action.Separator;
b59134e1 28import org.eclipse.swt.SWT;
2fc582d2 29import org.eclipse.swt.custom.CLabel;
f7d9ea05
BH
30import org.eclipse.swt.custom.SashForm;
31import org.eclipse.swt.custom.ScrolledComposite;
720d67cb
PT
32import org.eclipse.swt.events.MouseAdapter;
33import org.eclipse.swt.events.MouseEvent;
65cdf787 34import org.eclipse.swt.events.MouseWheelListener;
720d67cb
PT
35import org.eclipse.swt.events.PaintEvent;
36import org.eclipse.swt.events.PaintListener;
2fc582d2 37import org.eclipse.swt.graphics.GC;
720d67cb 38import org.eclipse.swt.graphics.Image;
f7d9ea05 39import org.eclipse.swt.graphics.Point;
720d67cb 40import org.eclipse.swt.graphics.Rectangle;
b59134e1 41import org.eclipse.swt.layout.GridData;
252ae4bd 42import org.eclipse.swt.layout.GridLayout;
2fc582d2 43import org.eclipse.swt.layout.RowLayout;
6e512b93 44import org.eclipse.swt.widgets.Composite;
2fc582d2 45import org.eclipse.swt.widgets.Control;
80c930fa 46import org.eclipse.swt.widgets.Display;
e8c79054 47import org.eclipse.swt.widgets.Event;
720d67cb 48import org.eclipse.swt.widgets.Label;
e8c79054
BH
49import org.eclipse.swt.widgets.Listener;
50import org.eclipse.swt.widgets.Sash;
2bdf0193
AM
51import org.eclipse.tracecompass.internal.tmf.ui.Activator;
52import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants;
53import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
54import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType;
e8c79054 55import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
2bdf0193 56import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
e8c79054 57import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
2bdf0193 58import org.eclipse.tracecompass.tmf.core.signal.TmfSignalThrottler;
2bdf0193
AM
59import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
60import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
61import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal;
62import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
63import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal;
e8c79054 64import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
2bdf0193
AM
65import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
66import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
67import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
68import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
21852dfa 69import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
2bdf0193 70import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
e8c79054
BH
71import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo;
72import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentSignal;
73import org.eclipse.tracecompass.tmf.ui.views.ITmfTimeAligned;
2bdf0193 74import org.eclipse.tracecompass.tmf.ui.views.TmfView;
95aa81ef 75import org.eclipse.ui.IActionBars;
6e512b93 76
544fe9b7 77/**
faa38350 78 * The purpose of this view is to provide graphical time distribution statistics about the trace events.
544fe9b7 79 * <p>
c392540b
FC
80 * The view is composed of two histograms and two controls:
81 * <ul>
faa38350 82 * <li>an event distribution histogram for the whole trace;
c392540b
FC
83 * <li>an event distribution histogram for current time window (window span);
84 * <li>the timestamp of the currently selected event;
85 * <li>the window span (size of the time window of the smaller histogram).
86 * </ul>
87 * The histograms x-axis show their respective time range.
abbdd66a 88 *
f8177ba2 89 * @version 2.0
2af7df97 90 * @author Francois Chouinard
544fe9b7 91 */
e8c79054 92public class HistogramView extends TmfView implements ITmfTimeAligned {
c392540b
FC
93
94 // ------------------------------------------------------------------------
95 // Constants
96 // ------------------------------------------------------------------------
97
b544077e
BH
98 /**
99 * The view ID as defined in plugin.xml
100 */
dab5f596 101 public static final @NonNull String ID = "org.eclipse.linuxtools.tmf.ui.views.histogram"; //$NON-NLS-1$
c392540b 102
d2e4afa7 103 private static final Image LINK_IMG = Activator.getDefault().getImageFromPath(ITmfImageConstants.IMG_UI_LINK);
720d67cb 104
f7d9ea05
BH
105 private static final int[] DEFAULT_WEIGHTS = {1, 3};
106
c392540b
FC
107 // ------------------------------------------------------------------------
108 // Attributes
109 // ------------------------------------------------------------------------
110
faa38350
PT
111 // The current trace
112 private ITmfTrace fTrace;
c392540b 113
f8177ba2 114 // Current timestamp/time window - everything in the TIME_SCALE
faa38350
PT
115 private long fTraceStartTime;
116 private long fTraceEndTime;
c392540b
FC
117 private long fWindowStartTime;
118 private long fWindowEndTime;
d7ee91bb 119 private long fWindowSpan;
0fcf3b09
PT
120 private long fSelectionBeginTime;
121 private long fSelectionEndTime;
c392540b 122
e8c79054
BH
123 // SashForm
124 private SashForm fSashForm;
f7d9ea05
BH
125 private ScrolledComposite fScrollComposite;
126 private Composite fTimeControlsComposite;
e8c79054
BH
127 private Composite fTimeRangeComposite;
128 private Listener fSashDragListener;
f7d9ea05 129
c392540b 130 // Time controls
720d67cb
PT
131 private HistogramTextControl fSelectionStartControl;
132 private HistogramTextControl fSelectionEndControl;
c392540b
FC
133 private HistogramTextControl fTimeSpanControl;
134
720d67cb
PT
135 // Link
136 private Label fLinkButton;
137 private boolean fLinkState;
138
c392540b
FC
139 // Histogram/request for the full trace range
140 private static FullTraceHistogram fFullTraceHistogram;
141 private HistogramRequest fFullTraceRequest;
142
143 // Histogram/request for the selected time range
144 private static TimeRangeHistogram fTimeRangeHistogram;
145 private HistogramRequest fTimeRangeRequest;
146
2fc582d2
XR
147 // Legend area
148 private Composite fLegendArea;
149 private Image[] fLegendImages;
150
38df2c82
AM
151 // Throttlers for the time sync and time-range sync signals
152 private final TmfSignalThrottler fTimeSyncThrottle;
153 private final TmfSignalThrottler fTimeRangeSyncThrottle;
154
95aa81ef
JCK
155 // Action for toggle showing the lost events
156 private Action hideLostEventsAction;
2fc582d2
XR
157 // Action for toggle showing the traces
158 private Action showTraceAction;
95aa81ef 159
c392540b
FC
160 // ------------------------------------------------------------------------
161 // Constructor
162 // ------------------------------------------------------------------------
163
b544077e
BH
164 /**
165 * Default constructor
166 */
c392540b
FC
167 public HistogramView() {
168 super(ID);
38df2c82
AM
169 fTimeSyncThrottle = new TmfSignalThrottler(this, 200);
170 fTimeRangeSyncThrottle = new TmfSignalThrottler(this, 200);
c392540b
FC
171 }
172
6a13fa07 173 @Override
c392540b 174 public void dispose() {
1b055dfa 175 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
4dc47e28
FC
176 fTimeRangeRequest.cancel();
177 }
1b055dfa 178 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
4dc47e28
FC
179 fFullTraceRequest.cancel();
180 }
6a13fa07
FC
181 fFullTraceHistogram.dispose();
182 fTimeRangeHistogram.dispose();
720d67cb
PT
183 fSelectionStartControl.dispose();
184 fSelectionEndControl.dispose();
f8177ba2 185 fTimeSpanControl.dispose();
03ec1f6a
MAL
186 disposeLegendImages();
187
4dc47e28 188 super.dispose();
c392540b
FC
189 }
190
03ec1f6a
MAL
191 private void disposeLegendImages() {
192 if (fLegendImages != null) {
193 for (Image i: fLegendImages) {
194 i.dispose();
195 }
196 }
197 fLegendImages = null;
198 }
199
c392540b
FC
200 // ------------------------------------------------------------------------
201 // TmfView
202 // ------------------------------------------------------------------------
203
204 @Override
c392540b 205 public void createPartControl(Composite parent) {
e8c79054 206 super.createPartControl(parent);
c392540b
FC
207
208 // Control labels
720d67cb
PT
209 final String selectionStartLabel = Messages.HistogramView_selectionStartLabel;
210 final String selectionEndLabel = Messages.HistogramView_selectionEndLabel;
c392540b
FC
211 final String windowSpanLabel = Messages.HistogramView_windowSpanLabel;
212
213 // --------------------------------------------------------------------
214 // Set the HistogramView layout
215 // --------------------------------------------------------------------
e8c79054 216 Composite viewComposite = new Composite(getParentComposite(), SWT.FILL);
f7d9ea05 217 GridLayout gridLayout = new GridLayout(1, false);
c392540b
FC
218 gridLayout.verticalSpacing = 0;
219 gridLayout.marginHeight = 0;
220 gridLayout.marginWidth = 0;
221 viewComposite.setLayout(gridLayout);
222
f7d9ea05
BH
223 // --------------------------------------------------------------------
224 // Add a sash for time controls and time range histogram
225 // --------------------------------------------------------------------
e8c79054
BH
226
227 /*
228 * The ScrolledComposite preferred size can be larger than its visible
229 * width. This affects the preferred width of the SashForm. Set the
230 * preferred width to 1 to prevent it from affecting the preferred width
231 * of the view composite.
232 */
233 fSashForm = new SashForm(viewComposite, SWT.NONE) {
234 @Override
235 public Point computeSize(int wHint, int hHint) {
236 Point computedSize = super.computeSize(wHint, hHint);
237 if (wHint == SWT.DEFAULT) {
238 return new Point(1, computedSize.y);
239 }
240 return computedSize;
241 }
242 @Override
243 public Point computeSize(int wHint, int hHint, boolean changed) {
244 Point computedSize = super.computeSize(wHint, hHint, changed);
245 if (wHint == SWT.DEFAULT) {
246 return new Point(1, computedSize.y);
247 }
248 return computedSize;
249 }
250 };
f7d9ea05 251 GridData gridData = new GridData(GridData.FILL, GridData.FILL, false, true);
e8c79054 252 fSashForm.setLayoutData(gridData);
f7d9ea05 253
c392540b
FC
254 // --------------------------------------------------------------------
255 // Time controls
256 // --------------------------------------------------------------------
e8c79054 257 fScrollComposite = new PackedScrolledComposite(fSashForm, SWT.H_SCROLL | SWT.V_SCROLL);
f7d9ea05
BH
258 fTimeControlsComposite = new Composite(fScrollComposite, SWT.NONE);
259 fScrollComposite.setContent(fTimeControlsComposite);
260 gridLayout = new GridLayout(1, false);
261 gridLayout.marginHeight = 0;
262 gridLayout.marginWidth = 0;
263 fScrollComposite.setLayout(gridLayout);
264 fScrollComposite.setExpandHorizontal(true);
265 fScrollComposite.setExpandVertical(true);
c392540b 266
f7d9ea05
BH
267 gridLayout = new GridLayout(1, false);
268 gridLayout.marginHeight = 0;
269 gridLayout.marginWidth = 0;
270 fTimeControlsComposite.setLayout(gridLayout);
271 gridData = new GridData(GridData.FILL, GridData.CENTER, false, true);
272 fTimeControlsComposite.setLayoutData(gridData);
273
274 Composite innerComp = new Composite(fTimeControlsComposite, SWT.NONE);
275
276 gridLayout = new GridLayout(2, false);
277 innerComp.setLayout(gridLayout);
c392540b
FC
278 gridLayout.marginHeight = 0;
279 gridLayout.marginWidth = 0;
280 gridLayout.horizontalSpacing = 5;
720d67cb 281 gridLayout.verticalSpacing = 1;
f7d9ea05
BH
282 gridData = new GridData(GridData.FILL, GridData.CENTER, false, true);
283 innerComp.setLayoutData(gridData);
720d67cb 284
f7d9ea05
BH
285 Composite selectionGroup = new Composite(innerComp, SWT.BORDER);
286 gridLayout = new GridLayout(1, false);
720d67cb
PT
287 gridLayout.marginHeight = 0;
288 gridLayout.marginWidth = 0;
720d67cb 289 selectionGroup.setLayout(gridLayout);
f7d9ea05
BH
290 gridData = new GridData(GridData.BEGINNING, GridData.CENTER, false, false);
291 selectionGroup.setLayoutData(gridData);
c392540b 292
720d67cb 293 // Selection start control
f7d9ea05 294 gridData = new GridData(GridData.FILL, GridData.CENTER, false, false);
720d67cb
PT
295 fSelectionStartControl = new HistogramSelectionStartControl(this, selectionGroup, selectionStartLabel, 0L);
296 fSelectionStartControl.setLayoutData(gridData);
297 fSelectionStartControl.setValue(Long.MIN_VALUE);
298
299 // Selection end control
f7d9ea05 300 gridData = new GridData(GridData.FILL, GridData.CENTER, false, false);
720d67cb
PT
301 fSelectionEndControl = new HistogramSelectionEndControl(this, selectionGroup, selectionEndLabel, 0L);
302 fSelectionEndControl.setLayoutData(gridData);
303 fSelectionEndControl.setValue(Long.MIN_VALUE);
304
305 // Link button
f7d9ea05
BH
306 gridData = new GridData(GridData.BEGINNING, GridData.CENTER, false, false);
307 fLinkButton = new Label(innerComp, SWT.NONE);
720d67cb
PT
308 fLinkButton.setImage(LINK_IMG);
309 fLinkButton.setLayoutData(gridData);
310 addLinkButtonListeners();
c392540b
FC
311
312 // Window span time control
f7d9ea05
BH
313 gridData = new GridData(GridData.FILL, GridData.CENTER, false, false);
314 fTimeSpanControl = new HistogramTimeRangeControl(this, innerComp, windowSpanLabel, 0L);
c392540b 315 fTimeSpanControl.setLayoutData(gridData);
da7bdcbc 316 fTimeSpanControl.setValue(Long.MIN_VALUE);
c392540b
FC
317
318 // --------------------------------------------------------------------
319 // Time range histogram
320 // --------------------------------------------------------------------
e8c79054 321 fTimeRangeComposite = new Composite(fSashForm, SWT.NONE);
f7d9ea05
BH
322 gridLayout = new GridLayout(1, true);
323 gridLayout.marginTop = 0;
e8c79054
BH
324 gridLayout.marginWidth = 0;
325 fTimeRangeComposite.setLayout(gridLayout);
c392540b
FC
326
327 // Use remaining horizontal space
f7d9ea05 328 gridData = new GridData(GridData.FILL, GridData.FILL, true, true);
e8c79054 329 fTimeRangeComposite.setLayoutData(gridData);
c392540b
FC
330
331 // Histogram
e8c79054 332 fTimeRangeHistogram = new TimeRangeHistogram(this, fTimeRangeComposite, true);
c392540b
FC
333
334 // --------------------------------------------------------------------
335 // Full range histogram
336 // --------------------------------------------------------------------
f7d9ea05
BH
337 final Composite fullRangeComposite = new Composite(viewComposite, SWT.FILL);
338 gridLayout = new GridLayout(1, true);
c392540b
FC
339 fullRangeComposite.setLayout(gridLayout);
340
341 // Use remaining horizontal space
f7d9ea05 342 gridData = new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1);
c392540b
FC
343 fullRangeComposite.setLayoutData(gridData);
344
345 // Histogram
346 fFullTraceHistogram = new FullTraceHistogram(this, fullRangeComposite);
347
2fc582d2
XR
348 fLegendArea = new Composite(viewComposite, SWT.FILL);
349 fLegendArea.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, true, false, 2, 1));
350 fLegendArea.setLayout(new RowLayout());
351
65cdf787
PT
352 // Add mouse wheel listener to time span control
353 MouseWheelListener listener = fFullTraceHistogram.getZoom();
354 fTimeSpanControl.addMouseWheelListener(listener);
355
95aa81ef
JCK
356 // View Action Handling
357 contributeToActionBars();
358
21852dfa 359 ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
3ac5721a
AM
360 if (trace != null) {
361 traceSelected(new TmfTraceSelectedSignal(this, trace));
1b055dfa 362 }
f7d9ea05 363
e8c79054
BH
364 fSashForm.setVisible(true);
365 fSashForm.setWeights(DEFAULT_WEIGHTS);
366
367 fTimeControlsComposite.addPaintListener(new PaintListener() {
368 @Override
369 public void paintControl(PaintEvent e) {
370 // Sashes in a SashForm are being created on layout so add the
371 // drag listener here
372 if (fSashDragListener == null) {
373 for (Control control : fSashForm.getChildren()) {
374 if (control instanceof Sash) {
375 fSashDragListener = new Listener() {
376 @Override
377 public void handleEvent(Event event) {
378 TmfSignalManager.dispatchSignal(new TmfTimeViewAlignmentSignal(fSashForm, getTimeViewAlignmentInfo()));
379 }
380 };
381 control.removePaintListener(this);
382 control.addListener(SWT.Selection, fSashDragListener);
383 // There should be only one sash
384 break;
385 }
386 }
387 }
388 }
389 });
ecfd1d41 390 }
c392540b
FC
391
392 @Override
c392540b 393 public void setFocus() {
faa38350 394 fFullTraceHistogram.fCanvas.setFocus();
833a21aa 395 }
c392540b 396
f8177ba2 397 void refresh() {
e8c79054
BH
398 getParentComposite().layout(true);
399 }
400
401 /**
402 * @since 1.0
403 */
404 @Override
405 public TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo() {
406 if (fSashForm == null) {
407 return null;
408 }
409 return new TmfTimeViewAlignmentInfo(fSashForm.getShell(), fSashForm.toDisplay(0, 0), getTimeAxisOffset());
410 }
411
412 private int getTimeAxisOffset() {
413 int[] weights = fSashForm.getWeights();
414 int width = (int) (((float) weights[0] / (weights[0] + weights[1])) * fSashForm.getBounds().width);
415 int curTimeAxisOffset = width + fSashForm.getSashWidth() + fTimeRangeHistogram.getPointAreaOffset();
416 return curTimeAxisOffset;
417 }
418
419 /**
420 * @since 1.0
421 */
422 @Override
423 public int getAvailableWidth(int requestedOffset) {
424 int pointAreaWidth = fTimeRangeHistogram.getPointAreaWidth();
425 int curTimeAxisOffset = getTimeAxisOffset();
426 if (pointAreaWidth <= 0) {
427 pointAreaWidth = fSashForm.getBounds().width - curTimeAxisOffset;
428 }
429 // TODO this is just an approximation that assumes that the end will be at the same position but that can change for a different data range/scaling
430 int endOffset = curTimeAxisOffset + pointAreaWidth;
431 GridLayout layout = (GridLayout) fTimeRangeComposite.getLayout();
432 int endOffsetWithoutMargin = endOffset + layout.marginRight;
433 int availableWidth = endOffsetWithoutMargin - requestedOffset;
434 availableWidth = Math.min(fSashForm.getBounds().width, Math.max(0, availableWidth));
435
436 return availableWidth;
437 }
438
439 /**
440 * @since 1.0
441 */
442 @Override
443 public void performAlign(int offset, int width) {
e8c79054 444 int total = fSashForm.getBounds().width;
c34ab48a
PT
445 int plotAreaOffset = fTimeRangeHistogram.getPointAreaOffset();
446 int width1 = Math.max(0, offset - plotAreaOffset - fSashForm.getSashWidth());
447 int width2 = Math.max(0, total - width1 - fSashForm.getSashWidth());
e8c79054
BH
448 fSashForm.setWeights(new int[] { width1, width2 });
449 fSashForm.layout();
450
451 // calculate right margin
452 GridLayout layout = (GridLayout) fTimeRangeComposite.getLayout();
453 int timeBasedControlsWidth = fTimeRangeComposite.getSize().x;
454 int marginSize = timeBasedControlsWidth - width - plotAreaOffset;
455 layout.marginRight = Math.max(0, marginSize);
456 fTimeRangeComposite.layout();
f8177ba2
FC
457 }
458
c392540b
FC
459 // ------------------------------------------------------------------------
460 // Accessors
461 // ------------------------------------------------------------------------
462
faa38350
PT
463 /**
464 * Returns the current trace handled by the view
465 *
466 * @return the current trace
faa38350
PT
467 */
468 public ITmfTrace getTrace() {
469 return fTrace;
470 }
471
b544077e
BH
472 /**
473 * Returns the time range of the current selected window (base on default time scale).
abbdd66a 474 *
b544077e
BH
475 * @return the time range of current selected window.
476 */
c392540b 477 public TmfTimeRange getTimeRange() {
f8177ba2
FC
478 return new TmfTimeRange(
479 new TmfTimestamp(fWindowStartTime, ITmfTimestamp.NANOSECOND_SCALE),
480 new TmfTimestamp(fWindowEndTime, ITmfTimestamp.NANOSECOND_SCALE));
c392540b
FC
481 }
482
95aa81ef
JCK
483 /**
484 * get the show lost events action
485 *
486 * @return The action object
95aa81ef
JCK
487 */
488 public Action getShowLostEventsAction() {
489 if (hideLostEventsAction == null) {
490 /* show lost events */
491 hideLostEventsAction = new Action(Messages.HistogramView_hideLostEvents, IAction.AS_CHECK_BOX) {
492 @Override
493 public void run() {
494 HistogramScaledData.hideLostEvents = hideLostEventsAction.isChecked();
495 long maxNbEvents = HistogramScaledData.hideLostEvents ? fFullTraceHistogram.fScaledData.fMaxValue : fFullTraceHistogram.fScaledData.fMaxCombinedValue;
3311a6ca 496 fFullTraceHistogram.setMaxNbEvents(maxNbEvents);
95aa81ef 497 maxNbEvents = HistogramScaledData.hideLostEvents ? fTimeRangeHistogram.fScaledData.fMaxValue : fTimeRangeHistogram.fScaledData.fMaxCombinedValue;
3311a6ca 498 fTimeRangeHistogram.setMaxNbEvents(maxNbEvents);
95aa81ef
JCK
499 }
500 };
501 hideLostEventsAction.setText(Messages.HistogramView_hideLostEvents);
502 hideLostEventsAction.setToolTipText(Messages.HistogramView_hideLostEvents);
503 hideLostEventsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LOST_EVENTS));
504 }
505 return hideLostEventsAction;
506 }
507
2fc582d2
XR
508 /**
509 * get the show trace action
510 *
511 * @return The action object
2fc582d2
XR
512 */
513 public Action getShowTraceAction() {
514 if (showTraceAction == null) {
515 /* show lost events */
516 showTraceAction = new Action(Messages.HistogramView_showTraces, IAction.AS_CHECK_BOX) {
517 @Override
518 public void run() {
519 Histogram.showTraces = showTraceAction.isChecked();
520 fFullTraceHistogram.fCanvas.redraw();
521 fTimeRangeHistogram.fCanvas.redraw();
522 updateLegendArea();
523 }
524 };
525 showTraceAction.setChecked(true);
526 showTraceAction.setText(Messages.HistogramView_showTraces);
527 showTraceAction.setToolTipText(Messages.HistogramView_showTraces);
528 showTraceAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_HIST_TRACES));
529 }
530 return showTraceAction;
531 }
532
c392540b
FC
533 // ------------------------------------------------------------------------
534 // Operations
535 // ------------------------------------------------------------------------
536
b544077e 537 /**
0fcf3b09
PT
538 * Broadcast TmfSignal about new current selection time range.
539 * @param beginTime the begin time of current selection.
540 * @param endTime the end time of current selection.
b544077e 541 */
0fcf3b09
PT
542 void updateSelectionTime(long beginTime, long endTime) {
543 updateDisplayedSelectionTime(beginTime, endTime);
544 TmfTimestamp beginTs = new TmfTimestamp(beginTime, ITmfTimestamp.NANOSECOND_SCALE);
545 TmfTimestamp endTs = new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE);
97c71024 546 TmfSelectionRangeUpdatedSignal signal = new TmfSelectionRangeUpdatedSignal(this, beginTs, endTs);
0fcf3b09 547 fTimeSyncThrottle.queue(signal);
c392540b
FC
548 }
549
720d67cb
PT
550 /**
551 * Get selection begin time
552 * @return the begin time of current selection
553 */
554 long getSelectionBegin() {
555 return fSelectionBeginTime;
556 }
557
558 /**
559 * Get selection end time
560 * @return the end time of current selection
561 */
562 long getSelectionEnd() {
563 return fSelectionEndTime;
564 }
565
566 /**
567 * Get the link state
568 * @return true if begin and end selection time should be linked
569 */
570 boolean getLinkState() {
571 return fLinkState;
572 }
573
b544077e 574 /**
0fcf3b09 575 * Broadcast TmfSignal about new selection time range.
b544077e
BH
576 * @param startTime the new start time
577 * @param endTime the new end time
578 */
f8177ba2 579 void updateTimeRange(long startTime, long endTime) {
faa38350 580 if (fTrace != null) {
c392540b 581 // Build the new time range; keep the current time
f8177ba2
FC
582 TmfTimeRange timeRange = new TmfTimeRange(
583 new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE),
584 new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE));
c392540b
FC
585 fTimeSpanControl.setValue(endTime - startTime);
586
38df2c82
AM
587 updateDisplayedTimeRange(startTime, endTime);
588
c392540b 589 // Send the FW signal
97c71024 590 TmfWindowRangeUpdatedSignal signal = new TmfWindowRangeUpdatedSignal(this, timeRange);
38df2c82 591 fTimeRangeSyncThrottle.queue(signal);
c392540b
FC
592 }
593 }
594
b544077e
BH
595 /**
596 * Broadcast TmfSignal about new selected time range.
597 * @param newDuration new duration (relative to current start time)
598 */
c392540b 599 public synchronized void updateTimeRange(long newDuration) {
faa38350 600 if (fTrace != null) {
6a13fa07 601 long delta = newDuration - fWindowSpan;
1c6a842a 602 long newStartTime = fWindowStartTime - (delta / 2);
6a13fa07 603 setNewRange(newStartTime, newDuration);
c392540b
FC
604 }
605 }
606
607 private void setNewRange(long startTime, long duration) {
41b5c37f
AM
608 long realStart = startTime;
609
610 if (realStart < fTraceStartTime) {
611 realStart = fTraceStartTime;
1b055dfa 612 }
c392540b 613
41b5c37f 614 long endTime = realStart + duration;
faa38350
PT
615 if (endTime > fTraceEndTime) {
616 endTime = fTraceEndTime;
1c6a842a 617 if ((endTime - duration) > fTraceStartTime) {
41b5c37f 618 realStart = endTime - duration;
1b055dfa 619 } else {
41b5c37f 620 realStart = fTraceStartTime;
6a13fa07 621 }
c392540b 622 }
41b5c37f 623 updateTimeRange(realStart, endTime);
833a21aa 624 }
c392540b
FC
625
626 // ------------------------------------------------------------------------
627 // Signal handlers
628 // ------------------------------------------------------------------------
629
b544077e 630 /**
faa38350 631 * Handles trace opened signal. Loads histogram if new trace time range is not
b544077e 632 * equal <code>TmfTimeRange.NULL_RANGE</code>
fec1ac0b 633 * @param signal the trace opened signal
b544077e 634 */
1406f802 635 @TmfSignalHandler
faa38350 636 public void traceOpened(TmfTraceOpenedSignal signal) {
c392540b 637 assert (signal != null);
faa38350
PT
638 fTrace = signal.getTrace();
639 loadTrace();
ecfd1d41 640 }
550d787e 641
faa38350
PT
642 /**
643 * Handles trace selected signal. Loads histogram if new trace time range is not
644 * equal <code>TmfTimeRange.NULL_RANGE</code>
645 * @param signal the trace selected signal
faa38350
PT
646 */
647 @TmfSignalHandler
648 public void traceSelected(TmfTraceSelectedSignal signal) {
649 assert (signal != null);
650 if (fTrace != signal.getTrace()) {
651 fTrace = signal.getTrace();
652 loadTrace();
653 }
654 }
655
656 private void loadTrace() {
c392540b 657 initializeHistograms();
e8c79054 658 getParentComposite().redraw();
550d787e
FC
659 }
660
ea279a69 661 /**
faa38350
PT
662 * Handles trace closed signal. Clears the view and data model and cancels requests.
663 * @param signal the trace closed signal
ea279a69
FC
664 */
665 @TmfSignalHandler
faa38350
PT
666 public void traceClosed(TmfTraceClosedSignal signal) {
667
668 if (signal.getTrace() != fTrace) {
669 return;
670 }
ea279a69
FC
671
672 // Kill any running request
673 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
674 fTimeRangeRequest.cancel();
675 }
676 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
677 fFullTraceRequest.cancel();
678 }
679
680 // Initialize the internal data
faa38350
PT
681 fTrace = null;
682 fTraceStartTime = 0L;
683 fTraceEndTime = 0L;
f8177ba2
FC
684 fWindowStartTime = 0L;
685 fWindowEndTime = 0L;
d7ee91bb 686 fWindowSpan = 0L;
0fcf3b09
PT
687 fSelectionBeginTime = 0L;
688 fSelectionEndTime = 0L;
ea279a69
FC
689
690 // Clear the UI widgets
691 fFullTraceHistogram.clear();
692 fTimeRangeHistogram.clear();
720d67cb
PT
693 fSelectionStartControl.setValue(Long.MIN_VALUE);
694 fSelectionEndControl.setValue(Long.MIN_VALUE);
f8177ba2 695
da7bdcbc 696 fTimeSpanControl.setValue(Long.MIN_VALUE);
2fc582d2
XR
697
698 for (Control c: fLegendArea.getChildren()) {
699 c.dispose();
700 }
03ec1f6a 701 disposeLegendImages();
2fc582d2
XR
702 fLegendArea.layout();
703 fLegendArea.getParent().layout();
ea279a69
FC
704 }
705
b544077e 706 /**
faa38350 707 * Handles trace range updated signal. Extends histogram according to the new time range. If a
b544077e
BH
708 * HistogramRequest is already ongoing, it will be cancelled and a new request with the new range
709 * will be issued.
abbdd66a 710 *
faa38350 711 * @param signal the trace range updated signal
b544077e 712 */
74237cc3 713 @TmfSignalHandler
faa38350 714 public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) {
74237cc3 715
faa38350 716 if (signal.getTrace() != fTrace) {
09d11238
PT
717 return;
718 }
719
74237cc3
FC
720 TmfTimeRange fullRange = signal.getRange();
721
faa38350
PT
722 fTraceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
723 fTraceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
74237cc3 724
faa38350
PT
725 fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
726 fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
74237cc3 727
74237cc3
FC
728 sendFullRangeRequest(fullRange);
729 }
c392540b 730
b544077e 731 /**
faa38350
PT
732 * Handles the trace updated signal. Used to update time limits (start and end time)
733 * @param signal the trace updated signal
b544077e 734 */
a28d503d 735 @TmfSignalHandler
faa38350
PT
736 public void traceUpdated(TmfTraceUpdatedSignal signal) {
737 if (signal.getTrace() != fTrace) {
a28d503d
PT
738 return;
739 }
faa38350
PT
740 TmfTimeRange fullRange = signal.getTrace().getTimeRange();
741 fTraceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
742 fTraceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
a28d503d 743
faa38350
PT
744 fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
745 fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
746
747 if ((fFullTraceRequest != null) && fFullTraceRequest.getRange().getEndTime().compareTo(signal.getRange().getEndTime()) < 0) {
748 sendFullRangeRequest(fullRange);
749 }
750}
a28d503d 751
b544077e 752 /**
97c71024
AM
753 * Handles the selection range updated signal. Sets the current time
754 * selection in the time range histogram as well as the full histogram.
abbdd66a 755 *
97c71024
AM
756 * @param signal
757 * the signal to process
758 * @since 1.0
b544077e 759 */
c392540b 760 @TmfSignalHandler
97c71024 761 public void selectionRangeUpdated(final TmfSelectionRangeUpdatedSignal signal) {
80c930fa
PT
762 if (Display.getCurrent() == null) {
763 // Make sure the signal is handled in the UI thread
764 Display.getDefault().asyncExec(new Runnable() {
765 @Override
766 public void run() {
e8c79054 767 if (getParentComposite().isDisposed()) {
80c930fa
PT
768 return;
769 }
97c71024 770 selectionRangeUpdated(signal);
80c930fa
PT
771 }
772 });
773 return;
774 }
c392540b 775
0fcf3b09
PT
776 // Update the selected time range
777 ITmfTimestamp beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE);
778 ITmfTimestamp endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE);
779 updateDisplayedSelectionTime(beginTime.getValue(), endTime.getValue());
ecfd1d41 780 }
f05aabed 781
b544077e 782 /**
97c71024
AM
783 * Updates the current window time range in the time range histogram and
784 * full range histogram.
785 *
786 * @param signal
787 * the signal to process
788 * @since 1.0
b544077e 789 */
c392540b 790 @TmfSignalHandler
97c71024 791 public void windowRangeUpdated(final TmfWindowRangeUpdatedSignal signal) {
80c930fa
PT
792 if (Display.getCurrent() == null) {
793 // Make sure the signal is handled in the UI thread
794 Display.getDefault().asyncExec(new Runnable() {
795 @Override
796 public void run() {
e8c79054 797 if (getParentComposite().isDisposed()) {
80c930fa
PT
798 return;
799 }
97c71024 800 windowRangeUpdated(signal);
80c930fa
PT
801 }
802 });
803 return;
804 }
c392540b 805
faa38350 806 if (fTrace != null) {
1c6a842a
PT
807 // Validate the time range
808 TmfTimeRange range = signal.getCurrentRange().getIntersection(fTrace.getTimeRange());
809 if (range == null) {
810 return;
811 }
812
38df2c82
AM
813 updateDisplayedTimeRange(
814 range.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(),
815 range.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue());
c392540b 816
38df2c82 817 // Send the event request to populate the small histogram
c392540b 818 sendTimeRangeRequest(fWindowStartTime, fWindowEndTime);
f8177ba2 819
c392540b
FC
820 fTimeSpanControl.setValue(fWindowSpan);
821 }
b59134e1 822 }
c392540b
FC
823
824 // ------------------------------------------------------------------------
825 // Helper functions
826 // ------------------------------------------------------------------------
827
828 private void initializeHistograms() {
faa38350 829 TmfTimeRange fullRange = updateTraceTimeRange();
21852dfa
AM
830
831 TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
832 long selectionBeginTime = ctx.getSelectionRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
833 long selectionEndTime = ctx.getSelectionRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
834 long startTime = ctx.getWindowRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
835 long duration = ctx.getWindowRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue() - startTime;
74237cc3 836
faa38350
PT
837 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
838 fTimeRangeRequest.cancel();
839 }
74237cc3 840 fTimeRangeHistogram.clear();
faa38350 841 fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
d7ee91bb 842 fTimeRangeHistogram.setTimeRange(startTime, duration);
0fcf3b09 843 fTimeRangeHistogram.setSelection(selectionBeginTime, selectionEndTime);
2fc582d2 844 fTimeRangeHistogram.fDataModel.setTrace(fTrace);
c392540b 845
faa38350
PT
846 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
847 fFullTraceRequest.cancel();
848 }
74237cc3 849 fFullTraceHistogram.clear();
faa38350 850 fFullTraceHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
d7ee91bb 851 fFullTraceHistogram.setTimeRange(startTime, duration);
0fcf3b09 852 fFullTraceHistogram.setSelection(selectionBeginTime, selectionEndTime);
2fc582d2 853 fFullTraceHistogram.fDataModel.setTrace(fTrace);
c392540b 854
d7ee91bb
PT
855 fWindowStartTime = startTime;
856 fWindowSpan = duration;
857 fWindowEndTime = startTime + duration;
6a13fa07 858
0fcf3b09
PT
859 fSelectionBeginTime = selectionBeginTime;
860 fSelectionEndTime = selectionEndTime;
720d67cb
PT
861 fSelectionStartControl.setValue(fSelectionBeginTime);
862 fSelectionEndControl.setValue(fSelectionEndTime);
f8177ba2 863
f7d9ea05
BH
864 // make sure that the scrollbar is setup properly
865 fScrollComposite.setMinSize(fTimeControlsComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
d7ee91bb 866 fTimeSpanControl.setValue(duration);
6a13fa07 867
c14c0757
GB
868 Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(fTrace);
869 if (!traces.isEmpty()) {
870 this.showTraceAction.setEnabled(traces.size() < fFullTraceHistogram.getMaxNbTraces());
2fc582d2
XR
871 }
872 updateLegendArea();
873
2af7df97 874 if (!fullRange.equals(TmfTimeRange.NULL_RANGE)) {
d7ee91bb 875 sendTimeRangeRequest(startTime, startTime + duration);
2af7df97
FC
876 sendFullRangeRequest(fullRange);
877 }
74237cc3
FC
878 }
879
2fc582d2
XR
880 private void updateLegendArea() {
881 for (Control c: fLegendArea.getChildren()) {
882 c.dispose();
883 }
03ec1f6a 884 disposeLegendImages();
2fc582d2 885 if (fFullTraceHistogram.showTraces()) {
c14c0757
GB
886 Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(fTrace);
887 fLegendImages = new Image[traces.size()];
2fc582d2
XR
888 int traceIndex = 0;
889 for (ITmfTrace trace : traces) {
890 fLegendImages[traceIndex] = new Image(fLegendArea.getDisplay(), 16, 16);
891 GC gc = new GC(fLegendImages[traceIndex]);
892 gc.setBackground(fFullTraceHistogram.getTraceColor(traceIndex));
893 gc.fillRectangle(0, 0, 15, 15);
894 gc.setForeground(fLegendArea.getDisplay().getSystemColor(SWT.COLOR_BLACK));
895 gc.drawRectangle(0, 0, 15, 15);
896 gc.dispose();
897
898 CLabel label = new CLabel(fLegendArea, SWT.NONE);
899 label.setText(trace.getName());
900 label.setImage(fLegendImages[traceIndex]);
901 traceIndex++;
902 }
903 }
904 fLegendArea.layout();
905 fLegendArea.getParent().layout();
906 }
907
0fcf3b09
PT
908 private void updateDisplayedSelectionTime(long beginTime, long endTime) {
909 fSelectionBeginTime = beginTime;
910 fSelectionEndTime = endTime;
38df2c82 911
0fcf3b09
PT
912 fFullTraceHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime);
913 fTimeRangeHistogram.setSelection(fSelectionBeginTime, fSelectionEndTime);
720d67cb
PT
914 fSelectionStartControl.setValue(fSelectionBeginTime);
915 fSelectionEndControl.setValue(fSelectionEndTime);
38df2c82
AM
916 }
917
918 private void updateDisplayedTimeRange(long start, long end) {
919 fWindowStartTime = start;
920 fWindowEndTime = end;
921 fWindowSpan = fWindowEndTime - fWindowStartTime;
922 fFullTraceHistogram.setTimeRange(fWindowStartTime, fWindowSpan);
923 }
924
faa38350
PT
925 private TmfTimeRange updateTraceTimeRange() {
926 fTraceStartTime = 0L;
927 fTraceEndTime = 0L;
74237cc3 928
faa38350 929 TmfTimeRange timeRange = fTrace.getTimeRange();
c6023803 930 if (!timeRange.equals(TmfTimeRange.NULL_RANGE)) {
faa38350
PT
931 fTraceStartTime = timeRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
932 fTraceEndTime = timeRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
74237cc3
FC
933 }
934 return timeRange;
b59134e1 935 }
c392540b
FC
936
937 private void sendTimeRangeRequest(long startTime, long endTime) {
1b055dfa 938 if ((fTimeRangeRequest != null) && !fTimeRangeRequest.isCompleted()) {
c392540b 939 fTimeRangeRequest.cancel();
088c1d4e 940 }
f8177ba2
FC
941 TmfTimestamp startTS = new TmfTimestamp(startTime, ITmfTimestamp.NANOSECOND_SCALE);
942 TmfTimestamp endTS = new TmfTimestamp(endTime, ITmfTimestamp.NANOSECOND_SCALE);
c392540b
FC
943 TmfTimeRange timeRange = new TmfTimeRange(startTS, endTS);
944
945 fTimeRangeHistogram.clear();
15844a4e 946 fTimeRangeHistogram.setFullRange(fTraceStartTime, fTraceEndTime);
c392540b 947 fTimeRangeHistogram.setTimeRange(startTime, endTime - startTime);
4cf201de 948
faa38350 949 int cacheSize = fTrace.getCacheSize();
2740e05c
AM
950 fTimeRangeRequest = new HistogramRequest(fTimeRangeHistogram.getDataModel(),
951 timeRange, 0, ITmfEventRequest.ALL_DATA, cacheSize, ExecutionType.FOREGROUND, false);
faa38350 952 fTrace.sendRequest(fTimeRangeRequest);
088c1d4e 953 }
c392540b 954
74237cc3 955 private void sendFullRangeRequest(TmfTimeRange fullRange) {
1b055dfa 956 if ((fFullTraceRequest != null) && !fFullTraceRequest.isCompleted()) {
c392540b
FC
957 fFullTraceRequest.cancel();
958 }
faa38350 959 int cacheSize = fTrace.getCacheSize();
2740e05c
AM
960 fFullTraceRequest = new HistogramRequest(fFullTraceHistogram.getDataModel(),
961 fullRange,
962 (int) fFullTraceHistogram.fDataModel.getNbEvents(),
963 ITmfEventRequest.ALL_DATA,
964 cacheSize,
965 ExecutionType.BACKGROUND, true);
faa38350 966 fTrace.sendRequest(fFullTraceRequest);
ed4b3b9f 967 }
c392540b 968
95aa81ef
JCK
969 private void contributeToActionBars() {
970 IActionBars bars = getViewSite().getActionBars();
971 bars.getToolBarManager().add(getShowLostEventsAction());
2fc582d2 972 bars.getToolBarManager().add(getShowTraceAction());
95aa81ef
JCK
973 bars.getToolBarManager().add(new Separator());
974 }
975
720d67cb
PT
976 private void addLinkButtonListeners() {
977 fLinkButton.addMouseListener(new MouseAdapter() {
978 @Override
979 public void mouseDown(MouseEvent e) {
980 fSelectionEndControl.setEnabled(fLinkState);
981 fLinkState = !fLinkState;
982 fLinkButton.redraw();
983 }
984 });
985
986 fLinkButton.addPaintListener(new PaintListener() {
987 @Override
988 public void paintControl(PaintEvent e) {
989 if (fLinkState) {
990 Rectangle r = fLinkButton.getBounds();
991 r.x = -1;
992 r.y = -1;
993 e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
994 e.gc.drawRectangle(r);
995 r.x = 0;
996 r.y = 0;
997 e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_DARK_GRAY));
998 e.gc.drawRectangle(r);
999 }
1000 }
1001 });
1002 }
f7d9ea05
BH
1003
1004 private static class PackedScrolledComposite extends ScrolledComposite {
1005 Point fScrollBarSize; // Size of OS-specific scrollbar
1006
1007 public PackedScrolledComposite(Composite parent, int style) {
1008 super(parent, style);
1009 Composite composite = new Composite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
1010 composite.setSize(1, 1);
1011 fScrollBarSize = composite.computeSize(0, 0);
1012 composite.dispose();
1013 }
1014
1015 @Override
1016 public Point computeSize(int wHint, int hHint, boolean changed) {
1017 Point point = super.computeSize(wHint, hHint, changed);
1018 // Remove scrollbar size if applicable
1019 point.x += ((getStyle() & SWT.V_SCROLL) != 0) ? -fScrollBarSize.x : 0;
1020 point.y += ((getStyle() & SWT.H_SCROLL) != 0) ? -fScrollBarSize.y : 0;
1021 return point;
1022 }
1023 }
6e512b93 1024}
This page took 0.148488 seconds and 5 git commands to generate.