Mercurial > projects > dwt-linux
annotate dwt/widgets/Spinner.d @ 240:ce446666f5a2
Update to SWT 3.4M7
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 12 May 2008 19:13:01 +0200 |
parents | 380bad9f6852 |
children | 5a30aa9820f3 |
rev | line source |
---|---|
72 | 1 /******************************************************************************* |
63 | 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 | |
72 | 10 * Port to the D programming language: |
11 * Frank Benoit <benoit@tionex.de> | |
63 | 12 *******************************************************************************/ |
13 module dwt.widgets.Spinner; | |
14 | |
15 | |
16 import dwt.widgets.Composite; | |
17 import dwt.widgets.TypedListener; | |
18 import dwt.widgets.Event; | |
19 import dwt.widgets.Widget; | |
71 | 20 import dwt.DWT; |
63 | 21 import dwt.internal.gtk.OS; |
22 import dwt.graphics.Point; | |
23 import dwt.graphics.Rectangle; | |
24 import dwt.events.SelectionListener; | |
25 import dwt.events.SelectionEvent; | |
26 import dwt.events.ModifyListener; | |
27 import dwt.events.VerifyListener; | |
28 | |
29 import tango.stdc.stringz; | |
30 import tango.util.Convert; | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
31 import dwt.dwthelper.utils; |
63 | 32 |
33 /** | |
34 * Instances of this class are selectable user interface | |
35 * objects that allow the user to enter and modify numeric | |
36 * values. | |
37 * <p> | |
38 * Note that although this class is a subclass of <code>Composite</code>, | |
39 * it does not make sense to add children to it, or set a layout on it. | |
40 * </p><p> | |
41 * <dl> | |
42 * <dt><b>Styles:</b></dt> | |
43 * <dd>READ_ONLY, WRAP</dd> | |
44 * <dt><b>Events:</b></dt> | |
45 * <dd>Selection, Modify, Verify</dd> | |
46 * </dl> | |
47 * </p><p> | |
48 * IMPORTANT: This class is <em>not</em> intended to be subclassed. | |
49 * </p> | |
50 * | |
51 * @since 3.1 | |
52 */ | |
53 public class Spinner : Composite { | |
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
113
diff
changeset
|
54 |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
113
diff
changeset
|
55 alias Composite.computeSize computeSize; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
113
diff
changeset
|
56 alias Composite.createHandle createHandle; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
113
diff
changeset
|
57 alias Composite.setBackgroundColor setBackgroundColor; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
113
diff
changeset
|
58 alias Composite.setCursor setCursor; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
113
diff
changeset
|
59 alias Composite.translateTraversal translateTraversal; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
113
diff
changeset
|
60 |
63 | 61 static final int INNER_BORDER = 2; |
62 static final int MIN_ARROW_WIDTH = 6; | |
63 int lastEventTime = 0; | |
64 GdkEventKey* gdkEventKey; | |
65 int fixStart = -1, fixEnd = -1; | |
66 | |
240 | 67 /** |
68 * The maximum number of characters that can be entered | |
69 * into a text widget. | |
70 * <p> | |
71 * Note that this value is platform dependent, based upon | |
72 * the native widget implementation. | |
73 * </p> | |
74 */ | |
75 public const static int LIMIT = 0x7FFFFFFF; | |
76 | |
63 | 77 /** |
78 * Constructs a new instance of this class given its parent | |
79 * and a style value describing its behavior and appearance. | |
80 * <p> | |
81 * The style value is either one of the style constants defined in | |
71 | 82 * class <code>DWT</code> which is applicable to instances of this |
63 | 83 * class, or must be built by <em>bitwise OR</em>'ing together |
84 * (that is, using the <code>int</code> "|" operator) two or more | |
71 | 85 * of those <code>DWT</code> style constants. The class description |
63 | 86 * lists the style constants that are applicable to the class. |
87 * Style bits are also inherited from superclasses. | |
88 * </p> | |
89 * | |
90 * @param parent a composite control which will be the parent of the new instance (cannot be null) | |
91 * @param style the style of control to construct | |
92 * | |
93 * @exception IllegalArgumentException <ul> | |
94 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
95 * </ul> | |
71 | 96 * @exception DWTException <ul> |
63 | 97 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> |
98 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
99 * </ul> | |
100 * | |
71 | 101 * @see DWT#READ_ONLY |
102 * @see DWT#WRAP | |
63 | 103 * @see Widget#checkSubclass |
104 * @see Widget#getStyle | |
105 */ | |
106 public this (Composite parent, int style) { | |
107 super (parent, checkStyle (style)); | |
108 } | |
109 | |
110 /** | |
111 * Adds the listener to the collection of listeners who will | |
112 * be notified when the receiver's text is modified, by sending | |
113 * it one of the messages defined in the <code>ModifyListener</code> | |
114 * interface. | |
115 * | |
116 * @param listener the listener which should be notified | |
117 * | |
118 * @exception IllegalArgumentException <ul> | |
119 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
120 * </ul> | |
71 | 121 * @exception DWTException <ul> |
63 | 122 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
123 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
124 * </ul> | |
125 * | |
126 * @see ModifyListener | |
127 * @see #removeModifyListener | |
128 */ | |
129 public void addModifyListener (ModifyListener listener) { | |
130 checkWidget (); | |
71 | 131 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
63 | 132 TypedListener typedListener = new TypedListener (listener); |
71 | 133 addListener (DWT.Modify, typedListener); |
63 | 134 } |
135 | |
136 /** | |
137 * Adds the listener to the collection of listeners who will | |
138 * be notified when the control is selected by the user, by sending | |
139 * it one of the messages defined in the <code>SelectionListener</code> | |
140 * interface. | |
141 * <p> | |
142 * <code>widgetSelected</code> is not called for texts. | |
143 * <code>widgetDefaultSelected</code> is typically called when ENTER is pressed in a single-line text. | |
144 * </p> | |
145 * | |
146 * @param listener the listener which should be notified when the control is selected by the user | |
147 * | |
148 * @exception IllegalArgumentException <ul> | |
149 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
150 * </ul> | |
71 | 151 * @exception DWTException <ul> |
63 | 152 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
153 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
154 * </ul> | |
155 * | |
156 * @see SelectionListener | |
157 * @see #removeSelectionListener | |
158 * @see SelectionEvent | |
159 */ | |
160 public void addSelectionListener(SelectionListener listener) { | |
161 checkWidget (); | |
71 | 162 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
63 | 163 TypedListener typedListener = new TypedListener(listener); |
71 | 164 addListener(DWT.Selection,typedListener); |
165 addListener(DWT.DefaultSelection,typedListener); | |
63 | 166 } |
167 | |
168 /** | |
169 * Adds the listener to the collection of listeners who will | |
170 * be notified when the receiver's text is verified, by sending | |
171 * it one of the messages defined in the <code>VerifyListener</code> | |
172 * interface. | |
173 * | |
174 * @param listener the listener which should be notified | |
175 * | |
176 * @exception IllegalArgumentException <ul> | |
177 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
178 * </ul> | |
71 | 179 * @exception DWTException <ul> |
63 | 180 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
181 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
182 * </ul> | |
183 * | |
184 * @see VerifyListener | |
185 * @see #removeVerifyListener | |
186 */ | |
187 void addVerifyListener (VerifyListener listener) { | |
188 checkWidget(); | |
71 | 189 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
63 | 190 TypedListener typedListener = new TypedListener (listener); |
71 | 191 addListener (DWT.Verify, typedListener); |
63 | 192 } |
193 | |
194 static int checkStyle (int style) { | |
195 /* | |
196 * Even though it is legal to create this widget | |
197 * with scroll bars, they serve no useful purpose | |
198 * because they do not automatically scroll the | |
199 * widget's client area. The fix is to clear | |
71 | 200 * the DWT style. |
63 | 201 */ |
71 | 202 return style & ~(DWT.H_SCROLL | DWT.V_SCROLL); |
63 | 203 } |
204 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
205 protected override void checkSubclass () { |
71 | 206 if (!isValidSubclass ()) error (DWT.ERROR_INVALID_SUBCLASS); |
63 | 207 } |
208 | |
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
113
diff
changeset
|
209 public override Point computeSize (int wHint, int hHint, bool changed) { |
63 | 210 checkWidget (); |
71 | 211 if (wHint !is DWT.DEFAULT && wHint < 0) wHint = 0; |
212 if (hHint !is DWT.DEFAULT && hHint < 0) hHint = 0; | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
213 int[1] w, h; |
63 | 214 OS.gtk_widget_realize (handle); |
215 auto layout = OS.gtk_entry_get_layout (cast(GtkEntry*)handle); | |
216 auto adjustment = OS.gtk_spin_button_get_adjustment (cast(GtkSpinButton*)handle); | |
217 int digits = OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle); | |
218 for (int i = 0; i < digits; i++) adjustment.upper *= 10; | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
219 String string = to!(String)( (cast(int) adjustment.upper) ); |
63 | 220 if (digits > 0) { |
221 //PROTING_TODO: Efficiency | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
222 String buffer = string ~ getDecimalSeparator (); |
63 | 223 int count = digits - string.length; |
224 while (count >= 0) { | |
225 buffer ~= "0"; | |
226 count--; | |
227 } | |
228 string = buffer; | |
229 } | |
230 char [] buffer1 = string; | |
231 auto ptr = OS.pango_layout_get_text (layout); | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
232 String buffer2 = fromStringz( ptr ).dup; |
63 | 233 OS.pango_layout_set_text (layout, buffer1.ptr, buffer1.length); |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
234 OS.pango_layout_get_size (layout, w.ptr, h.ptr); |
63 | 235 OS.pango_layout_set_text (layout, buffer2.ptr, buffer2.length); |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
236 int width = OS.PANGO_PIXELS (w [0]); |
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
237 int height = OS.PANGO_PIXELS (h [0]); |
71 | 238 width = wHint is DWT.DEFAULT ? width : wHint; |
239 height = hHint is DWT.DEFAULT ? height : hHint; | |
63 | 240 Rectangle trim = computeTrim (0, 0, width, height); |
241 return new Point (trim.width, trim.height); | |
242 } | |
243 | |
244 override public Rectangle computeTrim (int x, int y, int width, int height) { | |
245 checkWidget (); | |
246 int xborder = 0, yborder = 0; | |
247 auto style = OS.gtk_widget_get_style (handle); | |
71 | 248 if ((this.style & DWT.BORDER) !is 0) { |
63 | 249 xborder += OS.gtk_style_get_xthickness (style); |
250 yborder += OS.gtk_style_get_ythickness (style); | |
251 } | |
252 xborder += INNER_BORDER; | |
253 yborder += INNER_BORDER; | |
254 int property; | |
255 OS.gtk_widget_style_get1 (handle, OS.interior_focus.ptr, &property); | |
256 if (property is 0) { | |
257 OS.gtk_widget_style_get1 (handle, OS.focus_line_width.ptr, &property); | |
258 xborder += property; | |
259 yborder += property; | |
260 } | |
261 auto fontDesc = OS.gtk_style_get_font_desc (style); | |
262 int fontSize = OS.pango_font_description_get_size (fontDesc); | |
263 int arrowSize = Math.max (OS.PANGO_PIXELS (fontSize), MIN_ARROW_WIDTH); | |
264 arrowSize = arrowSize - arrowSize % 2; | |
265 Rectangle trim = super.computeTrim (x, y, width, height); | |
266 trim.x -= xborder; | |
267 trim.y -= yborder; | |
268 trim.width += 2 * xborder; | |
269 trim.height += 2 * yborder; | |
270 trim.width += arrowSize + (2 * OS.gtk_style_get_xthickness (style)); | |
271 return new Rectangle (trim.x, trim.y, trim.width, trim.height); | |
272 } | |
273 | |
274 /** | |
275 * Copies the selected text. | |
276 * <p> | |
277 * The current selection is copied to the clipboard. | |
278 * </p> | |
279 * | |
71 | 280 * @exception DWTException <ul> |
63 | 281 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
282 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
283 * </ul> | |
284 */ | |
285 public void copy () { | |
286 checkWidget (); | |
287 OS.gtk_editable_copy_clipboard (cast(GtkEditable*)handle); | |
288 } | |
289 | |
290 override void createHandle (int index) { | |
291 state |= HANDLE | MENU; | |
292 fixedHandle = cast(GtkWidget*)OS.g_object_new (display.gtk_fixed_get_type (), null); | |
71 | 293 if (fixedHandle is null) error (DWT.ERROR_NO_HANDLES); |
63 | 294 OS.gtk_fixed_set_has_window (cast(GtkFixed*)fixedHandle, true); |
295 auto adjustment = OS.gtk_adjustment_new (0, 0, 100, 1, 10, 0); | |
71 | 296 if (adjustment is null) error (DWT.ERROR_NO_HANDLES); |
63 | 297 handle = cast(GtkWidget*)OS.gtk_spin_button_new (cast(GtkAdjustment*)adjustment, 1, 0); |
71 | 298 if (handle is null) error (DWT.ERROR_NO_HANDLES); |
63 | 299 OS.gtk_container_add (cast(GtkContainer*)fixedHandle, handle); |
71 | 300 OS.gtk_editable_set_editable (cast(GtkEditable*)handle, (style & DWT.READ_ONLY) is 0); |
301 OS.gtk_entry_set_has_frame (cast(GtkEntry*)handle, (style & DWT.BORDER) !is 0); | |
302 OS.gtk_spin_button_set_wrap (cast(GtkSpinButton*)handle, (style & DWT.WRAP) !is 0); | |
63 | 303 } |
304 | |
305 /** | |
306 * Cuts the selected text. | |
307 * <p> | |
308 * The current selection is first copied to the | |
309 * clipboard and then deleted from the widget. | |
310 * </p> | |
311 * | |
71 | 312 * @exception DWTException <ul> |
63 | 313 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
314 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
315 * </ul> | |
316 */ | |
317 public void cut () { | |
318 checkWidget (); | |
319 OS.gtk_editable_cut_clipboard (cast(GtkEditable*)handle); | |
320 } | |
321 | |
322 override void deregister () { | |
323 super.deregister (); | |
324 auto imContext = imContext (); | |
325 if (imContext !is null) display.removeWidget (cast(GtkWidget*)imContext); | |
326 } | |
327 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
328 override GdkDrawable* eventWindow () { |
63 | 329 return paintWindow (); |
330 } | |
331 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
332 override GtkWidget* enterExitHandle () { |
63 | 333 return fixedHandle; |
334 } | |
335 | |
336 override bool filterKey (int keyval, GdkEventKey* event) { | |
337 int time = OS.gdk_event_get_time (cast(GdkEvent*)event); | |
338 if (time !is lastEventTime) { | |
339 lastEventTime = time; | |
340 auto imContext = imContext (); | |
341 if (imContext !is null) { | |
342 return cast(bool)OS.gtk_im_context_filter_keypress (imContext, event); | |
343 } | |
344 } | |
345 gdkEventKey = event; | |
346 return false; | |
347 } | |
348 | |
349 void fixIM () { | |
350 /* | |
351 * The IM filter has to be called one time for each key press event. | |
352 * When the IM is open the key events are duplicated. The first event | |
71 | 353 * is filtered by DWT and the second event is filtered by GTK. In some |
63 | 354 * cases the GTK handler does not run (the widget is destroyed, the |
355 * application code consumes the event, etc), for these cases the IM | |
71 | 356 * filter has to be called by DWT. |
63 | 357 */ |
358 if (gdkEventKey !is null && gdkEventKey !is cast(GdkEventKey*)-1) { | |
359 auto imContext = imContext (); | |
360 if (imContext !is null) { | |
361 OS.gtk_im_context_filter_keypress (imContext, gdkEventKey); | |
362 gdkEventKey = cast(GdkEventKey*)-1; | |
363 return; | |
364 } | |
365 } | |
366 gdkEventKey = null; | |
367 } | |
368 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
369 override GdkColor* getBackgroundColor () { |
63 | 370 return getBaseColor (); |
371 } | |
372 | |
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
113
diff
changeset
|
373 public override int getBorderWidth () { |
63 | 374 checkWidget(); |
375 auto style = OS.gtk_widget_get_style (handle); | |
71 | 376 if ((this.style & DWT.BORDER) !is 0) { |
63 | 377 return OS.gtk_style_get_xthickness (style); |
378 } | |
379 return 0; | |
380 } | |
381 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
382 override GdkColor* getForegroundColor () { |
63 | 383 return getTextColor (); |
384 } | |
385 | |
386 /** | |
387 * Returns the amount that the receiver's value will be | |
388 * modified by when the up/down arrows are pressed. | |
389 * | |
390 * @return the increment | |
391 * | |
71 | 392 * @exception DWTException <ul> |
63 | 393 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
394 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
395 * </ul> | |
396 */ | |
397 public int getIncrement () { | |
398 checkWidget (); | |
399 auto adjustment = OS.gtk_spin_button_get_adjustment (cast(GtkSpinButton*)handle); | |
400 int digits = OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle); | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
401 auto value = adjustment.step_increment; |
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
402 for (int i = 0; i < digits; i++) value *= 10; |
240 | 403 return cast(int) (value > 0 ? value + 0.5 : value - 0.5); |
63 | 404 } |
405 | |
406 /** | |
407 * Returns the maximum value which the receiver will allow. | |
408 * | |
409 * @return the maximum | |
410 * | |
71 | 411 * @exception DWTException <ul> |
63 | 412 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
413 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
414 * </ul> | |
415 */ | |
416 public int getMaximum () { | |
417 checkWidget (); | |
418 auto adjustment = OS.gtk_spin_button_get_adjustment (cast(GtkSpinButton*)handle); | |
419 int digits = OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle); | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
420 auto value = adjustment.upper; |
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
421 for (int i = 0; i < digits; i++) value *= 10; |
240 | 422 return cast(int) (value > 0 ? value + 0.5 : value - 0.5); |
63 | 423 } |
424 | |
425 /** | |
426 * Returns the minimum value which the receiver will allow. | |
427 * | |
428 * @return the minimum | |
429 * | |
71 | 430 * @exception DWTException <ul> |
63 | 431 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
432 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
433 * </ul> | |
434 */ | |
435 public int getMinimum () { | |
436 checkWidget (); | |
437 auto adjustment = OS.gtk_spin_button_get_adjustment (cast(GtkSpinButton*)handle); | |
438 int digits = OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle); | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
439 auto value = adjustment.lower; |
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
440 for (int i = 0; i < digits; i++) value *= 10; |
240 | 441 return cast(int) (value > 0 ? value + 0.5 : value - 0.5); |
63 | 442 } |
443 | |
444 /** | |
445 * Returns the amount that the receiver's position will be | |
446 * modified by when the page up/down keys are pressed. | |
447 * | |
448 * @return the page increment | |
449 * | |
71 | 450 * @exception DWTException <ul> |
63 | 451 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
452 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
453 * </ul> | |
454 */ | |
455 public int getPageIncrement () { | |
456 checkWidget (); | |
457 auto adjustment = OS.gtk_spin_button_get_adjustment (cast(GtkSpinButton*)handle); | |
458 int digits = OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle); | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
459 auto value = adjustment.page_increment; |
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
460 for (int i = 0; i < digits; i++) value *= 10; |
240 | 461 return cast(int) (value > 0 ? value + 0.5 : value - 0.5); |
63 | 462 } |
463 | |
464 /** | |
465 * Returns the <em>selection</em>, which is the receiver's position. | |
466 * | |
467 * @return the selection | |
468 * | |
71 | 469 * @exception DWTException <ul> |
63 | 470 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
471 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
472 * </ul> | |
473 */ | |
474 public int getSelection () { | |
475 checkWidget (); | |
476 auto adjustment = OS.gtk_spin_button_get_adjustment (cast(GtkSpinButton*)handle); | |
477 int digits = OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle); | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
478 auto value = adjustment.value; |
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
479 for (int i = 0; i < digits; i++) value *= 10; |
240 | 480 return cast(int) (value > 0 ? value + 0.5 : value - 0.5); |
481 } | |
482 | |
483 public String getText () { | |
484 checkWidget (); | |
485 auto str = OS.gtk_entry_get_text (handle); | |
486 return tango.stdc.stringz.fromStringz(str).dup; | |
487 } | |
488 | |
489 public int getTextLimit () { | |
490 checkWidget (); | |
491 int limit = OS.gtk_entry_get_max_length (handle); | |
492 return limit is 0 ? 0xFFFF : limit; | |
63 | 493 } |
494 | |
495 /** | |
496 * Returns the number of decimal places used by the receiver. | |
497 * | |
498 * @return the digits | |
499 * | |
71 | 500 * @exception DWTException <ul> |
63 | 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 public int getDigits () { | |
506 checkWidget (); | |
507 return OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle); | |
508 } | |
509 | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
510 String getDecimalSeparator () { |
63 | 511 auto ptr = OS.localeconv_decimal_point (); |
158
de2578a843a7
Tango update to rev 3158, TracedException>Exception, fromUtf8z>fromStringz,Fix Bug in MenuItem Thanx to nascent for the report.
Frank Benoit <benoit@tionex.de>
parents:
152
diff
changeset
|
512 return fromStringz( ptr ).dup; |
63 | 513 } |
514 | |
515 override int /*long*/ gtk_activate (GtkWidget* widget) { | |
71 | 516 postEvent (DWT.DefaultSelection); |
63 | 517 return 0; |
518 } | |
519 | |
520 override int /*long*/ gtk_changed (GtkWidget* widget) { | |
521 auto str = OS.gtk_entry_get_text (cast(GtkEntry*)handle); | |
522 int length = tango.stdc.string.strlen (str); | |
523 if (length > 0) { | |
524 char* endptr; | |
525 double value = OS.g_strtod (str, &endptr); | |
526 if (endptr is str + length) { | |
527 auto adjustment = OS.gtk_spin_button_get_adjustment (cast(GtkSpinButton*)handle); | |
528 if (value !is adjustment.value && adjustment.lower <= value && value <= adjustment.upper) { | |
529 OS.gtk_spin_button_update (cast(GtkSpinButton*)handle); | |
530 } | |
531 } | |
532 } | |
533 | |
534 /* | |
535 * Feature in GTK. When the user types, GTK positions | |
536 * the caret after sending the changed signal. This | |
537 * means that application code that attempts to position | |
538 * the caret during a changed signal will fail. The fix | |
539 * is to post the modify event when the user is typing. | |
540 */ | |
541 bool keyPress = false; | |
542 auto eventPtr = OS.gtk_get_current_event (); | |
543 if (eventPtr !is null) { | |
544 GdkEventKey* gdkEvent = cast(GdkEventKey*)eventPtr; | |
545 switch (gdkEvent.type) { | |
546 case OS.GDK_KEY_PRESS: | |
547 keyPress = true; | |
548 break; | |
549 default: | |
550 } | |
551 OS.gdk_event_free (eventPtr); | |
552 } | |
553 if (keyPress) { | |
71 | 554 postEvent (DWT.Modify); |
63 | 555 } else { |
71 | 556 sendEvent (DWT.Modify); |
63 | 557 } |
558 return 0; | |
559 } | |
560 | |
561 int /*long*/ gtk_commit (GtkIMContext* imContext, char* text) { | |
562 if (text is null) return 0; | |
563 if (!OS.gtk_editable_get_editable (cast(GtkEditable*)handle)) return 0; | |
158
de2578a843a7
Tango update to rev 3158, TracedException>Exception, fromUtf8z>fromStringz,Fix Bug in MenuItem Thanx to nascent for the report.
Frank Benoit <benoit@tionex.de>
parents:
152
diff
changeset
|
564 char [] chars = fromStringz( text ).dup; |
63 | 565 if (chars.length is 0) return 0; |
71 | 566 char [] newChars = sendIMKeyEvent (DWT.KeyDown, null, chars); |
63 | 567 if (newChars is null) return 0; |
568 /* | |
569 * Feature in GTK. For a GtkEntry, during the insert-text signal, | |
570 * GTK allows the programmer to change only the caret location, | |
571 * not the selection. If the programmer changes the selection, | |
572 * the new selection is lost. The fix is to detect a selection | |
573 * change and set it after the insert-text signal has completed. | |
574 */ | |
575 fixStart = fixEnd = -1; | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
576 OS.g_signal_handlers_block_matched (imContext, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCOMMIT); |
63 | 577 int id = OS.g_signal_lookup (OS.commit.ptr, OS.gtk_im_context_get_type ()); |
578 int mask = OS.G_SIGNAL_MATCH_DATA | OS.G_SIGNAL_MATCH_ID; | |
579 OS.g_signal_handlers_unblock_matched (imContext, mask, id, 0, null, null, cast(void*)handle); | |
580 if (newChars is chars) { | |
581 OS.g_signal_emit_by_name1 (imContext, OS.commit.ptr, cast(int)text); | |
582 } else { | |
583 OS.g_signal_emit_by_name1 (imContext, OS.commit.ptr, cast(int)toStringz(newChars)); | |
584 } | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
585 OS.g_signal_handlers_unblock_matched (imContext, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCOMMIT); |
67 | 586 OS.g_signal_handlers_block_matched (imContext, mask, id, 0, null, null, cast(void*)handle); |
63 | 587 if (fixStart !is -1 && fixEnd !is -1) { |
588 OS.gtk_editable_set_position (cast(GtkEditable*)handle, fixStart); | |
589 OS.gtk_editable_select_region (cast(GtkEditable*)handle, fixStart, fixEnd); | |
590 } | |
591 fixStart = fixEnd = -1; | |
592 return 0; | |
593 } | |
594 | |
595 override int /*long*/ gtk_delete_text (GtkWidget* widget, int start_pos, int end_pos) { | |
71 | 596 if (!hooks (DWT.Verify) && !filters (DWT.Verify)) return 0; |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
597 String newText = verifyText ("", cast(int)/*64*/start_pos, cast(int)/*64*/end_pos); |
63 | 598 if (newText is null) { |
599 OS.g_signal_stop_emission_by_name (handle, OS.delete_text.ptr); | |
600 } else { | |
601 if (newText.length > 0) { | |
602 int pos; | |
603 pos = cast(int)/*64*/end_pos; | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
604 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
605 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); |
63 | 606 OS.gtk_editable_insert_text (cast(GtkEditable*)handle, newText.ptr, newText.length, &pos); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
607 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
608 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
63 | 609 OS.gtk_editable_set_position (cast(GtkEditable*)handle, pos); |
610 } | |
611 } | |
612 return 0; | |
613 } | |
614 | |
615 override int /*long*/ gtk_event_after (GtkWidget* widget, GdkEvent* gdkEvent) { | |
113
1401263f71b0
renamed setCursor(Gtk..) to gtk_setCursor, so the public interface do not need a cast for passing null
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
616 if (cursor !is null) gtk_setCursor (cursor.handle); |
63 | 617 return super.gtk_event_after (widget, gdkEvent); |
618 } | |
619 | |
620 override int /*long*/ gtk_focus_out_event (GtkWidget* widget, GdkEventFocus* event) { | |
621 fixIM (); | |
622 return super.gtk_focus_out_event (widget, event); | |
623 } | |
624 | |
625 override int /*long*/ gtk_insert_text (GtkEditable* widget, char* new_text, int new_text_length, int position) { | |
71 | 626 // if (!hooks (DWT.Verify) && !filters (DWT.Verify)) return 0; |
63 | 627 if (new_text is null || new_text_length is 0) return 0; |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
628 String oldText = new_text[ 0 .. new_text_length ].dup; |
63 | 629 int pos; |
630 pos = position; | |
631 if (pos is -1) { | |
632 auto ptr = OS.gtk_entry_get_text (cast(GtkEntry*)handle); | |
633 pos = cast(int)/*64*/OS.g_utf8_strlen (ptr, -1); | |
634 } | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
635 String newText = verifyText (oldText, pos, pos); |
63 | 636 if (newText !is oldText) { |
637 int newStart, newEnd; | |
638 OS.gtk_editable_get_selection_bounds (cast(GtkEditable*)handle, &newStart, &newEnd); | |
639 if (newText !is null) { | |
640 if (newStart !is newEnd) { | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
641 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_TEXT); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
642 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
63 | 643 OS.gtk_editable_delete_selection (cast(GtkEditable*)handle); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
644 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_TEXT); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
645 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
63 | 646 } |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
647 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); |
63 | 648 OS.gtk_editable_insert_text (cast(GtkEditable*)handle, newText.ptr, newText.length, &pos); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
649 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); |
63 | 650 newStart = newEnd = pos; |
651 } | |
652 pos = newEnd; | |
653 if (newStart !is newEnd ) { | |
654 fixStart = newStart ; | |
655 fixEnd = newEnd ; | |
656 } | |
657 position = pos; | |
658 OS.g_signal_stop_emission_by_name (handle, OS.insert_text.ptr); | |
659 } | |
660 return 0; | |
661 } | |
662 | |
663 override int /*long*/ gtk_key_press_event (GtkWidget* widget, GdkEventKey* event) { | |
664 auto result = super.gtk_key_press_event (widget, event); | |
665 if (result !is 0) fixIM (); | |
666 if (gdkEventKey is cast(GdkEventKey*)-1) result = 1; | |
667 gdkEventKey = null; | |
668 return result; | |
669 } | |
670 | |
240 | 671 override int /*long*/ gtk_populate_popup (GtkWidget* widget, GtkWidget* menu) { |
672 if ((style & DWT.RIGHT_TO_LEFT) !is 0) { | |
673 OS.gtk_widget_set_direction (menu, OS.GTK_TEXT_DIR_RTL); | |
674 display.doSetDirectionProc( menu, OS.GTK_TEXT_DIR_RTL); | |
675 } | |
676 return 0; | |
677 } | |
678 | |
63 | 679 override int /*long*/ gtk_value_changed (int adjustment) { |
71 | 680 postEvent (DWT.Selection); |
63 | 681 return 0; |
682 } | |
683 | |
684 override void hookEvents () { | |
685 super.hookEvents(); | |
686 OS.g_signal_connect_closure (handle, OS.changed.ptr, display.closures [CHANGED], true); | |
687 OS.g_signal_connect_closure (handle, OS.insert_text.ptr, display.closures [INSERT_TEXT], false); | |
688 OS.g_signal_connect_closure (handle, OS.delete_text.ptr, display.closures [DELETE_TEXT], false); | |
689 OS.g_signal_connect_closure (handle, OS.value_changed.ptr, display.closures [VALUE_CHANGED], false); | |
690 OS.g_signal_connect_closure (handle, OS.activate.ptr, display.closures [ACTIVATE], false); | |
240 | 691 OS.g_signal_connect_closure (handle, OS.populate_popup.ptr, display.closures [POPULATE_POPUP], false); |
63 | 692 auto imContext = imContext (); |
693 if (imContext !is null) { | |
694 OS.g_signal_connect_closure (imContext, OS.commit.ptr, display.closures [COMMIT], false); | |
695 int id = OS.g_signal_lookup (OS.commit.ptr, OS.gtk_im_context_get_type ()); | |
696 int mask = OS.G_SIGNAL_MATCH_DATA | OS.G_SIGNAL_MATCH_ID; | |
67 | 697 OS.g_signal_handlers_block_matched (imContext, mask, id, 0, null, null, cast(void*)handle); |
63 | 698 } |
699 } | |
700 | |
701 GtkIMContext* imContext () { | |
702 return OS.GTK_ENTRY_IM_CONTEXT (cast(GtkEntry*)handle); | |
703 } | |
704 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
705 override GdkDrawable* paintWindow () { |
63 | 706 auto window = super.paintWindow (); |
707 auto children = OS.gdk_window_get_children (window); | |
708 if (children !is null) window = cast(GdkDrawable*)OS.g_list_data (children); | |
709 OS.g_list_free (children); | |
710 return window; | |
711 } | |
712 | |
713 /** | |
714 * Pastes text from clipboard. | |
715 * <p> | |
716 * The selected text is deleted from the widget | |
717 * and new text inserted from the clipboard. | |
718 * </p> | |
719 * | |
71 | 720 * @exception DWTException <ul> |
63 | 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 public void paste () { | |
726 checkWidget (); | |
727 OS.gtk_editable_paste_clipboard (cast(GtkEditable*)handle); | |
728 } | |
729 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
730 override void register () { |
63 | 731 super.register (); |
732 auto imContext = imContext (); | |
733 if (imContext !is null) display.addWidget (cast(GtkWidget*)imContext, this); | |
734 } | |
735 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
736 override void releaseWidget () { |
63 | 737 super.releaseWidget (); |
738 fixIM (); | |
739 } | |
740 | |
741 /** | |
742 * Removes the listener from the collection of listeners who will | |
743 * be notified when the receiver's text is modified. | |
744 * | |
745 * @param listener the listener which should no longer be notified | |
746 * | |
747 * @exception IllegalArgumentException <ul> | |
748 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
749 * </ul> | |
71 | 750 * @exception DWTException <ul> |
63 | 751 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
752 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
753 * </ul> | |
754 * | |
755 * @see ModifyListener | |
756 * @see #addModifyListener | |
757 */ | |
758 public void removeModifyListener (ModifyListener listener) { | |
759 checkWidget (); | |
71 | 760 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
63 | 761 if (eventTable is null) return; |
71 | 762 eventTable.unhook (DWT.Modify, listener); |
63 | 763 } |
764 | |
765 /** | |
766 * Removes the listener from the collection of listeners who will | |
767 * be notified when the control is selected by the user. | |
768 * | |
769 * @param listener the listener which should no longer be notified | |
770 * | |
771 * @exception IllegalArgumentException <ul> | |
772 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
773 * </ul> | |
71 | 774 * @exception DWTException <ul> |
63 | 775 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
776 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
777 * </ul> | |
778 * | |
779 * @see SelectionListener | |
780 * @see #addSelectionListener | |
781 */ | |
782 public void removeSelectionListener(SelectionListener listener) { | |
783 checkWidget (); | |
71 | 784 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
63 | 785 if (eventTable is null) return; |
71 | 786 eventTable.unhook(DWT.Selection, listener); |
787 eventTable.unhook(DWT.DefaultSelection,listener); | |
63 | 788 } |
789 | |
790 /** | |
791 * Removes the listener from the collection of listeners who will | |
792 * be notified when the control is verified. | |
793 * | |
794 * @param listener the listener which should be notified | |
795 * | |
796 * @exception IllegalArgumentException <ul> | |
797 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
798 * </ul> | |
71 | 799 * @exception DWTException <ul> |
63 | 800 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
801 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
802 * </ul> | |
803 * | |
804 * @see VerifyListener | |
805 * @see #addVerifyListener | |
806 */ | |
807 void removeVerifyListener (VerifyListener listener) { | |
808 checkWidget (); | |
71 | 809 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
63 | 810 if (eventTable is null) return; |
71 | 811 eventTable.unhook (DWT.Verify, listener); |
63 | 812 } |
813 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
814 override void setBackgroundColor (GdkColor* color) { |
63 | 815 super.setBackgroundColor (color); |
816 OS.gtk_widget_modify_base (handle, 0, color); | |
817 } | |
818 | |
113
1401263f71b0
renamed setCursor(Gtk..) to gtk_setCursor, so the public interface do not need a cast for passing null
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
819 override void gtk_setCursor (GdkCursor* cursor) { |
63 | 820 GdkCursor* defaultCursor; |
821 if (cursor is null) defaultCursor = OS.gdk_cursor_new (OS.GDK_XTERM); | |
113
1401263f71b0
renamed setCursor(Gtk..) to gtk_setCursor, so the public interface do not need a cast for passing null
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
822 super.gtk_setCursor (cursor !is null ? cursor : defaultCursor); |
63 | 823 if (cursor is null) OS.gdk_cursor_destroy (defaultCursor); |
824 } | |
825 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
826 override void setFontDescription (PangoFontDescription* font) { |
63 | 827 super.setFontDescription (font); |
828 } | |
829 | |
830 /** | |
831 * Sets the amount that the receiver's value will be | |
832 * modified by when the up/down arrows are pressed to | |
833 * the argument, which must be at least one. | |
834 * | |
835 * @param value the new increment (must be greater than zero) | |
836 * | |
71 | 837 * @exception DWTException <ul> |
63 | 838 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
839 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
840 * </ul> | |
841 */ | |
842 public void setIncrement (int value) { | |
843 checkWidget (); | |
844 if (value < 1) return; | |
845 auto adjustment = OS.gtk_spin_button_get_adjustment (cast(GtkSpinButton*)handle); | |
846 double newValue = value; | |
847 int digits = OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle); | |
848 for (int i = 0; i < digits; i++) newValue /= 10; | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
849 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udVALUE_CHANGED); |
63 | 850 OS.gtk_spin_button_set_increments (cast(GtkSpinButton*)handle, newValue, adjustment.page_increment); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
851 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udVALUE_CHANGED); |
63 | 852 } |
853 | |
854 /** | |
855 * Sets the maximum value that the receiver will allow. This new | |
856 * value will be ignored if it is not greater than the receiver's current | |
857 * minimum value. If the new maximum is applied then the receiver's | |
858 * selection value will be adjusted if necessary to fall within its new range. | |
859 * | |
860 * @param value the new maximum, which must be greater than the current minimum | |
861 * | |
71 | 862 * @exception DWTException <ul> |
63 | 863 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
864 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
865 * </ul> | |
866 */ | |
867 public void setMaximum (int value) { | |
868 checkWidget (); | |
869 auto adjustment = OS.gtk_spin_button_get_adjustment (cast(GtkSpinButton*)handle); | |
870 double newValue = value; | |
871 int digits = OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle); | |
872 for (int i = 0; i < digits; i++) newValue /= 10; | |
873 if (newValue <= adjustment.lower) return; | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
874 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udVALUE_CHANGED); |
63 | 875 OS.gtk_spin_button_set_range (cast(GtkSpinButton*)handle, adjustment.lower, newValue); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
876 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udVALUE_CHANGED); |
63 | 877 } |
878 | |
879 /** | |
880 * Sets the minimum value that the receiver will allow. This new | |
881 * value will be ignored if it is negative or is not less than the receiver's | |
882 * current maximum value. If the new minimum is applied then the receiver's | |
883 * selection value will be adjusted if necessary to fall within its new range. | |
884 * | |
885 * @param value the new minimum, which must be nonnegative and less than the current maximum | |
886 * | |
71 | 887 * @exception DWTException <ul> |
63 | 888 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
889 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
890 * </ul> | |
891 */ | |
892 public void setMinimum (int value) { | |
893 checkWidget (); | |
894 auto adjustment = OS.gtk_spin_button_get_adjustment (cast(GtkSpinButton*)handle); | |
895 double newValue = value; | |
896 int digits = OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle); | |
897 for (int i = 0; i < digits; i++) newValue /= 10; | |
898 if (newValue >= adjustment.upper) return; | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
899 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udVALUE_CHANGED); |
63 | 900 OS.gtk_spin_button_set_range (cast(GtkSpinButton*)handle, newValue, adjustment.upper); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
901 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udVALUE_CHANGED); |
63 | 902 } |
903 | |
904 /** | |
905 * Sets the amount that the receiver's position will be | |
906 * modified by when the page up/down keys are pressed | |
907 * to the argument, which must be at least one. | |
908 * | |
909 * @param value the page increment (must be greater than zero) | |
910 * | |
71 | 911 * @exception DWTException <ul> |
63 | 912 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
913 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
914 * </ul> | |
915 */ | |
916 public void setPageIncrement (int value) { | |
917 checkWidget (); | |
918 if (value < 1) return; | |
919 auto adjustment = OS.gtk_spin_button_get_adjustment (cast(GtkSpinButton*)handle); | |
920 double newValue = value; | |
921 int digits = OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle); | |
922 for (int i = 0; i < digits; i++) newValue /= 10; | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
923 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udVALUE_CHANGED); |
63 | 924 OS.gtk_spin_button_set_increments (cast(GtkSpinButton*)handle, adjustment.step_increment, newValue); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
925 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udVALUE_CHANGED); |
63 | 926 } |
927 | |
928 /** | |
929 * Sets the <em>selection</em>, which is the receiver's | |
930 * position, to the argument. If the argument is not within | |
931 * the range specified by minimum and maximum, it will be | |
932 * adjusted to fall within this range. | |
933 * | |
934 * @param value the new selection (must be zero or greater) | |
935 * | |
71 | 936 * @exception DWTException <ul> |
63 | 937 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
938 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
939 * </ul> | |
940 */ | |
941 public void setSelection (int value) { | |
942 checkWidget (); | |
943 double newValue = value; | |
944 int digits = OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle); | |
945 for (int i = 0; i < digits; i++) newValue /= 10; | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
946 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udVALUE_CHANGED); |
63 | 947 OS.gtk_spin_button_set_value (cast(GtkSpinButton*)handle, newValue); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
948 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udVALUE_CHANGED); |
63 | 949 } |
950 | |
240 | 951 public void setTextLimit (int limit) { |
952 checkWidget (); | |
953 if (limit is 0) error (DWT.ERROR_CANNOT_BE_ZERO); | |
954 OS.gtk_entry_set_max_length (handle, limit); | |
955 } | |
956 | |
63 | 957 /** |
958 * Sets the number of decimal places used by the receiver. | |
959 * <p> | |
960 * The digit setting is used to allow for floating point values in the receiver. | |
961 * For example, to set the selection to a floating point value of 1.37 call setDigits() with | |
962 * a value of 2 and setSelection() with a value of 137. Similarly, if getDigits() has a value | |
963 * of 2 and getSelection() returns 137 this should be interpreted as 1.37. This applies to all | |
964 * numeric APIs. | |
965 * </p> | |
966 * | |
967 * @param value the new digits (must be greater than or equal to zero) | |
968 * | |
969 * @exception IllegalArgumentException <ul> | |
970 * <li>ERROR_INVALID_ARGUMENT - if the value is less than zero</li> | |
971 * </ul> | |
71 | 972 * @exception DWTException <ul> |
63 | 973 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
974 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
975 * </ul> | |
976 */ | |
977 public void setDigits (int value) { | |
978 checkWidget (); | |
71 | 979 if (value < 0) error (DWT.ERROR_INVALID_ARGUMENT); |
63 | 980 int digits = OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle); |
981 if (value is digits) return; | |
982 auto adjustment = OS.gtk_spin_button_get_adjustment (cast(GtkSpinButton*)handle); | |
983 int diff = Math.abs (value - digits); | |
984 int factor = 1; | |
985 for (int i = 0; i < diff; i++) factor *= 10; | |
986 if (digits > value) { | |
987 adjustment.value *= factor; | |
988 adjustment.upper *= factor; | |
989 adjustment.lower *= factor; | |
990 adjustment.step_increment *= factor; | |
991 adjustment.page_increment *= factor; | |
992 } else { | |
993 adjustment.value /= factor; | |
994 adjustment.upper /= factor; | |
995 adjustment.lower /= factor; | |
996 adjustment.step_increment /= factor; | |
997 adjustment.page_increment /= factor; | |
998 } | |
999 OS.gtk_spin_button_set_digits (cast(GtkSpinButton*)handle, value); | |
1000 } | |
1001 | |
1002 /** | |
1003 * Sets the receiver's selection, minimum value, maximum | |
1004 * value, digits, increment and page increment all at once. | |
1005 * <p> | |
1006 * Note: This is similar to setting the values individually | |
1007 * using the appropriate methods, but may be implemented in a | |
1008 * more efficient fashion on some platforms. | |
1009 * </p> | |
1010 * | |
1011 * @param selection the new selection value | |
1012 * @param minimum the new minimum value | |
1013 * @param maximum the new maximum value | |
1014 * @param digits the new digits value | |
1015 * @param increment the new increment value | |
1016 * @param pageIncrement the new pageIncrement value | |
1017 * | |
71 | 1018 * @exception DWTException <ul> |
63 | 1019 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1020 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1021 * </ul> | |
1022 * | |
1023 * @since 3.2 | |
1024 */ | |
1025 public void setValues (int selection, int minimum, int maximum, int digits, int increment, int pageIncrement) { | |
1026 checkWidget (); | |
1027 if (maximum <= minimum) return; | |
1028 if (digits < 0) return; | |
1029 if (increment < 1) return; | |
1030 if (pageIncrement < 1) return; | |
1031 selection = Math.min (Math.max (minimum, selection), maximum); | |
1032 double factor = 1; | |
1033 for (int i = 0; i < digits; i++) factor *= 10; | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
1034 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udVALUE_CHANGED); |
63 | 1035 OS.gtk_spin_button_set_range (cast(GtkSpinButton*)handle, minimum / factor, maximum / factor); |
1036 OS.gtk_spin_button_set_increments (cast(GtkSpinButton*)handle, increment / factor, pageIncrement / factor); | |
1037 OS.gtk_spin_button_set_value (cast(GtkSpinButton*)handle, selection / factor); | |
1038 OS.gtk_spin_button_set_digits (cast(GtkSpinButton*)handle, digits); | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
63
diff
changeset
|
1039 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udVALUE_CHANGED); |
63 | 1040 } |
1041 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
1042 override bool translateTraversal (GdkEventKey* keyEvent) { |
63 | 1043 int key = keyEvent.keyval; |
1044 switch (key) { | |
1045 case OS.GDK_KP_Enter: | |
1046 case OS.GDK_Return: { | |
1047 auto imContext = imContext (); | |
1048 if (imContext !is null) { | |
1049 char* preeditString; | |
1050 OS.gtk_im_context_get_preedit_string (imContext, &preeditString, null, null); | |
1051 if (preeditString !is null) { | |
1052 int length = tango.stdc.string.strlen (preeditString); | |
1053 OS.g_free (preeditString); | |
1054 if (length !is 0) return false; | |
1055 } | |
1056 } | |
1057 default: | |
1058 } | |
1059 } | |
1060 return super.translateTraversal (keyEvent); | |
1061 } | |
1062 | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
1063 String verifyText (String string, int start, int end) { |
63 | 1064 if (string.length is 0 && start is end) return null; |
1065 Event event = new Event (); | |
1066 event.text = string; | |
1067 event.start = start; | |
1068 event.end = end; | |
1069 auto eventPtr = OS.gtk_get_current_event (); | |
1070 if (eventPtr !is null) { | |
1071 GdkEventKey* gdkEvent = cast(GdkEventKey*)eventPtr; | |
1072 switch (gdkEvent.type) { | |
1073 case OS.GDK_KEY_PRESS: | |
1074 setKeyState (event, gdkEvent); | |
1075 break; | |
1076 default: | |
1077 } | |
1078 OS.gdk_event_free (eventPtr); | |
1079 } | |
1080 int index = 0; | |
1081 if (OS.gtk_spin_button_get_digits (cast(GtkSpinButton*)handle) > 0) { | |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
1082 String decimalSeparator = getDecimalSeparator (); |
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
1083 index = string.indexOf( decimalSeparator ); |
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
1084 if (index !is -1 ) { |
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
1085 string = string.substring( 0, index ) ~ string.substring( index + 1 ); |
63 | 1086 } |
1087 index = 0; | |
1088 } | |
240 | 1089 if (string.length > 0) { |
1090 auto adjustment = OS.gtk_spin_button_get_adjustment (handle); | |
1091 if (adjustment.lower < 0 && string.charAt (0) is '-') index++; | |
1092 } | |
63 | 1093 while (index < string.length) { |
212
8ab606c00520
Fix side effects in getter methods
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
1094 if (!CharacterIsDigit (string.charAt(index))) break; |
63 | 1095 index++; |
1096 } | |
1097 event.doit = index is string.length; | |
1098 /* | |
1099 * It is possible (but unlikely), that application | |
1100 * code could have disposed the widget in the verify | |
1101 * event. If this happens, answer null to cancel | |
1102 * the operation. | |
1103 */ | |
71 | 1104 sendEvent (DWT.Verify, event); |
63 | 1105 if (!event.doit || isDisposed ()) return null; |
1106 return event.text; | |
1107 } | |
1108 | |
1109 } |