2010-10-27 Francois Chouinard <fchouinard@gmail.com> Contribution for Bug316467
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.ui / src / org / eclipse / linuxtools / lttng / ui / views / histogram / TimeTextGroup.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.histogram;
14
15import org.eclipse.swt.SWT;
16import org.eclipse.swt.events.FocusEvent;
17import org.eclipse.swt.events.FocusListener;
18import org.eclipse.swt.events.KeyEvent;
19import org.eclipse.swt.events.KeyListener;
20import org.eclipse.swt.graphics.Font;
21import org.eclipse.swt.graphics.FontData;
22import org.eclipse.swt.layout.GridData;
23import org.eclipse.swt.layout.GridLayout;
24import org.eclipse.swt.widgets.Composite;
25import org.eclipse.swt.widgets.Display;
26import org.eclipse.swt.widgets.Group;
27import org.eclipse.swt.widgets.Label;
28import org.eclipse.swt.widgets.Text;
29
544fe9b7
WB
30/**
31 * <b><u>TimeTextGroup</u></b>
32 * <p>
33 * Special control for HistogramView
34 * <p>
35 * This control will give you a group, a text box and a label at once.
36 */
6e512b93 37public class TimeTextGroup implements FocusListener, KeyListener {
3e9fdb8b
FC
38
39/*
40 // 2010-06-10 Yuriy: Has been moved to header into HistogramView.java
7c1540ab 41 protected static final String NANOSEC_LABEL = "sec";
3e9fdb8b 42*/
f05aabed
FC
43 private static final String LONGEST_STRING_VALUE = "." + Long.MAX_VALUE;
44 private static final int MAX_CHAR_IN_TEXTBOX = LONGEST_STRING_VALUE.length();
6e512b93 45
82513d52 46 // The "small font" height used to display time will be "default font" minus this constant
f05aabed
FC
47 private static final int VERY_SMALL_FONT_MODIFIER = 2;
48 private static final int SMALL_FONT_MODIFIER = 1;
82513d52 49
7c1540ab 50 // Indentation size
1a971e96 51// private static final int DEFAULT_INDENT_SIZE = 10;
6e512b93 52
f05aabed
FC
53 private HistogramView parentView = null;
54 private AsyncTimeTextGroupRedrawer asyncRedrawer = null;
6e512b93 55
f05aabed
FC
56 private Group grpName = null;
57 private Text txtNanosec = null;
58 private Label lblNanosec = null;
7c1540ab 59
f05aabed 60 private long timeValue = 0L;
6e512b93 61
544fe9b7
WB
62 /**
63 * Default Constructor.<p>
64 *
65 * @param newParentView Parent HistogramView
66 * @param parent Parent Composite, used to position the inner controls.
67 * @param textStyle Style of the textbox. Usually SWT.BORDER or SWT.NONE (or anything that suit a Text)
68 * @param groupStyle Style of the group. Anything that suite a Text
69 */
6e512b93 70 public TimeTextGroup(HistogramView newParentView, Composite parent, int textStyle, int groupStyle) {
7c1540ab
WB
71 this(newParentView, parent, textStyle, groupStyle, "", HistogramConstant.formatNanoSecondsTime(0L), false);
72 }
73
74 /**
75 * Default Constructor with adjustement for small screen.<p>
76 *
77 * @param newParentView Parent HistogramView
78 * @param parent Parent Composite, used to position the inner controls.
79 * @param textStyle Style of the textbox. Usually SWT.BORDER or SWT.NONE (or anything that suit a Text)
80 * @param groupStyle Style of the group. Anything that suite a Text
81 * @param isSpaceSaverNeeded Value that tell if we try to save some space in the control.
82 */
83 public TimeTextGroup(HistogramView newParentView, Composite parent, int textStyle, int groupStyle, boolean isSpaceSaverNeeded) {
84 this(newParentView, parent, textStyle, groupStyle, "", HistogramConstant.formatNanoSecondsTime(0L), isSpaceSaverNeeded);
6e512b93
ASL
85 }
86
544fe9b7
WB
87 /**
88 * Default Constructor, allow you to give the groupname and the textbox value.<p>
89 *
90 * @param newParentView Parent HistogramView
91 * @param parent Parent Composite, used to position the inner controls.
92 * @param textStyle Style of the textbox. Usually SWT.BORDER or SWT.NONE (or anything that suit a Text)
93 * @param groupStyle Style of the group. Anything that suite a Text
94 * @param groupValue Value (label) of the group.
95 * @param textValue Value of the textbox.
96 */
6e512b93 97 public TimeTextGroup(HistogramView newParentView, Composite parent, int textStyle, int groupStyle, String groupValue, String textValue) {
7c1540ab
WB
98 this(newParentView, parent, textStyle, groupStyle, groupValue, textValue, false);
99 }
100
101 /**
1a971e96
FC
102 * Default Constructor with adjustment for small screen, allow you to give the group name and the text box value.<p>
103 *
7c1540ab
WB
104 * @param newParentView Parent HistogramView
105 * @param parent Parent Composite, used to position the inner controls.
1a971e96 106 * @param textStyle Style of the text box. Usually SWT.BORDER or SWT.NONE (or anything that suit a Text)
7c1540ab
WB
107 * @param groupStyle Style of the group. Anything that suite a Text
108 * @param groupValue Value (label) of the group.
1a971e96 109 * @param textValue Value of the text box.
7c1540ab
WB
110 * @param isSpaceSaverNeeded Value that tell if we try to save some space in the control.
111 */
112 public TimeTextGroup(HistogramView newParentView, Composite parent, int textStyle, int groupStyle, String groupValue, String textValue, boolean isSpaceSaverNeeded) {
6e512b93
ASL
113 Font font = parent.getFont();
114 FontData tmpFontData = font.getFontData()[0];
7c1540ab
WB
115
116 Font smallFont = null;
117 int textBoxSize = -1;
1a971e96 118// int indentSize = -1;
7c1540ab
WB
119
120 // If we were asked to save size, calculate the correct value here
121 if ( isSpaceSaverNeeded == true ) {
122 smallFont = new Font(font.getDevice(), tmpFontData.getName(), tmpFontData.getHeight()-VERY_SMALL_FONT_MODIFIER, tmpFontData.getStyle());
123
124 // No minimum textBoxSize and no indent size
125 textBoxSize = 0;
1a971e96 126// indentSize = 0;
7c1540ab
WB
127 }
128 else {
129 // We use only a slightly smaller font
130 smallFont = new Font(font.getDevice(), tmpFontData.getName(), tmpFontData.getHeight()-SMALL_FONT_MODIFIER, tmpFontData.getStyle());
131
132 // ** Creation of the textbox
133 // Calculate the optimal size of the textbox already
134 // This will avoid the control to move around and resize when bigger value are given
135 textBoxSize = HistogramConstant.getTextSizeInControl(parent, LONGEST_STRING_VALUE);
136
137 // Default indent
1a971e96 138// indentSize = DEFAULT_INDENT_SIZE;
7c1540ab
WB
139 }
140
6e512b93
ASL
141 parentView = newParentView;
142
544fe9b7 143 // ** Creation of the group
1a971e96
FC
144// GridLayout gridLayoutgroup = new GridLayout(2, false);
145 GridLayout gridLayoutgroup = new GridLayout(1, false);
82513d52
WB
146 gridLayoutgroup.horizontalSpacing = 0;
147 gridLayoutgroup.verticalSpacing = 0;
6e512b93
ASL
148 grpName = new Group(parent, groupStyle);
149 grpName.setText(groupValue);
150 grpName.setFont(smallFont);
82513d52 151 grpName.setLayout(gridLayoutgroup);
6e512b93
ASL
152
153 txtNanosec = new Text(grpName, textStyle);
154 txtNanosec.setTextLimit( MAX_CHAR_IN_TEXTBOX );
1a971e96 155 txtNanosec.setText(textValue);
82513d52
WB
156 txtNanosec.setFont(smallFont);
157 GridData gridDataTextBox = new GridData(SWT.LEFT, SWT.CENTER, true, false);
1a971e96 158 gridDataTextBox.horizontalIndent = 0; // indentSize;
82513d52 159 gridDataTextBox.verticalIndent = 0;
6e512b93
ASL
160 gridDataTextBox.minimumWidth = textBoxSize;
161 txtNanosec.setLayoutData(gridDataTextBox);
162
544fe9b7 163 // ** Creation of the label
3e9fdb8b 164/*
6e512b93
ASL
165 lblNanosec = new Label(grpName, SWT.LEFT);
166 lblNanosec.setText(NANOSEC_LABEL);
167 lblNanosec.setFont(smallFont);
82513d52 168 GridData gridDataLabel = new GridData(SWT.LEFT, SWT.CENTER, false, false);
7c1540ab 169 gridDataLabel.horizontalIndent = indentSize;
82513d52
WB
170 gridDataLabel.verticalIndent = 0;
171 lblNanosec.setLayoutData(gridDataLabel);
3e9fdb8b 172*/
6e512b93 173
544fe9b7 174 // Add all listener
6e512b93
ASL
175 addNeededListeners();
176 }
177
544fe9b7
WB
178 /*
179 * Create and add all listeners needed by our control.<p>
180 */
7c1540ab 181 protected void addNeededListeners() {
6e512b93
ASL
182
183 // AsyncCanvasRedrawer is an internal class
184 // This is used to redraw the canvas without danger from a different thread
185 asyncRedrawer = new AsyncTimeTextGroupRedrawer(this);
186
187 txtNanosec.addFocusListener(this);
188 txtNanosec.addKeyListener(this);
189 }
190
544fe9b7
WB
191 /**
192 * Getter for the layout data currently in use.<p>
193 *
194 * @return the layout
195 */
196 public Object getLayoutData() {
197 return grpName.getLayoutData();
198 }
6e512b93 199
544fe9b7
WB
200 /**
201 * Set a new layoutData for our control.<p>
202 *
203 * @param layoutData the new layout data
204 */
6e512b93
ASL
205 public void setLayoutData(Object layoutData) {
206 grpName.setLayoutData(layoutData);
207 }
208
544fe9b7
WB
209 /**
210 * Get the control's parent.<p>
211 *
212 * @return Currently used parent
213 */
6e512b93
ASL
214 public Composite getParent() {
215 return grpName.getParent();
216 }
217
544fe9b7
WB
218 /**
219 * Set a new parent for the control.<p>
220 *
221 * @return Currently used parent
222 */
6e512b93
ASL
223 public void setParent(Composite newParent) {
224 grpName.setParent(newParent);
225 txtNanosec.setParent(newParent);
226 lblNanosec.setParent(newParent);
227 }
228
c1c69938
FC
229
230 public boolean isDisposed() {
231 return grpName.isDisposed();
232 }
233
544fe9b7
WB
234 /**
235 * Getter for the time value of the control.<p>
236 *
237 * @return The nanoseconds time value
238 */
1406f802 239 public long getValue() {
6e512b93
ASL
240 return timeValue;
241 }
242
544fe9b7
WB
243 /**
244 * Set a new String value to the control.<p>
1406f802 245 * Note : The String value will be converted in long before being applied;
544fe9b7
WB
246 * if any conversion error occur, 0 will be used. <p>
247 *
248 * @param newTimeAsString The value to convert and set.
249 */
250 public void setValue(String newTimeAsString) {
1406f802 251 long timeAsLong = HistogramConstant.convertStringToNanoseconds(newTimeAsString);
544fe9b7
WB
252 setValue( timeAsLong );
253 }
6e512b93 254
544fe9b7
WB
255 /**
256 * Set a new value to the control.<p>
257 * Note : The value will be formatted as nanosecond value,
258 * missing zero will be added if needed.<p>
259 *
260 * @param newTime The value to set.
261 */
1406f802 262 public void setValue(long newTime) {
544fe9b7
WB
263 timeValue = newTime;
264 txtNanosec.setText( HistogramConstant.formatNanoSecondsTime(newTime) );
265 }
266
267 /**
268 * Set a new String value, asynchronously.<p>
269 * This will call setValue(String) in async.Exec to avoid Thread Access problem to UI.<p>
270 *
271 * @param newTimeAsString The value to convert and set.
272 */
6e512b93 273 public void setValueAsynchronously(String newTimeAsString) {
1406f802 274 long timeAsLong = HistogramConstant.convertStringToNanoseconds(newTimeAsString);
6e512b93
ASL
275 setValueAsynchronously( timeAsLong );
276 }
277
544fe9b7
WB
278 /**
279 * Set a new String value, asynchronously.<p>
1406f802 280 * This will call setValue(long) in async.Exec to avoid Thread Access problem to UI.<p>
544fe9b7
WB
281 *
282 * @param newTimeAsString The value to set.
283 */
1406f802 284 public void setValueAsynchronously(long newTime) {
6e512b93
ASL
285 // Set the correct value ASAP
286 timeValue = newTime;
287
288 // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
289 if ( asyncRedrawer == null ) {
290 asyncRedrawer = new AsyncTimeTextGroupRedrawer(this);
291 }
292
293 asyncRedrawer.asynchronousSetValue(newTime);
294 }
295
544fe9b7
WB
296 /**
297 * Set a new group name (label) for this control.<p>
298 *
299 * @param newName The new name to set.
300 */
301 public void setGroupName(String newName) {
302 grpName.setText(newName);
6e512b93
ASL
303 }
304
544fe9b7
WB
305 /**
306 * Set a new group name (label) for this control, asynchronously.<p>
1406f802 307 * This will call setValue(long) in async.Exec to avoid Thread Access problem to UI.<p>
544fe9b7
WB
308 *
309 * @param newName The new name to set.
310 */
311 public void setGroupNameAsynchronously(String newGroupName) {
312 // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
313 if ( asyncRedrawer == null ) {
314 asyncRedrawer = new AsyncTimeTextGroupRedrawer(this);
315 }
316
317 asyncRedrawer.asynchronousSetGroupName(newGroupName);
088c1d4e 318 }
6e512b93 319
544fe9b7
WB
320
321 /**
322 * Method to call the "Asynchronous redrawer" for this time text group<p>
323 * This allow safe redraw from different threads.
324 */
325 public void redrawAsynchronously() {
326 // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
327 if ( asyncRedrawer == null ) {
328 asyncRedrawer = new AsyncTimeTextGroupRedrawer(this);
329 }
330
331 asyncRedrawer.asynchronousRedraw();
332 }
333
334 /**
335 * Redraw the control
336 */
337 public void redraw () {
338 grpName.redraw();
339 txtNanosec.redraw();
340 lblNanosec.redraw();
341 }
342
343 /*
344 * This function is called when an user enter a new string in the control by hand.<p>
345 * It will ensure the format of the String is valid.
346 */
7c1540ab 347 protected void handleNewStringValue() {
6e512b93 348 String valueInText = txtNanosec.getText();
1406f802 349 long valueAsLong = HistogramConstant.convertStringToNanoseconds(valueInText);
6e512b93
ASL
350
351 if ( getValue() != valueAsLong ) {
352 setValue(valueAsLong);
544fe9b7 353 // Notify our parent that the control was updated
6e512b93
ASL
354 notifyParentUpdatedTextGroupValue();
355 }
356 }
357
544fe9b7
WB
358 /**
359 * This function notify our parent HistogramView that our value changed.
360 */
6e512b93
ASL
361 public void notifyParentUpdatedTextGroupValue() {
362 parentView.timeTextGroupChangeNotification();
363 }
364
544fe9b7
WB
365 /**
366 * Function that is called when the canvas get focus.<p>
367 *
368 * Doesn't do anything yet...
369 *
370 * @param event The focus event generated.
371 */
d4011df2 372 @Override
6e512b93
ASL
373 public void focusGained(FocusEvent event) {
374 // Nothing to do yet
375 }
376
544fe9b7
WB
377 /**
378 * Function that is called when the canvas loose focus.<p>
379 * It will validate that the String entered by the user (if any) is valid.<p>
380 *
381 * @param event The focus event generated.
382 */
d4011df2 383 @Override
6e512b93
ASL
384 public void focusLost(FocusEvent event) {
385 handleNewStringValue();
386 }
387
544fe9b7
WB
388 /**
389 * Function that is called when a key is pressed.<p>
390 * Possible actions :
391 * - Enter (CR) : Validate the entered String.<p>
392 *
393 * @param event The KeyEvent generated when the key was pressed.
394 */
d4011df2 395 @Override
6e512b93
ASL
396 public void keyPressed(KeyEvent event) {
397 switch (event.keyCode) {
398 // SWT.CR is "ENTER" Key
399 case SWT.CR:
400 handleNewStringValue();
401 break;
402 default:
403 break;
404 }
405 }
406
407 /**
544fe9b7
WB
408 * Function that is called when a key is released.<p>
409 * Possible actions :
410 * Nothing yet
6e512b93 411 *
544fe9b7 412 * @param event The KeyEvent generated when the key was pressed.
6e512b93 413 */
d4011df2 414 @Override
544fe9b7 415 public void keyReleased(KeyEvent e) {
6e512b93
ASL
416
417 }
418}
419
420/**
421 * <b><u>AsyncTimeTextGroupRedrawer Inner Class</u></b>
422 * <p>
423 * Asynchronous redrawer for the TimeTextGroup
424 * <p>
425 * This class role is to call method that update the UI on asynchronously.
426 * This should prevent any "invalid thread access" exception when trying to update UI from a different thread.
427 */
428class AsyncTimeTextGroupRedrawer {
429
430 private TimeTextGroup parentTimeTextGroup = null;
431
432 /**
433 * AsyncTimeTextGroupRedrawer constructor.
434 *
435 * @param newParent Related time text group.
436 */
437 public AsyncTimeTextGroupRedrawer(TimeTextGroup newParent) {
438 parentTimeTextGroup = newParent;
439 }
440
441 /**
544fe9b7 442 * Asynchronous SetValue for time text group.
6e512b93
ASL
443 *
444 * Basically, it just run "getParent().setValue(time)" in asyncExec.
445 *
446 * @param newTime The new time to set
447 */
1a971e96 448 public void asynchronousSetValue(final long newTime) {
db1ea19b 449 // Ignore setting of value if widget is disposed
c1c69938 450 if (parentTimeTextGroup.isDisposed()) return;
db1ea19b 451
6e512b93
ASL
452 Display display = parentTimeTextGroup.getParent().getDisplay();
453 display.asyncExec(new Runnable() {
d4011df2 454 @Override
c1c69938
FC
455 public void run() {
456 if (!parentTimeTextGroup.isDisposed()) {
1a971e96 457 parentTimeTextGroup.setValue(newTime);
db1ea19b 458 }
6e512b93
ASL
459 }
460 });
461 }
462
544fe9b7
WB
463 /**
464 * Asynchronous SetGroupName for time text group.
465 *
466 * Basically, it just run "getParent().setGroupName(name)" in asyncExec.
467 *
468 * @param newGroupName The new group name to set
469 */
470 public void asynchronousSetGroupName(String newGroupName) {
db1ea19b 471 // Ignore setting of name if widget is disposed
c1c69938 472 if (parentTimeTextGroup.isDisposed()) return;
db1ea19b 473
544fe9b7 474 final String tmpName = newGroupName;
544fe9b7
WB
475 Display display = parentTimeTextGroup.getParent().getDisplay();
476 display.asyncExec(new Runnable() {
d4011df2 477 @Override
c1c69938
FC
478 public void run() {
479 if (!parentTimeTextGroup.isDisposed()) {
db1ea19b
FC
480 parentTimeTextGroup.setGroupName(tmpName);
481 }
544fe9b7
WB
482 }
483 });
484 }
485
6e512b93
ASL
486 /**
487 * Function to redraw the related time text group asynchonously.<p>
488 *
489 * Basically, it just run "getParent().redraw()" in asyncExec.
490 *
491 */
492 public void asynchronousRedraw() {
db1ea19b 493 // Ignore redraw if widget is disposed
c1c69938 494 if (parentTimeTextGroup.isDisposed()) return;
db1ea19b 495
6e512b93
ASL
496 Display display = parentTimeTextGroup.getParent().getDisplay();
497 display.asyncExec(new Runnable() {
d4011df2 498 @Override
c1c69938
FC
499 public void run() {
500 if (!parentTimeTextGroup.isDisposed()) {
db1ea19b
FC
501 parentTimeTextGroup.getParent().redraw();
502 }
6e512b93
ASL
503 }
504 });
505 }
506}
This page took 0.05517 seconds and 5 git commands to generate.