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