tmf: Fix incorrect histogram state when concurrently cleared during drag
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / histogram / TimeRangeHistogram.java
1 /*******************************************************************************
2 * Copyright (c) 2011, 2013 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:
10 * Francois Chouinard - Initial API and implementation
11 * Bernd Hufmann - Changed to updated histogram data model
12 * Francois Chouinard - Moved from LTTng to TMF
13 * Patrick Tasse - Update for mouse wheel zoom
14 *******************************************************************************/
15
16 package org.eclipse.linuxtools.tmf.ui.views.histogram;
17
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.events.MouseEvent;
20 import org.eclipse.swt.events.PaintEvent;
21 import org.eclipse.swt.graphics.GC;
22 import org.eclipse.swt.graphics.Image;
23 import org.eclipse.swt.widgets.Composite;
24
25 /**
26 * A basic histogram widget that displays the event distribution of a specific time range of a trace.
27 * It has the following additional features:
28 * <ul>
29 * <li>zoom in: mouse wheel up (or forward)
30 * <li>zoom out: mouse wheel down (or backward)
31 * </ul>
32 *
33 * @version 1.1
34 * @author Francois Chouinard
35 */
36 public class TimeRangeHistogram extends Histogram {
37
38 // ------------------------------------------------------------------------
39 // Attributes
40 // ------------------------------------------------------------------------
41
42 private HistogramZoom fZoom = null;
43
44 private long fRangeStartTime = 0L;
45 private long fRangeDuration;
46 private long fFullRangeStartTime = 0L;
47 private long fFullRangeEndTime = 0L;
48
49 // ------------------------------------------------------------------------
50 // Constructor
51 // ------------------------------------------------------------------------
52 /**
53 * Constructor
54 * @param view The parent histogram view
55 * @param parent The parent composite
56 */
57 public TimeRangeHistogram(HistogramView view, Composite parent) {
58 super(view, parent);
59 fZoom = new HistogramZoom(this, getStartTime(), getTimeLimit());
60 addMouseWheelListener(fZoom);
61 }
62
63 // ------------------------------------------------------------------------
64 // Operations
65 // ------------------------------------------------------------------------
66
67 @Override
68 public synchronized void clear() {
69 fRangeStartTime = 0L;
70 fRangeDuration = 0L;
71 fFullRangeStartTime = 0L;
72 fFullRangeEndTime = 0L;
73 setOffset(0);
74 if (fZoom != null) {
75 fZoom.setFullRange(0L, 0L);
76 fZoom.setNewRange(0L, 0L);
77 }
78 super.clear();
79 }
80
81 /**
82 * Sets the time range of the histogram
83 * @param startTime The start time
84 * @param duration The duration of the time range
85 */
86 public synchronized void setTimeRange(long startTime, long duration) {
87 fRangeStartTime = startTime;
88 fRangeDuration = duration;
89 fZoom.setNewRange(startTime, duration);
90 if (getDataModel().getNbEvents() == 0) {
91 getDataModel().setTimeRange(startTime, startTime + duration);
92 getDataModel().setEndTime(startTime + duration);
93 }
94 }
95
96 /**
97 * Sets the full time range of the whole trace.
98 * @param startTime The start time
99 * @param endTime The end time
100 */
101 public void setFullRange(long startTime, long endTime) {
102 fFullRangeStartTime = startTime;
103 fFullRangeEndTime = endTime;
104 fZoom.setFullRange(startTime, endTime);
105 fZoom.setNewRange(fRangeStartTime, fRangeDuration);
106 }
107
108 // ------------------------------------------------------------------------
109 // MouseListener
110 // ------------------------------------------------------------------------
111
112 private int fStartPosition;
113 private int fMinOffset;
114 private int fMaxOffset;
115
116 @Override
117 public void mouseDown(MouseEvent event) {
118 if (fScaledData != null && fDragState == DRAG_NONE && fDataModel.getStartTime() < fDataModel.getEndTime()) {
119 if (event.button == 2 || (event.button == 1 && (event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL)) {
120 fDragState = DRAG_RANGE;
121 fDragButton = event.button;
122 fStartPosition = event.x;
123 long maxOffset = (fRangeStartTime - fFullRangeStartTime) / fScaledData.fBucketDuration;
124 long minOffset = (fRangeStartTime + fRangeDuration - fFullRangeEndTime) / fScaledData.fBucketDuration;
125 fMaxOffset = (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, maxOffset));
126 fMinOffset = (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, minOffset));
127 return;
128 } else if (event.button == 3) {
129 fDragState = DRAG_ZOOM;
130 fDragButton = event.button;
131 fRangeStartTime = Math.min(getTimestamp(event.x), getEndTime());
132 fRangeDuration = 0;
133 fCanvas.redraw();
134 return;
135 }
136 }
137 super.mouseDown(event);
138 }
139
140 @Override
141 public void mouseUp(MouseEvent event) {
142 if (fDragState == DRAG_RANGE && event.button == fDragButton) {
143 fDragState = DRAG_NONE;
144 fDragButton = 0;
145 if (event.x != fStartPosition) {
146 int nbBuckets = event.x - fStartPosition;
147 long delta = nbBuckets * fScaledData.fBucketDuration;
148 long startTime = fRangeStartTime - delta;
149 fRangeStartTime = Math.max(fFullRangeStartTime, Math.min(fFullRangeEndTime - fRangeDuration, startTime));
150 ((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fRangeDuration);
151 setOffset(0);
152 }
153 return;
154 } else if (fDragState == DRAG_ZOOM && event.button == fDragButton) {
155 fDragState = DRAG_NONE;
156 fDragButton = 0;
157 if (fRangeDuration < 0) {
158 fRangeStartTime = fRangeStartTime + fRangeDuration;
159 fRangeDuration = -fRangeDuration;
160 }
161 if (fRangeDuration > 0) {
162 ((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fRangeDuration);
163 } else {
164 fRangeStartTime = fZoom.getStartTime();
165 fRangeDuration = fZoom.getDuration();
166 fCanvas.redraw();
167 }
168 return;
169 }
170 super.mouseUp(event);
171 }
172
173 // ------------------------------------------------------------------------
174 // MouseMoveListener
175 // ------------------------------------------------------------------------
176
177 @Override
178 public void mouseMove(MouseEvent event) {
179 if (fDragState == DRAG_RANGE) {
180 int offset = Math.max(fMinOffset, Math.min(fMaxOffset, event.x - fStartPosition));
181 setOffset(offset);
182 fCanvas.redraw();
183 return;
184 } else if (fDragState == DRAG_ZOOM) {
185 long endTime = Math.max(getStartTime(), Math.min(getEndTime(), getTimestamp(event.x)));
186 fRangeDuration = endTime - fRangeStartTime;
187 fCanvas.redraw();
188 return;
189 }
190 super.mouseMove(event);
191 }
192
193 // ------------------------------------------------------------------------
194 // PaintListener
195 // ------------------------------------------------------------------------
196
197 @Override
198 public void paintControl(PaintEvent event) {
199 super.paintControl(event);
200
201 if (fDragState == DRAG_ZOOM) {
202 Image image = (Image) fCanvas.getData(IMAGE_KEY);
203 assert image != null;
204
205 Image rangeRectangleImage = new Image(image.getDevice(), image, SWT.IMAGE_COPY);
206 GC rangeWindowGC = new GC(rangeRectangleImage);
207
208 drawTimeRangeWindow(rangeWindowGC, fRangeStartTime, fRangeDuration);
209
210 // Draws the buffer image onto the canvas.
211 event.gc.drawImage(rangeRectangleImage, 0, 0);
212
213 rangeWindowGC.dispose();
214 rangeRectangleImage.dispose();
215 }
216 }
217
218 }
This page took 0.035846 seconds and 5 git commands to generate.