Mercurial > projects > dwt-linux
annotate dwt/widgets/Combo.d @ 241:4653e99936cf
Fix missing switch default in Combo
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 12 May 2008 19:27:09 +0200 |
parents | ce446666f5a2 |
children | 5a30aa9820f3 |
rev | line source |
---|---|
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
1 /******************************************************************************* |
69 | 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> | |
69 | 12 *******************************************************************************/ |
13 module dwt.widgets.Combo; | |
14 | |
15 | |
71 | 16 import dwt.DWT; |
69 | 17 import dwt.internal.gtk.OS; |
18 import dwt.graphics.Point; | |
19 import dwt.events.SelectionListener; | |
20 import dwt.events.SelectionEvent; | |
21 import dwt.events.ModifyListener; | |
22 import dwt.events.VerifyListener; | |
23 import dwt.widgets.Shell; | |
24 import dwt.widgets.Composite; | |
25 import dwt.widgets.Event; | |
26 import dwt.widgets.TypedListener; | |
27 | |
200
08789b28bdf3
import dwt.dwthelper.utils now explicit
Frank Benoit <benoit@tionex.de>
parents:
158
diff
changeset
|
28 import dwt.dwthelper.utils; |
69 | 29 import tango.stdc.stringz; |
30 import Math = tango.math.Math; | |
31 | |
32 /** | |
33 * Instances of this class are controls that allow the user | |
34 * to choose an item from a list of items, or optionally | |
35 * enter a new value by typing it into an editable text | |
36 * field. Often, <code>Combo</code>s are used in the same place | |
37 * where a single selection <code>List</code> widget could | |
38 * be used but space is limited. A <code>Combo</code> takes | |
39 * less space than a <code>List</code> widget and shows | |
40 * similar information. | |
41 * <p> | |
42 * Note: Since <code>Combo</code>s can contain both a list | |
43 * and an editable text field, it is possible to confuse methods | |
44 * which access one versus the other (compare for example, | |
45 * <code>clearSelection()</code> and <code>deselectAll()</code>). | |
46 * The API documentation is careful to indicate either "the | |
47 * receiver's list" or the "the receiver's text field" to | |
48 * distinguish between the two cases. | |
49 * </p><p> | |
50 * Note that although this class is a subclass of <code>Composite</code>, | |
51 * it does not make sense to add children to it, or set a layout on it. | |
52 * </p> | |
53 * <dl> | |
54 * <dt><b>Styles:</b></dt> | |
55 * <dd>DROP_DOWN, READ_ONLY, SIMPLE</dd> | |
56 * <dt><b>Events:</b></dt> | |
57 * <dd>DefaultSelection, Modify, Selection, Verify</dd> | |
58 * </dl> | |
59 * <p> | |
60 * Note: Only one of the styles DROP_DOWN and SIMPLE may be specified. | |
61 * </p><p> | |
62 * IMPORTANT: This class is <em>not</em> intended to be subclassed. | |
63 * </p> | |
64 * | |
65 * @see List | |
66 */ | |
67 public class Combo : Composite { | |
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
68 |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
69 alias Composite.computeSize computeSize; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
70 alias Composite.createHandle createHandle; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
71 alias Composite.dragDetect dragDetect; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
72 alias Composite.setBackgroundColor setBackgroundColor; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
73 alias Composite.setBounds setBounds; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
74 alias Composite.setForegroundColor setForegroundColor; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
75 alias Composite.setToolTipText setToolTipText; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
76 alias Composite.translateTraversal translateTraversal; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
77 |
240 | 78 GtkWidget* buttonHandle, entryHandle, listHandle, textRenderer, cellHandle, popupHandle; |
69 | 79 int lastEventTime, visibleCount = 5; |
80 GdkEventKey* gdkEventKey; | |
81 int fixStart = -1, fixEnd = -1; | |
238 | 82 String[] items; |
69 | 83 bool ignoreSelect, lockText; |
84 | |
85 static const int INNER_BORDER = 2; | |
86 | |
87 /** | |
88 * the operating system limit for the number of characters | |
89 * that the text field in an instance of this class can hold | |
90 */ | |
91 public const static int LIMIT = 0xFFFF; | |
92 | |
93 /* | |
94 * These values can be different on different platforms. | |
95 * Therefore they are not initialized in the declaration | |
96 * to stop the compiler from inlining. | |
97 */ | |
98 //static { | |
99 // LIMIT = 0xFFFF; | |
100 //} | |
101 | |
102 /** | |
103 * Constructs a new instance of this class given its parent | |
104 * and a style value describing its behavior and appearance. | |
105 * <p> | |
106 * The style value is either one of the style constants defined in | |
71 | 107 * class <code>DWT</code> which is applicable to instances of this |
69 | 108 * class, or must be built by <em>bitwise OR</em>'ing together |
109 * (that is, using the <code>int</code> "|" operator) two or more | |
71 | 110 * of those <code>DWT</code> style constants. The class description |
69 | 111 * lists the style constants that are applicable to the class. |
112 * Style bits are also inherited from superclasses. | |
113 * </p> | |
114 * | |
115 * @param parent a composite control which will be the parent of the new instance (cannot be null) | |
116 * @param style the style of control to construct | |
117 * | |
118 * @exception IllegalArgumentException <ul> | |
119 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
120 * </ul> | |
71 | 121 * @exception DWTException <ul> |
69 | 122 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> |
123 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
124 * </ul> | |
125 * | |
71 | 126 * @see DWT#DROP_DOWN |
127 * @see DWT#READ_ONLY | |
128 * @see DWT#SIMPLE | |
69 | 129 * @see Widget#checkSubclass |
130 * @see Widget#getStyle | |
131 */ | |
132 public this (Composite parent, int style) { | |
133 super (parent, checkStyle (style)); | |
134 } | |
135 | |
136 /** | |
137 * Adds the argument to the end of the receiver's list. | |
138 * | |
139 * @param string the new item | |
140 * | |
141 * @exception IllegalArgumentException <ul> | |
142 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
143 * </ul> | |
71 | 144 * @exception DWTException <ul> |
69 | 145 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
146 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
147 * </ul> | |
148 * | |
149 * @see #add(String,int) | |
150 */ | |
238 | 151 public void add (String string) { |
69 | 152 checkWidget(); |
71 | 153 if (string is null) error (DWT.ERROR_NULL_ARGUMENT); |
69 | 154 add (string, items.length); |
155 } | |
156 | |
157 /** | |
158 * Adds the argument to the receiver's list at the given | |
159 * zero-relative index. | |
160 * <p> | |
161 * Note: To add an item at the end of the list, use the | |
162 * result of calling <code>getItemCount()</code> as the | |
163 * index or use <code>add(String)</code>. | |
164 * </p> | |
165 * | |
166 * @param string the new item | |
167 * @param index the index for the item | |
168 * | |
169 * @exception IllegalArgumentException <ul> | |
170 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
171 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list (inclusive)</li> | |
172 * </ul> | |
71 | 173 * @exception DWTException <ul> |
69 | 174 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
175 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
176 * </ul> | |
177 * | |
178 * @see #add(String) | |
179 */ | |
238 | 180 public void add (String string, int index) { |
69 | 181 checkWidget(); |
71 | 182 if (string is null) error (DWT.ERROR_NULL_ARGUMENT); |
69 | 183 if (!(0 <= index && index <= items.length)) { |
71 | 184 error (DWT.ERROR_INVALID_RANGE); |
69 | 185 } |
238 | 186 String [] newItems = new String[]( items.length + 1 ); |
69 | 187 System.arraycopy (items, 0, newItems, 0, index); |
188 newItems [index] = string; | |
189 System.arraycopy (items, index, newItems, index + 1, items.length - index); | |
190 items = newItems; | |
191 char* buffer = toStringz(string); | |
192 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
193 OS.gtk_combo_box_insert_text (handle, index, buffer); |
240 | 194 if ((style & DWT.RIGHT_TO_LEFT) !is 0 && popupHandle !is null) { |
195 display.doSetDirectionProc( popupHandle, OS.GTK_TEXT_DIR_RTL); | |
196 } | |
69 | 197 } else { |
198 /* | |
199 * Feature in GTK. When the list is empty and the first item | |
200 * is added, the combo box selects that item replacing the | |
201 * text in the entry field. The fix is to avoid this by | |
202 * stopping the "delete" and "insert_text" signal emission. | |
203 */ | |
204 ignoreSelect = lockText = true; | |
205 auto item = OS.gtk_list_item_new_with_label (buffer); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
206 auto label = OS.gtk_bin_get_child (item); |
69 | 207 setForegroundColor (label, getForegroundColor ()); |
208 OS.gtk_widget_modify_font (label, getFontDescription ()); | |
209 OS.gtk_widget_set_direction (label, OS.gtk_widget_get_direction (handle)); | |
210 OS.gtk_widget_show (item); | |
211 auto items = OS.g_list_append (null, item); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
212 OS.gtk_list_insert_items (listHandle, items, index); |
69 | 213 ignoreSelect = lockText = false; |
214 } | |
215 } | |
216 | |
217 /** | |
218 * Adds the listener to the collection of listeners who will | |
219 * be notified when the receiver's text is modified, by sending | |
220 * it one of the messages defined in the <code>ModifyListener</code> | |
221 * interface. | |
222 * | |
223 * @param listener the listener which should be notified | |
224 * | |
225 * @exception IllegalArgumentException <ul> | |
226 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
227 * </ul> | |
71 | 228 * @exception DWTException <ul> |
69 | 229 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
230 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
231 * </ul> | |
232 * | |
233 * @see ModifyListener | |
234 * @see #removeModifyListener | |
235 */ | |
236 public void addModifyListener (ModifyListener listener) { | |
237 checkWidget(); | |
71 | 238 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
69 | 239 TypedListener typedListener = new TypedListener (listener); |
71 | 240 addListener (DWT.Modify, typedListener); |
69 | 241 } |
242 | |
243 /** | |
244 * Adds the listener to the collection of listeners who will | |
245 * be notified when the user changes the receiver's selection, by sending | |
246 * it one of the messages defined in the <code>SelectionListener</code> | |
247 * interface. | |
248 * <p> | |
249 * <code>widgetSelected</code> is called when the user changes the combo's list selection. | |
250 * <code>widgetDefaultSelected</code> is typically called when ENTER is pressed the combo's text area. | |
251 * </p> | |
252 * | |
253 * @param listener the listener which should be notified | |
254 * | |
255 * @exception IllegalArgumentException <ul> | |
256 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
257 * </ul> | |
71 | 258 * @exception DWTException <ul> |
69 | 259 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
260 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
261 * </ul> | |
262 * | |
263 * @see SelectionListener | |
264 * @see #removeSelectionListener | |
265 * @see SelectionEvent | |
266 */ | |
267 public void addSelectionListener(SelectionListener listener) { | |
268 checkWidget(); | |
71 | 269 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
69 | 270 TypedListener typedListener = new TypedListener (listener); |
71 | 271 addListener (DWT.Selection,typedListener); |
272 addListener (DWT.DefaultSelection,typedListener); | |
69 | 273 } |
274 | |
275 /** | |
276 * Adds the listener to the collection of listeners who will | |
277 * be notified when the receiver's text is verified, by sending | |
278 * it one of the messages defined in the <code>VerifyListener</code> | |
279 * interface. | |
280 * | |
281 * @param listener the listener which should be notified | |
282 * | |
283 * @exception IllegalArgumentException <ul> | |
284 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
285 * </ul> | |
71 | 286 * @exception DWTException <ul> |
69 | 287 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
288 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
289 * </ul> | |
290 * | |
291 * @see VerifyListener | |
292 * @see #removeVerifyListener | |
293 * | |
294 * @since 3.1 | |
295 */ | |
296 public void addVerifyListener (VerifyListener listener) { | |
297 checkWidget (); | |
71 | 298 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
69 | 299 TypedListener typedListener = new TypedListener (listener); |
71 | 300 addListener (DWT.Verify, typedListener); |
69 | 301 } |
302 | |
303 static int checkStyle (int style) { | |
304 /* | |
305 * Feature in Windows. It is not possible to create | |
306 * a combo box that has a border using Windows style | |
307 * bits. All combo boxes draw their own border and | |
308 * do not use the standard Windows border styles. | |
309 * Therefore, no matter what style bits are specified, | |
71 | 310 * clear the BORDER bits so that the DWT style will |
69 | 311 * match the Windows widget. |
312 * | |
313 * The Windows behavior is currently implemented on | |
314 * all platforms. | |
315 */ | |
71 | 316 style &= ~DWT.BORDER; |
69 | 317 |
318 /* | |
319 * Even though it is legal to create this widget | |
320 * with scroll bars, they serve no useful purpose | |
321 * because they do not automatically scroll the | |
322 * widget's client area. The fix is to clear | |
71 | 323 * the DWT style. |
69 | 324 */ |
71 | 325 style &= ~(DWT.H_SCROLL | DWT.V_SCROLL); |
326 style = checkBits (style, DWT.DROP_DOWN, DWT.SIMPLE, 0, 0, 0, 0); | |
327 if ((style & DWT.SIMPLE) !is 0) return style & ~DWT.READ_ONLY; | |
69 | 328 return style; |
329 } | |
330 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
331 protected override void checkSubclass () { |
71 | 332 if (!isValidSubclass ()) error (DWT.ERROR_INVALID_SUBCLASS); |
69 | 333 } |
334 | |
335 /** | |
336 * Sets the selection in the receiver's text field to an empty | |
337 * selection starting just before the first character. If the | |
338 * text field is editable, this has the effect of placing the | |
339 * i-beam at the start of the text. | |
340 * <p> | |
341 * Note: To clear the selected items in the receiver's list, | |
342 * use <code>deselectAll()</code>. | |
343 * </p> | |
344 * | |
71 | 345 * @exception DWTException <ul> |
69 | 346 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
347 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
348 * </ul> | |
349 * | |
350 * @see #deselectAll | |
351 */ | |
352 public void clearSelection () { | |
353 checkWidget(); | |
354 if (entryHandle !is null) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
355 int position = OS.gtk_editable_get_position (entryHandle); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
356 OS.gtk_editable_select_region (entryHandle, position, position); |
69 | 357 } |
358 } | |
359 | |
360 void clearText () { | |
361 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
362 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); | |
71 | 363 if ((style & DWT.READ_ONLY) !is 0) { |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
364 int index = OS.gtk_combo_box_get_active (handle); |
69 | 365 if (index !is -1) { |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
366 auto modelHandle = OS.gtk_combo_box_get_model (handle); |
69 | 367 char* ptr; |
368 GtkTreeIter iter; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
369 OS.gtk_tree_model_iter_nth_child (modelHandle, &iter, null, index); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
370 OS.gtk_tree_model_get1 (modelHandle, &iter, 0, cast(void**)&ptr ); |
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
|
371 if (fromStringz(ptr).length > 0) postEvent (DWT.Modify); |
69 | 372 OS.g_free (ptr); |
373 } | |
374 } else { | |
375 char dummy = '\0'; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
376 OS.gtk_entry_set_text (entryHandle, &dummy ); |
69 | 377 } |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
378 OS.gtk_combo_box_set_active (handle, -1); |
69 | 379 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
380 } | |
381 } | |
382 | |
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
383 public override Point computeSize (int wHint, int hHint, bool changed) { |
69 | 384 checkWidget (); |
385 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
386 return computeNativeSize (handle, wHint, hHint, changed); | |
387 } | |
71 | 388 if (wHint !is DWT.DEFAULT && wHint < 0) wHint = 0; |
389 if (hHint !is DWT.DEFAULT && hHint < 0) hHint = 0; | |
69 | 390 int w, h; |
391 OS.gtk_widget_realize (entryHandle); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
392 auto layout = OS.gtk_entry_get_layout (entryHandle); |
69 | 393 OS.pango_layout_get_size (layout, &w, &h); |
394 int xborder = INNER_BORDER, yborder = INNER_BORDER; | |
395 auto style = OS.gtk_widget_get_style (entryHandle); | |
396 xborder += OS.gtk_style_get_xthickness (style); | |
397 yborder += OS.gtk_style_get_ythickness (style); | |
398 int property; | |
399 OS.gtk_widget_style_get1 (entryHandle, OS.interior_focus.ptr, &property); | |
400 if (property is 0) { | |
401 OS.gtk_widget_style_get1 (entryHandle, OS.focus_line_width.ptr, &property); | |
402 xborder += property ; | |
403 yborder += property ; | |
404 } | |
405 int width = OS.PANGO_PIXELS (w ) + xborder * 2; | |
406 int height = OS.PANGO_PIXELS (h ) + yborder * 2; | |
407 | |
408 GtkRequisition arrowRequesition; | |
409 OS.gtk_widget_size_request (buttonHandle, &arrowRequesition); | |
410 GtkRequisition listRequesition; | |
411 auto listParent = OS.gtk_widget_get_parent (listHandle); | |
412 OS.gtk_widget_size_request (listParent !is null ? listParent : listHandle, &listRequesition); | |
413 | |
414 width = Math.max (listRequesition.width, width) + arrowRequesition.width + 4; | |
71 | 415 width = wHint is DWT.DEFAULT ? width : wHint; |
416 height = hHint is DWT.DEFAULT ? height : hHint; | |
69 | 417 return new Point (width, height); |
418 } | |
419 | |
420 /** | |
421 * Copies the selected text. | |
422 * <p> | |
423 * The current selection is copied to the clipboard. | |
424 * </p> | |
425 * | |
71 | 426 * @exception DWTException <ul> |
69 | 427 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
428 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
429 * </ul> | |
430 * | |
431 * @since 2.1 | |
432 */ | |
433 public void copy () { | |
434 checkWidget (); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
435 if (entryHandle !is null) OS.gtk_editable_copy_clipboard (entryHandle); |
69 | 436 } |
437 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
438 override void createHandle (int index) { |
69 | 439 state |= HANDLE | MENU; |
440 fixedHandle = cast(GtkWidget*)OS.g_object_new (display.gtk_fixed_get_type (), null); | |
71 | 441 if (fixedHandle is null) error (DWT.ERROR_NO_HANDLES); |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
442 OS.gtk_fixed_set_has_window (fixedHandle, true); |
69 | 443 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { |
240 | 444 auto oldList = OS.gtk_window_list_toplevels (); |
71 | 445 if ((style & DWT.READ_ONLY) !is 0) { |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
446 handle = OS.gtk_combo_box_new_text (); |
71 | 447 if (handle is null) error (DWT.ERROR_NO_HANDLES); |
240 | 448 cellHandle = OS.gtk_bin_get_child (handle); |
449 if (cellHandle is null) error (DWT.ERROR_NO_HANDLES); | |
69 | 450 } else { |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
451 handle = OS.gtk_combo_box_entry_new_text (); |
71 | 452 if (handle is null) error (DWT.ERROR_NO_HANDLES); |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
453 entryHandle = OS.gtk_bin_get_child (handle); |
71 | 454 if (entryHandle is null) error (DWT.ERROR_NO_HANDLES); |
69 | 455 } |
240 | 456 popupHandle = findPopupHandle (oldList); |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
457 OS.gtk_container_add (fixedHandle, handle); |
69 | 458 textRenderer = cast(GtkWidget*)OS.gtk_cell_renderer_text_new (); |
71 | 459 if (textRenderer is null) error (DWT.ERROR_NO_HANDLES); |
69 | 460 /* |
461 * Feature in GTK. In order to make a read only combo box the same | |
462 * height as an editable combo box the ypad must be set to 0. In | |
463 * versions 2.4.x of GTK, a pad of 0 will clip some letters. The | |
464 * fix is to set the pad to 1. | |
465 */ | |
466 int pad = 0; | |
467 if (OS.GTK_VERSION < OS.buildVERSION(2, 6, 0)) pad = 1; | |
468 OS.g_object_set1 (textRenderer, OS.ypad.ptr, pad); | |
469 /* | |
470 * Feature in GTK. In version 2.4.9 of GTK, a warning is issued | |
471 * when a call to gtk_cell_layout_clear() is made. The fix is to hide | |
472 * the warning. | |
473 */ | |
474 bool warnings = display.getWarnings (); | |
475 display.setWarnings (false); | |
476 OS.gtk_cell_layout_clear (handle); | |
477 display.setWarnings (warnings); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
478 OS.gtk_cell_layout_pack_start (handle, textRenderer, true); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
479 OS.gtk_cell_layout_set_attributes1 (handle, textRenderer, OS.text.ptr, null); |
69 | 480 |
481 /* | |
482 * Feature in GTK. There is no API to query the button | |
483 * handle from a combo box although it is possible to get the | |
484 * text field. The button handle is needed to hook events. The | |
485 * fix is to walk the combo tree and find the first child that is | |
486 * an instance of button. | |
487 */ | |
488 display.allChildrenCollect (handle, 0); | |
489 if (display.allChildren !is null) { | |
490 auto list = display.allChildren; | |
491 while (list !is null) { | |
492 auto widget = OS.g_list_data (list); | |
493 if (OS.GTK_IS_BUTTON (cast(GTypeInstance*)widget)) { | |
494 buttonHandle = cast(GtkWidget*)widget; | |
495 break; | |
496 } | |
497 list = OS.g_list_next (list); | |
498 } | |
499 OS.g_list_free (display.allChildren); | |
500 display.allChildren = null; | |
501 } | |
240 | 502 /* |
503 * Feature in GTK. By default, read only combo boxes | |
504 * process the RETURN key rather than allowing the | |
505 * default button to process the key. The fix is to | |
506 * clear the GTK_RECEIVES_DEFAULT flag. | |
507 */ | |
508 if ((style & DWT.READ_ONLY) !is 0 && buttonHandle !is null) { | |
509 OS.GTK_WIDGET_UNSET_FLAGS (buttonHandle, OS.GTK_RECEIVES_DEFAULT); | |
510 } | |
69 | 511 } else { |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
512 handle = OS.gtk_combo_new (); |
71 | 513 if (handle is null) error (DWT.ERROR_NO_HANDLES); |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
514 OS.gtk_container_add (fixedHandle, handle); |
69 | 515 GtkCombo* combo = cast(GtkCombo*)handle; |
516 entryHandle = combo.entry; | |
517 listHandle = combo.list; | |
518 | |
240 | 519 if (OS.GTK_VERSION < OS.buildVERSION (2, 4, 0)) { |
520 GtkWidget* parentHandle = null; | |
521 auto temp = listHandle; | |
522 while ((temp = OS.gtk_widget_get_parent(temp)) !is null) { | |
523 parentHandle = temp; | |
524 } | |
525 popupHandle = parentHandle; | |
526 if (popupHandle !is null) { | |
527 GtkWidget* modalGroup = getShell().modalGroup; | |
528 if (modalGroup !is null) { | |
529 OS.gtk_window_group_add_window (modalGroup, popupHandle); | |
530 } | |
531 } | |
532 } | |
69 | 533 /* |
534 * Feature in GTK. There is no API to query the arrow | |
535 * handle from a combo box although it is possible to | |
536 * get the list and text field. The arrow handle is needed | |
537 * to hook events. The fix is to find the first child that is | |
538 * not the entry or list and assume this is the arrow handle. | |
539 */ | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
540 auto list = OS.gtk_container_get_children (handle); |
69 | 541 if (list !is null) { |
542 int i = 0, count = OS.g_list_length (list); | |
543 while (i<count) { | |
544 auto childHandle = OS.g_list_nth_data (list, i); | |
545 if (childHandle !is entryHandle && childHandle !is listHandle) { | |
546 buttonHandle = cast(GtkWidget*)childHandle; | |
547 break; | |
548 } | |
549 i++; | |
550 } | |
551 OS.g_list_free (list); | |
552 } | |
553 | |
71 | 554 bool editable = (style & DWT.READ_ONLY) is 0; |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
555 OS.gtk_editable_set_editable (entryHandle, editable); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
556 OS.gtk_combo_disable_activate (handle); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
557 OS.gtk_combo_set_case_sensitive (handle, true); |
69 | 558 } |
559 } | |
560 | |
561 /** | |
562 * Cuts the selected text. | |
563 * <p> | |
564 * The current selection is first copied to the | |
565 * clipboard and then deleted from the widget. | |
566 * </p> | |
567 * | |
71 | 568 * @exception DWTException <ul> |
69 | 569 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
570 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
571 * </ul> | |
572 * | |
573 * @since 2.1 | |
574 */ | |
575 public void cut () { | |
576 checkWidget (); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
577 if (entryHandle !is null) OS.gtk_editable_cut_clipboard (entryHandle); |
69 | 578 } |
579 | |
580 override void deregister () { | |
581 super.deregister (); | |
582 if (buttonHandle !is null) display.removeWidget (buttonHandle); | |
583 if (entryHandle !is null) display.removeWidget (entryHandle); | |
584 if (listHandle !is null) display.removeWidget (listHandle); | |
585 auto imContext = imContext (); | |
586 if (imContext !is null) display.removeWidget (cast(GtkWidget*)imContext); | |
587 } | |
588 | |
589 override bool filterKey (int keyval, GdkEventKey* event) { | |
590 int time = OS.gdk_event_get_time (cast(GdkEvent*)event); | |
591 if (time !is lastEventTime) { | |
592 lastEventTime = time; | |
593 auto imContext = imContext (); | |
594 if (imContext !is null) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
595 return cast(bool)OS.gtk_im_context_filter_keypress (imContext, event); |
69 | 596 } |
597 } | |
598 gdkEventKey = event; | |
599 return false; | |
600 } | |
601 | |
240 | 602 GtkWidget* findPopupHandle (GList* oldList) { |
603 GtkWidget* hdl = null; | |
604 GList* currentList = OS.gtk_window_list_toplevels(); | |
605 GList* oldFromList = oldList; | |
606 GList* newFromList = currentList; | |
607 bool isFound; | |
608 while (newFromList !is null) { | |
609 void* newToplevel = OS.g_list_data(newFromList); | |
610 isFound = false; | |
611 oldFromList = oldList; | |
612 while (oldFromList !is null) { | |
613 void* oldToplevel = OS.g_list_data(oldFromList); | |
614 if (newToplevel is oldToplevel) { | |
615 isFound = true; | |
616 break; | |
617 } | |
618 oldFromList = OS.g_list_next(oldFromList); | |
619 } | |
620 if (!isFound) { | |
621 hdl = cast(GtkWidget*)newToplevel; | |
622 break; | |
623 } | |
624 newFromList = OS.g_list_next(newFromList); | |
625 } | |
626 OS.g_list_free(oldList); | |
627 OS.g_list_free(currentList); | |
628 return hdl; | |
629 } | |
630 | |
631 override void fixModal (GtkWidget* group, GtkWidget* modalGroup) { | |
632 if (popupHandle !is null) { | |
633 if (group !is null) { | |
634 OS.gtk_window_group_add_window (group, popupHandle); | |
635 } else { | |
636 if (modalGroup !is null) { | |
637 OS.gtk_window_group_remove_window (modalGroup, popupHandle); | |
638 } | |
639 } | |
640 } | |
641 } | |
642 | |
69 | 643 void fixIM () { |
644 /* | |
645 * The IM filter has to be called one time for each key press event. | |
646 * When the IM is open the key events are duplicated. The first event | |
71 | 647 * is filtered by DWT and the second event is filtered by GTK. In some |
69 | 648 * cases the GTK handler does not run (the widget is destroyed, the |
649 * application code consumes the event, etc), for these cases the IM | |
71 | 650 * filter has to be called by DWT. |
69 | 651 */ |
652 if (gdkEventKey !is null && gdkEventKey !is cast(GdkEventKey*)-1) { | |
653 auto imContext = imContext (); | |
654 if (imContext !is null) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
655 OS.gtk_im_context_filter_keypress (imContext, gdkEventKey); |
69 | 656 gdkEventKey = cast(GdkEventKey*)-1; |
657 return; | |
658 } | |
659 } | |
660 gdkEventKey = null; | |
661 } | |
662 | |
663 override GtkWidget* fontHandle () { | |
664 if (entryHandle !is null) return entryHandle; | |
665 return super.fontHandle (); | |
666 } | |
667 | |
668 override GtkWidget* focusHandle () { | |
669 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
71 | 670 if ((style & DWT.READ_ONLY) !is 0 && buttonHandle !is null) return buttonHandle; |
69 | 671 } |
672 if (entryHandle !is null) return entryHandle; | |
673 return super.focusHandle (); | |
674 } | |
675 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
676 override bool hasFocus () { |
69 | 677 if (super.hasFocus ()) return true; |
678 if (entryHandle !is null && OS.GTK_WIDGET_HAS_FOCUS (entryHandle)) return true; | |
679 if (listHandle !is null && OS.GTK_WIDGET_HAS_FOCUS (listHandle)) return true; | |
680 return false; | |
681 } | |
682 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
683 override void hookEvents () { |
69 | 684 super.hookEvents (); |
685 if (OS.GTK_VERSION >= OS.buildVERSION(2, 4, 0)) { | |
686 OS.g_signal_connect_closure (handle, OS.changed.ptr, display.closures [CHANGED], true); | |
687 } | |
688 | |
689 if (entryHandle !is null) { | |
690 OS.g_signal_connect_closure (entryHandle, OS.changed.ptr, display.closures [CHANGED], true); | |
691 OS.g_signal_connect_closure (entryHandle, OS.insert_text.ptr, display.closures [INSERT_TEXT], false); | |
692 OS.g_signal_connect_closure (entryHandle, OS.delete_text.ptr, display.closures [DELETE_TEXT], false); | |
693 OS.g_signal_connect_closure (entryHandle, OS.activate.ptr, display.closures [ACTIVATE], false); | |
240 | 694 OS.g_signal_connect_closure (entryHandle, OS.populate_popup.ptr, display.closures [POPULATE_POPUP], false); |
69 | 695 } |
696 int eventMask = OS.GDK_POINTER_MOTION_MASK | OS.GDK_BUTTON_PRESS_MASK | | |
697 OS.GDK_BUTTON_RELEASE_MASK; | |
698 GtkWidget*[] handles = [ buttonHandle, entryHandle, listHandle ]; | |
699 for (int i=0; i<handles.length; i++) { | |
700 auto eventHandle = handles [i]; | |
701 if (eventHandle !is null) { | |
702 /* Connect the mouse signals */ | |
703 OS.gtk_widget_add_events (eventHandle, eventMask); | |
704 OS.g_signal_connect_closure_by_id (eventHandle, display.signalIds [BUTTON_PRESS_EVENT], 0, display.closures [BUTTON_PRESS_EVENT], false); | |
705 OS.g_signal_connect_closure_by_id (eventHandle, display.signalIds [BUTTON_RELEASE_EVENT], 0, display.closures [BUTTON_RELEASE_EVENT], false); | |
706 OS.g_signal_connect_closure_by_id (eventHandle, display.signalIds [MOTION_NOTIFY_EVENT], 0, display.closures [MOTION_NOTIFY_EVENT], false); | |
707 /* | |
708 * Feature in GTK. Events such as mouse move are propagated up | |
709 * the widget hierarchy and are seen by the parent. This is the | |
71 | 710 * correct GTK behavior but not correct for DWT. The fix is to |
69 | 711 * hook a signal after and stop the propagation using a negative |
712 * event number to distinguish this case. | |
713 */ | |
714 OS.g_signal_connect_closure_by_id (eventHandle, display.signalIds [BUTTON_PRESS_EVENT], 0, display.closures [BUTTON_PRESS_EVENT_INVERSE], true); | |
715 OS.g_signal_connect_closure_by_id (eventHandle, display.signalIds [BUTTON_RELEASE_EVENT], 0, display.closures [BUTTON_RELEASE_EVENT_INVERSE], true); | |
716 OS.g_signal_connect_closure_by_id (eventHandle, display.signalIds [MOTION_NOTIFY_EVENT], 0, display.closures [MOTION_NOTIFY_EVENT_INVERSE], true); | |
717 | |
718 /* Connect the event_after signal for both key and mouse */ | |
719 if (eventHandle !is focusHandle ()) { | |
720 OS.g_signal_connect_closure_by_id (eventHandle, display.signalIds [EVENT_AFTER], 0, display.closures [EVENT_AFTER], false); | |
721 } | |
722 } | |
723 } | |
724 auto imContext = imContext (); | |
725 if (imContext !is null) { | |
726 OS.g_signal_connect_closure (imContext, OS.commit.ptr, display.closures [COMMIT], false); | |
727 int id = OS.g_signal_lookup (OS.commit.ptr, OS.gtk_im_context_get_type ()); | |
728 int blockMask = OS.G_SIGNAL_MATCH_DATA | OS.G_SIGNAL_MATCH_ID; | |
729 OS.g_signal_handlers_block_matched (imContext, blockMask, id, 0, null, null, entryHandle); | |
730 } | |
731 } | |
732 | |
733 GtkIMContext* imContext () { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
734 return entryHandle !is null ? OS.GTK_ENTRY_IM_CONTEXT (entryHandle) : null; |
69 | 735 } |
736 | |
737 /** | |
738 * Deselects the item at the given zero-relative index in the receiver's | |
739 * list. If the item at the index was already deselected, it remains | |
740 * deselected. Indices that are out of range are ignored. | |
741 * | |
742 * @param index the index of the item to deselect | |
743 * | |
71 | 744 * @exception DWTException <ul> |
69 | 745 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
746 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
747 * </ul> | |
748 */ | |
749 public void deselect (int index) { | |
750 checkWidget(); | |
751 if (index < 0 || index >= items.length) return; | |
752 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
753 if (OS.gtk_combo_box_get_active (handle) is index) { |
69 | 754 clearText (); |
755 } | |
756 } else { | |
757 ignoreSelect = true; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
758 auto children = OS.gtk_container_get_children (listHandle); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
759 auto item = OS.g_list_nth_data (children, index); |
69 | 760 bool selected = OS.GTK_WIDGET_STATE (item) is OS.GTK_STATE_SELECTED; |
761 if (selected) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
762 OS.gtk_list_unselect_all (listHandle); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
763 OS.gtk_entry_set_text (entryHandle, "".ptr ); |
69 | 764 } |
765 OS.g_list_free (children); | |
766 ignoreSelect = false; | |
767 } | |
768 } | |
769 | |
770 /** | |
771 * Deselects all selected items in the receiver's list. | |
772 * <p> | |
773 * Note: To clear the selection in the receiver's text field, | |
774 * use <code>clearSelection()</code>. | |
775 * </p> | |
776 * | |
71 | 777 * @exception DWTException <ul> |
69 | 778 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
779 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
780 * </ul> | |
781 * | |
782 * @see #clearSelection | |
783 */ | |
784 public void deselectAll () { | |
785 checkWidget(); | |
786 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
787 clearText (); | |
788 } else { | |
789 ignoreSelect = true; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
790 OS.gtk_list_unselect_all (listHandle); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
791 OS.gtk_entry_set_text (entryHandle, "".ptr ); |
69 | 792 ignoreSelect = false; |
793 } | |
794 } | |
795 | |
796 | |
797 override bool dragDetect(int x, int y, bool filter, bool* consume) { | |
798 if (filter && entryHandle !is null) { | |
799 int index; | |
800 int trailing; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
801 auto layout = OS.gtk_entry_get_layout (entryHandle); |
69 | 802 OS.pango_layout_xy_to_index (layout, x * OS.PANGO_SCALE, y * OS.PANGO_SCALE, &index, &trailing); |
803 auto ptr = OS.pango_layout_get_text (layout); | |
804 int position = cast(int)/*64*/OS.g_utf8_pointer_to_offset (ptr, ptr + index) + trailing; | |
805 Point selection = getSelection (); | |
806 if (selection.x <= position && position < selection.y) { | |
807 if (super.dragDetect (x, y, filter, consume)) { | |
808 if (consume !is null) *consume = true; | |
809 return true; | |
810 } | |
811 } | |
812 return false; | |
813 } | |
814 return super.dragDetect (x, y, filter, consume); | |
815 } | |
816 | |
817 override GtkWidget* enterExitHandle () { | |
818 return fixedHandle; | |
819 } | |
820 | |
821 override GdkDrawable* eventWindow () { | |
822 return paintWindow (); | |
823 } | |
824 | |
825 override GdkColor* getBackgroundColor () { | |
826 return getBaseColor (); | |
827 } | |
828 | |
829 override GdkColor* getForegroundColor () { | |
830 return getTextColor (); | |
831 } | |
832 | |
833 /** | |
834 * Returns the item at the given, zero-relative index in the | |
835 * receiver's list. Throws an exception if the index is out | |
836 * of range. | |
837 * | |
838 * @param index the index of the item to return | |
839 * @return the item at the given index | |
840 * | |
841 * @exception IllegalArgumentException <ul> | |
842 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
843 * </ul> | |
71 | 844 * @exception DWTException <ul> |
69 | 845 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
846 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
847 * </ul> | |
848 */ | |
238 | 849 public String getItem (int index) { |
69 | 850 checkWidget(); |
851 if (!(0 <= index && index < items.length)) { | |
71 | 852 error (DWT.ERROR_INVALID_RANGE); |
69 | 853 } |
854 return items [index]; | |
855 } | |
856 | |
857 /** | |
858 * Returns the number of items contained in the receiver's list. | |
859 * | |
860 * @return the number of items | |
861 * | |
71 | 862 * @exception DWTException <ul> |
69 | 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 int getItemCount () { | |
868 checkWidget(); | |
869 return items.length; | |
870 } | |
871 | |
872 /** | |
873 * Returns the height of the area which would be used to | |
874 * display <em>one</em> of the items in the receiver's list. | |
875 * | |
876 * @return the height of one item | |
877 * | |
71 | 878 * @exception DWTException <ul> |
69 | 879 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
880 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
881 * </ul> | |
882 */ | |
883 public int getItemHeight () { | |
884 checkWidget(); | |
885 return fontHeight (getFontDescription (), listHandle !is null ? listHandle : handle); | |
886 } | |
887 | |
888 /** | |
889 * Returns a (possibly empty) array of <code>String</code>s which are | |
890 * the items in the receiver's list. | |
891 * <p> | |
892 * Note: This is not the actual structure used by the receiver | |
893 * to maintain its list of items, so modifying the array will | |
894 * not affect the receiver. | |
895 * </p> | |
896 * | |
897 * @return the items in the receiver's list | |
898 * | |
71 | 899 * @exception DWTException <ul> |
69 | 900 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
901 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
902 * </ul> | |
903 */ | |
238 | 904 public String [] getItems () { |
69 | 905 checkWidget(); |
238 | 906 String [] result = new String[](items.length); |
69 | 907 System.arraycopy (items, 0, result, 0, items.length); |
908 return result; | |
909 } | |
910 | |
240 | 911 public bool getListVisible () { |
912 checkWidget (); | |
913 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
914 return popupHandle !is null && OS.GTK_WIDGET_VISIBLE (popupHandle); | |
915 } | |
916 return false; | |
917 } | |
918 | |
919 String getNameText () { | |
920 return getText (); | |
921 } | |
922 | |
69 | 923 /** |
924 * Returns the orientation of the receiver. | |
925 * | |
926 * @return the orientation style | |
927 * | |
71 | 928 * @exception DWTException <ul> |
69 | 929 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
930 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
931 * </ul> | |
932 * | |
933 * @since 2.1.2 | |
934 */ | |
935 public int getOrientation () { | |
936 checkWidget(); | |
71 | 937 return style & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT); |
69 | 938 } |
939 | |
940 /** | |
941 * Returns a <code>Point</code> whose x coordinate is the | |
942 * character position representing the start of the selection | |
943 * in the receiver's text field, and whose y coordinate is the | |
944 * character position representing the end of the selection. | |
945 * An "empty" selection is indicated by the x and y coordinates | |
946 * having the same value. | |
947 * <p> | |
948 * Indexing is zero based. The range of a selection is from | |
949 * 0..N where N is the number of characters in the widget. | |
950 * </p> | |
951 * | |
952 * @return a point representing the selection start and end | |
953 * | |
71 | 954 * @exception DWTException <ul> |
69 | 955 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
956 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
957 * </ul> | |
958 */ | |
959 public Point getSelection () { | |
960 checkWidget (); | |
71 | 961 if ((style & DWT.READ_ONLY) !is 0) { |
69 | 962 int length = 0; |
963 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
964 int index = OS.gtk_combo_box_get_active (handle); |
69 | 965 if (index !is -1) length = getItem (index).length; |
966 } else { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
967 auto str = OS.gtk_entry_get_text (entryHandle); |
69 | 968 if (str !is null) length = cast(int)/*64*/OS.g_utf8_strlen (str, -1); |
969 } | |
970 return new Point (0, length); | |
971 } | |
972 int start; | |
973 int end; | |
974 if (entryHandle !is null) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
975 OS.gtk_editable_get_selection_bounds (entryHandle, &start, &end); |
69 | 976 } |
977 return new Point(start, end); | |
978 } | |
979 | |
980 /** | |
981 * Returns the zero-relative index of the item which is currently | |
982 * selected in the receiver's list, or -1 if no item is selected. | |
983 * | |
984 * @return the index of the selected item | |
985 * | |
71 | 986 * @exception DWTException <ul> |
69 | 987 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
988 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
989 * </ul> | |
990 */ | |
991 public int getSelectionIndex () { | |
992 checkWidget(); | |
993 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
994 return OS.gtk_combo_box_get_active (handle); |
69 | 995 } |
996 int index = 0, result = -1; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
997 auto children = OS.gtk_container_get_children (listHandle); |
69 | 998 auto temp = children; |
999 while (temp !is null) { | |
1000 auto item = OS.g_list_data (temp); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1001 if (OS.GTK_WIDGET_STATE (item) is OS.GTK_STATE_SELECTED) { |
69 | 1002 result = index; |
1003 break; | |
1004 } | |
1005 index++; | |
1006 temp = OS.g_list_next (temp); | |
1007 } | |
1008 OS.g_list_free (children); | |
1009 return result; | |
1010 } | |
1011 | |
1012 /** | |
1013 * Returns a string containing a copy of the contents of the | |
1014 * receiver's text field, or an empty string if there are no | |
1015 * contents. | |
1016 * | |
1017 * @return the receiver's text | |
1018 * | |
71 | 1019 * @exception DWTException <ul> |
69 | 1020 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1021 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1022 * </ul> | |
1023 */ | |
238 | 1024 public String getText () { |
69 | 1025 checkWidget(); |
1026 if (entryHandle !is null) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1027 auto str = OS.gtk_entry_get_text (entryHandle); |
69 | 1028 if (str is null) return ""; |
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
|
1029 return fromStringz(str).dup; |
69 | 1030 } else { |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1031 int index = OS.gtk_combo_box_get_active (handle); |
69 | 1032 return index !is -1 ? getItem (index) : ""; |
1033 } | |
1034 } | |
1035 | |
238 | 1036 String getText (int start, int stop) { |
69 | 1037 /* |
1038 * NOTE: The current implementation uses substring () | |
1039 * which can reference a potentially large character | |
1040 * array. | |
1041 */ | |
1042 return getText ()[ start .. stop - 1]; | |
1043 } | |
1044 | |
1045 /** | |
1046 * Returns the height of the receivers's text field. | |
1047 * | |
1048 * @return the text height | |
1049 * | |
71 | 1050 * @exception DWTException <ul> |
69 | 1051 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1052 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1053 * </ul> | |
1054 */ | |
1055 public int getTextHeight () { | |
1056 checkWidget(); | |
1057 GtkRequisition requisition; | |
1058 gtk_widget_size_request (handle, &requisition); | |
1059 return OS.GTK_WIDGET_REQUISITION_HEIGHT (handle); | |
1060 } | |
1061 | |
1062 /** | |
1063 * Returns the maximum number of characters that the receiver's | |
1064 * text field is capable of holding. If this has not been changed | |
1065 * by <code>setTextLimit()</code>, it will be the constant | |
1066 * <code>Combo.LIMIT</code>. | |
1067 * | |
1068 * @return the text limit | |
1069 * | |
71 | 1070 * @exception DWTException <ul> |
69 | 1071 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1072 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1073 * </ul> | |
1074 * | |
1075 * @see #LIMIT | |
1076 */ | |
1077 public int getTextLimit () { | |
1078 checkWidget(); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1079 int limit = entryHandle !is null ? OS.gtk_entry_get_max_length (entryHandle) : 0; |
69 | 1080 return limit is 0 ? LIMIT : limit; |
1081 } | |
1082 | |
1083 /** | |
1084 * Gets the number of items that are visible in the drop | |
1085 * down portion of the receiver's list. | |
1086 * <p> | |
1087 * Note: This operation is a hint and is not supported on | |
1088 * platforms that do not have this concept. | |
1089 * </p> | |
1090 * | |
1091 * @return the number of items that are visible | |
1092 * | |
71 | 1093 * @exception DWTException <ul> |
69 | 1094 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1095 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1096 * </ul> | |
1097 * | |
1098 * @since 3.0 | |
1099 */ | |
1100 public int getVisibleItemCount () { | |
1101 checkWidget (); | |
1102 return visibleCount; | |
1103 } | |
1104 | |
1105 override int /*long*/ gtk_activate (GtkWidget* widget) { | |
71 | 1106 postEvent (DWT.DefaultSelection); |
69 | 1107 return 0; |
1108 } | |
1109 | |
240 | 1110 override int /*long*/ gtk_button_press_event (GtkWidget* widget, GdkEventButton* event) { |
1111 /* | |
1112 * Feature in GTK. Depending on where the user clicks, GTK prevents | |
1113 * the left mouse button event from being propagated. The fix is to | |
1114 * send the mouse event from the event_after handler. | |
1115 */ | |
1116 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
1117 if (event.type is OS.GDK_BUTTON_PRESS) return 0; | |
1118 } | |
1119 return super.gtk_button_press_event (widget, event); | |
1120 } | |
1121 | |
69 | 1122 override int gtk_changed (GtkWidget* widget) { |
1123 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
1124 if (widget is handle) { | |
1125 if (entryHandle is null) { | |
71 | 1126 sendEvent(DWT.Modify); |
69 | 1127 if (isDisposed ()) return 0; |
1128 } | |
1129 /* | |
1130 * Feature in GTK. GTK emits a changed signal whenever | |
1131 * the contents of a combo box are altered by typing or | |
1132 * by selecting an item in the list, but the event should | |
1133 * only be sent when the list is selected. The fix is to | |
1134 * only send out a selection event when there is a selected | |
1135 * item. | |
1136 * | |
1137 * NOTE: This code relies on GTK clearing the selected | |
1138 * item and not matching the item as the user types. | |
1139 */ | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1140 int index = OS.gtk_combo_box_get_active (handle); |
71 | 1141 if (index !is -1) postEvent (DWT.Selection); |
69 | 1142 return 0; |
1143 } | |
1144 } else { | |
1145 if (!ignoreSelect) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1146 auto ptr = OS.gtk_entry_get_text (entryHandle); |
238 | 1147 String text = fromStringz(ptr).dup; |
69 | 1148 for (int i = 0; i < items.length; i++) { |
1149 if (items [i] ==/*eq*/ text) { | |
71 | 1150 postEvent (DWT.Selection); |
69 | 1151 break; |
1152 } | |
1153 } | |
1154 } | |
1155 } | |
1156 /* | |
1157 * Feature in GTK. When the user types, GTK positions | |
1158 * the caret after sending the changed signal. This | |
1159 * means that application code that attempts to position | |
1160 * the caret during a changed signal will fail. The fix | |
1161 * is to post the modify event when the user is typing. | |
1162 */ | |
1163 bool keyPress = false; | |
1164 auto eventPtr = OS.gtk_get_current_event (); | |
1165 if (eventPtr !is null) { | |
1166 GdkEventKey* gdkEvent = cast(GdkEventKey*)eventPtr; | |
1167 switch (gdkEvent.type) { | |
1168 case OS.GDK_KEY_PRESS: | |
1169 keyPress = true; | |
1170 break; | |
1171 default: | |
1172 } | |
1173 OS.gdk_event_free (eventPtr); | |
1174 } | |
1175 if (keyPress) { | |
71 | 1176 postEvent (DWT.Modify); |
69 | 1177 } else { |
71 | 1178 sendEvent (DWT.Modify); |
69 | 1179 } |
1180 return 0; | |
1181 } | |
1182 | |
1183 override int gtk_commit (GtkIMContext* imContext, char* text) { | |
1184 if (text is null) return 0; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1185 if (!OS.gtk_editable_get_editable (entryHandle)) 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
|
1186 char [] chars = fromStringz(text); |
69 | 1187 if (chars.length is 0) return 0; |
71 | 1188 char [] newChars = sendIMKeyEvent (DWT.KeyDown, null, chars); |
69 | 1189 if (newChars is null) return 0; |
1190 /* | |
1191 * Feature in GTK. For a GtkEntry, during the insert-text signal, | |
1192 * GTK allows the programmer to change only the caret location, | |
1193 * not the selection. If the programmer changes the selection, | |
1194 * the new selection is lost. The fix is to detect a selection | |
1195 * change and set it after the insert-text signal has completed. | |
1196 */ | |
1197 fixStart = fixEnd = -1; | |
1198 OS.g_signal_handlers_block_matched (imContext, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCOMMIT); | |
1199 int id = OS.g_signal_lookup (OS.commit.ptr, OS.gtk_im_context_get_type ()); | |
1200 int mask = OS.G_SIGNAL_MATCH_DATA | OS.G_SIGNAL_MATCH_ID; | |
1201 OS.g_signal_handlers_unblock_matched (imContext, mask, id, 0, null, null, entryHandle); | |
1202 if (newChars is chars) { | |
1203 OS.g_signal_emit_by_name1 (imContext, OS.commit.ptr, cast(int)text); | |
1204 } else { | |
1205 OS.g_signal_emit_by_name1 (imContext, OS.commit.ptr, cast(int)toStringz(newChars)); | |
1206 } | |
1207 OS.g_signal_handlers_unblock_matched (imContext, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCOMMIT); | |
1208 OS.g_signal_handlers_block_matched (imContext, mask, id, 0, null, null, entryHandle); | |
1209 if (fixStart !is -1 && fixEnd !is -1) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1210 OS.gtk_editable_set_position (entryHandle, fixStart); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1211 OS.gtk_editable_select_region (entryHandle, fixStart, fixEnd); |
69 | 1212 } |
1213 fixStart = fixEnd = -1; | |
1214 return 0; | |
1215 } | |
1216 | |
1217 override int gtk_delete_text (GtkWidget* widget, int start_pos, int end_pos) { | |
1218 if (lockText) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1219 OS.gtk_list_unselect_item (listHandle, 0); |
69 | 1220 OS.g_signal_stop_emission_by_name (entryHandle, OS.delete_text.ptr); |
1221 return 0; | |
1222 } | |
71 | 1223 if (!hooks (DWT.Verify) && !filters (DWT.Verify)) return 0; |
238 | 1224 String newText = verifyText ("", cast(int)/*64*/start_pos, cast(int)/*64*/end_pos); |
69 | 1225 if (newText is null) { |
1226 OS.g_signal_stop_emission_by_name (entryHandle, OS.delete_text.ptr); | |
1227 } else { | |
1228 if (newText.length > 0) { | |
1229 int pos; | |
1230 pos = cast(int)/*64*/end_pos; | |
1231 OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); | |
1232 OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1233 OS.gtk_editable_insert_text (entryHandle, newText.ptr, newText.length, &pos); |
69 | 1234 OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); |
1235 OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1236 OS.gtk_editable_set_position (entryHandle, pos ); |
69 | 1237 } |
1238 } | |
1239 return 0; | |
1240 } | |
1241 | |
240 | 1242 override int /*long*/ gtk_event_after (GtkWidget* widget, GdkEvent* event) { |
1243 /* | |
1244 * Feature in GTK. Depending on where the user clicks, GTK prevents | |
1245 * the left mouse button event from being propagated. The fix is to | |
1246 * send the mouse event from the event_after handler. | |
1247 * | |
1248 * Feature in GTK. When the user clicks anywhere in an editable | |
1249 * combo box, a single focus event should be issued, despite the | |
1250 * fact that focus might switch between the drop down button and | |
1251 * the text field. The fix is to use gtk_combo_box_set_focus_on_click () | |
1252 * to eat all focus events while focus is in the combo box. When the | |
1253 * user clicks on the drop down button focus is assigned to the text | |
1254 * field. | |
1255 */ | |
1256 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
1257 switch (event.type) { | |
1258 case OS.GDK_BUTTON_PRESS: { | |
1259 GdkEventButton* gdkEventButton = cast(GdkEventButton*)event; | |
1260 if (gdkEventButton.button is 1) { | |
1261 if (!sendMouseEvent (DWT.MouseDown, gdkEventButton.button, display.clickCount, 0, false, gdkEventButton.time, gdkEventButton.x_root, gdkEventButton.y_root, false, gdkEventButton.state)) { | |
1262 return 1; | |
1263 } | |
1264 if (OS.GTK_VERSION >= OS.buildVERSION (2, 6, 0)) { | |
1265 if ((style & DWT.READ_ONLY) is 0 && widget is buttonHandle) { | |
1266 OS.gtk_widget_grab_focus (entryHandle); | |
1267 } | |
1268 } | |
1269 } | |
1270 break; | |
1271 } | |
1272 case OS.GDK_FOCUS_CHANGE: { | |
1273 if (OS.GTK_VERSION >= OS.buildVERSION (2, 6, 0)) { | |
1274 if ((style & DWT.READ_ONLY) is 0) { | |
1275 GdkEventFocus* gdkEventFocus = cast(GdkEventFocus*)event; | |
1276 if (gdkEventFocus.in_ !is 0) { | |
1277 OS.gtk_combo_box_set_focus_on_click (handle, false); | |
1278 } else { | |
1279 OS.gtk_combo_box_set_focus_on_click (handle, true); | |
1280 } | |
1281 } | |
1282 } | |
1283 break; | |
1284 } | |
241
4653e99936cf
Fix missing switch default in Combo
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
1285 default: |
240 | 1286 } |
1287 } | |
1288 return super.gtk_event_after(widget, event); | |
1289 } | |
1290 | |
69 | 1291 override int gtk_focus_out_event (GtkWidget* widget, GdkEventFocus* event) { |
1292 fixIM (); | |
1293 return super.gtk_focus_out_event (widget, event); | |
1294 } | |
1295 | |
1296 override int gtk_insert_text (GtkEditable* widget, char* new_text, int new_text_length, int position) { | |
1297 if (lockText) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1298 OS.gtk_list_unselect_item (listHandle, 0); |
69 | 1299 OS.g_signal_stop_emission_by_name (entryHandle, OS.insert_text.ptr); |
1300 return 0; | |
1301 } | |
71 | 1302 if (!hooks (DWT.Verify) && !filters (DWT.Verify)) return 0; |
69 | 1303 if (new_text is null || new_text_length is 0) return 0; |
238 | 1304 String oldText = new_text[0..new_text_length]; |
69 | 1305 int pos; |
1306 pos = position; | |
1307 if (pos is -1) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1308 auto ptr = OS.gtk_entry_get_text (entryHandle); |
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
|
1309 pos = fromStringz(ptr).length; |
69 | 1310 } |
238 | 1311 String newText = verifyText (oldText, pos, pos); |
69 | 1312 if (newText !is oldText) { |
1313 int newStart, newEnd; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1314 OS.gtk_editable_get_selection_bounds (entryHandle, &newStart, &newEnd); |
69 | 1315 if (newText !is null) { |
1316 if (newStart !is newEnd) { | |
1317 OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_TEXT); | |
1318 OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1319 OS.gtk_editable_delete_selection (entryHandle); |
69 | 1320 OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_TEXT); |
1321 OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); | |
1322 } | |
1323 OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1324 OS.gtk_editable_insert_text (entryHandle, newText.ptr, newText.length, &pos); |
69 | 1325 OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); |
1326 newStart = newEnd = pos; | |
1327 } | |
1328 pos = newEnd; | |
1329 if (newStart !is newEnd) { | |
1330 fixStart = newStart; | |
1331 fixEnd = newEnd; | |
1332 } | |
1333 position = pos; | |
1334 OS.g_signal_stop_emission_by_name (entryHandle, OS.insert_text.ptr); | |
1335 } | |
1336 return 0; | |
1337 } | |
1338 | |
1339 override int gtk_key_press_event (GtkWidget* widget, GdkEventKey* event) { | |
1340 auto result = super.gtk_key_press_event (widget, event); | |
1341 if (result !is 0) fixIM (); | |
1342 if (gdkEventKey is cast(GdkEventKey*)-1) result = 1; | |
1343 gdkEventKey = null; | |
240 | 1344 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0) && (style & DWT.READ_ONLY) is 0) { |
1345 GdkEventKey* keyEvent = cast(GdkEventKey*)event; | |
1346 int oldIndex = OS.gtk_combo_box_get_active (handle); | |
1347 int newIndex = oldIndex; | |
1348 int key = keyEvent.keyval; | |
1349 switch (key) { | |
1350 case OS.GDK_Down: | |
1351 case OS.GDK_KP_Down: | |
1352 if (oldIndex !is (items.length - 1)) { | |
1353 newIndex = oldIndex + 1; | |
1354 } | |
1355 break; | |
1356 case OS.GDK_Up: | |
1357 case OS.GDK_KP_Up: | |
1358 if (oldIndex !is -1 && oldIndex !is 0) { | |
1359 newIndex = oldIndex - 1; | |
1360 } | |
1361 break; | |
1362 /* | |
1363 * Feature in GTK. In gtk_combo_box, the PageUp and PageDown keys | |
1364 * go the first and last items in the list rather than scrolling | |
1365 * a page at a time. The fix is to emulate this behavior for | |
1366 * gtk_combo_box_entry. | |
1367 */ | |
1368 case OS.GDK_Page_Up: | |
1369 case OS.GDK_KP_Page_Up: | |
1370 newIndex = 0; | |
1371 break; | |
1372 case OS.GDK_Page_Down: | |
1373 case OS.GDK_KP_Page_Down: | |
1374 newIndex = items.length - 1; | |
1375 break; | |
241
4653e99936cf
Fix missing switch default in Combo
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
1376 default: |
240 | 1377 } |
1378 if (newIndex !is oldIndex) { | |
1379 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); | |
1380 OS.gtk_combo_box_set_active (handle, newIndex); | |
1381 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); | |
1382 return 1; | |
1383 } | |
1384 } | |
69 | 1385 return result; |
1386 } | |
1387 | |
240 | 1388 override int /*long*/ gtk_populate_popup (GtkWidget* widget, GtkWidget* menu) { |
1389 if ((style & DWT.RIGHT_TO_LEFT) !is 0) { | |
1390 OS.gtk_widget_set_direction (menu, OS.GTK_TEXT_DIR_RTL); | |
1391 display.doSetDirectionProc(menu, OS.GTK_TEXT_DIR_RTL); | |
1392 } | |
1393 return 0; | |
1394 } | |
1395 | |
69 | 1396 /** |
1397 * Searches the receiver's list starting at the first item | |
1398 * (index 0) until an item is found that is equal to the | |
1399 * argument, and returns the index of that item. If no item | |
1400 * is found, returns -1. | |
1401 * | |
1402 * @param string the search item | |
1403 * @return the index of the item | |
1404 * | |
1405 * @exception IllegalArgumentException <ul> | |
1406 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
1407 * </ul> | |
71 | 1408 * @exception DWTException <ul> |
69 | 1409 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1410 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1411 * </ul> | |
1412 */ | |
238 | 1413 public int indexOf (String string) { |
69 | 1414 checkWidget(); |
1415 return indexOf (string, 0); | |
1416 } | |
1417 | |
1418 /** | |
1419 * Searches the receiver's list starting at the given, | |
1420 * zero-relative index until an item is found that is equal | |
1421 * to the argument, and returns the index of that item. If | |
1422 * no item is found or the starting index is out of range, | |
1423 * returns -1. | |
1424 * | |
1425 * @param string the search item | |
1426 * @param start the zero-relative index at which to begin the search | |
1427 * @return the index of the item | |
1428 * | |
1429 * @exception IllegalArgumentException <ul> | |
1430 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
1431 * </ul> | |
71 | 1432 * @exception DWTException <ul> |
69 | 1433 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1434 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1435 * </ul> | |
1436 */ | |
238 | 1437 public int indexOf (String string, int start) { |
69 | 1438 checkWidget(); |
71 | 1439 if (string is null) error (DWT.ERROR_NULL_ARGUMENT); |
69 | 1440 if (!(0 <= start && start < items.length)) return -1; |
1441 for (int i=start; i<items.length; i++) { | |
1442 if (string==/*eq*/items [i]) return i; | |
1443 } | |
1444 return -1; | |
1445 } | |
1446 | |
240 | 1447 override bool isFocusHandle(GtkWidget* widget) { |
1448 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
1449 if (buttonHandle !is null && widget is buttonHandle) return true; | |
1450 if (entryHandle !is null && widget is entryHandle) return true; | |
1451 } | |
1452 return super.isFocusHandle (widget); | |
1453 } | |
1454 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
1455 override GdkDrawable* paintWindow () { |
69 | 1456 auto childHandle = entryHandle !is null ? entryHandle : handle; |
1457 OS.gtk_widget_realize (childHandle); | |
1458 auto window = OS.GTK_WIDGET_WINDOW (childHandle); | |
1459 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
71 | 1460 if ((style & DWT.READ_ONLY) !is 0) return window; |
69 | 1461 } |
1462 auto children = OS.gdk_window_get_children (window); | |
1463 if (children !is null) window = cast(GdkDrawable*)OS.g_list_data (children); | |
1464 OS.g_list_free (children); | |
1465 return window; | |
1466 } | |
1467 | |
1468 /** | |
1469 * Pastes text from clipboard. | |
1470 * <p> | |
1471 * The selected text is deleted from the widget | |
1472 * and new text inserted from the clipboard. | |
1473 * </p> | |
1474 * | |
71 | 1475 * @exception DWTException <ul> |
69 | 1476 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1477 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1478 * </ul> | |
1479 * | |
1480 * @since 2.1 | |
1481 */ | |
1482 public void paste () { | |
1483 checkWidget (); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1484 if (entryHandle !is null) OS.gtk_editable_paste_clipboard (entryHandle); |
69 | 1485 } |
1486 | |
1487 override GtkWidget* parentingHandle() { | |
1488 return fixedHandle; | |
1489 } | |
1490 | |
1491 override void register () { | |
1492 super.register (); | |
1493 if (buttonHandle !is null) display.addWidget (buttonHandle, this); | |
1494 if (entryHandle !is null) display.addWidget (entryHandle, this); | |
1495 if (listHandle !is null) display.addWidget (listHandle, this); | |
1496 auto imContext = imContext (); | |
1497 if (imContext !is null) display.addWidget (cast(GtkWidget*)imContext, this); | |
1498 } | |
1499 | |
1500 override void releaseHandle () { | |
1501 super.releaseHandle (); | |
1502 buttonHandle = entryHandle = listHandle = null; | |
1503 } | |
1504 | |
1505 override void releaseWidget () { | |
1506 super.releaseWidget (); | |
1507 textRenderer = null; | |
1508 fixIM (); | |
1509 } | |
1510 | |
1511 /** | |
1512 * Removes the item from the receiver's list at the given | |
1513 * zero-relative index. | |
1514 * | |
1515 * @param index the index for the item | |
1516 * | |
1517 * @exception IllegalArgumentException <ul> | |
1518 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
1519 * </ul> | |
71 | 1520 * @exception DWTException <ul> |
69 | 1521 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1522 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1523 * </ul> | |
1524 */ | |
1525 public void remove (int index) { | |
1526 checkWidget(); | |
1527 if (!(0 <= index && index < items.length)) { | |
71 | 1528 error (DWT.ERROR_INVALID_RANGE); |
69 | 1529 } |
238 | 1530 String [] oldItems = items; |
1531 String [] newItems = new String[]( oldItems.length - 1 ); | |
69 | 1532 System.arraycopy (oldItems, 0, newItems, 0, index); |
1533 System.arraycopy (oldItems, index + 1, newItems, index, oldItems.length - index - 1); | |
1534 items = newItems; | |
1535 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1536 if (OS.gtk_combo_box_get_active (handle) is index) clearText (); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1537 OS.gtk_combo_box_remove_text (handle, index); |
69 | 1538 } else { |
1539 ignoreSelect = true; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1540 auto children = OS.gtk_container_get_children (listHandle); |
69 | 1541 auto item = OS.g_list_nth_data (children, index); |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1542 bool selected = OS.GTK_WIDGET_STATE (item) is OS.GTK_STATE_SELECTED; |
69 | 1543 auto items = OS.g_list_append (null, item); |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1544 OS.gtk_list_remove_items (listHandle, items); |
69 | 1545 OS.g_list_free (items); |
1546 OS.g_list_free (children); | |
1547 if (selected) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1548 OS.gtk_entry_set_text (entryHandle, "".ptr); |
69 | 1549 } |
1550 ignoreSelect = false; | |
1551 } | |
1552 } | |
1553 | |
1554 /** | |
1555 * Removes the items from the receiver's list which are | |
1556 * between the given zero-relative start and end | |
1557 * indices (inclusive). | |
1558 * | |
1559 * @param start the start of the range | |
1560 * @param end the end of the range | |
1561 * | |
1562 * @exception IllegalArgumentException <ul> | |
1563 * <li>ERROR_INVALID_RANGE - if either the start or end are not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
1564 * </ul> | |
71 | 1565 * @exception DWTException <ul> |
69 | 1566 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1567 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1568 * </ul> | |
1569 */ | |
1570 public void remove (int start, int end) { | |
1571 checkWidget(); | |
1572 if (start > end) return; | |
1573 if (!(0 <= start && start <= end && end < items.length)) { | |
71 | 1574 error (DWT.ERROR_INVALID_RANGE); |
69 | 1575 } |
238 | 1576 String [] oldItems = items; |
1577 String [] newItems = new String[](oldItems.length - (end - start + 1)); | |
69 | 1578 System.arraycopy (oldItems, 0, newItems, 0, start); |
1579 System.arraycopy (oldItems, end + 1, newItems, start, oldItems.length - end - 1); | |
1580 items = newItems; | |
1581 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1582 int index = OS.gtk_combo_box_get_active (handle); |
69 | 1583 if (start <= index && index <= end) clearText(); |
1584 for (int i = end; i >= start; i--) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1585 OS.gtk_combo_box_remove_text (handle, i); |
69 | 1586 } |
1587 } else { | |
1588 bool selected = false; | |
1589 ignoreSelect = true; | |
1590 GList* items; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1591 auto children = OS.gtk_container_get_children (listHandle); |
69 | 1592 for (int i = start; i <= end; i++) { |
1593 auto item = OS.g_list_nth_data (children, i); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1594 selected |= OS.GTK_WIDGET_STATE (item) is OS.GTK_STATE_SELECTED; |
69 | 1595 items = OS.g_list_append (items, item); |
1596 } | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1597 OS.gtk_list_remove_items (listHandle, items); |
69 | 1598 OS.g_list_free (items); |
1599 OS.g_list_free (children); | |
1600 if (selected) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1601 OS.gtk_entry_set_text (entryHandle, "".ptr ); |
69 | 1602 } |
1603 ignoreSelect = false; | |
1604 } | |
1605 } | |
1606 | |
1607 /** | |
1608 * Searches the receiver's list starting at the first item | |
1609 * until an item is found that is equal to the argument, | |
1610 * and removes that item from the list. | |
1611 * | |
1612 * @param string the item to remove | |
1613 * | |
1614 * @exception IllegalArgumentException <ul> | |
1615 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
1616 * <li>ERROR_INVALID_ARGUMENT - if the string is not found in the list</li> | |
1617 * </ul> | |
71 | 1618 * @exception DWTException <ul> |
69 | 1619 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1620 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1621 * </ul> | |
1622 */ | |
238 | 1623 public void remove (String string) { |
69 | 1624 checkWidget(); |
71 | 1625 if (string is null) error (DWT.ERROR_NULL_ARGUMENT); |
69 | 1626 int index = indexOf (string, 0); |
71 | 1627 if (index is -1) error (DWT.ERROR_INVALID_ARGUMENT); |
69 | 1628 remove (index); |
1629 } | |
1630 | |
1631 /** | |
1632 * Removes all of the items from the receiver's list and clear the | |
1633 * contents of receiver's text field. | |
1634 * <p> | |
71 | 1635 * @exception DWTException <ul> |
69 | 1636 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1637 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1638 * </ul> | |
1639 */ | |
1640 public void removeAll () { | |
1641 checkWidget(); | |
1642 int count = items.length; | |
1643 items = null; | |
1644 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
1645 clearText (); | |
1646 for (int i = count - 1; i >= 0; i--) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1647 OS.gtk_combo_box_remove_text (handle, i); |
69 | 1648 } |
1649 } else { | |
1650 ignoreSelect = true; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1651 OS.gtk_list_clear_items (listHandle, 0, -1); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1652 OS.gtk_entry_set_text (entryHandle, "".ptr); |
69 | 1653 ignoreSelect = false; |
1654 } | |
1655 } | |
1656 | |
1657 /** | |
1658 * Removes the listener from the collection of listeners who will | |
1659 * be notified when the receiver's text is modified. | |
1660 * | |
1661 * @param listener the listener which should no longer be notified | |
1662 * | |
1663 * @exception IllegalArgumentException <ul> | |
1664 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1665 * </ul> | |
71 | 1666 * @exception DWTException <ul> |
69 | 1667 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1668 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1669 * </ul> | |
1670 * | |
1671 * @see ModifyListener | |
1672 * @see #addModifyListener | |
1673 */ | |
1674 public void removeModifyListener (ModifyListener listener) { | |
1675 checkWidget(); | |
71 | 1676 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
69 | 1677 if (eventTable is null) return; |
71 | 1678 eventTable.unhook (DWT.Modify, listener); |
69 | 1679 } |
1680 | |
1681 /** | |
1682 * Removes the listener from the collection of listeners who will | |
1683 * be notified when the user changes the receiver's selection. | |
1684 * | |
1685 * @param listener the listener which should no longer be notified | |
1686 * | |
1687 * @exception IllegalArgumentException <ul> | |
1688 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1689 * </ul> | |
71 | 1690 * @exception DWTException <ul> |
69 | 1691 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1692 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1693 * </ul> | |
1694 * | |
1695 * @see SelectionListener | |
1696 * @see #addSelectionListener | |
1697 */ | |
1698 public void removeSelectionListener (SelectionListener listener) { | |
1699 checkWidget(); | |
71 | 1700 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
69 | 1701 if (eventTable is null) return; |
71 | 1702 eventTable.unhook (DWT.Selection, listener); |
1703 eventTable.unhook (DWT.DefaultSelection,listener); | |
69 | 1704 } |
1705 | |
1706 /** | |
1707 * Removes the listener from the collection of listeners who will | |
1708 * be notified when the control is verified. | |
1709 * | |
1710 * @param listener the listener which should no longer be notified | |
1711 * | |
1712 * @exception IllegalArgumentException <ul> | |
1713 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1714 * </ul> | |
71 | 1715 * @exception DWTException <ul> |
69 | 1716 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1717 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1718 * </ul> | |
1719 * | |
1720 * @see VerifyListener | |
1721 * @see #addVerifyListener | |
1722 * | |
1723 * @since 3.1 | |
1724 */ | |
1725 public void removeVerifyListener (VerifyListener listener) { | |
1726 checkWidget (); | |
71 | 1727 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
69 | 1728 if (eventTable is null) return; |
71 | 1729 eventTable.unhook (DWT.Verify, listener); |
69 | 1730 } |
1731 | |
1732 /** | |
1733 * Selects the item at the given zero-relative index in the receiver's | |
1734 * list. If the item at the index was already selected, it remains | |
1735 * selected. Indices that are out of range are ignored. | |
1736 * | |
1737 * @param index the index of the item to select | |
1738 * | |
71 | 1739 * @exception DWTException <ul> |
69 | 1740 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1741 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1742 * </ul> | |
1743 */ | |
1744 public void select (int index) { | |
1745 checkWidget(); | |
1746 if (index < 0 || index >= items.length) return; | |
1747 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
1748 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1749 OS.gtk_combo_box_set_active (handle, index); |
69 | 1750 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
240 | 1751 if ((style & DWT.READ_ONLY) !is 0) { |
1752 /* | |
1753 * Feature in GTK. Read Only combo boxes do not get a chance to send out a | |
1754 * Modify event in the gtk_changed callback. The fix is to send a Modify event | |
1755 * here. | |
1756 */ | |
1757 sendEvent (DWT.Modify); | |
1758 } | |
69 | 1759 } else { |
1760 ignoreSelect = true; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1761 OS.gtk_list_select_item (listHandle, index); |
69 | 1762 ignoreSelect = false; |
1763 } | |
1764 } | |
1765 | |
1766 override void setBackgroundColor (GdkColor* color) { | |
1767 super.setBackgroundColor (color); | |
1768 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
1769 if (entryHandle !is null) OS.gtk_widget_modify_base (entryHandle, 0, color); | |
1770 OS.g_object_set1 (textRenderer, OS.background_gdk.ptr, cast(int)color); | |
1771 } else { | |
1772 OS.gtk_widget_modify_base (entryHandle, 0, color); | |
1773 if (listHandle !is null) OS.gtk_widget_modify_base (listHandle, 0, color); | |
1774 } | |
1775 } | |
1776 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
1777 override int setBounds (int x, int y, int width, int height, bool move, bool resize) { |
240 | 1778 int newHeight = height; |
1779 if (resize) newHeight = Math.max (getTextHeight (), height); | |
69 | 1780 return super.setBounds (x, y, width, newHeight, move, resize); |
1781 } | |
1782 | |
1783 override void setFontDescription (PangoFontDescription* font) { | |
1784 super.setFontDescription (font); | |
1785 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
1786 if (entryHandle !is null) OS.gtk_widget_modify_font (entryHandle, font); | |
1787 OS.g_object_set1 (textRenderer, OS.font_desc.ptr, cast(int)font); | |
71 | 1788 if ((style & DWT.READ_ONLY) !is 0) { |
69 | 1789 /* |
1790 * Bug in GTK. Setting the font can leave the combo box with an | |
1791 * invalid minimum size. The fix is to temporarily change the | |
1792 * selected item to force the combo box to resize. | |
1793 */ | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1794 int index = OS.gtk_combo_box_get_active (handle); |
69 | 1795 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1796 OS.gtk_combo_box_set_active (handle, -1); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1797 OS.gtk_combo_box_set_active (handle, index); |
69 | 1798 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
1799 } | |
1800 } else { | |
1801 OS.gtk_widget_modify_font (entryHandle, font); | |
1802 if (listHandle !is null) { | |
1803 OS.gtk_widget_modify_font (listHandle, font); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1804 auto itemsList = OS.gtk_container_get_children (listHandle); |
69 | 1805 if (itemsList !is null) { |
1806 int count = OS.g_list_length (itemsList); | |
1807 for (int i=count - 1; i>=0; i--) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1808 auto widget = OS.gtk_bin_get_child (OS.g_list_nth_data (itemsList, i)); |
69 | 1809 OS.gtk_widget_modify_font (widget, font); |
1810 } | |
1811 OS.g_list_free (itemsList); | |
1812 } | |
1813 } | |
1814 } | |
1815 } | |
1816 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
1817 override void setForegroundColor (GdkColor* color) { |
69 | 1818 super.setForegroundColor (color); |
1819 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
1820 if (entryHandle !is null) setForegroundColor (entryHandle, color); | |
1821 OS.g_object_set1 (textRenderer, OS.foreground_gdk.ptr, cast(int)color); | |
1822 } else { | |
1823 setForegroundColor (entryHandle, color); | |
1824 if (listHandle !is null) { | |
1825 setForegroundColor (listHandle, color); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1826 auto itemsList = OS.gtk_container_get_children (listHandle); |
69 | 1827 if (itemsList !is null) { |
1828 int count = OS.g_list_length (itemsList); | |
1829 for (int i=count - 1; i>=0; i--) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1830 auto widget = OS.gtk_bin_get_child (OS.g_list_nth_data (itemsList, i)); |
69 | 1831 setForegroundColor (widget, color); |
1832 } | |
1833 OS.g_list_free (itemsList); | |
1834 } | |
1835 } | |
1836 } | |
1837 } | |
1838 | |
1839 /** | |
1840 * Sets the text of the item in the receiver's list at the given | |
1841 * zero-relative index to the string argument. | |
1842 * | |
1843 * @param index the index for the item | |
1844 * @param string the new text for the item | |
1845 * | |
1846 * @exception IllegalArgumentException <ul> | |
1847 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
1848 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
1849 * </ul> | |
71 | 1850 * @exception DWTException <ul> |
69 | 1851 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1852 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1853 * </ul> | |
1854 */ | |
238 | 1855 public void setItem (int index, String string) { |
69 | 1856 checkWidget(); |
71 | 1857 if (string is null) error (DWT.ERROR_NULL_ARGUMENT); |
69 | 1858 if (!(0 <= index && index < items.length)) { |
71 | 1859 error (DWT.ERROR_INVALID_ARGUMENT); |
69 | 1860 } |
1861 items [index] = string; | |
1862 char* buffer = toStringz(string); | |
1863 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1864 OS.gtk_combo_box_remove_text (handle, index); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1865 OS.gtk_combo_box_insert_text (handle, index, buffer); |
240 | 1866 if ((style & DWT.RIGHT_TO_LEFT) !is 0 && popupHandle !is null) { |
1867 display.doSetDirectionProc(popupHandle, OS.GTK_TEXT_DIR_RTL); | |
1868 } | |
69 | 1869 } else { |
1870 ignoreSelect = true; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1871 auto children = OS.gtk_container_get_children (listHandle); |
69 | 1872 auto item = OS.g_list_nth_data (children, index); |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1873 auto label = OS.gtk_bin_get_child (item); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1874 OS.gtk_label_set_text (label, buffer); |
69 | 1875 OS.g_list_free (children); |
1876 ignoreSelect = false; | |
1877 } | |
1878 } | |
1879 | |
1880 /** | |
1881 * Sets the receiver's list to be the given array of items. | |
1882 * | |
1883 * @param items the array of items | |
1884 * | |
1885 * @exception IllegalArgumentException <ul> | |
1886 * <li>ERROR_NULL_ARGUMENT - if the items array is null</li> | |
1887 * <li>ERROR_INVALID_ARGUMENT - if an item in the items array is null</li> | |
1888 * </ul> | |
71 | 1889 * @exception DWTException <ul> |
69 | 1890 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1891 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1892 * </ul> | |
1893 */ | |
238 | 1894 public void setItems (String [] items) { |
69 | 1895 checkWidget(); |
71 | 1896 if (items is null) error (DWT.ERROR_NULL_ARGUMENT); |
69 | 1897 for (int i=0; i<items.length; i++) { |
71 | 1898 if (items [i] is null) error (DWT.ERROR_INVALID_ARGUMENT); |
69 | 1899 } |
1900 int count = this.items.length; | |
238 | 1901 this.items = new String[](items.length); |
69 | 1902 System.arraycopy (items, 0, this.items, 0, items.length); |
1903 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
1904 clearText (); | |
1905 for (int i = count - 1; i >= 0; i--) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1906 OS.gtk_combo_box_remove_text (handle, i); |
69 | 1907 } |
1908 for (int i = 0; i < items.length; i++) { | |
238 | 1909 String string = items [i]; |
69 | 1910 char* buffer = toStringz(string); |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1911 OS.gtk_combo_box_insert_text (handle, i, buffer); |
240 | 1912 if ((style & DWT.RIGHT_TO_LEFT) !is 0 && popupHandle !is null) { |
1913 display.doSetDirectionProc(popupHandle, OS.GTK_TEXT_DIR_RTL); | |
1914 } | |
69 | 1915 } |
1916 } else { | |
1917 lockText = ignoreSelect = true; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1918 OS.gtk_list_clear_items (listHandle, 0, -1); |
69 | 1919 auto font = getFontDescription (); |
1920 GdkColor* color = getForegroundColor (); | |
1921 int direction = OS.gtk_widget_get_direction (handle); | |
1922 int i = 0; | |
1923 while (i < items.length) { | |
238 | 1924 String string = items [i]; |
69 | 1925 char * buffer = toStringz(string); |
1926 auto item = OS.gtk_list_item_new_with_label (buffer); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1927 auto label = OS.gtk_bin_get_child (item); |
69 | 1928 setForegroundColor (label, color); |
1929 OS.gtk_widget_modify_font (label, font); | |
1930 OS.gtk_widget_set_direction (label, direction); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1931 OS.gtk_container_add (listHandle, item); |
69 | 1932 OS.gtk_widget_show (item); |
1933 i++; | |
1934 } | |
1935 lockText = ignoreSelect = false; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1936 OS.gtk_entry_set_text (entryHandle, "".ptr); |
69 | 1937 } |
1938 } | |
1939 | |
240 | 1940 public void setListVisible (bool visible) { |
69 | 1941 checkWidget (); |
1942 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
1943 if (visible) { | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1944 OS.gtk_combo_box_popup (handle); |
69 | 1945 } else { |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1946 OS.gtk_combo_box_popdown (handle); |
69 | 1947 } |
1948 } | |
1949 } | |
1950 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
1951 override void setOrientation() { |
69 | 1952 super.setOrientation(); |
71 | 1953 if ((style & DWT.RIGHT_TO_LEFT) !is 0) { |
69 | 1954 if (listHandle !is null) OS.gtk_widget_set_direction (listHandle, OS.GTK_TEXT_DIR_RTL); |
1955 if (entryHandle !is null) OS.gtk_widget_set_direction (entryHandle, OS.GTK_TEXT_DIR_RTL); | |
240 | 1956 if (cellHandle !is null) OS.gtk_widget_set_direction (cellHandle, OS.GTK_TEXT_DIR_RTL); |
69 | 1957 } |
1958 } | |
1959 | |
1960 /** | |
1961 * Sets the orientation of the receiver, which must be one | |
71 | 1962 * of the constants <code>DWT.LEFT_TO_RIGHT</code> or <code>DWT.RIGHT_TO_LEFT</code>. |
69 | 1963 * <p> |
1964 * | |
1965 * @param orientation new orientation style | |
1966 * | |
71 | 1967 * @exception DWTException <ul> |
69 | 1968 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1969 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1970 * </ul> | |
1971 * | |
1972 * @since 2.1.2 | |
1973 */ | |
1974 public void setOrientation (int orientation) { | |
240 | 1975 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { |
1976 checkWidget(); | |
1977 int flags = DWT.RIGHT_TO_LEFT | DWT.LEFT_TO_RIGHT; | |
1978 if ((orientation & flags) is 0 || (orientation & flags) is flags) return; | |
1979 style &= ~flags; | |
1980 style |= orientation & flags; | |
1981 int dir = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? OS.GTK_TEXT_DIR_RTL : OS.GTK_TEXT_DIR_LTR; | |
1982 OS.gtk_widget_set_direction (fixedHandle, dir); | |
1983 OS.gtk_widget_set_direction (handle, dir); | |
1984 if (entryHandle !is null) OS.gtk_widget_set_direction (entryHandle, dir); | |
1985 if (listHandle !is null) { | |
1986 OS.gtk_widget_set_direction (listHandle, dir); | |
1987 auto itemsList = OS.gtk_container_get_children (listHandle); | |
1988 if (itemsList !is null) { | |
1989 int count = OS.g_list_length (itemsList); | |
1990 for (int i=count - 1; i>=0; i--) { | |
1991 auto widget = OS.gtk_bin_get_child (OS.g_list_nth_data (itemsList, i)); | |
1992 OS.gtk_widget_set_direction (widget, dir); | |
1993 } | |
1994 OS.g_list_free (itemsList); | |
69 | 1995 } |
1996 } | |
240 | 1997 if (cellHandle !is null) OS.gtk_widget_set_direction (cellHandle, dir); |
1998 if (popupHandle !is null) display.doSetDirectionProc (popupHandle, dir); | |
69 | 1999 } |
2000 } | |
2001 | |
2002 /** | |
2003 * Sets the selection in the receiver's text field to the | |
2004 * range specified by the argument whose x coordinate is the | |
2005 * start of the selection and whose y coordinate is the end | |
2006 * of the selection. | |
2007 * | |
2008 * @param selection a point representing the new selection start and end | |
2009 * | |
2010 * @exception IllegalArgumentException <ul> | |
2011 * <li>ERROR_NULL_ARGUMENT - if the point is null</li> | |
2012 * </ul> | |
71 | 2013 * @exception DWTException <ul> |
69 | 2014 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
2015 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2016 * </ul> | |
2017 */ | |
2018 public void setSelection (Point selection) { | |
2019 checkWidget(); | |
71 | 2020 if (selection is null) error (DWT.ERROR_NULL_ARGUMENT); |
2021 if ((style & DWT.READ_ONLY) !is 0) return; | |
69 | 2022 if (entryHandle !is null) { |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
2023 OS.gtk_editable_set_position (entryHandle, selection.x); |
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
2024 OS.gtk_editable_select_region (entryHandle, selection.x, selection.y); |
69 | 2025 } |
2026 } | |
2027 | |
2028 /** | |
2029 * Sets the contents of the receiver's text field to the | |
2030 * given string. | |
2031 * <p> | |
2032 * Note: The text field in a <code>Combo</code> is typically | |
2033 * only capable of displaying a single line of text. Thus, | |
2034 * setting the text to a string containing line breaks or | |
2035 * other special characters will probably cause it to | |
2036 * display incorrectly. | |
2037 * </p> | |
2038 * | |
2039 * @param string the new text | |
2040 * | |
2041 * @exception IllegalArgumentException <ul> | |
2042 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
2043 * </ul> | |
71 | 2044 * @exception DWTException <ul> |
69 | 2045 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
2046 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2047 * </ul> | |
2048 */ | |
238 | 2049 public void setText (String string) { |
69 | 2050 checkWidget(); |
71 | 2051 if (string is null) error (DWT.ERROR_NULL_ARGUMENT); |
2052 if ((style & DWT.READ_ONLY) !is 0) { | |
69 | 2053 int index = indexOf (string); |
2054 if (index is -1) return; | |
2055 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
2056 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
2057 OS.gtk_combo_box_set_active (handle, index); |
69 | 2058 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
240 | 2059 /* |
2060 * Feature in GTK. Read Only combo boxes do not get a chance to send out a | |
2061 * Modify event in the gtk_changed callback. The fix is to send a Modify event | |
2062 * here. | |
2063 */ | |
2064 sendEvent (DWT.Modify); | |
69 | 2065 return; |
2066 } | |
2067 } | |
2068 /* | |
2069 * Feature in gtk. When text is set in gtk, separate events are fired for the deletion and | |
2070 * insertion of the text. This is not wrong, but is inconsistent with other platforms. The | |
2071 * fix is to block the firing of these events and fire them ourselves in a consistent manner. | |
2072 */ | |
71 | 2073 if (hooks (DWT.Verify) || filters (DWT.Verify)) { |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
2074 auto ptr = OS.gtk_entry_get_text (entryHandle); |
69 | 2075 string = verifyText (string, 0, cast(int)/*64*/OS.g_utf8_strlen (ptr, -1)); |
2076 if (string is null) return; | |
2077 } | |
2078 auto buffer = toStringz(string); | |
2079 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { | |
2080 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); | |
2081 } | |
2082 OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); | |
2083 OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_TEXT); | |
2084 OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
2085 OS.gtk_entry_set_text (entryHandle, buffer); |
69 | 2086 if (OS.GTK_VERSION >= OS.buildVERSION (2, 4, 0)) { |
2087 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); | |
2088 } | |
2089 OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); | |
2090 OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_TEXT); | |
2091 OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); | |
71 | 2092 sendEvent (DWT.Modify); |
69 | 2093 } |
2094 | |
2095 /** | |
2096 * Sets the maximum number of characters that the receiver's | |
2097 * text field is capable of holding to be the argument. | |
2098 * <p> | |
2099 * To reset this value to the default, use <code>setTextLimit(Combo.LIMIT)</code>. | |
2100 * Specifying a limit value larger than <code>Combo.LIMIT</code> sets the | |
2101 * receiver's limit to <code>Combo.LIMIT</code>. | |
2102 * </p> | |
2103 * @param limit new text limit | |
2104 * | |
2105 * @exception IllegalArgumentException <ul> | |
2106 * <li>ERROR_CANNOT_BE_ZERO - if the limit is zero</li> | |
2107 * </ul> | |
71 | 2108 * @exception DWTException <ul> |
69 | 2109 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
2110 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2111 * </ul> | |
2112 * | |
2113 * @see #LIMIT | |
2114 */ | |
2115 public void setTextLimit (int limit) { | |
2116 checkWidget(); | |
71 | 2117 if (limit is 0) error (DWT.ERROR_CANNOT_BE_ZERO); |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
2118 if (entryHandle !is null) OS.gtk_entry_set_max_length (entryHandle, limit); |
69 | 2119 } |
2120 | |
238 | 2121 override void setToolTipText (Shell shell, String newString) { |
69 | 2122 if (entryHandle !is null) shell.setToolTipText (entryHandle, newString); |
2123 if (buttonHandle !is null) shell.setToolTipText (buttonHandle, newString); | |
2124 } | |
2125 | |
2126 /** | |
2127 * Sets the number of items that are visible in the drop | |
2128 * down portion of the receiver's list. | |
2129 * <p> | |
2130 * Note: This operation is a hint and is not supported on | |
2131 * platforms that do not have this concept. | |
2132 * </p> | |
2133 * | |
2134 * @param count the new number of items to be visible | |
2135 * | |
71 | 2136 * @exception DWTException <ul> |
69 | 2137 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
2138 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2139 * </ul> | |
2140 * | |
2141 * @since 3.0 | |
2142 */ | |
2143 public void setVisibleItemCount (int count) { | |
2144 checkWidget (); | |
2145 if (count < 0) return; | |
2146 visibleCount = count; | |
2147 } | |
2148 | |
2149 override bool translateTraversal (GdkEventKey* keyEvent) { | |
2150 int key = keyEvent.keyval; | |
2151 switch (key) { | |
2152 case OS.GDK_KP_Enter: | |
2153 case OS.GDK_Return: { | |
2154 auto imContext = imContext (); | |
2155 if (imContext !is null) { | |
2156 char* preeditString; | |
73
1f0d924801f4
GTK function arguments to void*, so much less casts will be needed and more lines will pass without edit
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
2157 OS.gtk_im_context_get_preedit_string (imContext, &preeditString, null, null); |
69 | 2158 if (preeditString !is null) { |
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
|
2159 int length = fromStringz(preeditString).length; |
69 | 2160 OS.g_free (preeditString); |
2161 if (length !is 0) return false; | |
2162 } | |
2163 } | |
2164 } | |
2165 default: | |
2166 } | |
2167 return super.translateTraversal (keyEvent); | |
2168 } | |
2169 | |
238 | 2170 String verifyText (String string, int start, int end) { |
69 | 2171 if (string.length is 0 && start is end) return null; |
2172 Event event = new Event (); | |
2173 event.text = string; | |
2174 event.start = start; | |
2175 event.end = end; | |
2176 auto eventPtr = OS.gtk_get_current_event (); | |
2177 if (eventPtr !is null) { | |
2178 GdkEventKey* gdkEvent = cast(GdkEventKey*)eventPtr; | |
2179 switch (gdkEvent.type) { | |
2180 case OS.GDK_KEY_PRESS: | |
2181 setKeyState (event, gdkEvent); | |
2182 break; | |
2183 default: | |
2184 } | |
2185 OS.gdk_event_free (eventPtr); | |
2186 } | |
2187 /* | |
2188 * It is possible (but unlikely), that application | |
2189 * code could have disposed the widget in the verify | |
2190 * event. If this happens, answer null to cancel | |
2191 * the operation. | |
2192 */ | |
71 | 2193 sendEvent (DWT.Verify, event); |
69 | 2194 if (!event.doit || isDisposed ()) return null; |
2195 return event.text; | |
2196 } | |
2197 | |
2198 } |