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