Mercurial > projects > dwt-mac
comparison dwt/widgets/Spinner.d @ 0:380af2bdd8e5
Upload of whole dwt tree
author | Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com> |
---|---|
date | Sat, 09 Aug 2008 17:00:02 +0200 |
parents | |
children | 649b8e223d5a |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:380af2bdd8e5 |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2007 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 *******************************************************************************/ | |
11 module dwt.widgets.Spinner; | |
12 | |
13 import dwt.dwthelper.utils; | |
14 | |
15 import dwt.DWT; | |
16 import dwt.DWTException; | |
17 import dwt.events.ModifyListener; | |
18 import dwt.events.SelectionEvent; | |
19 import dwt.events.SelectionListener; | |
20 import dwt.events.VerifyListener; | |
21 import dwt.graphics.Point; | |
22 import dwt.graphics.Rectangle; | |
23 import dwt.internal.cocoa.NSAttributedString; | |
24 import dwt.internal.cocoa.NSCell; | |
25 import dwt.internal.cocoa.NSMutableDictionary; | |
26 import dwt.internal.cocoa.NSRect; | |
27 import dwt.internal.cocoa.NSSize; | |
28 import dwt.internal.cocoa.NSStepper; | |
29 import dwt.internal.cocoa.NSString; | |
30 import dwt.internal.cocoa.NSTextField; | |
31 import dwt.internal.cocoa.OS; | |
32 import dwt.internal.cocoa.SWTStepper; | |
33 import dwt.internal.cocoa.SWTTextField; | |
34 import dwt.internal.cocoa.SWTView; | |
35 | |
36 /** | |
37 * Instances of this class are selectable user interface | |
38 * objects that allow the user to enter and modify numeric | |
39 * values. | |
40 * <p> | |
41 * Note that although this class is a subclass of <code>Composite</code>, | |
42 * it does not make sense to add children to it, or set a layout on it. | |
43 * </p><p> | |
44 * <dl> | |
45 * <dt><b>Styles:</b></dt> | |
46 * <dd>READ_ONLY, WRAP</dd> | |
47 * <dt><b>Events:</b></dt> | |
48 * <dd>Selection, Modify, Verify</dd> | |
49 * </dl> | |
50 * </p><p> | |
51 * IMPORTANT: This class is <em>not</em> intended to be subclassed. | |
52 * </p> | |
53 * | |
54 * @since 3.1 | |
55 */ | |
56 public class Spinner extends Composite { | |
57 NSTextField textView; | |
58 NSStepper buttonView; | |
59 int pageIncrement = 10; | |
60 int digits = 0; | |
61 | |
62 static int GAP = 0; | |
63 | |
64 /** | |
65 * Constructs a new instance of this class given its parent | |
66 * and a style value describing its behavior and appearance. | |
67 * <p> | |
68 * The style value is either one of the style constants defined in | |
69 * class <code>DWT</code> which is applicable to instances of this | |
70 * class, or must be built by <em>bitwise OR</em>'ing together | |
71 * (that is, using the <code>int</code> "|" operator) two or more | |
72 * of those <code>DWT</code> style constants. The class description | |
73 * lists the style constants that are applicable to the class. | |
74 * Style bits are also inherited from superclasses. | |
75 * </p> | |
76 * | |
77 * @param parent a composite control which will be the parent of the new instance (cannot be null) | |
78 * @param style the style of control to construct | |
79 * | |
80 * @exception IllegalArgumentException <ul> | |
81 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
82 * </ul> | |
83 * @exception DWTException <ul> | |
84 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
85 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
86 * </ul> | |
87 * | |
88 * @see DWT#READ_ONLY | |
89 * @see DWT#WRAP | |
90 * @see Widget#checkSubclass | |
91 * @see Widget#getStyle | |
92 */ | |
93 public Spinner (Composite parent, int style) { | |
94 super (parent, checkStyle (style)); | |
95 } | |
96 | |
97 /** | |
98 * Adds the listener to the collection of listeners who will | |
99 * be notified when the receiver's text is modified, by sending | |
100 * it one of the messages defined in the <code>ModifyListener</code> | |
101 * interface. | |
102 * | |
103 * @param listener the listener which should be notified | |
104 * | |
105 * @exception IllegalArgumentException <ul> | |
106 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
107 * </ul> | |
108 * @exception DWTException <ul> | |
109 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
110 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
111 * </ul> | |
112 * | |
113 * @see ModifyListener | |
114 * @see #removeModifyListener | |
115 */ | |
116 public void addModifyListener (ModifyListener listener) { | |
117 checkWidget (); | |
118 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
119 TypedListener typedListener = new TypedListener (listener); | |
120 addListener (DWT.Modify, typedListener); | |
121 } | |
122 | |
123 /** | |
124 * Adds the listener to the collection of listeners who will | |
125 * be notified when the control is selected by the user, by sending | |
126 * it one of the messages defined in the <code>SelectionListener</code> | |
127 * interface. | |
128 * <p> | |
129 * <code>widgetSelected</code> is not called for texts. | |
130 * <code>widgetDefaultSelected</code> is typically called when ENTER is pressed in a single-line text. | |
131 * </p> | |
132 * | |
133 * @param listener the listener which should be notified when the control is selected by the user | |
134 * | |
135 * @exception IllegalArgumentException <ul> | |
136 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
137 * </ul> | |
138 * @exception DWTException <ul> | |
139 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
140 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
141 * </ul> | |
142 * | |
143 * @see SelectionListener | |
144 * @see #removeSelectionListener | |
145 * @see SelectionEvent | |
146 */ | |
147 public void addSelectionListener(SelectionListener listener) { | |
148 checkWidget (); | |
149 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
150 TypedListener typedListener = new TypedListener(listener); | |
151 addListener (DWT.Selection,typedListener); | |
152 addListener (DWT.DefaultSelection,typedListener); | |
153 } | |
154 | |
155 /** | |
156 * Adds the listener to the collection of listeners who will | |
157 * be notified when the receiver's text is verified, by sending | |
158 * it one of the messages defined in the <code>VerifyListener</code> | |
159 * interface. | |
160 * | |
161 * @param listener the listener which should be notified | |
162 * | |
163 * @exception IllegalArgumentException <ul> | |
164 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
165 * </ul> | |
166 * @exception DWTException <ul> | |
167 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
168 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
169 * </ul> | |
170 * | |
171 * @see VerifyListener | |
172 * @see #removeVerifyListener | |
173 */ | |
174 void addVerifyListener (VerifyListener listener) { | |
175 checkWidget(); | |
176 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
177 TypedListener typedListener = new TypedListener (listener); | |
178 addListener (DWT.Verify, typedListener); | |
179 } | |
180 | |
181 static int checkStyle (int style) { | |
182 /* | |
183 * Even though it is legal to create this widget | |
184 * with scroll bars, they serve no useful purpose | |
185 * because they do not automatically scroll the | |
186 * widget's client area. The fix is to clear | |
187 * the DWT style. | |
188 */ | |
189 return style & ~(DWT.H_SCROLL | DWT.V_SCROLL); | |
190 } | |
191 | |
192 protected void checkSubclass () { | |
193 if (!isValidSubclass ()) error (DWT.ERROR_INVALID_SUBCLASS); | |
194 } | |
195 | |
196 public Point computeSize (int wHint, int hHint, bool changed) { | |
197 checkWidget (); | |
198 float width = 0, height = 0; | |
199 String string = Double.toString (buttonView.maxValue ()); | |
200 NSMutableDictionary dict = NSMutableDictionary.dictionaryWithCapacity (1); | |
201 dict.setObject(textView.font (), OS.NSFontAttributeName ()); | |
202 int length = string.length (); | |
203 char [] chars = new char [length]; | |
204 string.getChars (0, length, chars, 0); | |
205 NSString nsString = NSString.stringWithCharacters (chars, length); | |
206 NSAttributedString str = ((NSAttributedString) new NSAttributedString ().alloc ()).initWithString_attributes_ (nsString, dict); | |
207 NSSize size = str.size (); | |
208 str.release (); | |
209 width = size.width; | |
210 height = size.height; | |
211 NSRect frameRect = textView.frame(); | |
212 NSCell cell = new NSCell (textView.cell ()); | |
213 NSRect cellRect = cell.drawingRectForBounds(frameRect); | |
214 width += frameRect.width - cellRect.width; | |
215 height += frameRect.height - cellRect.height; | |
216 width += GAP; | |
217 NSRect oldRect = buttonView.frame (); | |
218 buttonView.sizeToFit(); | |
219 NSRect newRect = buttonView.frame (); | |
220 buttonView.setFrame (oldRect); | |
221 width += newRect.width; | |
222 height = Math.max (height, newRect.height); | |
223 if (wHint !is DWT.DEFAULT) width = wHint; | |
224 if (hHint !is DWT.DEFAULT) height = hHint; | |
225 Rectangle trim = computeTrim (0, 0, (int) width, (int) height); | |
226 return new Point (trim.width, trim.height); | |
227 } | |
228 | |
229 /** | |
230 * Copies the selected text. | |
231 * <p> | |
232 * The current selection is copied to the clipboard. | |
233 * </p> | |
234 * | |
235 * @exception DWTException <ul> | |
236 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
237 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
238 * </ul> | |
239 */ | |
240 public void copy () { | |
241 checkWidget (); | |
242 // short [] selection = new short [2]; | |
243 // if (OS.GetControlData (textHandle, (short)OS.kControlEntireControl, OS.kControlEditTextSelectionTag, 4, selection, null) !is OS.noErr) return; | |
244 // if (selection [0] is selection [1]) return; | |
245 // int [] actualSize = new int [1]; | |
246 // int [] ptr = new int [1]; | |
247 // if (OS.GetControlData (textHandle, (short)OS.kControlEntireControl, OS.kControlEditTextCFStringTag, 4, ptr, actualSize) !is OS.noErr) return; | |
248 // CFRange range = new CFRange (); | |
249 // range.location = selection [0]; | |
250 // range.length = selection [1] - selection [0]; | |
251 // char [] buffer= new char [range.length]; | |
252 // OS.CFStringGetCharacters (ptr [0], range, buffer); | |
253 // OS.CFRelease (ptr [0]); | |
254 // copyToClipboard (buffer); | |
255 } | |
256 | |
257 void createHandle () { | |
258 SWTView widget = (SWTView)new SWTView().alloc(); | |
259 widget.initWithFrame(new NSRect()); | |
260 // widget.setDrawsBackground(false); | |
261 widget.setTag(jniRef); | |
262 NSStepper buttonWidget = (NSStepper)new SWTStepper().alloc(); | |
263 buttonWidget.initWithFrame(new NSRect()); | |
264 buttonWidget.setValueWraps((style & DWT.WRAP) !is 0); | |
265 buttonWidget.setTarget(buttonWidget); | |
266 buttonWidget.setAction(OS.sel_sendSelection); | |
267 buttonWidget.setTag(jniRef); | |
268 NSTextField textWidget = (NSTextField)new SWTTextField().alloc(); | |
269 textWidget.initWithFrame(new NSRect()); | |
270 // textWidget.setTarget(widget); | |
271 textWidget.setTag(jniRef); | |
272 textWidget.setEditable((style & DWT.READ_ONLY) is 0); | |
273 widget.addSubview_(textWidget); | |
274 widget.addSubview_(buttonWidget); | |
275 buttonView = buttonWidget; | |
276 textView = textWidget; | |
277 view = widget; | |
278 parent.contentView().addSubview_(widget); | |
279 setSelection (0, false, true, false); | |
280 } | |
281 | |
282 /** | |
283 * Cuts the selected text. | |
284 * <p> | |
285 * The current selection is first copied to the | |
286 * clipboard and then deleted from the widget. | |
287 * </p> | |
288 * | |
289 * @exception DWTException <ul> | |
290 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
291 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
292 * </ul> | |
293 */ | |
294 public void cut () { | |
295 checkWidget (); | |
296 if ((style & DWT.READ_ONLY) !is 0) return; | |
297 // short [] selection = new short [2]; | |
298 // if (OS.GetControlData (textHandle, (short)OS.kControlEntireControl, OS.kControlEditTextSelectionTag, 4, selection, null) !is OS.noErr) return; | |
299 // if (selection [0] is selection [1]) return; | |
300 // char [] buffer = setText ("", selection [0], selection [1], true); | |
301 // if (buffer !is null) { | |
302 // copyToClipboard (buffer); | |
303 // } | |
304 } | |
305 | |
306 void enableWidget (bool enabled) { | |
307 buttonView.setEnabled(enabled); | |
308 textView.setEnabled(enabled); | |
309 } | |
310 | |
311 /** | |
312 * Returns the number of decimal places used by the receiver. | |
313 * | |
314 * @return the digits | |
315 * | |
316 * @exception DWTException <ul> | |
317 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
318 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
319 * </ul> | |
320 */ | |
321 public int getDigits () { | |
322 checkWidget (); | |
323 return digits; | |
324 } | |
325 | |
326 /** | |
327 * Returns the amount that the receiver's value will be | |
328 * modified by when the up/down arrows are pressed. | |
329 * | |
330 * @return the increment | |
331 * | |
332 * @exception DWTException <ul> | |
333 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
334 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
335 * </ul> | |
336 */ | |
337 public int getIncrement () { | |
338 checkWidget (); | |
339 return (int)buttonView.increment(); | |
340 } | |
341 | |
342 /** | |
343 * Returns the maximum value which the receiver will allow. | |
344 * | |
345 * @return the maximum | |
346 * | |
347 * @exception DWTException <ul> | |
348 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
349 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
350 * </ul> | |
351 */ | |
352 public int getMaximum () { | |
353 checkWidget (); | |
354 return (int)buttonView.maxValue(); | |
355 } | |
356 | |
357 /** | |
358 * Returns the minimum value which the receiver will allow. | |
359 * | |
360 * @return the minimum | |
361 * | |
362 * @exception DWTException <ul> | |
363 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
364 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
365 * </ul> | |
366 */ | |
367 public int getMinimum () { | |
368 checkWidget (); | |
369 return (int)buttonView.minValue(); | |
370 } | |
371 | |
372 /** | |
373 * Returns the amount that the receiver's position will be | |
374 * modified by when the page up/down keys are pressed. | |
375 * | |
376 * @return the page increment | |
377 * | |
378 * @exception DWTException <ul> | |
379 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
380 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
381 * </ul> | |
382 */ | |
383 public int getPageIncrement () { | |
384 checkWidget (); | |
385 return pageIncrement; | |
386 } | |
387 | |
388 /** | |
389 * Returns the <em>selection</em>, which is the receiver's position. | |
390 * | |
391 * @return the selection | |
392 * | |
393 * @exception DWTException <ul> | |
394 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
395 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
396 * </ul> | |
397 */ | |
398 public int getSelection () { | |
399 checkWidget (); | |
400 return (int)((NSStepper)buttonView).doubleValue(); | |
401 } | |
402 | |
403 int getSelectionText () { | |
404 return -1; | |
405 } | |
406 | |
407 /** | |
408 * Pastes text from clipboard. | |
409 * <p> | |
410 * The selected text is deleted from the widget | |
411 * and new text inserted from the clipboard. | |
412 * </p> | |
413 * | |
414 * @exception DWTException <ul> | |
415 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
416 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
417 * </ul> | |
418 */ | |
419 public void paste () { | |
420 checkWidget (); | |
421 if ((style & DWT.READ_ONLY) !is 0) return; | |
422 // String text = getClipboardText (); | |
423 // short [] selection = new short [2]; | |
424 // if (OS.GetControlData (textHandle, (short)OS.kControlEntireControl, OS.kControlEditTextSelectionTag, 4, selection, null) !is OS.noErr) return; | |
425 // setText (text, selection [0], selection [1], true); | |
426 } | |
427 | |
428 void releaseHandle () { | |
429 super.releaseHandle(); | |
430 if (buttonView !is null) { | |
431 buttonView.setTag(-1); | |
432 buttonView.release(); | |
433 } | |
434 if (textView !is null) { | |
435 textView.setTag(-1); | |
436 textView.release(); | |
437 } | |
438 buttonView = null; | |
439 textView = null; | |
440 } | |
441 | |
442 /** | |
443 * Removes the listener from the collection of listeners who will | |
444 * be notified when the receiver's text is modified. | |
445 * | |
446 * @param listener the listener which should no longer be notified | |
447 * | |
448 * @exception IllegalArgumentException <ul> | |
449 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
450 * </ul> | |
451 * @exception DWTException <ul> | |
452 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
453 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
454 * </ul> | |
455 * | |
456 * @see ModifyListener | |
457 * @see #addModifyListener | |
458 */ | |
459 public void removeModifyListener (ModifyListener listener) { | |
460 checkWidget (); | |
461 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
462 if (eventTable is null) return; | |
463 eventTable.unhook (DWT.Modify, listener); | |
464 } | |
465 | |
466 /** | |
467 * Removes the listener from the collection of listeners who will | |
468 * be notified when the control is selected by the user. | |
469 * | |
470 * @param listener the listener which should no longer be notified | |
471 * | |
472 * @exception IllegalArgumentException <ul> | |
473 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
474 * </ul> | |
475 * @exception DWTException <ul> | |
476 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
477 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
478 * </ul> | |
479 * | |
480 * @see SelectionListener | |
481 * @see #addSelectionListener | |
482 */ | |
483 public void removeSelectionListener(SelectionListener listener) { | |
484 checkWidget (); | |
485 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
486 if (eventTable is null) return; | |
487 eventTable.unhook (DWT.Selection, listener); | |
488 eventTable.unhook (DWT.DefaultSelection,listener); | |
489 } | |
490 | |
491 /** | |
492 * Removes the listener from the collection of listeners who will | |
493 * be notified when the control is verified. | |
494 * | |
495 * @param listener the listener which should be notified | |
496 * | |
497 * @exception IllegalArgumentException <ul> | |
498 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
499 * </ul> | |
500 * @exception DWTException <ul> | |
501 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
502 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
503 * </ul> | |
504 * | |
505 * @see VerifyListener | |
506 * @see #addVerifyListener | |
507 */ | |
508 void removeVerifyListener (VerifyListener listener) { | |
509 checkWidget (); | |
510 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
511 if (eventTable is null) return; | |
512 eventTable.unhook (DWT.Verify, listener); | |
513 } | |
514 | |
515 void sendSelection () { | |
516 setSelection (getSelection(), false, true, true); | |
517 } | |
518 | |
519 int setBounds (int x, int y, int width, int height, bool move, bool resize) { | |
520 int result = super.setBounds(x, y, width, height, move, resize); | |
521 if ((result & RESIZED) !is 0) { | |
522 buttonView.sizeToFit(); | |
523 NSRect buttonFrame = buttonView.bounds(); | |
524 NSRect frame = view.frame(); | |
525 buttonFrame.x = frame.width - buttonFrame.width; | |
526 buttonFrame.y = 0; | |
527 frame.x = 0; | |
528 frame.y = 0; | |
529 frame.width -= buttonFrame.width + GAP; | |
530 textView.setFrame(frame); | |
531 buttonView.setFrame(buttonFrame); | |
532 } | |
533 return result; | |
534 } | |
535 | |
536 /** | |
537 * Sets the number of decimal places used by the receiver. | |
538 * <p> | |
539 * The digit setting is used to allow for floating point values in the receiver. | |
540 * For example, to set the selection to a floating point value of 1.37 call setDigits() with | |
541 * a value of 2 and setSelection() with a value of 137. Similarly, if getDigits() has a value | |
542 * of 2 and getSelection() returns 137 this should be interpreted as 1.37. This applies to all | |
543 * numeric APIs. | |
544 * </p> | |
545 * | |
546 * @param value the new digits (must be greater than or equal to zero) | |
547 * | |
548 * @exception IllegalArgumentException <ul> | |
549 * <li>ERROR_INVALID_ARGUMENT - if the value is less than zero</li> | |
550 * </ul> | |
551 * @exception DWTException <ul> | |
552 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
553 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
554 * </ul> | |
555 */ | |
556 public void setDigits (int value) { | |
557 checkWidget (); | |
558 if (value < 0) error (DWT.ERROR_INVALID_ARGUMENT); | |
559 // if (value is digits) return; | |
560 // digits = value; | |
561 // int pos = OS.GetControl32BitValue (buttonHandle); | |
562 // setSelection (pos, false, true, false); | |
563 } | |
564 | |
565 /** | |
566 * Sets the amount that the receiver's value will be | |
567 * modified by when the up/down arrows are pressed to | |
568 * the argument, which must be at least one. | |
569 * | |
570 * @param value the new increment (must be greater than zero) | |
571 * | |
572 * @exception DWTException <ul> | |
573 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
574 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
575 * </ul> | |
576 */ | |
577 public void setIncrement (int value) { | |
578 checkWidget (); | |
579 if (value < 1) return; | |
580 buttonView.setIncrement(value); | |
581 } | |
582 | |
583 /** | |
584 * Sets the maximum value that the receiver will allow. This new | |
585 * value will be ignored if it is not greater than the receiver's current | |
586 * minimum value. If the new maximum is applied then the receiver's | |
587 * selection value will be adjusted if necessary to fall within its new range. | |
588 * | |
589 * @param value the new maximum, which must be greater than the current minimum | |
590 * | |
591 * @exception DWTException <ul> | |
592 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
593 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
594 * </ul> | |
595 */ | |
596 public void setMaximum (int value) { | |
597 checkWidget (); | |
598 if (value < 0) return; | |
599 int min = getMinimum (); | |
600 if (value <= min) return; | |
601 int pos = getSelection(); | |
602 buttonView.setMaxValue(value); | |
603 if (pos > value) setSelection (value, true, true, false); | |
604 } | |
605 | |
606 /** | |
607 * Sets the minimum value that the receiver will allow. This new | |
608 * value will be ignored if it is negative or is not less than the receiver's | |
609 * current maximum value. If the new minimum is applied then the receiver's | |
610 * selection value will be adjusted if necessary to fall within its new range. | |
611 * | |
612 * @param value the new minimum, which must be nonnegative and less than the current maximum | |
613 * | |
614 * @exception DWTException <ul> | |
615 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
616 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
617 * </ul> | |
618 */ | |
619 public void setMinimum (int value) { | |
620 checkWidget (); | |
621 if (value < 0) return; | |
622 int max = getMaximum(); | |
623 if (value >= max) return; | |
624 int pos = getSelection(); | |
625 buttonView.setMinValue(value); | |
626 if (pos < value) setSelection (value, true, true, false); | |
627 } | |
628 | |
629 /** | |
630 * Sets the amount that the receiver's position will be | |
631 * modified by when the page up/down keys are pressed | |
632 * to the argument, which must be at least one. | |
633 * | |
634 * @param value the page increment (must be greater than zero) | |
635 * | |
636 * @exception DWTException <ul> | |
637 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
638 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
639 * </ul> | |
640 */ | |
641 public void setPageIncrement (int value) { | |
642 checkWidget (); | |
643 if (value < 1) return; | |
644 pageIncrement = value; | |
645 } | |
646 | |
647 /** | |
648 * Sets the <em>selection</em>, which is the receiver's | |
649 * position, to the argument. If the argument is not within | |
650 * the range specified by minimum and maximum, it will be | |
651 * adjusted to fall within this range. | |
652 * | |
653 * @param value the new selection (must be zero or greater) | |
654 * | |
655 * @exception DWTException <ul> | |
656 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
657 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
658 * </ul> | |
659 */ | |
660 public void setSelection (int value) { | |
661 checkWidget (); | |
662 int min = getMinimum(); | |
663 int max = getMaximum(); | |
664 value = Math.min (Math.max (min, value), max); | |
665 setSelection (value, true, true, false); | |
666 } | |
667 | |
668 void setSelection (int value, bool setPos, bool setText, bool notify) { | |
669 if (setPos) { | |
670 ((NSStepper)buttonView).setDoubleValue(value); | |
671 } | |
672 if (setText) { | |
673 String string = String.valueOf (value); | |
674 if (digits > 0) { | |
675 String decimalSeparator = ".";//getDecimalSeparator (); | |
676 int index = string.length () - digits; | |
677 StringBuffer buffer = new StringBuffer (); | |
678 if (index > 0) { | |
679 buffer.append (string.substring (0, index)); | |
680 buffer.append (decimalSeparator); | |
681 buffer.append (string.substring (index)); | |
682 } else { | |
683 buffer.append ("0"); | |
684 buffer.append (decimalSeparator); | |
685 while (index++ < 0) buffer.append ("0"); | |
686 buffer.append (string); | |
687 } | |
688 string = buffer.toString (); | |
689 } | |
690 NSCell cell = new NSCell(textView.cell()); | |
691 if (hooks (DWT.Verify) || filters (DWT.Verify)) { | |
692 int length = cell.title().length(); | |
693 string = verifyText (string, 0, length, null); | |
694 if (string is null) return; | |
695 } | |
696 cell.setTitle(NSString.stringWith(string)); | |
697 // short [] selection = new short [] {0, (short)string.length ()}; | |
698 // OS.SetControlData (textHandle, (short)OS.kControlEntireControl, OS.kControlEditTextSelectionTag, 4, selection); | |
699 sendEvent (DWT.Modify); | |
700 } | |
701 if (notify) postEvent (DWT.Selection); | |
702 } | |
703 | |
704 /** | |
705 * Sets the receiver's selection, minimum value, maximum | |
706 * value, digits, increment and page increment all at once. | |
707 * <p> | |
708 * Note: This is similar to setting the values individually | |
709 * using the appropriate methods, but may be implemented in a | |
710 * more efficient fashion on some platforms. | |
711 * </p> | |
712 * | |
713 * @param selection the new selection value | |
714 * @param minimum the new minimum value | |
715 * @param maximum the new maximum value | |
716 * @param digits the new digits value | |
717 * @param increment the new increment value | |
718 * @param pageIncrement the new pageIncrement value | |
719 * | |
720 * @exception DWTException <ul> | |
721 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
722 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
723 * </ul> | |
724 * | |
725 * @since 3.2 | |
726 */ | |
727 public void setValues (int selection, int minimum, int maximum, int digits, int increment, int pageIncrement) { | |
728 checkWidget (); | |
729 if (minimum < 0) return; | |
730 if (maximum <= minimum) return; | |
731 if (digits < 0) return; | |
732 if (increment < 1) return; | |
733 if (pageIncrement < 1) return; | |
734 selection = Math.min (Math.max (minimum, selection), maximum); | |
735 this.pageIncrement = pageIncrement; | |
736 this.digits = digits; | |
737 buttonView.setIncrement(increment); | |
738 buttonView.setMaxValue(maximum); | |
739 buttonView.setMinValue(minimum); | |
740 setSelection (selection, true, true, false); | |
741 } | |
742 | |
743 String verifyText (String string, int start, int end, Event keyEvent) { | |
744 Event event = new Event (); | |
745 event.text = string; | |
746 event.start = start; | |
747 event.end = end; | |
748 if (keyEvent !is null) { | |
749 event.character = keyEvent.character; | |
750 event.keyCode = keyEvent.keyCode; | |
751 event.stateMask = keyEvent.stateMask; | |
752 } | |
753 int index = 0; | |
754 if (digits > 0) { | |
755 String decimalSeparator = ".";//getDecimalSeparator (); | |
756 index = string.indexOf (decimalSeparator); | |
757 if (index !is -1) { | |
758 string = string.substring (0, index) + string.substring (index + 1); | |
759 } | |
760 index = 0; | |
761 } | |
762 while (index < string.length ()) { | |
763 if (!Character.isDigit (string.charAt (index))) break; | |
764 index++; | |
765 } | |
766 event.doit = index is string.length (); | |
767 /* | |
768 * It is possible (but unlikely), that application | |
769 * code could have disposed the widget in the verify | |
770 * event. If this happens, answer null to cancel | |
771 * the operation. | |
772 */ | |
773 sendEvent (DWT.Verify, event); | |
774 if (!event.doit || isDisposed ()) return null; | |
775 return event.text; | |
776 } | |
777 | |
778 } |