Mercurial > projects > dwt2
annotate org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/widgets/TreeItem.d @ 51:c01d033c633a
[swt lin]
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 27 Mar 2009 19:58:06 +0100 |
parents | 7a2dd761a8b2 |
children |
rev | line source |
---|---|
25 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2008 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module org.eclipse.swt.widgets.TreeItem; | |
14 | |
15 import java.lang.all; | |
16 | |
17 | |
18 | |
19 import org.eclipse.swt.SWT; | |
20 import org.eclipse.swt.SWTException; | |
21 import org.eclipse.swt.graphics.Color; | |
22 import org.eclipse.swt.graphics.Font; | |
23 import org.eclipse.swt.graphics.Image; | |
24 import org.eclipse.swt.graphics.Rectangle; | |
25 import org.eclipse.swt.internal.gtk.OS; | |
26 import org.eclipse.swt.widgets.Item; | |
27 import org.eclipse.swt.widgets.Tree; | |
28 import org.eclipse.swt.widgets.ImageList; | |
29 | |
30 | |
31 /** | |
32 * Instances of this class represent a selectable user interface object | |
33 * that represents a hierarchy of tree items in a tree widget. | |
34 * | |
35 * <dl> | |
36 * <dt><b>Styles:</b></dt> | |
37 * <dd>(none)</dd> | |
38 * <dt><b>Events:</b></dt> | |
39 * <dd>(none)</dd> | |
40 * </dl> | |
41 * <p> | |
42 * IMPORTANT: This class is <em>not</em> intended to be subclassed. | |
43 * </p> | |
44 * | |
45 * @see <a href="http://www.eclipse.org/swt/snippets/#tree">Tree, TreeItem, TreeColumn snippets</a> | |
46 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> | |
47 */ | |
48 public class TreeItem : Item { | |
49 Tree parent; | |
50 Font font; | |
51 Font[] cellFont; | |
52 bool cached, grayed; | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
53 static const int EXPANDER_EXTRA_PADDING = 4; |
25 | 54 |
55 /** | |
56 * Constructs a new instance of this class given its parent | |
57 * (which must be a <code>Tree</code> or a <code>TreeItem</code>) | |
58 * and a style value describing its behavior and appearance. | |
59 * The item is added to the end of the items maintained by its parent. | |
60 * <p> | |
61 * The style value is either one of the style constants defined in | |
62 * class <code>SWT</code> which is applicable to instances of this | |
63 * class, or must be built by <em>bitwise OR</em>'ing together | |
64 * (that is, using the <code>int</code> "|" operator) two or more | |
65 * of those <code>SWT</code> style constants. The class description | |
66 * lists the style constants that are applicable to the class. | |
67 * Style bits are also inherited from superclasses. | |
68 * </p> | |
69 * | |
70 * @param parent a tree control which will be the parent of the new instance (cannot be null) | |
71 * @param style the style of control to construct | |
72 * | |
73 * @exception IllegalArgumentException <ul> | |
74 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
75 * </ul> | |
76 * @exception SWTException <ul> | |
77 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
78 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
79 * </ul> | |
80 * | |
81 * @see SWT | |
82 * @see Widget#checkSubclass | |
83 * @see Widget#getStyle | |
84 */ | |
85 public this (Tree parent, int style) { | |
86 this (checkNull (parent), null, style, -1, true); | |
87 } | |
88 | |
89 /** | |
90 * Constructs a new instance of this class given its parent | |
91 * (which must be a <code>Tree</code> or a <code>TreeItem</code>), | |
92 * a style value describing its behavior and appearance, and the index | |
93 * at which to place it in the items maintained by its parent. | |
94 * <p> | |
95 * The style value is either one of the style constants defined in | |
96 * class <code>SWT</code> which is applicable to instances of this | |
97 * class, or must be built by <em>bitwise OR</em>'ing together | |
98 * (that is, using the <code>int</code> "|" operator) two or more | |
99 * of those <code>SWT</code> style constants. The class description | |
100 * lists the style constants that are applicable to the class. | |
101 * Style bits are also inherited from superclasses. | |
102 * </p> | |
103 * | |
104 * @param parent a tree control which will be the parent of the new instance (cannot be null) | |
105 * @param style the style of control to construct | |
106 * @param index the zero-relative index to store the receiver in its parent | |
107 * | |
108 * @exception IllegalArgumentException <ul> | |
109 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
110 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> | |
111 * </ul> | |
112 * @exception SWTException <ul> | |
113 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
114 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
115 * </ul> | |
116 * | |
117 * @see SWT | |
118 * @see Widget#checkSubclass | |
119 * @see Widget#getStyle | |
120 */ | |
121 public this (Tree parent, int style, int index) { | |
122 this (checkNull (parent), null, style, checkIndex (index), true); | |
123 } | |
124 | |
125 /** | |
126 * Constructs a new instance of this class given its parent | |
127 * (which must be a <code>Tree</code> or a <code>TreeItem</code>) | |
128 * and a style value describing its behavior and appearance. | |
129 * The item is added to the end of the items maintained by its parent. | |
130 * <p> | |
131 * The style value is either one of the style constants defined in | |
132 * class <code>SWT</code> which is applicable to instances of this | |
133 * class, or must be built by <em>bitwise OR</em>'ing together | |
134 * (that is, using the <code>int</code> "|" operator) two or more | |
135 * of those <code>SWT</code> style constants. The class description | |
136 * lists the style constants that are applicable to the class. | |
137 * Style bits are also inherited from superclasses. | |
138 * </p> | |
139 * | |
140 * @param parentItem a tree control which will be the parent of the new instance (cannot be null) | |
141 * @param style the style of control to construct | |
142 * | |
143 * @exception IllegalArgumentException <ul> | |
144 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
145 * </ul> | |
146 * @exception SWTException <ul> | |
147 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
148 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
149 * </ul> | |
150 * | |
151 * @see SWT | |
152 * @see Widget#checkSubclass | |
153 * @see Widget#getStyle | |
154 */ | |
155 public this (TreeItem parentItem, int style) { | |
156 this (checkNull (parentItem).parent, cast(GtkTreeIter*)parentItem.handle, style, -1, true); | |
157 } | |
158 | |
159 /** | |
160 * Constructs a new instance of this class given its parent | |
161 * (which must be a <code>Tree</code> or a <code>TreeItem</code>), | |
162 * a style value describing its behavior and appearance, and the index | |
163 * at which to place it in the items maintained by its parent. | |
164 * <p> | |
165 * The style value is either one of the style constants defined in | |
166 * class <code>SWT</code> which is applicable to instances of this | |
167 * class, or must be built by <em>bitwise OR</em>'ing together | |
168 * (that is, using the <code>int</code> "|" operator) two or more | |
169 * of those <code>SWT</code> style constants. The class description | |
170 * lists the style constants that are applicable to the class. | |
171 * Style bits are also inherited from superclasses. | |
172 * </p> | |
173 * | |
174 * @param parentItem a tree control which will be the parent of the new instance (cannot be null) | |
175 * @param style the style of control to construct | |
176 * @param index the zero-relative index to store the receiver in its parent | |
177 * | |
178 * @exception IllegalArgumentException <ul> | |
179 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
180 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> | |
181 * </ul> | |
182 * @exception SWTException <ul> | |
183 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
184 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
185 * </ul> | |
186 * | |
187 * @see SWT | |
188 * @see Widget#checkSubclass | |
189 * @see Widget#getStyle | |
190 */ | |
191 public this (TreeItem parentItem, int style, int index) { | |
192 this (checkNull (parentItem).parent, cast(GtkTreeIter*)parentItem.handle, style, checkIndex (index), true); | |
193 } | |
194 | |
195 this (Tree parent, GtkTreeIter* parentIter, int style, int index, bool create) { | |
196 super (parent, style); | |
197 this.parent = parent; | |
198 if (create) { | |
199 parent.createItem (this, parentIter, index); | |
200 } else { | |
201 handle = cast(GtkWidget*)OS.g_malloc (GtkTreeIter.sizeof); | |
202 OS.gtk_tree_model_iter_nth_child (parent.modelHandle, handle, parentIter, index); | |
203 } | |
204 } | |
205 | |
206 static int checkIndex (int index) { | |
207 if (index < 0) SWT.error (SWT.ERROR_INVALID_RANGE); | |
208 return index; | |
209 } | |
210 | |
211 static TreeItem checkNull (TreeItem item) { | |
212 if (item is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); | |
213 return item; | |
214 } | |
215 | |
216 static Tree checkNull (Tree control) { | |
217 if (control is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); | |
218 return control; | |
219 } | |
220 | |
221 protected override void checkSubclass () { | |
222 if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); | |
223 } | |
224 | |
225 Color _getBackground () { | |
226 void* ptr; | |
227 OS.gtk_tree_model_get1 (parent.modelHandle, handle, Tree.BACKGROUND_COLUMN, &ptr); | |
228 if (ptr is null) return parent.getBackground (); | |
229 GdkColor* gdkColor = new GdkColor (); | |
230 *gdkColor = *cast(GdkColor*) ptr; | |
231 return Color.gtk_new (display, gdkColor); | |
232 } | |
233 | |
234 Color _getBackground (int index) { | |
235 int count = Math.max (1, parent.columnCount); | |
236 if (0 > index || index > count - 1) return _getBackground (); | |
237 void* ptr; | |
238 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; | |
239 OS.gtk_tree_model_get1 (parent.modelHandle, handle, modelIndex + Tree.CELL_BACKGROUND, &ptr); | |
240 if (ptr is null) return _getBackground (); | |
241 GdkColor* gdkColor = new GdkColor (); | |
242 *gdkColor = *cast(GdkColor*) ptr; | |
243 return Color.gtk_new (display, gdkColor); | |
244 } | |
245 | |
246 bool _getChecked () { | |
247 void* ptr; | |
248 OS.gtk_tree_model_get1 (parent.modelHandle, handle, Tree.CHECKED_COLUMN, &ptr); | |
249 return ptr !is null; | |
250 } | |
251 | |
252 Color _getForeground () { | |
253 void* ptr; | |
254 OS.gtk_tree_model_get1 (parent.modelHandle, handle, Tree.FOREGROUND_COLUMN, &ptr); | |
255 if (ptr is null) return parent.getForeground (); | |
256 GdkColor* gdkColor = new GdkColor (); | |
257 *gdkColor = *cast(GdkColor*) ptr; | |
258 return Color.gtk_new (display, gdkColor); | |
259 } | |
260 | |
261 Color _getForeground (int index) { | |
262 int count = Math.max (1, parent.columnCount); | |
263 if (0 > index || index > count - 1) return _getForeground (); | |
264 void* ptr; | |
265 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; | |
266 OS.gtk_tree_model_get1 (parent.modelHandle, handle, modelIndex + Tree.CELL_FOREGROUND, &ptr); | |
267 if (ptr is null) return _getForeground (); | |
268 GdkColor* gdkColor = new GdkColor (); | |
269 *gdkColor = *cast(GdkColor*) ptr; | |
270 return Color.gtk_new (display, gdkColor); | |
271 } | |
272 | |
273 Image _getImage (int index) { | |
274 int count = Math.max (1, parent.getColumnCount ()); | |
275 if (0 > index || index > count - 1) return null; | |
276 void* ptr; | |
277 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; | |
278 OS.gtk_tree_model_get1 (parent.modelHandle, handle, modelIndex + Tree.CELL_PIXBUF, &ptr); | |
279 if (ptr is null) return null; | |
280 ImageList imageList = parent.imageList; | |
281 int imageIndex = imageList.indexOf (ptr); | |
282 if (imageIndex is -1) return null; | |
283 return imageList.get (imageIndex); | |
284 } | |
285 | |
286 String _getText (int index) { | |
287 int count = Math.max (1, parent.getColumnCount ()); | |
288 if (0 > index || index > count - 1) return ""; | |
289 void* ptr; | |
290 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; | |
291 OS.gtk_tree_model_get1 (parent.modelHandle, handle, modelIndex + Tree.CELL_TEXT, &ptr); | |
292 if (ptr is null) return ""; //$NON-NLS-1$ | |
51 | 293 String buffer = fromStringz( cast(char*)ptr)._idup(); |
25 | 294 OS.g_free (ptr); |
295 return buffer; | |
296 } | |
297 | |
298 void clear () { | |
299 if (parent.currentItem is this) return; | |
300 if (cached || (parent.style & SWT.VIRTUAL) is 0) { | |
301 int columnCount = OS.gtk_tree_model_get_n_columns (parent.modelHandle); | |
302 for (int i=Tree.CHECKED_COLUMN; i<columnCount; i++) { | |
303 OS.gtk_tree_store_set1(parent.modelHandle, cast(GtkTreeIter*)handle, i, null); | |
304 } | |
305 /* | |
306 * Bug in GTK. When using fixed-height-mode, | |
307 * row changes do not cause the row to be repainted. The fix is to | |
308 * invalidate the row when it is cleared. | |
309 */ | |
310 if ((parent.style & SWT.VIRTUAL) !is 0) { | |
311 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { | |
312 redraw (); | |
313 } | |
314 } | |
315 } | |
316 cached = false; | |
317 font = null; | |
318 cellFont = null; | |
319 } | |
320 | |
321 /** | |
322 * Clears the item at the given zero-relative index in the receiver. | |
323 * The text, icon and other attributes of the item are set to the default | |
324 * value. If the tree was created with the <code>SWT.VIRTUAL</code> style, | |
325 * these attributes are requested again as needed. | |
326 * | |
327 * @param index the index of the item to clear | |
328 * @param all <code>true</code> if all child items of the indexed item should be | |
329 * cleared recursively, and <code>false</code> otherwise | |
330 * | |
331 * @exception IllegalArgumentException <ul> | |
332 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
333 * </ul> | |
334 * @exception SWTException <ul> | |
335 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
336 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
337 * </ul> | |
338 * | |
339 * @see SWT#VIRTUAL | |
340 * @see SWT#SetData | |
341 * | |
342 * @since 3.2 | |
343 */ | |
344 public void clear (int index, bool all) { | |
345 checkWidget (); | |
346 parent.clear (cast(GtkTreeIter*)handle, index, all); | |
347 } | |
348 | |
349 /** | |
350 * Clears all the items in the receiver. The text, icon and other | |
351 * attributes of the items are set to their default values. If the | |
352 * tree was created with the <code>SWT.VIRTUAL</code> style, these | |
353 * attributes are requested again as needed. | |
354 * | |
355 * @param all <code>true</code> if all child items should be cleared | |
356 * recursively, and <code>false</code> otherwise | |
357 * | |
358 * @exception SWTException <ul> | |
359 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
360 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
361 * </ul> | |
362 * | |
363 * @see SWT#VIRTUAL | |
364 * @see SWT#SetData | |
365 * | |
366 * @since 3.2 | |
367 */ | |
368 public void clearAll (bool all) { | |
369 checkWidget (); | |
370 parent.clearAll (all, cast(GtkTreeIter*)handle); | |
371 } | |
372 | |
373 override void destroyWidget () { | |
374 parent.releaseItem (this, false); | |
375 parent.destroyItem (this); | |
376 releaseHandle (); | |
377 } | |
378 | |
379 /** | |
380 * Returns the receiver's background color. | |
381 * | |
382 * @return the background color | |
383 * | |
384 * @exception SWTException <ul> | |
385 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
386 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
387 * </ul> | |
388 * | |
389 * @since 2.0 | |
390 * | |
391 */ | |
392 public Color getBackground () { | |
393 checkWidget (); | |
394 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
395 return _getBackground (); | |
396 } | |
397 | |
398 /** | |
399 * Returns the background color at the given column index in the receiver. | |
400 * | |
401 * @param index the column index | |
402 * @return the background color | |
403 * | |
404 * @exception SWTException <ul> | |
405 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
406 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
407 * </ul> | |
408 * | |
409 * @since 3.1 | |
410 */ | |
411 public Color getBackground (int index) { | |
412 checkWidget (); | |
413 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
414 return _getBackground (index); | |
415 } | |
416 | |
417 /** | |
418 * Returns a rectangle describing the receiver's size and location | |
419 * relative to its parent at a column in the tree. | |
420 * | |
421 * @param index the index that specifies the column | |
422 * @return the receiver's bounding column rectangle | |
423 * | |
424 * @exception SWTException <ul> | |
425 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
426 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
427 * </ul> | |
428 * | |
429 * @since 3.1 | |
430 */ | |
431 public Rectangle getBounds (int index) { | |
432 // TODO fully test on early and later versions of GTK | |
433 checkWidget(); | |
434 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
435 auto parentHandle = parent.handle; | |
436 GtkTreeViewColumn* column; | |
437 if (index >= 0 && index < parent.columnCount) { | |
438 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; | |
439 } else { | |
440 column = OS.gtk_tree_view_get_column (parentHandle, index); | |
441 } | |
442 if (column is null) return new Rectangle (0, 0, 0, 0); | |
443 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); | |
444 OS.gtk_widget_realize (parentHandle); | |
445 GdkRectangle rect; | |
446 OS.gtk_tree_view_get_cell_area (parentHandle, path, column, &rect); | |
447 if ((parent.getStyle () & SWT.MIRRORED) !is 0) rect.x = parent.getClientWidth () - rect.width - rect.x; | |
448 | |
449 if (OS.GTK_VERSION < OS.buildVERSION (2, 8, 18) && OS.gtk_tree_view_get_expander_column (parentHandle) is column) { | |
450 int buffer; | |
451 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &buffer); | |
452 rect.x += buffer + TreeItem.EXPANDER_EXTRA_PADDING; | |
453 rect.width -= buffer + TreeItem.EXPANDER_EXTRA_PADDING; | |
454 OS.gtk_widget_style_get1 (parentHandle, OS.horizontal_separator.ptr, &buffer); | |
455 rect.x += buffer; | |
456 //rect.width -= buffer [0]; // TODO Is this required for some versions? | |
457 } | |
458 /* | |
459 * Bug in GTK. In GTK 2.8.x, the cell area is left aligned even | |
460 * when the widget is mirrored. The fix is to sum up the indentation | |
461 * of the expanders. | |
462 */ | |
463 if ((parent.getStyle () & SWT.MIRRORED) !is 0 && (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0))) { | |
464 int depth = OS.gtk_tree_path_get_depth (path); | |
465 int expanderSize; | |
466 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &expanderSize); | |
467 rect.x += depth * (expanderSize + TreeItem.EXPANDER_EXTRA_PADDING); | |
468 } | |
469 OS.gtk_tree_path_free (path); | |
470 | |
471 if (index is 0 && (parent.style & SWT.CHECK) !is 0) { | |
472 if (OS.GTK_VERSION >= OS.buildVERSION (2, 1, 3)) { | |
473 int x, w; | |
474 OS.gtk_tree_view_column_cell_get_position (column, parent.checkRenderer, &x, &w); | |
475 rect.x += x + w; | |
476 rect.width -= x + w; | |
477 } else { | |
478 int w; | |
479 OS.gtk_cell_renderer_get_size (parent.checkRenderer, parentHandle, null, null, null, &w, null); | |
480 int buffer; | |
481 OS.gtk_widget_style_get1 (parentHandle, OS.horizontal_separator.ptr, &buffer); | |
482 rect.x += w + buffer; | |
483 rect.width -= w + buffer; | |
484 } | |
485 } | |
486 int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width + 1 : 0; | |
487 return new Rectangle (rect.x, rect.y, width, rect.height + 1); | |
488 } | |
489 | |
490 /** | |
491 * Returns a rectangle describing the receiver's size and location | |
492 * relative to its parent. | |
493 * | |
494 * @return the receiver's bounding rectangle | |
495 * | |
496 * @exception SWTException <ul> | |
497 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
498 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
499 * </ul> | |
500 */ | |
501 public Rectangle getBounds () { | |
502 // TODO fully test on early and later versions of GTK | |
503 // shifted a bit too far right on later versions of GTK - however, old Tree also had this problem | |
504 checkWidget (); | |
505 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
506 auto parentHandle = parent.handle; | |
507 auto column = OS.gtk_tree_view_get_column (parentHandle, 0); | |
508 if (column is null) return new Rectangle (0, 0, 0, 0); | |
509 auto textRenderer = parent.getTextRenderer (column); | |
510 auto pixbufRenderer = parent.getPixbufRenderer (column); | |
511 if (textRenderer is null || pixbufRenderer is null) return new Rectangle (0, 0, 0, 0); | |
512 | |
513 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); | |
514 OS.gtk_widget_realize (parentHandle); | |
515 | |
516 bool isExpander = OS.gtk_tree_model_iter_n_children (parent.modelHandle, handle) > 0; | |
517 bool isExpanded = cast(bool)OS.gtk_tree_view_row_expanded (parentHandle, path); | |
518 OS.gtk_tree_view_column_cell_set_cell_data (column, parent.modelHandle, handle, isExpander, isExpanded); | |
519 | |
520 GdkRectangle rect; | |
521 OS.gtk_tree_view_get_cell_area (parentHandle, path, column, &rect); | |
522 if ((parent.getStyle () & SWT.MIRRORED) !is 0) rect.x = parent.getClientWidth () - rect.width - rect.x; | |
523 int right = rect.x + rect.width; | |
524 | |
525 int x, w; | |
526 parent.ignoreSize = true; | |
527 OS.gtk_cell_renderer_get_size (textRenderer, parentHandle, null, null, null, &w, null); | |
528 parent.ignoreSize = false; | |
529 rect.width = w; | |
530 int buffer; | |
531 if (OS.GTK_VERSION < OS.buildVERSION (2, 8, 18) && OS.gtk_tree_view_get_expander_column (parentHandle) is column) { | |
532 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &buffer); | |
533 rect.x += buffer + TreeItem.EXPANDER_EXTRA_PADDING; | |
534 } | |
535 /* | |
536 * Bug in GTK. In GTK 2.8.x, the cell area is left aligned even | |
537 * when the widget is mirrored. The fix is to sum up the indentation | |
538 * of the expanders. | |
539 */ | |
540 if ((parent.getStyle () & SWT.MIRRORED) !is 0 && (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0))) { | |
541 int depth = OS.gtk_tree_path_get_depth (path); | |
542 int expanderSize; | |
543 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &expanderSize); | |
544 rect.x += depth * (expanderSize + TreeItem.EXPANDER_EXTRA_PADDING); | |
545 } | |
546 OS.gtk_tree_path_free (path); | |
547 | |
548 OS.gtk_widget_style_get1 (parentHandle, OS.horizontal_separator.ptr, &buffer); | |
549 int horizontalSeparator = buffer; | |
550 rect.x += horizontalSeparator; | |
551 | |
552 if (OS.GTK_VERSION >= OS.buildVERSION (2, 1, 3)) { | |
553 OS.gtk_tree_view_column_cell_get_position (column, textRenderer, &x, null); | |
554 rect.x += x; | |
555 } else { | |
556 if ((parent.style & SWT.CHECK) !is 0) { | |
557 OS.gtk_cell_renderer_get_size (parent.checkRenderer, parentHandle, null, null, null, &w, null); | |
558 rect.x += w + horizontalSeparator; | |
559 } | |
560 OS.gtk_cell_renderer_get_size (pixbufRenderer, parentHandle, null, null, null, &w, null); | |
561 rect.x += w + horizontalSeparator; | |
562 } | |
563 if (parent.columnCount > 0) { | |
564 if (rect.x + rect.width > right) { | |
565 rect.width = Math.max (0, right - rect.x); | |
566 } | |
567 } | |
568 int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width + 1 : 0; | |
569 return new Rectangle (rect.x, rect.y, width, rect.height + 1); | |
570 } | |
571 | |
572 /** | |
573 * Returns <code>true</code> if the receiver is checked, | |
574 * and false otherwise. When the parent does not have | |
575 * the <code>CHECK style, return false. | |
576 * <p> | |
577 * | |
578 * @return the checked state | |
579 * | |
580 * @exception SWTException <ul> | |
581 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
582 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
583 * </ul> | |
584 */ | |
585 public bool getChecked () { | |
586 checkWidget(); | |
587 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
588 if ((parent.style & SWT.CHECK) is 0) return false; | |
589 return _getChecked (); | |
590 } | |
591 | |
592 /** | |
593 * Returns <code>true</code> if the receiver is expanded, | |
594 * and false otherwise. | |
595 * <p> | |
596 * | |
597 * @return the expanded state | |
598 * | |
599 * @exception SWTException <ul> | |
600 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
601 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
602 * </ul> | |
603 */ | |
604 public bool getExpanded () { | |
605 checkWidget(); | |
606 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); | |
607 bool answer = cast(bool)OS.gtk_tree_view_row_expanded (parent.handle, path); | |
608 OS.gtk_tree_path_free (path); | |
609 return answer; | |
610 } | |
611 | |
612 /** | |
613 * Returns the font that the receiver will use to paint textual information for this item. | |
614 * | |
615 * @return the receiver's font | |
616 * | |
617 * @exception SWTException <ul> | |
618 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
619 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
620 * </ul> | |
621 * | |
622 * @since 3.0 | |
623 */ | |
624 public Font getFont () { | |
625 checkWidget (); | |
626 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
627 return font !is null ? font : parent.getFont (); | |
628 } | |
629 | |
630 /** | |
631 * Returns the font that the receiver will use to paint textual information | |
632 * for the specified cell in this item. | |
633 * | |
634 * @param index the column index | |
635 * @return the receiver's font | |
636 * | |
637 * @exception SWTException <ul> | |
638 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
639 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
640 * </ul> | |
641 * | |
642 * @since 3.1 | |
643 */ | |
644 public Font getFont (int index) { | |
645 checkWidget (); | |
646 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
647 int count = Math.max (1, parent.columnCount); | |
648 if (0 > index || index > count - 1) return getFont (); | |
649 if (cellFont is null || cellFont [index] is null) return getFont (); | |
650 return cellFont [index]; | |
651 } | |
652 | |
653 | |
654 /** | |
655 * Returns the foreground color that the receiver will use to draw. | |
656 * | |
657 * @return the receiver's foreground color | |
658 * | |
659 * @exception SWTException <ul> | |
660 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
661 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
662 * </ul> | |
663 * | |
664 * @since 2.0 | |
665 * | |
666 */ | |
667 public Color getForeground () { | |
668 checkWidget (); | |
669 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
670 return _getForeground (); | |
671 } | |
672 | |
673 /** | |
674 * | |
675 * Returns the foreground color at the given column index in the receiver. | |
676 * | |
677 * @param index the column index | |
678 * @return the foreground color | |
679 * | |
680 * @exception SWTException <ul> | |
681 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
682 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
683 * </ul> | |
684 * | |
685 * @since 3.1 | |
686 */ | |
687 public Color getForeground (int index) { | |
688 checkWidget (); | |
689 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
690 return _getForeground (index); | |
691 } | |
692 | |
693 /** | |
694 * Returns <code>true</code> if the receiver is grayed, | |
695 * and false otherwise. When the parent does not have | |
696 * the <code>CHECK style, return false. | |
697 * <p> | |
698 * | |
699 * @return the grayed state of the checkbox | |
700 * | |
701 * @exception SWTException <ul> | |
702 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
703 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
704 * </ul> | |
705 */ | |
706 public bool getGrayed () { | |
707 checkWidget (); | |
708 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
709 if ((parent.style & SWT.CHECK) is 0) return false; | |
710 return grayed; | |
711 } | |
712 | |
713 public override Image getImage () { | |
714 checkWidget (); | |
715 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
716 return getImage (0); | |
717 } | |
718 | |
719 /** | |
720 * Returns the image stored at the given column index in the receiver, | |
721 * or null if the image has not been set or if the column does not exist. | |
722 * | |
723 * @param index the column index | |
724 * @return the image stored at the given column index in the receiver | |
725 * | |
726 * @exception SWTException <ul> | |
727 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
728 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
729 * </ul> | |
730 * | |
731 * @since 3.1 | |
732 */ | |
733 public Image getImage (int index) { | |
734 checkWidget (); | |
735 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
736 return _getImage (index); | |
737 } | |
738 | |
739 /** | |
740 * Returns a rectangle describing the size and location | |
741 * relative to its parent of an image at a column in the | |
742 * tree. | |
743 * | |
744 * @param index the index that specifies the column | |
745 * @return the receiver's bounding image rectangle | |
746 * | |
747 * @exception SWTException <ul> | |
748 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
749 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
750 * </ul> | |
751 * | |
752 * @since 3.1 | |
753 */ | |
754 public Rectangle getImageBounds (int index) { | |
755 // TODO fully test on early and later versions of GTK | |
756 checkWidget (); | |
757 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
758 auto parentHandle = parent.handle; | |
759 GtkTreeViewColumn* column; | |
760 if (index >= 0 && index < parent.getColumnCount ()) { | |
761 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; | |
762 } else { | |
763 column = OS.gtk_tree_view_get_column (parentHandle, index); | |
764 } | |
765 if (column is null) return new Rectangle (0, 0, 0, 0); | |
766 auto pixbufRenderer = parent.getPixbufRenderer (column); | |
767 if (pixbufRenderer is null) return new Rectangle (0, 0, 0, 0); | |
768 GdkRectangle rect; | |
769 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); | |
770 OS.gtk_widget_realize (parentHandle); | |
771 OS.gtk_tree_view_get_cell_area (parentHandle, path, column, &rect); | |
772 if ((parent.getStyle () & SWT.MIRRORED) !is 0) rect.x = parent.getClientWidth () - rect.width - rect.x; | |
773 if (OS.GTK_VERSION < OS.buildVERSION (2, 8, 18) && OS.gtk_tree_view_get_expander_column (parentHandle) is column) { | |
774 int buffer; | |
775 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &buffer); | |
776 rect.x += buffer + TreeItem.EXPANDER_EXTRA_PADDING; | |
777 rect.width -= buffer + TreeItem.EXPANDER_EXTRA_PADDING; | |
778 //OS.gtk_widget_style_get (parentHandle, OS.horizontal_separator, buffer, 0); | |
779 //int horizontalSeparator = buffer[0]; | |
780 //rect.x += horizontalSeparator; | |
781 } | |
782 /* | |
783 * Bug in GTK. In GTK 2.8.x, the cell area is left aligned even | |
784 * when the widget is mirrored. The fix is to sum up the indentation | |
785 * of the expanders. | |
786 */ | |
787 if ((parent.getStyle () & SWT.MIRRORED) !is 0 && (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0))) { | |
788 int depth = OS.gtk_tree_path_get_depth (path); | |
789 int expanderSize; | |
790 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &expanderSize); | |
791 rect.x += depth * (expanderSize + TreeItem.EXPANDER_EXTRA_PADDING); | |
792 } | |
793 OS.gtk_tree_path_free (path); | |
794 | |
795 /* | |
796 * The OS call gtk_cell_renderer_get_size() provides the width of image to be drawn | |
797 * by the cell renderer. If there is no image in the cell, the width is zero. If the table contains | |
798 * images of varying widths, gtk_cell_renderer_get_size() will return the width of the image, | |
799 * not the width of the area in which the image is drawn. | |
800 * New API was added in GTK 2.1.3 for determining the full width of the renderer area. | |
801 * For earlier versions of GTK, the result is only correct if all rows have images of the same | |
802 * width. | |
803 */ | |
804 if (OS.GTK_VERSION >= OS.buildVERSION (2, 1, 3)) { | |
805 int x, w; | |
806 OS.gtk_tree_view_column_cell_get_position (column, pixbufRenderer, &x, &w); | |
807 rect.x += x; | |
808 rect.width = w; | |
809 } else { | |
810 int w; | |
811 OS.gtk_tree_view_column_cell_set_cell_data (column, parent.modelHandle, handle, false, false); | |
812 OS.gtk_cell_renderer_get_size (pixbufRenderer, parentHandle, null, null, null, &w, null); | |
813 rect.width = w; | |
814 } | |
815 int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width : 0; | |
816 return new Rectangle (rect.x, rect.y, width, rect.height + 1); | |
817 } | |
818 | |
819 /** | |
820 * Returns the number of items contained in the receiver | |
821 * that are direct item children of the receiver. | |
822 * | |
823 * @return the number of items | |
824 * | |
825 * @exception SWTException <ul> | |
826 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
827 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
828 * </ul> | |
829 */ | |
830 public int getItemCount () { | |
831 checkWidget(); | |
832 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
833 return OS.gtk_tree_model_iter_n_children (parent.modelHandle, handle); | |
834 } | |
835 | |
836 /** | |
837 * Returns the item at the given, zero-relative index in the | |
838 * receiver. Throws an exception if the index is out of range. | |
839 * | |
840 * @param index the index of the item to return | |
841 * @return the item at the given index | |
842 * | |
843 * @exception IllegalArgumentException <ul> | |
844 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
845 * </ul> | |
846 * @exception SWTException <ul> | |
847 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
848 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
849 * </ul> | |
850 * | |
851 * @since 3.1 | |
852 */ | |
853 public TreeItem getItem (int index) { | |
854 checkWidget(); | |
855 if (index < 0) error (SWT.ERROR_INVALID_RANGE); | |
856 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
857 int itemCount = OS.gtk_tree_model_iter_n_children (parent.modelHandle, handle); | |
858 if (index >= itemCount) error (SWT.ERROR_INVALID_RANGE); | |
859 return parent._getItem (cast(GtkTreeIter*)handle, index); | |
860 } | |
861 | |
862 /** | |
863 * Returns a (possibly empty) array of <code>TreeItem</code>s which | |
864 * are the direct item children of the receiver. | |
865 * <p> | |
866 * Note: This is not the actual structure used by the receiver | |
867 * to maintain its list of items, so modifying the array will | |
868 * not affect the receiver. | |
869 * </p> | |
870 * | |
871 * @return the receiver's items | |
872 * | |
873 * @exception SWTException <ul> | |
874 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
875 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
876 * </ul> | |
877 */ | |
878 public TreeItem [] getItems () { | |
879 checkWidget(); | |
880 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
881 return parent.getItems (cast(GtkTreeIter*)handle); | |
882 } | |
883 | |
884 override String getNameText () { | |
885 if ((parent.style & SWT.VIRTUAL) !is 0) { | |
886 if (!cached) return "*virtual*"; //$NON-NLS-1$ | |
887 } | |
888 return super.getNameText (); | |
889 } | |
890 | |
891 /** | |
892 * Returns the receiver's parent, which must be a <code>Tree</code>. | |
893 * | |
894 * @return the receiver's parent | |
895 * | |
896 * @exception SWTException <ul> | |
897 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
898 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
899 * </ul> | |
900 */ | |
901 public Tree getParent () { | |
902 checkWidget (); | |
903 return parent; | |
904 } | |
905 | |
906 /** | |
907 * Returns the receiver's parent item, which must be a | |
908 * <code>TreeItem</code> or null when the receiver is a | |
909 * root. | |
910 * | |
911 * @return the receiver's parent item | |
912 * | |
913 * @exception SWTException <ul> | |
914 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
915 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
916 * </ul> | |
917 */ | |
918 public TreeItem getParentItem () { | |
919 checkWidget(); | |
920 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); | |
921 TreeItem item = null; | |
922 int depth = OS.gtk_tree_path_get_depth (path); | |
923 if (depth > 1) { | |
924 OS.gtk_tree_path_up (path); | |
925 GtkTreeIter iter; | |
926 if (OS.gtk_tree_model_get_iter (parent.modelHandle, &iter, path)) { | |
927 item = parent._getItem (&iter); | |
928 } | |
929 } | |
930 OS.gtk_tree_path_free (path); | |
931 return item; | |
932 } | |
933 | |
934 public override String getText () { | |
935 checkWidget (); | |
936 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
937 return getText (0); | |
938 } | |
939 | |
940 /** | |
941 * Returns the text stored at the given column index in the receiver, | |
942 * or empty string if the text has not been set. | |
943 * | |
944 * @param index the column index | |
945 * @return the text stored at the given column index in the receiver | |
946 * | |
947 * @exception SWTException <ul> | |
948 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
949 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
950 * </ul> | |
951 * | |
952 * @since 3.1 | |
953 */ | |
954 public String getText (int index) { | |
955 checkWidget (); | |
956 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
957 return _getText (index); | |
958 } | |
959 | |
960 /** | |
961 * Returns a rectangle describing the size and location | |
962 * relative to its parent of the text at a column in the | |
963 * tree. | |
964 * | |
965 * @param index the index that specifies the column | |
966 * @return the receiver's bounding text rectangle | |
967 * | |
968 * @exception SWTException <ul> | |
969 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
970 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
971 * </ul> | |
972 * | |
973 * @since 3.3 | |
974 */ | |
975 public Rectangle getTextBounds (int index) { | |
976 checkWidget (); | |
977 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); | |
978 int count = Math.max (1, parent.getColumnCount ()); | |
979 if (0 > index || index > count - 1) return new Rectangle (0, 0, 0, 0); | |
980 // TODO fully test on early and later versions of GTK | |
981 // shifted a bit too far right on later versions of GTK - however, old Tree also had this problem | |
982 auto parentHandle = parent.handle; | |
983 GtkTreeViewColumn* column; | |
984 if (index >= 0 && index < parent.columnCount) { | |
985 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; | |
986 } else { | |
987 column = OS.gtk_tree_view_get_column (parentHandle, index); | |
988 } | |
989 if (column is null) return new Rectangle (0, 0, 0, 0); | |
990 auto textRenderer = parent.getTextRenderer (column); | |
991 auto pixbufRenderer = parent.getPixbufRenderer (column); | |
992 if (textRenderer is null || pixbufRenderer is null) return new Rectangle (0, 0, 0, 0); | |
993 | |
994 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); | |
995 OS.gtk_widget_realize (parentHandle); | |
996 | |
997 bool isExpander = OS.gtk_tree_model_iter_n_children (parent.modelHandle, handle) > 0; | |
998 bool isExpanded = cast(bool)OS.gtk_tree_view_row_expanded (parentHandle, path); | |
999 OS.gtk_tree_view_column_cell_set_cell_data (column, parent.modelHandle, handle, isExpander, isExpanded); | |
1000 | |
1001 GdkRectangle rect; | |
1002 OS.gtk_tree_view_get_cell_area (parentHandle, path, column, &rect); | |
1003 if ((parent.getStyle () & SWT.MIRRORED) !is 0) rect.x = parent.getClientWidth () - rect.width - rect.x; | |
1004 int right = rect.x + rect.width; | |
1005 | |
1006 int x, w; | |
1007 parent.ignoreSize = true; | |
1008 OS.gtk_cell_renderer_get_size (textRenderer, parentHandle, null, null, null, &w, null); | |
1009 parent.ignoreSize = false; | |
1010 int buffer; | |
1011 if (OS.GTK_VERSION < OS.buildVERSION (2, 8, 18) && OS.gtk_tree_view_get_expander_column (parentHandle) is column) { | |
1012 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &buffer); | |
1013 rect.x += buffer + TreeItem.EXPANDER_EXTRA_PADDING; | |
1014 } | |
1015 /* | |
1016 * Bug in GTK. In GTK 2.8.x, the cell area is left aligned even | |
1017 * when the widget is mirrored. The fix is to sum up the indentation | |
1018 * of the expanders. | |
1019 */ | |
1020 if ((parent.getStyle () & SWT.MIRRORED) !is 0 && (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0))) { | |
1021 int depth = OS.gtk_tree_path_get_depth (path); | |
1022 int expanderSize; | |
1023 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &expanderSize); | |
1024 rect.x += depth * (expanderSize + TreeItem.EXPANDER_EXTRA_PADDING); | |
1025 } | |
1026 OS.gtk_tree_path_free (path); | |
1027 | |
1028 OS.gtk_widget_style_get1 (parentHandle, OS.horizontal_separator.ptr, &buffer); | |
1029 int horizontalSeparator = buffer; | |
1030 rect.x += horizontalSeparator; | |
1031 if (OS.GTK_VERSION >= OS.buildVERSION (2, 1, 3)) { | |
1032 OS.gtk_tree_view_column_cell_get_position (column, textRenderer, &x, null); | |
1033 rect.x += x; | |
1034 } else { | |
1035 if ((parent.style & SWT.CHECK) !is 0) { | |
1036 OS.gtk_cell_renderer_get_size (parent.checkRenderer, parentHandle, null, null, null, &w, null); | |
1037 rect.x += w + horizontalSeparator; | |
1038 } | |
1039 OS.gtk_cell_renderer_get_size (pixbufRenderer, parentHandle, null, null, null, &w, null); | |
1040 rect.x += w + horizontalSeparator; | |
1041 } | |
1042 if (parent.columnCount > 0) { | |
1043 if (rect.x + rect.width > right) { | |
1044 rect.width = Math.max (0, right - rect.x); | |
1045 } | |
1046 } | |
1047 int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width + 1 : 0; | |
1048 return new Rectangle (rect.x, rect.y, width, rect.height + 1); | |
1049 } | |
1050 | |
1051 /** | |
1052 * Searches the receiver's list starting at the first item | |
1053 * (index 0) until an item is found that is equal to the | |
1054 * argument, and returns the index of that item. If no item | |
1055 * is found, returns -1. | |
1056 * | |
1057 * @param item the search item | |
1058 * @return the index of the item | |
1059 * | |
1060 * @exception IllegalArgumentException <ul> | |
1061 * <li>ERROR_NULL_ARGUMENT - if the item is null</li> | |
1062 * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li> | |
1063 * </ul> | |
1064 * @exception SWTException <ul> | |
1065 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1066 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1067 * </ul> | |
1068 * | |
1069 * @since 3.1 | |
1070 */ | |
1071 public int indexOf (TreeItem item) { | |
1072 checkWidget(); | |
1073 if (item is null) error (SWT.ERROR_NULL_ARGUMENT); | |
1074 if (item.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT); | |
1075 int index = -1; | |
1076 bool isParent = false; | |
1077 auto currentPath = OS.gtk_tree_model_get_path (parent.modelHandle, handle); | |
1078 auto parentPath = OS.gtk_tree_model_get_path (parent.modelHandle, item.handle); | |
1079 int depth = OS.gtk_tree_path_get_depth (parentPath); | |
1080 if (depth > 1 && OS.gtk_tree_path_up(parentPath)) { | |
1081 if (OS.gtk_tree_path_compare(currentPath, parentPath) is 0) isParent = true; | |
1082 } | |
1083 OS.gtk_tree_path_free (currentPath); | |
1084 OS.gtk_tree_path_free (parentPath); | |
1085 if (!isParent) return index; | |
1086 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, item.handle); | |
1087 if (depth > 1) { | |
1088 auto indices = OS.gtk_tree_path_get_indices (path); | |
1089 if (indices !is null) { | |
1090 int[] temp = indices[ 0 .. depth]; | |
1091 index = temp[temp.length - 1]; | |
1092 } | |
1093 } | |
1094 OS.gtk_tree_path_free (path); | |
1095 return index; | |
1096 } | |
1097 | |
1098 void redraw () { | |
1099 auto parentHandle = parent.handle; | |
1100 if ((OS.GTK_WIDGET_FLAGS (parentHandle) & OS.GTK_REALIZED) !is 0) { | |
1101 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); | |
1102 GdkRectangle rect; | |
1103 OS.gtk_tree_view_get_cell_area (parentHandle, path, null, &rect); | |
1104 OS.gtk_tree_path_free (path); | |
1105 auto window = OS.gtk_tree_view_get_bin_window (parentHandle); | |
1106 rect.x = 0; | |
1107 int w, h; | |
1108 OS.gdk_drawable_get_size (window, &w, &h); | |
1109 rect.width = w; | |
1110 OS.gdk_window_invalidate_rect (window, &rect, false); | |
1111 } | |
1112 } | |
1113 | |
1114 override void releaseChildren (bool destroy) { | |
1115 if (destroy) { | |
1116 parent.releaseItems (cast(GtkTreeIter*)handle); | |
1117 } | |
1118 super.releaseChildren (destroy); | |
1119 } | |
1120 | |
1121 override void releaseHandle () { | |
1122 if (handle !is null) OS.g_free (handle); | |
1123 handle = null; | |
1124 super.releaseHandle (); | |
1125 parent = null; | |
1126 } | |
1127 | |
1128 override void releaseWidget () { | |
1129 super.releaseWidget (); | |
1130 font = null; | |
1131 cellFont = null; | |
1132 } | |
1133 | |
1134 /** | |
1135 * Removes all of the items from the receiver. | |
1136 * <p> | |
1137 * @exception SWTException <ul> | |
1138 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1139 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1140 * </ul> | |
1141 * | |
1142 * @since 3.1 | |
1143 */ | |
1144 public void removeAll () { | |
1145 checkWidget (); | |
1146 int length = OS.gtk_tree_model_iter_n_children (parent.modelHandle, handle); | |
1147 if (length is 0) return; | |
1148 GtkTreeIter iter; | |
1149 int index; | |
1150 while (OS.gtk_tree_model_iter_children (parent.modelHandle, &iter, handle)) { | |
1151 OS.gtk_tree_model_get1 (parent.modelHandle, &iter, Tree.ID_COLUMN, cast(void**)&index); | |
1152 if (index !is -1) { | |
1153 TreeItem item = parent.items [index]; | |
1154 if (item !is null && !item.isDisposed ()) { | |
1155 item.dispose (); | |
1156 } | |
1157 } | |
1158 } | |
1159 } | |
1160 | |
1161 /** | |
1162 * Sets the receiver's background color to the color specified | |
1163 * by the argument, or to the default system color for the item | |
1164 * if the argument is null. | |
1165 * | |
1166 * @param color the new color (or null) | |
1167 * | |
1168 * @exception IllegalArgumentException <ul> | |
1169 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
1170 * </ul> | |
1171 * @exception SWTException <ul> | |
1172 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1173 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1174 * </ul> | |
1175 * | |
1176 * @since 2.0 | |
1177 * | |
1178 */ | |
1179 public void setBackground (Color color) { | |
1180 checkWidget (); | |
1181 if (color !is null && color.isDisposed ()) { | |
1182 SWT.error (SWT.ERROR_INVALID_ARGUMENT); | |
1183 } | |
1184 if (_getBackground ().opEquals (color)) return; | |
1185 GdkColor* gdkColor = color !is null ? color.handle : null; | |
1186 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, Tree.BACKGROUND_COLUMN, gdkColor); | |
1187 /* | |
1188 * Bug in GTK. When using fixed-height-mode, | |
1189 * row changes do not cause the row to be repainted. The fix is to | |
1190 * invalidate the row when it is cleared. | |
1191 */ | |
1192 if ((parent.style & SWT.VIRTUAL) !is 0) { | |
1193 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { | |
1194 redraw (); | |
1195 } | |
1196 } | |
1197 cached = true; | |
1198 } | |
1199 | |
1200 /** | |
1201 * Sets the background color at the given column index in the receiver | |
1202 * to the color specified by the argument, or to the default system color for the item | |
1203 * if the argument is null. | |
1204 * | |
1205 * @param index the column index | |
1206 * @param color the new color (or null) | |
1207 * | |
1208 * @exception IllegalArgumentException <ul> | |
1209 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
1210 * </ul> | |
1211 * @exception SWTException <ul> | |
1212 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1213 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1214 * </ul> | |
1215 * | |
1216 * @since 3.1 | |
1217 * | |
1218 */ | |
1219 public void setBackground (int index, Color color) { | |
1220 checkWidget (); | |
1221 if (color !is null && color.isDisposed ()) { | |
1222 SWT.error (SWT.ERROR_INVALID_ARGUMENT); | |
1223 } | |
1224 if (_getBackground (index).opEquals (color)) return; | |
1225 int count = Math.max (1, parent.getColumnCount ()); | |
1226 if (0 > index || index > count - 1) return; | |
1227 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; | |
1228 GdkColor* gdkColor = color !is null ? color.handle : null; | |
1229 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, modelIndex + Tree.CELL_BACKGROUND, gdkColor); | |
1230 /* | |
1231 * Bug in GTK. When using fixed-height-mode, | |
1232 * row changes do not cause the row to be repainted. The fix is to | |
1233 * invalidate the row when it is cleared. | |
1234 */ | |
1235 if ((parent.style & SWT.VIRTUAL) !is 0) { | |
1236 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { | |
1237 redraw (); | |
1238 } | |
1239 } | |
1240 cached = true; | |
1241 | |
1242 if (color !is null) { | |
1243 bool customDraw = (parent.columnCount is 0) ? parent.firstCustomDraw : parent.columns [index].customDraw; | |
1244 if (!customDraw) { | |
1245 if ((parent.style & SWT.VIRTUAL) is 0) { | |
1246 auto parentHandle = parent.handle; | |
1247 GtkTreeViewColumn* column; | |
1248 if (parent.columnCount > 0) { | |
1249 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; | |
1250 } else { | |
1251 column = OS.gtk_tree_view_get_column (parentHandle, index); | |
1252 } | |
1253 if (column is null) return; | |
1254 auto textRenderer = parent.getTextRenderer (column); | |
1255 auto imageRenderer = parent.getPixbufRenderer (column); | |
1256 display.doCellDataProc( parentHandle, cast(GtkTreeViewColumn*)column, cast(GtkCellRenderer*)textRenderer ); | |
1257 display.doCellDataProc( parentHandle, cast(GtkTreeViewColumn*)column, cast(GtkCellRenderer*)imageRenderer ); | |
1258 } | |
1259 if (parent.columnCount is 0) { | |
1260 parent.firstCustomDraw = true; | |
1261 } else { | |
1262 parent.columns [index].customDraw = true; | |
1263 } | |
1264 } | |
1265 } | |
1266 } | |
1267 | |
1268 /** | |
1269 * Sets the checked state of the receiver. | |
1270 * <p> | |
1271 * | |
1272 * @param checked the new checked state | |
1273 * | |
1274 * @exception SWTException <ul> | |
1275 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1276 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1277 * </ul> | |
1278 */ | |
1279 public void setChecked (bool checked) { | |
1280 checkWidget(); | |
1281 if ((parent.style & SWT.CHECK) is 0) return; | |
1282 if (_getChecked () is checked) return; | |
1283 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, Tree.CHECKED_COLUMN, cast(void*)cast(int)checked); | |
1284 /* | |
1285 * GTK+'s "inconsistent" state does not match SWT's concept of grayed. To | |
1286 * show checked+grayed differently from unchecked+grayed, we must toggle the | |
1287 * grayed state on check and uncheck. | |
1288 */ | |
1289 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, Tree.GRAYED_COLUMN, cast(void*)cast(int)( !checked ? false : grayed)); | |
1290 cached = true; | |
1291 } | |
1292 | |
1293 /** | |
1294 * Sets the expanded state of the receiver. | |
1295 * <p> | |
1296 * | |
1297 * @param expanded the new expanded state | |
1298 * | |
1299 * @exception SWTException <ul> | |
1300 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1301 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1302 * </ul> | |
1303 */ | |
1304 public void setExpanded (bool expanded) { | |
1305 checkWidget(); | |
1306 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); | |
1307 if (expanded) { | |
1308 OS.g_signal_handlers_block_matched (parent.handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEST_EXPAND_ROW); | |
1309 OS.gtk_tree_view_expand_row (parent.handle, path, false); | |
1310 OS.g_signal_handlers_unblock_matched (parent.handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEST_EXPAND_ROW); | |
1311 } else { | |
1312 OS.g_signal_handlers_block_matched (parent.handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEST_COLLAPSE_ROW); | |
1313 OS.gtk_widget_realize (parent.handle); | |
1314 OS.gtk_tree_view_collapse_row (parent.handle, path); | |
1315 OS.g_signal_handlers_unblock_matched (parent.handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEST_COLLAPSE_ROW); | |
1316 } | |
1317 OS.gtk_tree_path_free (path); | |
1318 cached = true; | |
1319 } | |
1320 | |
1321 | |
1322 /** | |
1323 * Sets the font that the receiver will use to paint textual information | |
1324 * for this item to the font specified by the argument, or to the default font | |
1325 * for that kind of control if the argument is null. | |
1326 * | |
1327 * @param font the new font (or null) | |
1328 * | |
1329 * @exception IllegalArgumentException <ul> | |
1330 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
1331 * </ul> | |
1332 * @exception SWTException <ul> | |
1333 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1334 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1335 * </ul> | |
1336 * | |
1337 * @since 3.0 | |
1338 */ | |
1339 public void setFont (Font font){ | |
1340 checkWidget (); | |
1341 if (font !is null && font.isDisposed ()) { | |
1342 SWT.error (SWT.ERROR_INVALID_ARGUMENT); | |
1343 } | |
1344 Font oldFont = this.font; | |
1345 if (oldFont is font) return; | |
1346 this.font = font; | |
1347 if (oldFont !is null && oldFont.opEquals (font)) return; | |
1348 void* fontHandle = font !is null ? font.handle : null; | |
1349 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, Tree.FONT_COLUMN, fontHandle); | |
1350 /* | |
1351 * Bug in GTK. When using fixed-height-mode, | |
1352 * row changes do not cause the row to be repainted. The fix is to | |
1353 * invalidate the row when it is cleared. | |
1354 */ | |
1355 if ((parent.style & SWT.VIRTUAL) !is 0) { | |
1356 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { | |
1357 redraw (); | |
1358 } | |
1359 } | |
1360 cached = true; | |
1361 } | |
1362 | |
1363 /** | |
1364 * Sets the font that the receiver will use to paint textual information | |
1365 * for the specified cell in this item to the font specified by the | |
1366 * argument, or to the default font for that kind of control if the | |
1367 * argument is null. | |
1368 * | |
1369 * @param index the column index | |
1370 * @param font the new font (or null) | |
1371 * | |
1372 * @exception IllegalArgumentException <ul> | |
1373 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
1374 * </ul> | |
1375 * @exception SWTException <ul> | |
1376 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1377 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1378 * </ul> | |
1379 * | |
1380 * @since 3.1 | |
1381 */ | |
1382 public void setFont (int index, Font font) { | |
1383 checkWidget (); | |
1384 if (font !is null && font.isDisposed ()) { | |
1385 SWT.error (SWT.ERROR_INVALID_ARGUMENT); | |
1386 } | |
1387 int count = Math.max (1, parent.getColumnCount ()); | |
1388 if (0 > index || index > count - 1) return; | |
1389 if (cellFont is null) { | |
1390 if (font is null) return; | |
1391 cellFont = new Font [count]; | |
1392 } | |
1393 Font oldFont = cellFont [index]; | |
1394 if (oldFont is font) return; | |
1395 cellFont [index] = font; | |
1396 if (oldFont !is null && oldFont.opEquals (font)) return; | |
1397 | |
1398 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; | |
1399 auto fontHandle = font !is null ? font.handle : null; | |
1400 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, modelIndex + Tree.CELL_FONT, fontHandle); | |
1401 /* | |
1402 * Bug in GTK. When using fixed-height-mode, | |
1403 * row changes do not cause the row to be repainted. The fix is to | |
1404 * invalidate the row when it is cleared. | |
1405 */ | |
1406 if ((parent.style & SWT.VIRTUAL) !is 0) { | |
1407 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { | |
1408 redraw (); | |
1409 } | |
1410 } | |
1411 cached = true; | |
1412 | |
1413 if (font !is null) { | |
1414 bool customDraw = (parent.columnCount is 0) ? parent.firstCustomDraw : parent.columns [index].customDraw; | |
1415 if (!customDraw) { | |
1416 if ((parent.style & SWT.VIRTUAL) is 0) { | |
1417 auto parentHandle = parent.handle; | |
1418 GtkTreeViewColumn* column; | |
1419 if (parent.columnCount > 0) { | |
1420 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; | |
1421 } else { | |
1422 column = OS.gtk_tree_view_get_column (parentHandle, index); | |
1423 } | |
1424 if (column is null) return; | |
1425 auto textRenderer = parent.getTextRenderer (column); | |
1426 auto imageRenderer = parent.getPixbufRenderer (column); | |
1427 display.doCellDataProc( parentHandle, cast(GtkTreeViewColumn*)column, cast(GtkCellRenderer*)textRenderer ); | |
1428 display.doCellDataProc( parentHandle, cast(GtkTreeViewColumn*)column, cast(GtkCellRenderer*)imageRenderer ); | |
1429 } | |
1430 if (parent.columnCount is 0) { | |
1431 parent.firstCustomDraw = true; | |
1432 } else { | |
1433 parent.columns [index].customDraw = true; | |
1434 } | |
1435 } | |
1436 } | |
1437 } | |
1438 | |
1439 /** | |
1440 * Sets the receiver's foreground color to the color specified | |
1441 * by the argument, or to the default system color for the item | |
1442 * if the argument is null. | |
1443 * | |
1444 * @param color the new color (or null) | |
1445 * | |
1446 * @since 2.0 | |
1447 * | |
1448 * @exception IllegalArgumentException <ul> | |
1449 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
1450 * </ul> | |
1451 * @exception SWTException <ul> | |
1452 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1453 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1454 * </ul> | |
1455 * | |
1456 * @since 2.0 | |
1457 * | |
1458 */ | |
1459 public void setForeground (Color color){ | |
1460 checkWidget (); | |
1461 if (color !is null && color.isDisposed ()) { | |
1462 SWT.error (SWT.ERROR_INVALID_ARGUMENT); | |
1463 } | |
1464 if (_getForeground ().opEquals (color)) return; | |
1465 GdkColor *gdkColor = color !is null ? color.handle : null; | |
1466 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, Tree.FOREGROUND_COLUMN, gdkColor); | |
1467 /* | |
1468 * Bug in GTK. When using fixed-height-mode, | |
1469 * row changes do not cause the row to be repainted. The fix is to | |
1470 * invalidate the row when it is cleared. | |
1471 */ | |
1472 if ((parent.style & SWT.VIRTUAL) !is 0) { | |
1473 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { | |
1474 redraw (); | |
1475 } | |
1476 } | |
1477 cached = true; | |
1478 } | |
1479 | |
1480 /** | |
1481 * Sets the foreground color at the given column index in the receiver | |
1482 * to the color specified by the argument, or to the default system color for the item | |
1483 * if the argument is null. | |
1484 * | |
1485 * @param index the column index | |
1486 * @param color the new color (or null) | |
1487 * | |
1488 * @exception IllegalArgumentException <ul> | |
1489 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
1490 * </ul> | |
1491 * @exception SWTException <ul> | |
1492 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1493 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1494 * </ul> | |
1495 * | |
1496 * @since 3.1 | |
1497 * | |
1498 */ | |
1499 public void setForeground (int index, Color color){ | |
1500 checkWidget (); | |
1501 if (color !is null && color.isDisposed ()) { | |
1502 SWT.error (SWT.ERROR_INVALID_ARGUMENT); | |
1503 } | |
1504 if (_getForeground (index).opEquals (color)) return; | |
1505 int count = Math.max (1, parent.getColumnCount ()); | |
1506 if (0 > index || index > count - 1) return; | |
1507 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; | |
1508 GdkColor *gdkColor = color !is null ? color.handle : null; | |
1509 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, modelIndex + Tree.CELL_FOREGROUND, gdkColor); | |
1510 /* | |
1511 * Bug in GTK. When using fixed-height-mode, | |
1512 * row changes do not cause the row to be repainted. The fix is to | |
1513 * invalidate the row when it is cleared. | |
1514 */ | |
1515 if ((parent.style & SWT.VIRTUAL) !is 0) { | |
1516 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { | |
1517 redraw (); | |
1518 } | |
1519 } | |
1520 cached = true; | |
1521 | |
1522 if (color !is null) { | |
1523 bool customDraw = (parent.columnCount is 0) ? parent.firstCustomDraw : parent.columns [index].customDraw; | |
1524 if (!customDraw) { | |
1525 if ((parent.style & SWT.VIRTUAL) is 0) { | |
1526 auto parentHandle = parent.handle; | |
1527 GtkTreeViewColumn* column; | |
1528 if (parent.columnCount > 0) { | |
1529 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; | |
1530 } else { | |
1531 column = OS.gtk_tree_view_get_column (parentHandle, index); | |
1532 } | |
1533 if (column is null) return; | |
1534 auto textRenderer = parent.getTextRenderer (column); | |
1535 auto imageRenderer = parent.getPixbufRenderer (column); | |
1536 display.doCellDataProc( parentHandle, cast(GtkTreeViewColumn*)column, cast(GtkCellRenderer*)textRenderer ); | |
1537 display.doCellDataProc( parentHandle, cast(GtkTreeViewColumn*)column, cast(GtkCellRenderer*)imageRenderer ); | |
1538 } | |
1539 if (parent.columnCount is 0) { | |
1540 parent.firstCustomDraw = true; | |
1541 } else { | |
1542 parent.columns [index].customDraw = true; | |
1543 } | |
1544 } | |
1545 } | |
1546 } | |
1547 | |
1548 /** | |
1549 * Sets the grayed state of the checkbox for this item. This state change | |
1550 * only applies if the Tree was created with the SWT.CHECK style. | |
1551 * | |
1552 * @param grayed the new grayed state of the checkbox | |
1553 * | |
1554 * @exception SWTException <ul> | |
1555 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1556 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1557 * </ul> | |
1558 */ | |
1559 public void setGrayed (bool grayed) { | |
1560 checkWidget(); | |
1561 if ((parent.style & SWT.CHECK) is 0) return; | |
1562 if (this.grayed is grayed) return; | |
1563 this.grayed = grayed; | |
1564 /* | |
1565 * GTK+'s "inconsistent" state does not match SWT's concept of grayed. | |
1566 * Render checked+grayed as "inconsistent", unchecked+grayed as blank. | |
1567 */ | |
1568 void* ptr; | |
1569 OS.gtk_tree_model_get1 (parent.modelHandle, handle, Tree.CHECKED_COLUMN, &ptr); | |
1570 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, Tree.GRAYED_COLUMN, cast(void*)cast(int)( ptr is null ? false : grayed)); | |
1571 cached = true; | |
1572 } | |
1573 | |
1574 /** | |
1575 * Sets the receiver's image at a column. | |
1576 * | |
1577 * @param index the column index | |
1578 * @param image the new image | |
1579 * | |
1580 * @exception IllegalArgumentException <ul> | |
1581 * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li> | |
1582 * </ul> | |
1583 * @exception SWTException <ul> | |
1584 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1585 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1586 * </ul> | |
1587 * | |
1588 * @since 3.1 | |
1589 */ | |
1590 public void setImage (int index, Image image) { | |
1591 checkWidget (); | |
1592 if (image !is null && image.isDisposed()) { | |
1593 error(SWT.ERROR_INVALID_ARGUMENT); | |
1594 } | |
1595 if (image !is null && image.type is SWT.ICON) { | |
1596 if (image.opEquals (_getImage (index))) return; | |
1597 } | |
1598 int count = Math.max (1, parent.getColumnCount ()); | |
1599 if (0 > index || index > count - 1) return; | |
1600 GdkPixbuf* pixbuf; | |
1601 if (image !is null) { | |
1602 ImageList imageList = parent.imageList; | |
1603 if (imageList is null) imageList = parent.imageList = new ImageList (); | |
1604 int imageIndex = imageList.indexOf (image); | |
1605 if (imageIndex is -1) imageIndex = imageList.add (image); | |
1606 pixbuf = imageList.getPixbuf (imageIndex); | |
1607 } | |
1608 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; | |
1609 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, modelIndex + Tree.CELL_PIXBUF, pixbuf); | |
1610 /* | |
1611 * Bug in GTK. When using fixed-height-mode, | |
1612 * row changes do not cause the row to be repainted. The fix is to | |
1613 * invalidate the row when the image changes. | |
1614 */ | |
1615 if ((parent.style & SWT.VIRTUAL) !is 0) { | |
1616 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { | |
1617 if (parent.columnCount is 0) { | |
1618 redraw (); | |
1619 } | |
1620 } | |
1621 } | |
1622 /* | |
1623 * Bug in GTK. When using fixed-height-mode, GTK does not recalculate the cell renderer width | |
1624 * when the image is changed in the model. The fix is to force it to recalculate the width if | |
1625 * more space is required. | |
1626 */ | |
1627 if ((parent.style & SWT.VIRTUAL) !is 0 && parent.currentItem is null) { | |
1628 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2)) { | |
1629 if (image !is null) { | |
1630 auto parentHandle = parent.handle; | |
1631 auto column = OS.gtk_tree_view_get_column (parentHandle, index); | |
1632 int w; | |
1633 auto pixbufRenderer = parent.getPixbufRenderer(column); | |
1634 OS.gtk_tree_view_column_cell_get_position (column, pixbufRenderer, null, &w); | |
1635 if (w < image.getBounds().width) { | |
1636 /* | |
1637 * There is no direct way to clear the cell renderer width so we | |
1638 * are relying on the fact that it is done as part of modifying | |
1639 * the style. | |
1640 */ | |
1641 auto style = OS.gtk_widget_get_modifier_style (parentHandle); | |
1642 parent.modifyStyle (parentHandle, style); | |
1643 } | |
1644 } | |
1645 } | |
1646 } | |
1647 cached = true; | |
1648 } | |
1649 | |
1650 public override void setImage (Image image) { | |
1651 checkWidget (); | |
1652 setImage (0, image); | |
1653 } | |
1654 | |
1655 /** | |
1656 * Sets the image for multiple columns in the tree. | |
1657 * | |
1658 * @param images the array of new images | |
1659 * | |
1660 * @exception IllegalArgumentException <ul> | |
1661 * <li>ERROR_INVALID_ARGUMENT - if one of the images has been disposed</li> | |
1662 * </ul> | |
1663 * @exception SWTException <ul> | |
1664 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1665 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1666 * </ul> | |
1667 * | |
1668 * @since 3.1 | |
1669 */ | |
1670 public void setImage (Image [] images) { | |
1671 checkWidget (); | |
1672 // SWT extension: allow null for zero length string | |
1673 //if (images is null) error (SWT.ERROR_NULL_ARGUMENT); | |
1674 for (int i=0; i<images.length; i++) { | |
1675 setImage (i, images [i]); | |
1676 } | |
1677 } | |
1678 | |
1679 /** | |
1680 * Sets the number of child items contained in the receiver. | |
1681 * | |
1682 * @param count the number of items | |
1683 * | |
1684 * @exception SWTException <ul> | |
1685 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1686 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1687 * </ul> | |
1688 * | |
1689 * @since 3.2 | |
1690 */ | |
1691 public void setItemCount (int count) { | |
1692 checkWidget (); | |
1693 count = Math.max (0, count); | |
1694 parent.setItemCount (cast(GtkTreeIter*)handle, count); | |
1695 } | |
1696 | |
1697 /** | |
1698 * Sets the receiver's text at a column | |
1699 * | |
1700 * @param index the column index | |
1701 * @param string the new text | |
1702 * | |
1703 * @exception SWTException <ul> | |
1704 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1705 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1706 * </ul> | |
1707 * | |
1708 * @since 3.1 | |
1709 */ | |
1710 public void setText (int index, String string) { | |
1711 checkWidget (); | |
1712 // SWT extension: allow null for zero length string | |
1713 //if (string is null) error (SWT.ERROR_NULL_ARGUMENT); | |
1714 if (_getText (index).equals (string)) return; | |
1715 int count = Math.max (1, parent.getColumnCount ()); | |
1716 if (0 > index || index > count - 1) return; | |
1717 char* buffer = toStringz(string); | |
1718 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; | |
1719 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, modelIndex + Tree.CELL_TEXT, buffer); | |
1720 /* | |
1721 * Bug in GTK. When using fixed-height-mode, | |
1722 * row changes do not cause the row to be repainted. The fix is to | |
1723 * invalidate the row when the text changes. | |
1724 */ | |
1725 if ((parent.style & SWT.VIRTUAL) !is 0) { | |
1726 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { | |
1727 redraw (); | |
1728 } | |
1729 } | |
1730 cached = true; | |
1731 } | |
1732 | |
1733 public override void setText (String string) { | |
1734 checkWidget (); | |
1735 setText (0, string); | |
1736 } | |
1737 | |
1738 /** | |
1739 * Sets the text for multiple columns in the tree. | |
1740 * | |
1741 * @param strings the array of new strings | |
1742 * | |
1743 * @exception SWTException <ul> | |
1744 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1745 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1746 * </ul> | |
1747 * | |
1748 * @since 3.1 | |
1749 */ | |
1750 public void setText (String [] strings) { | |
1751 checkWidget (); | |
1752 // SWT extension: allow null for zero length string | |
1753 //if (strings is null) error (SWT.ERROR_NULL_ARGUMENT); | |
1754 for (int i=0; i<strings.length; i++) { | |
1755 String string = strings [i]; | |
1756 if (string !is null) setText (i, string); | |
1757 } | |
1758 } | |
1759 } |