Internalize lttng.core APIs
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.ui / src / org / eclipse / linuxtools / lttng / ui / views / timeframe / SpinnerGroup.java
CommitLineData
6e512b93
ASL
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
13package org.eclipse.linuxtools.lttng.ui.views.timeframe;
14
4df4581d 15import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
6c13869b
FC
16import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
17import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
6e512b93
ASL
18import org.eclipse.swt.SWT;
19import org.eclipse.swt.events.ModifyEvent;
20import org.eclipse.swt.events.ModifyListener;
21import org.eclipse.swt.layout.GridData;
22import org.eclipse.swt.widgets.Composite;
23import org.eclipse.swt.widgets.Group;
24import org.eclipse.swt.widgets.Label;
25import 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 */
40public class SpinnerGroup {
41
42 // The nanosecond scale (10^9)
8d2e2848
FC
43 private static final int NS_PER_SECOND = 1000 * 1000 * 1000;
44 private static final byte NS_SCALING_FACTOR = -9;
6e512b93 45
62d1696a 46 // Labels
9c4eb5f7
FC
47 private static final String SECONDS_LABEL = "sec"; //$NON-NLS-1$
48 private static final String NANOSEC_LABEL = "ns"; //$NON-NLS-1$
62d1696a 49
6e512b93
ASL
50 // Widgets
51 private Group group;
52 private Spinner seconds;
53 private Spinner nanosec;
54
55 // The valid time range - start time
4df4581d 56 private ITmfTimestamp startTime;
6e512b93
ASL
57 private int startSeconds;
58 private int startNanosec;
59
60 // The valid time range - end time
4df4581d 61 private ITmfTimestamp endTime;
6e512b93
ASL
62 private int endSeconds;
63 private int endNanosec;
64
65 // The current time value
4df4581d 66 private ITmfTimestamp currentTime;
6e512b93
ASL
67 private int currentSeconds;
68 private int currentNanosec;
69
6e512b93
ASL
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 */
4df4581d 82 public SpinnerGroup(TimeFrameView owner, Composite parent, String groupName, TmfTimeRange range, ITmfTimestamp current) {
6e512b93 83
6e512b93
ASL
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() {
d4011df2
FC
96 @Override
97 public void modifyText(ModifyEvent e) {
6e512b93
ASL
98 currentSeconds = seconds.getSelection();
99 refreshCurrentTime();
100 }
101 });
102 seconds.setBounds(5, 25, 110, 25);
103
104 Label label = new Label(group, SWT.LEFT);
62d1696a 105 label.setText(SECONDS_LABEL);
6e512b93
ASL
106 label.setBounds(120, 28, 25, 22);
107
108 nanosec = new Spinner(group, SWT.BORDER);
109 nanosec.addModifyListener(new ModifyListener() {
d4011df2
FC
110 @Override
111 public void modifyText(ModifyEvent e) {
6e512b93
ASL
112 currentNanosec = nanosec.getSelection();
113 // Correct for nanosec underflow
114 if (currentNanosec < 0) {
115 currentSeconds--;
8d2e2848 116 currentNanosec = NS_PER_SECOND - 1;
6e512b93
ASL
117 }
118 // Correct for nanosec overflow
8d2e2848 119 if (currentNanosec >= NS_PER_SECOND) {
6e512b93
ASL
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);
62d1696a 129 label.setText(NANOSEC_LABEL);
6e512b93
ASL
130 label.setBounds(265, 28, 25, 22);
131
132 setContent(range, current);
133 }
134
135 private void refreshCurrentTime() {
8d2e2848
FC
136 long newCurrentTime = ((long) currentSeconds) * NS_PER_SECOND + currentNanosec;
137 TmfTimestamp ts = new TmfTimestamp(newCurrentTime, NS_SCALING_FACTOR, 0);
6e512b93 138 currentTime = ts;
09acd610 139// fOwner.synchTimeFrameWidgets(this);
6e512b93
ASL
140 }
141
142 // ====================================================================
143 // Get/Set
144 // ====================================================================
145
4df4581d 146 public ITmfTimestamp getStartTime() {
6e512b93
ASL
147 return startTime;
148 }
149
4df4581d 150 public ITmfTimestamp getEndTime() {
6e512b93
ASL
151 return endTime;
152 }
153
4df4581d 154 public ITmfTimestamp getCurrentTime() {
6e512b93
ASL
155 return currentTime;
156 }
157
158 public TmfTimestamp getSpan() {
5179fc01 159 TmfTimestamp span = (TmfTimestamp) startTime.getDelta(endTime);
6e512b93
ASL
160 return span;
161 }
162
163 public TmfTimeRange getTimeRange() {
164 TmfTimeRange range = new TmfTimeRange(startTime, endTime);
165 return range;
166 }
167
4df4581d 168 public void setStartTime(ITmfTimestamp ts) {
62d1696a 169 try {
5179fc01 170 startTime = (TmfTimestamp) ts.getDelta(new TmfTimestamp(0, NS_SCALING_FACTOR));
8d2e2848
FC
171 startSeconds = (int) (startTime.getValue() / NS_PER_SECOND);
172 startNanosec = (int) (startTime.getValue() % NS_PER_SECOND);
62d1696a
FC
173 }
174 catch (ArithmeticException e) {
175 }
6e512b93
ASL
176 }
177
4df4581d 178 public void setEndTime(ITmfTimestamp ts) {
62d1696a 179 try {
5179fc01 180 endTime = (TmfTimestamp) ts.getDelta(new TmfTimestamp(0, NS_SCALING_FACTOR));
8d2e2848
FC
181 endSeconds = (int) (endTime.getValue() / NS_PER_SECOND);
182 endNanosec = (int) (endTime.getValue() % NS_PER_SECOND);
62d1696a
FC
183 }
184 catch (ArithmeticException e) {
185 }
6e512b93
ASL
186 }
187
4df4581d 188 public void setCurrentTime(ITmfTimestamp ts) {
62d1696a 189 try {
5179fc01 190 currentTime = (TmfTimestamp) ts.getDelta(new TmfTimestamp(0, NS_SCALING_FACTOR));
8d2e2848
FC
191 currentSeconds = (int) (currentTime.getValue() / NS_PER_SECOND);
192 currentNanosec = (int) (currentTime.getValue() % NS_PER_SECOND);
62d1696a
FC
193 }
194 catch (ArithmeticException e) {
195 }
6e512b93
ASL
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 */
4df4581d 213 public void setContent(TmfTimeRange range, ITmfTimestamp current) {
6e512b93
ASL
214
215 if (range != null) {
216 // Extract the time range
4df4581d 217 ITmfTimestamp start = range.getStartTime();
218 ITmfTimestamp end = range.getEndTime();
6e512b93
ASL
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 */
4df4581d 255 public void setValue(ITmfTimestamp current) {
6e512b93
ASL
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() {
db1ea19b
FC
276 // Ignore update if disposed
277 if (seconds.isDisposed()) return;
278
6e512b93 279 seconds.getDisplay().asyncExec(new Runnable() {
d4011df2 280 @Override
6e512b93
ASL
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"
8d2e2848 298 int endns = NS_PER_SECOND;
6e512b93
ASL
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
09acd610
FC
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);
6e512b93
ASL
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 }
bf5aa8e4 322}
This page took 0.044808 seconds and 5 git commands to generate.