2d248001096136f938994d2bd10aea2e2d7ebf65
[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 /**
71 * <b><u>Constructor</u></b>
72 * <p>
73 * <li>Creates the display group and formats it for the grid cell
74 * <li>Sets the initial values for Start/End/Current time
75 * </li>
76 * <p>
77 * @param parent - the parent Composite
78 * @param groupName - the group name
79 * @param range - the valid time range (start/end time)
80 * @param current - the current time
81 */
82 public SpinnerGroup(TimeFrameView owner, Composite parent, String groupName, TmfTimeRange range, ITmfTimestamp current) {
83
84 // Create the group
85 group = new Group(parent, SWT.BORDER);
86 group.setText(groupName);
87
88 // Make it use the whole grid cell
89 GridData gridData = new GridData(SWT.LEFT, SWT.TOP, true, false);
90 gridData.horizontalAlignment = SWT.FILL;
91 group.setLayoutData(gridData);
92
93 // Create and position the widgets
94 seconds = new Spinner(group, SWT.BORDER);
95 seconds.addModifyListener(new ModifyListener() {
96 @Override
97 public void modifyText(ModifyEvent e) {
98 currentSeconds = seconds.getSelection();
99 refreshCurrentTime();
100 }
101 });
102 seconds.setBounds(5, 25, 110, 25);
103
104 Label label = new Label(group, SWT.LEFT);
105 label.setText(SECONDS_LABEL);
106 label.setBounds(120, 28, 25, 22);
107
108 nanosec = new Spinner(group, SWT.BORDER);
109 nanosec.addModifyListener(new ModifyListener() {
110 @Override
111 public void modifyText(ModifyEvent e) {
112 currentNanosec = nanosec.getSelection();
113 // Correct for nanosec underflow
114 if (currentNanosec < 0) {
115 currentSeconds--;
116 currentNanosec = NS_PER_SECOND - 1;
117 }
118 // Correct for nanosec overflow
119 if (currentNanosec >= NS_PER_SECOND) {
120 currentSeconds++;
121 currentNanosec = 0;
122 }
123 refreshCurrentTime();
124 }
125 });
126 nanosec.setBounds(150, 25, 110, 25);
127
128 label = new Label(group, SWT.LEFT);
129 label.setText(NANOSEC_LABEL);
130 label.setBounds(265, 28, 25, 22);
131
132 setContent(range, current);
133 }
134
135 private void refreshCurrentTime() {
136 long newCurrentTime = ((long) currentSeconds) * NS_PER_SECOND + currentNanosec;
137 TmfTimestamp ts = new TmfTimestamp(newCurrentTime, NS_SCALING_FACTOR, 0);
138 currentTime = ts;
139 // fOwner.synchTimeFrameWidgets(this);
140 }
141
142 // ====================================================================
143 // Get/Set
144 // ====================================================================
145
146 public ITmfTimestamp getStartTime() {
147 return startTime;
148 }
149
150 public ITmfTimestamp getEndTime() {
151 return endTime;
152 }
153
154 public ITmfTimestamp getCurrentTime() {
155 return currentTime;
156 }
157
158 public TmfTimestamp getSpan() {
159 TmfTimestamp span = (TmfTimestamp) startTime.getDelta(endTime);
160 return span;
161 }
162
163 public TmfTimeRange getTimeRange() {
164 TmfTimeRange range = new TmfTimeRange(startTime, endTime);
165 return range;
166 }
167
168 public void setStartTime(ITmfTimestamp ts) {
169 try {
170 startTime = (TmfTimestamp) ts.getDelta(new TmfTimestamp(0, NS_SCALING_FACTOR));
171 startSeconds = (int) (startTime.getValue() / NS_PER_SECOND);
172 startNanosec = (int) (startTime.getValue() % NS_PER_SECOND);
173 }
174 catch (ArithmeticException e) {
175 }
176 }
177
178 public void setEndTime(ITmfTimestamp ts) {
179 try {
180 endTime = (TmfTimestamp) ts.getDelta(new TmfTimestamp(0, NS_SCALING_FACTOR));
181 endSeconds = (int) (endTime.getValue() / NS_PER_SECOND);
182 endNanosec = (int) (endTime.getValue() % NS_PER_SECOND);
183 }
184 catch (ArithmeticException e) {
185 }
186 }
187
188 public void setCurrentTime(ITmfTimestamp ts) {
189 try {
190 currentTime = (TmfTimestamp) ts.getDelta(new TmfTimestamp(0, NS_SCALING_FACTOR));
191 currentSeconds = (int) (currentTime.getValue() / NS_PER_SECOND);
192 currentNanosec = (int) (currentTime.getValue() % NS_PER_SECOND);
193 }
194 catch (ArithmeticException e) {
195 }
196 }
197
198 // ====================================================================
199 // Operators
200 // ====================================================================
201
202 /**
203 * <b><u>setContent</u></b>
204 * <p>
205 * <li>validates that [startTime <= currentTime <= endTime] is respected
206 * <li>sets the start/current/end time and update the spinners
207 * </li>
208 * <p>
209 *
210 * @param range
211 * @param current
212 */
213 public void setContent(TmfTimeRange range, ITmfTimestamp current) {
214
215 if (range != null) {
216 // Extract the time range
217 ITmfTimestamp start = range.getStartTime();
218 ITmfTimestamp end = range.getEndTime();
219
220 // Assume start time is OK
221 setStartTime(start);
222
223 // Make sure end time >= start time
224 if (end.compareTo(start, false) < 0) {
225 end = start;
226 }
227 setEndTime(end);
228
229 // Make sure [start time <= current time <= end time]
230 // If not: current = min(max(start, current), end);
231 if (current.compareTo(start, false) < 0) {
232 current = start;
233 }
234 if (current.compareTo(end, false) > 0) {
235 current = end;
236 }
237 }
238 setCurrentTime(current);
239
240 // And configure the spinners
241 updateSpinners();
242 }
243
244 /**
245 * <b><u>setValue</u></b>
246 * <p>
247 * <li>validates that [startTime <= currentTime <= endTime] is respected
248 * <li>sets the current time and the spinners
249 * </li>
250 * <p>
251 *
252 * @param range
253 * @param current
254 */
255 public void setValue(ITmfTimestamp current) {
256
257 // Make sure [start time <= current time <= end time]
258 // If not: current = min(max(start, current), end);
259 if (current.compareTo(startTime, false) < 0) {
260 current = startTime;
261 }
262 if (current.compareTo(endTime, false) > 0) {
263 current = endTime;
264 }
265 setCurrentTime(current);
266
267 // And configure the spinners
268 updateSpinners();
269 }
270
271 /**
272 * Update the spinners with the new current time value
273 * Perform the update on the UI thread
274 */
275 public void updateSpinners() {
276 // Ignore update if disposed
277 if (seconds.isDisposed()) return;
278
279 seconds.getDisplay().asyncExec(new Runnable() {
280 @Override
281 public void run() {
282 if (!seconds.isDisposed() && !nanosec.isDisposed()) {
283 // If we are on the start second, ensure that [currentNS >= startNS]
284 // If the currentSeconds > startSeconds, set startns to -1 so we can
285 // "underflow"
286 int startns = -1;
287 if (currentSeconds <= startSeconds) {
288 currentSeconds = startSeconds;
289 startns = startNanosec;
290 if (currentNanosec < startns) {
291 currentNanosec = startns;
292 }
293 }
294
295 // If we are on the end second, ensure that [currentNS <= endNS]
296 // If the currentSeconds < endSeconds, set endns to MAX so we can
297 // "overflow"
298 int endns = NS_PER_SECOND;
299 if (currentSeconds >= endSeconds) {
300 currentSeconds = endSeconds;
301 endns = endNanosec;
302 if (currentNanosec > endns) {
303 currentNanosec = endns;
304 }
305 }
306
307 // Refresh the spinners (value, range, increments, ...)
308 // To ensure that the spinners are properly set, the range has to be > 0
309 // seconds.setValues(currentSeconds, startSeconds - 1, endSeconds + 1, 0, 1, 10);
310 // nanosec.setValues(currentNanosec, startns - 1, endns + 1, 0, 1, 1000000);
311 seconds.setValues(currentSeconds, startSeconds, endSeconds, 0, 1, 10);
312 nanosec.setValues(currentNanosec, startns, endns, 0, 100000, 10000000);
313
314 // If start == end (i.e. no range), disable the spinner
315 // (if start == end, the spinner widget range is set to [0..100] by default)
316 seconds.setEnabled(startSeconds != endSeconds);
317 nanosec.setEnabled(startns != endns);
318 }
319 }
320 });
321 }
322 }
This page took 0.039615 seconds and 4 git commands to generate.