Integrate the TmfEvent+ITmfTimestamp API
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.ui / src / org / eclipse / linuxtools / lttng / ui / views / timeframe / SpinnerGroup.java
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:
10 * Francois Chouinard - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.lttng.ui.views.timeframe;
14
15 import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
16 import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
17 import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.events.ModifyEvent;
20 import org.eclipse.swt.events.ModifyListener;
21 import org.eclipse.swt.layout.GridData;
22 import org.eclipse.swt.widgets.Composite;
23 import org.eclipse.swt.widgets.Group;
24 import org.eclipse.swt.widgets.Label;
25 import org.eclipse.swt.widgets.Spinner;
26
27 // ========================================================================
28 // SpinnerGroup
29 // ========================================================================
30
31 /**
32 * <b><u>SpinnerGroup</u></b>
33 * <p>
34 * A SpinnerGroup holds two coordinated spinners (for seconds and
35 * nanoseconds) representing the current time within the trace.
36 * <p>
37 * The current time can take any value anything within the time range (start
38 * and end time).
39 */
40 public class SpinnerGroup {
41
42 // The nanosecond scale (10^9)
43 private static final int NS_PER_SECOND = 1000 * 1000 * 1000;
44 private static final byte NS_SCALING_FACTOR = -9;
45
46 // Labels
47 private static final String SECONDS_LABEL = "sec"; //$NON-NLS-1$
48 private static final String NANOSEC_LABEL = "ns"; //$NON-NLS-1$
49
50 // Widgets
51 private Group group;
52 private Spinner seconds;
53 private Spinner nanosec;
54
55 // The valid time range - start time
56 private ITmfTimestamp startTime;
57 private int startSeconds;
58 private int startNanosec;
59
60 // The valid time range - end time
61 private ITmfTimestamp endTime;
62 private int endSeconds;
63 private int endNanosec;
64
65 // The current time value
66 private ITmfTimestamp currentTime;
67 private int currentSeconds;
68 private int currentNanosec;
69
70 @SuppressWarnings("unused")
71 private TimeFrameView fOwner;
72
73 /**
74 * <b><u>Constructor</u></b>
75 * <p>
76 * <li>Creates the display group and formats it for the grid cell
77 * <li>Sets the initial values for Start/End/Current time
78 * </li>
79 * <p>
80 * @param parent - the parent Composite
81 * @param groupName - the group name
82 * @param range - the valid time range (start/end time)
83 * @param current - the current time
84 */
85 public SpinnerGroup(TimeFrameView owner, Composite parent, String groupName, TmfTimeRange range, ITmfTimestamp current) {
86
87 fOwner = owner;
88
89 // Create the group
90 group = new Group(parent, SWT.BORDER);
91 group.setText(groupName);
92
93 // Make it use the whole grid cell
94 GridData gridData = new GridData(SWT.LEFT, SWT.TOP, true, false);
95 gridData.horizontalAlignment = SWT.FILL;
96 group.setLayoutData(gridData);
97
98 // Create and position the widgets
99 seconds = new Spinner(group, SWT.BORDER);
100 seconds.addModifyListener(new ModifyListener() {
101 @Override
102 public void modifyText(ModifyEvent e) {
103 currentSeconds = seconds.getSelection();
104 refreshCurrentTime();
105 }
106 });
107 seconds.setBounds(5, 25, 110, 25);
108
109 Label label = new Label(group, SWT.LEFT);
110 label.setText(SECONDS_LABEL);
111 label.setBounds(120, 28, 25, 22);
112
113 nanosec = new Spinner(group, SWT.BORDER);
114 nanosec.addModifyListener(new ModifyListener() {
115 @Override
116 public void modifyText(ModifyEvent e) {
117 currentNanosec = nanosec.getSelection();
118 // Correct for nanosec underflow
119 if (currentNanosec < 0) {
120 currentSeconds--;
121 currentNanosec = NS_PER_SECOND - 1;
122 }
123 // Correct for nanosec overflow
124 if (currentNanosec >= NS_PER_SECOND) {
125 currentSeconds++;
126 currentNanosec = 0;
127 }
128 refreshCurrentTime();
129 }
130 });
131 nanosec.setBounds(150, 25, 110, 25);
132
133 label = new Label(group, SWT.LEFT);
134 label.setText(NANOSEC_LABEL);
135 label.setBounds(265, 28, 25, 22);
136
137 setContent(range, current);
138 }
139
140 private void refreshCurrentTime() {
141 long newCurrentTime = ((long) currentSeconds) * NS_PER_SECOND + currentNanosec;
142 TmfTimestamp ts = new TmfTimestamp(newCurrentTime, NS_SCALING_FACTOR, 0);
143 currentTime = ts;
144 // fOwner.synchTimeFrameWidgets(this);
145 }
146
147 // ====================================================================
148 // Get/Set
149 // ====================================================================
150
151 public ITmfTimestamp getStartTime() {
152 return startTime;
153 }
154
155 public ITmfTimestamp getEndTime() {
156 return endTime;
157 }
158
159 public ITmfTimestamp getCurrentTime() {
160 return currentTime;
161 }
162
163 public TmfTimestamp getSpan() {
164 TmfTimestamp span = (TmfTimestamp) startTime.getDelta(endTime);
165 return span;
166 }
167
168 public TmfTimeRange getTimeRange() {
169 TmfTimeRange range = new TmfTimeRange(startTime, endTime);
170 return range;
171 }
172
173 public void setStartTime(ITmfTimestamp ts) {
174 try {
175 startTime = (TmfTimestamp) ts.getDelta(new TmfTimestamp(0, NS_SCALING_FACTOR));
176 startSeconds = (int) (startTime.getValue() / NS_PER_SECOND);
177 startNanosec = (int) (startTime.getValue() % NS_PER_SECOND);
178 }
179 catch (ArithmeticException e) {
180 }
181 }
182
183 public void setEndTime(ITmfTimestamp ts) {
184 try {
185 endTime = (TmfTimestamp) ts.getDelta(new TmfTimestamp(0, NS_SCALING_FACTOR));
186 endSeconds = (int) (endTime.getValue() / NS_PER_SECOND);
187 endNanosec = (int) (endTime.getValue() % NS_PER_SECOND);
188 }
189 catch (ArithmeticException e) {
190 }
191 }
192
193 public void setCurrentTime(ITmfTimestamp ts) {
194 try {
195 currentTime = (TmfTimestamp) ts.getDelta(new TmfTimestamp(0, NS_SCALING_FACTOR));
196 currentSeconds = (int) (currentTime.getValue() / NS_PER_SECOND);
197 currentNanosec = (int) (currentTime.getValue() % NS_PER_SECOND);
198 }
199 catch (ArithmeticException e) {
200 }
201 }
202
203 // ====================================================================
204 // Operators
205 // ====================================================================
206
207 /**
208 * <b><u>setContent</u></b>
209 * <p>
210 * <li>validates that [startTime <= currentTime <= endTime] is respected
211 * <li>sets the start/current/end time and update the spinners
212 * </li>
213 * <p>
214 *
215 * @param range
216 * @param current
217 */
218 public void setContent(TmfTimeRange range, ITmfTimestamp current) {
219
220 if (range != null) {
221 // Extract the time range
222 ITmfTimestamp start = range.getStartTime();
223 ITmfTimestamp end = range.getEndTime();
224
225 // Assume start time is OK
226 setStartTime(start);
227
228 // Make sure end time >= start time
229 if (end.compareTo(start, false) < 0) {
230 end = start;
231 }
232 setEndTime(end);
233
234 // Make sure [start time <= current time <= end time]
235 // If not: current = min(max(start, current), end);
236 if (current.compareTo(start, false) < 0) {
237 current = start;
238 }
239 if (current.compareTo(end, false) > 0) {
240 current = end;
241 }
242 }
243 setCurrentTime(current);
244
245 // And configure the spinners
246 updateSpinners();
247 }
248
249 /**
250 * <b><u>setValue</u></b>
251 * <p>
252 * <li>validates that [startTime <= currentTime <= endTime] is respected
253 * <li>sets the current time and the spinners
254 * </li>
255 * <p>
256 *
257 * @param range
258 * @param current
259 */
260 public void setValue(ITmfTimestamp current) {
261
262 // Make sure [start time <= current time <= end time]
263 // If not: current = min(max(start, current), end);
264 if (current.compareTo(startTime, false) < 0) {
265 current = startTime;
266 }
267 if (current.compareTo(endTime, false) > 0) {
268 current = endTime;
269 }
270 setCurrentTime(current);
271
272 // And configure the spinners
273 updateSpinners();
274 }
275
276 /**
277 * Update the spinners with the new current time value
278 * Perform the update on the UI thread
279 */
280 public void updateSpinners() {
281 // Ignore update if disposed
282 if (seconds.isDisposed()) return;
283
284 seconds.getDisplay().asyncExec(new Runnable() {
285 @Override
286 public void run() {
287 if (!seconds.isDisposed() && !nanosec.isDisposed()) {
288 // If we are on the start second, ensure that [currentNS >= startNS]
289 // If the currentSeconds > startSeconds, set startns to -1 so we can
290 // "underflow"
291 int startns = -1;
292 if (currentSeconds <= startSeconds) {
293 currentSeconds = startSeconds;
294 startns = startNanosec;
295 if (currentNanosec < startns) {
296 currentNanosec = startns;
297 }
298 }
299
300 // If we are on the end second, ensure that [currentNS <= endNS]
301 // If the currentSeconds < endSeconds, set endns to MAX so we can
302 // "overflow"
303 int endns = NS_PER_SECOND;
304 if (currentSeconds >= endSeconds) {
305 currentSeconds = endSeconds;
306 endns = endNanosec;
307 if (currentNanosec > endns) {
308 currentNanosec = endns;
309 }
310 }
311
312 // Refresh the spinners (value, range, increments, ...)
313 // To ensure that the spinners are properly set, the range has to be > 0
314 // seconds.setValues(currentSeconds, startSeconds - 1, endSeconds + 1, 0, 1, 10);
315 // nanosec.setValues(currentNanosec, startns - 1, endns + 1, 0, 1, 1000000);
316 seconds.setValues(currentSeconds, startSeconds, endSeconds, 0, 1, 10);
317 nanosec.setValues(currentNanosec, startns, endns, 0, 100000, 10000000);
318
319 // If start == end (i.e. no range), disable the spinner
320 // (if start == end, the spinner widget range is set to [0..100] by default)
321 seconds.setEnabled(startSeconds != endSeconds);
322 nanosec.setEnabled(startns != endns);
323 }
324 }
325 });
326 }
327 }
This page took 0.039982 seconds and 5 git commands to generate.