Source code: org/eclipse/swt/widgets/Scale.java
1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.swt.widgets;
12
13
14 import org.eclipse.swt.*;
15 import org.eclipse.swt.internal.gtk.*;
16 import org.eclipse.swt.graphics.*;
17 import org.eclipse.swt.events.*;
18
19 /**
20 * Instances of the receiver represent a selectable user
21 * interface object that present a range of continuous
22 * numeric values.
23 * <dl>
24 * <dt><b>Styles:</b></dt>
25 * <dd>HORIZONTAL, VERTICAL</dd>
26 * <dt><b>Events:</b></dt>
27 * <dd>Selection</dd>
28 * </dl>
29 * <p>
30 * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
31 * </p><p>
32 * <p>
33 * IMPORTANT: This class is intended to be subclassed <em>only</em>
34 * within the SWT implementation.
35 * </p>
36 */
37 public class Scale extends Control {
38
39 /**
40 * Constructs a new instance of this class given its parent
41 * and a style value describing its behavior and appearance.
42 * <p>
43 * The style value is either one of the style constants defined in
44 * class <code>SWT</code> which is applicable to instances of this
45 * class, or must be built by <em>bitwise OR</em>'ing together
46 * (that is, using the <code>int</code> "|" operator) two or more
47 * of those <code>SWT</code> style constants. The class description
48 * lists the style constants that are applicable to the class.
49 * Style bits are also inherited from superclasses.
50 * </p>
51 *
52 * @param parent a composite control which will be the parent of the new instance (cannot be null)
53 * @param style the style of control to construct
54 *
55 * @exception IllegalArgumentException <ul>
56 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
57 * </ul>
58 * @exception SWTException <ul>
59 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
60 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
61 * </ul>
62 *
63 * @see SWT#HORIZONTAL
64 * @see SWT#VERTICAL
65 * @see Widget#checkSubclass
66 * @see Widget#getStyle
67 */
68 public Scale (Composite parent, int style) {
69 super (parent, checkStyle (style));
70 }
71
72 /**
73 * Adds the listener to the collection of listeners who will
74 * be notified when the receiver's value changes, by sending
75 * it one of the messages defined in the <code>SelectionListener</code>
76 * interface.
77 *
78 * @param listener the listener which should be notified
79 *
80 * @exception IllegalArgumentException <ul>
81 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
82 * </ul>
83 * @exception SWTException <ul>
84 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
85 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
86 * </ul>
87 *
88 * @see SelectionListener
89 * @see #removeSelectionListener
90 */
91 public void addSelectionListener (SelectionListener listener) {
92 checkWidget ();
93 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
94 TypedListener typedListener = new TypedListener (listener);
95 addListener (SWT.Selection,typedListener);
96 addListener (SWT.DefaultSelection,typedListener);
97 }
98
99 static int checkStyle (int style) {
100 return checkBits (style, SWT.HORIZONTAL, SWT.VERTICAL, 0, 0, 0, 0);
101 }
102
103 public Point computeSize (int wHint, int hHint, boolean changed) {
104 checkWidget();
105 if (wHint != SWT.DEFAULT && wHint < 0) wHint = 0;
106 if (hHint != SWT.DEFAULT && hHint < 0) hHint = 0;
107 Point size = computeNativeSize(handle, wHint, hHint, changed);
108 if ((style & SWT.HORIZONTAL) != 0) {
109 if (wHint == SWT.DEFAULT) size.x = 2 * size.x;
110 } else {
111 if (hHint == SWT.DEFAULT) size.y = 2 * size.y;
112 }
113 return size;
114 }
115
116 void createHandle (int index) {
117 state |= HANDLE;
118 fixedHandle = OS.gtk_fixed_new ();
119 if (fixedHandle == 0) error (SWT.ERROR_NO_HANDLES);
120 OS.gtk_fixed_set_has_window (fixedHandle, true);
121 long /*int*/ hAdjustment = OS.gtk_adjustment_new (0, 0, 100, 1, 10, 0);
122 if (hAdjustment == 0) error (SWT.ERROR_NO_HANDLES);
123 if ((style & SWT.HORIZONTAL) != 0) {
124 handle = OS.gtk_hscale_new (hAdjustment);
125 } else {
126 handle = OS.gtk_vscale_new (hAdjustment);
127 }
128 if (handle == 0) error (SWT.ERROR_NO_HANDLES);
129 long /*int*/ parentHandle = parent.parentingHandle ();
130 OS.gtk_container_add (parentHandle, fixedHandle);
131 OS.gtk_container_add (fixedHandle, handle);
132 OS.gtk_widget_show (fixedHandle);
133 OS.gtk_widget_show (handle);
134 OS.gtk_scale_set_digits (handle, 0);
135 OS.gtk_scale_set_draw_value (handle, false);
136 }
137
138 void hookEvents () {
139 super.hookEvents ();
140 OS.g_signal_connect (handle, OS.value_changed, display.windowProc2, VALUE_CHANGED);
141 }
142
143 /**
144 * Returns the amount that the receiver's value will be
145 * modified by when the up/down (or right/left) arrows
146 * are pressed.
147 *
148 * @return the increment
149 *
150 * @exception SWTException <ul>
151 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
152 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
153 * </ul>
154 */
155 public int getIncrement () {
156 checkWidget ();
157 long /*int*/ hAdjustment = OS.gtk_range_get_adjustment (handle);
158 GtkAdjustment adjustment = new GtkAdjustment ();
159 OS.memmove (adjustment, hAdjustment);
160 return (int) adjustment.step_increment;
161 }
162
163 /**
164 * Returns the maximum value which the receiver will allow.
165 *
166 * @return the maximum
167 *
168 * @exception SWTException <ul>
169 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
170 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
171 * </ul>
172 */
173 public int getMaximum () {
174 checkWidget ();
175 long /*int*/ hAdjustment = OS.gtk_range_get_adjustment (handle);
176 GtkAdjustment adjustment = new GtkAdjustment ();
177 OS.memmove (adjustment, hAdjustment);
178 return (int) adjustment.upper;
179 }
180
181 /**
182 * Returns the minimum value which the receiver will allow.
183 *
184 * @return the minimum
185 *
186 * @exception SWTException <ul>
187 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
188 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
189 * </ul>
190 */
191 public int getMinimum () {
192 checkWidget ();
193 long /*int*/ hAdjustment = OS.gtk_range_get_adjustment (handle);
194 GtkAdjustment adjustment = new GtkAdjustment ();
195 OS.memmove (adjustment, hAdjustment);
196 return (int) adjustment.lower;
197 }
198
199 /**
200 * Returns the amount that the receiver's value will be
201 * modified by when the page increment/decrement areas
202 * are selected.
203 *
204 * @return the page increment
205 *
206 * @exception SWTException <ul>
207 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
208 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
209 * </ul>
210 */
211 public int getPageIncrement () {
212 checkWidget ();
213 long /*int*/ hAdjustment = OS.gtk_range_get_adjustment (handle);
214 GtkAdjustment adjustment = new GtkAdjustment ();
215 OS.memmove (adjustment, hAdjustment);
216 return (int) adjustment.page_increment;
217 }
218
219 /**
220 * Returns the single <em>selection</em> that is the receiver's position.
221 *
222 * @return the selection
223 *
224 * @exception SWTException <ul>
225 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
226 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
227 * </ul>
228 */
229 public int getSelection () {
230 checkWidget ();
231 long /*int*/ hAdjustment = OS.gtk_range_get_adjustment (handle);
232 GtkAdjustment adjustment = new GtkAdjustment ();
233 OS.memmove (adjustment, hAdjustment);
234 return (int) adjustment.value;
235 }
236
237 long /*int*/ gtk_value_changed (long /*int*/ adjustment) {
238 postEvent (SWT.Selection);
239 return 0;
240 }
241
242 /**
243 * Removes the listener from the collection of listeners who will
244 * be notified when the receiver's value changes.
245 *
246 * @param listener the listener which should no longer be notified
247 *
248 * @exception IllegalArgumentException <ul>
249 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
250 * </ul>
251 * @exception SWTException <ul>
252 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
253 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
254 * </ul>
255 *
256 * @see SelectionListener
257 * @see #addSelectionListener
258 */
259 public void removeSelectionListener (SelectionListener listener) {
260 checkWidget ();
261 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
262 if (eventTable == null) return;
263 eventTable.unhook (SWT.Selection, listener);
264 eventTable.unhook (SWT.DefaultSelection,listener);
265 }
266
267 /**
268 * Sets the amount that the receiver's value will be
269 * modified by when the up/down (or right/left) arrows
270 * are pressed to the argument, which must be at least
271 * one.
272 *
273 * @param increment the new increment (must be greater than zero)
274 *
275 * @exception SWTException <ul>
276 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
277 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
278 * </ul>
279 */
280 public void setIncrement (int value) {
281 checkWidget ();
282 if (value < 1) return;
283 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
284 OS.gtk_range_set_increments (handle, value, getPageIncrement ());
285 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
286 }
287
288 /**
289 * Sets the maximum value that the receiver will allow. This new
290 * value will be ignored if it is not greater than the receiver's current
291 * minimum value. If the new maximum is applied then the receiver's
292 * selection value will be adjusted if necessary to fall within its new range.
293 *
294 * @param value the new maximum, which must be greater than the current minimum
295 *
296 * @exception SWTException <ul>
297 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
298 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
299 * </ul>
300 */
301 public void setMaximum (int value) {
302 checkWidget ();
303 int minimum = getMinimum();
304 if (value <= minimum) return;
305 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
306 OS.gtk_range_set_range (handle, minimum, value);
307 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
308 }
309
310 /**
311 * Sets the minimum value that the receiver will allow. This new
312 * value will be ignored if it is negative or is not less than the receiver's
313 * current maximum value. If the new minimum is applied then the receiver's
314 * selection value will be adjusted if necessary to fall within its new range.
315 *
316 * @param value the new minimum, which must be nonnegative and less than the current maximum
317 *
318 * @exception SWTException <ul>
319 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
320 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
321 * </ul>
322 */
323 public void setMinimum (int value) {
324 checkWidget ();
325 if (value < 0) return;
326 int maximum = getMaximum ();
327 if (value >= maximum) return;
328 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
329 OS.gtk_range_set_range (handle, value, maximum);
330 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
331 }
332
333 /**
334 * Sets the amount that the receiver's value will be
335 * modified by when the page increment/decrement areas
336 * are selected to the argument, which must be at least
337 * one.
338 *
339 * @param pageIncrement the page increment (must be greater than zero)
340 *
341 * @exception SWTException <ul>
342 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
343 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
344 * </ul>
345 */
346 public void setPageIncrement (int value) {
347 checkWidget ();
348 if (value < 1) return;
349 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
350 OS.gtk_range_set_increments (handle, getIncrement (), value);
351 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
352 }
353
354 /**
355 * Sets the single <em>selection</em> that is the receiver's
356 * value to the argument which must be greater than or equal
357 * to zero.
358 *
359 * @param value the new selection (must be zero or greater)
360 *
361 * @exception SWTException <ul>
362 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
363 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
364 * </ul>
365 */
366 public void setSelection (int value) {
367 checkWidget ();
368 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
369 OS.gtk_range_set_value (handle, value);
370 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, VALUE_CHANGED);
371 }
372
373 }