Mercurial > projects > dwt2
comparison org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/widgets/TreeItem.d @ 0:6dd524f61e62
add dwt win and basic java stuff
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 02 Mar 2009 14:44:16 +0100 |
parents | |
children | 2e09b0e6857a |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:6dd524f61e62 |
---|---|
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 org.eclipse.swt.SWT; | |
16 import org.eclipse.swt.SWTException; | |
17 import org.eclipse.swt.graphics.Color; | |
18 import org.eclipse.swt.graphics.Font; | |
19 import org.eclipse.swt.graphics.Image; | |
20 import org.eclipse.swt.graphics.Point; | |
21 import org.eclipse.swt.graphics.Rectangle; | |
22 import org.eclipse.swt.internal.win32.OS; | |
23 | |
24 import org.eclipse.swt.widgets.Item; | |
25 import org.eclipse.swt.widgets.Widget; | |
26 import org.eclipse.swt.widgets.Tree; | |
27 import org.eclipse.swt.widgets.Event; | |
28 | |
29 import java.lang.all; | |
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 | |
49 public class TreeItem : Item { | |
50 /** | |
51 * the handle to the OS resource | |
52 * (Warning: This field is platform dependent) | |
53 * <p> | |
54 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT | |
55 * public API. It is marked public only so that it can be shared | |
56 * within the packages provided by SWT. It is not available on all | |
57 * platforms and should never be accessed from application code. | |
58 * </p> | |
59 */ | |
60 public HANDLE handle; | |
61 Tree parent; | |
62 String [] strings; | |
63 Image [] images; | |
64 Font font; | |
65 Font [] cellFont; | |
66 bool cached; | |
67 int background = -1, foreground = -1; | |
68 int [] cellBackground, cellForeground; | |
69 | |
70 /** | |
71 * Constructs a new instance of this class given its parent | |
72 * (which must be a <code>Tree</code> or a <code>TreeItem</code>) | |
73 * and a style value describing its behavior and appearance. | |
74 * The item is added to the end of the items maintained by its parent. | |
75 * <p> | |
76 * The style value is either one of the style constants defined in | |
77 * class <code>SWT</code> which is applicable to instances of this | |
78 * class, or must be built by <em>bitwise OR</em>'ing together | |
79 * (that is, using the <code>int</code> "|" operator) two or more | |
80 * of those <code>SWT</code> style constants. The class description | |
81 * lists the style constants that are applicable to the class. | |
82 * Style bits are also inherited from superclasses. | |
83 * </p> | |
84 * | |
85 * @param parent a tree control which will be the parent of the new instance (cannot be null) | |
86 * @param style the style of control to construct | |
87 * | |
88 * @exception IllegalArgumentException <ul> | |
89 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
90 * </ul> | |
91 * @exception SWTException <ul> | |
92 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
93 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
94 * </ul> | |
95 * | |
96 * @see SWT | |
97 * @see Widget#checkSubclass | |
98 * @see Widget#getStyle | |
99 */ | |
100 public this (Tree parent, int style) { | |
101 this (parent, style, cast(HANDLE)OS.TVGN_ROOT, cast(HANDLE)OS.TVI_LAST, null); | |
102 } | |
103 | |
104 /** | |
105 * Constructs a new instance of this class given its parent | |
106 * (which must be a <code>Tree</code> or a <code>TreeItem</code>), | |
107 * a style value describing its behavior and appearance, and the index | |
108 * at which to place it in the items maintained by its parent. | |
109 * <p> | |
110 * The style value is either one of the style constants defined in | |
111 * class <code>SWT</code> which is applicable to instances of this | |
112 * class, or must be built by <em>bitwise OR</em>'ing together | |
113 * (that is, using the <code>int</code> "|" operator) two or more | |
114 * of those <code>SWT</code> style constants. The class description | |
115 * lists the style constants that are applicable to the class. | |
116 * Style bits are also inherited from superclasses. | |
117 * </p> | |
118 * | |
119 * @param parent a tree control which will be the parent of the new instance (cannot be null) | |
120 * @param style the style of control to construct | |
121 * @param index the zero-relative index to store the receiver in its parent | |
122 * | |
123 * @exception IllegalArgumentException <ul> | |
124 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
125 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> | |
126 * </ul> | |
127 * @exception SWTException <ul> | |
128 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
129 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
130 * </ul> | |
131 * | |
132 * @see SWT | |
133 * @see Widget#checkSubclass | |
134 * @see Widget#getStyle | |
135 */ | |
136 public this (Tree parent, int style, int index) { | |
137 this (parent, style, cast(HANDLE) OS.TVGN_ROOT, findPrevious (parent, index), null); | |
138 } | |
139 | |
140 /** | |
141 * Constructs a new instance of this class given its parent | |
142 * (which must be a <code>Tree</code> or a <code>TreeItem</code>) | |
143 * and a style value describing its behavior and appearance. | |
144 * The item is added to the end of the items maintained by its parent. | |
145 * <p> | |
146 * The style value is either one of the style constants defined in | |
147 * class <code>SWT</code> which is applicable to instances of this | |
148 * class, or must be built by <em>bitwise OR</em>'ing together | |
149 * (that is, using the <code>int</code> "|" operator) two or more | |
150 * of those <code>SWT</code> style constants. The class description | |
151 * lists the style constants that are applicable to the class. | |
152 * Style bits are also inherited from superclasses. | |
153 * </p> | |
154 * | |
155 * @param parentItem a tree control which will be the parent of the new instance (cannot be null) | |
156 * @param style the style of control to construct | |
157 * | |
158 * @exception IllegalArgumentException <ul> | |
159 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
160 * </ul> | |
161 * @exception SWTException <ul> | |
162 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
163 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
164 * </ul> | |
165 * | |
166 * @see SWT | |
167 * @see Widget#checkSubclass | |
168 * @see Widget#getStyle | |
169 */ | |
170 public this (TreeItem parentItem, int style) { | |
171 this (checkNull (parentItem).parent, style, parentItem.handle, cast(HANDLE)OS.TVI_LAST, null); | |
172 } | |
173 | |
174 /** | |
175 * Constructs a new instance of this class given its parent | |
176 * (which must be a <code>Tree</code> or a <code>TreeItem</code>), | |
177 * a style value describing its behavior and appearance, and the index | |
178 * at which to place it in the items maintained by its parent. | |
179 * <p> | |
180 * The style value is either one of the style constants defined in | |
181 * class <code>SWT</code> which is applicable to instances of this | |
182 * class, or must be built by <em>bitwise OR</em>'ing together | |
183 * (that is, using the <code>int</code> "|" operator) two or more | |
184 * of those <code>SWT</code> style constants. The class description | |
185 * lists the style constants that are applicable to the class. | |
186 * Style bits are also inherited from superclasses. | |
187 * </p> | |
188 * | |
189 * @param parentItem a tree control which will be the parent of the new instance (cannot be null) | |
190 * @param style the style of control to construct | |
191 * @param index the zero-relative index to store the receiver in its parent | |
192 * | |
193 * @exception IllegalArgumentException <ul> | |
194 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
195 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> | |
196 * </ul> | |
197 * @exception SWTException <ul> | |
198 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
199 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
200 * </ul> | |
201 * | |
202 * @see SWT | |
203 * @see Widget#checkSubclass | |
204 * @see Widget#getStyle | |
205 */ | |
206 public this (TreeItem parentItem, int style, int index) { | |
207 this (checkNull (parentItem).parent, style, parentItem.handle, findPrevious (parentItem, index), null); | |
208 } | |
209 | |
210 this (Tree parent, int style, HANDLE hParent, HANDLE hInsertAfter, HANDLE hItem) { | |
211 super (parent, style); | |
212 this.parent = parent; | |
213 parent.createItem (this, hParent, hInsertAfter, hItem); | |
214 } | |
215 | |
216 static TreeItem checkNull (TreeItem item) { | |
217 if (item is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); | |
218 return item; | |
219 } | |
220 | |
221 static HANDLE findPrevious (Tree parent, int index) { | |
222 if (parent is null) return null; | |
223 if (index < 0) SWT.error (SWT.ERROR_INVALID_RANGE); | |
224 if (index is 0) return cast(HANDLE) OS.TVI_FIRST; | |
225 auto hwnd = parent.handle; | |
226 HANDLE hFirstItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); | |
227 HANDLE hItem = parent.findItem (hFirstItem, index - 1); | |
228 if (hItem is null) SWT.error (SWT.ERROR_INVALID_RANGE); | |
229 return hItem; | |
230 } | |
231 | |
232 static HANDLE findPrevious (TreeItem parentItem, int index) { | |
233 if (parentItem is null) return null; | |
234 if (index < 0) SWT.error (SWT.ERROR_INVALID_RANGE); | |
235 if (index is 0) return cast(HANDLE) OS.TVI_FIRST; | |
236 Tree parent = parentItem.parent; | |
237 auto hwnd = parent.handle; | |
238 auto hParent = parentItem.handle; | |
239 HANDLE hFirstItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hParent); | |
240 HANDLE hItem = parent.findItem (hFirstItem, index - 1); | |
241 if (hItem is null) SWT.error (SWT.ERROR_INVALID_RANGE); | |
242 return hItem; | |
243 } | |
244 | |
245 override protected void checkSubclass () { | |
246 if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); | |
247 } | |
248 | |
249 void clear () { | |
250 text = ""; | |
251 image = null; | |
252 strings = null; | |
253 images = null; | |
254 if ((parent.style & SWT.CHECK) !is 0) { | |
255 auto hwnd = parent.handle; | |
256 TVITEM tvItem; | |
257 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; | |
258 tvItem.stateMask = OS.TVIS_STATEIMAGEMASK; | |
259 tvItem.state = 1 << 12; | |
260 tvItem.hItem = cast(HTREEITEM)handle; | |
261 OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, &tvItem); | |
262 } | |
263 background = foreground = -1; | |
264 font = null; | |
265 cellBackground = cellForeground = null; | |
266 cellFont = null; | |
267 if ((parent.style & SWT.VIRTUAL) !is 0) cached = false; | |
268 } | |
269 | |
270 /** | |
271 * Clears the item at the given zero-relative index in the receiver. | |
272 * The text, icon and other attributes of the item are set to the default | |
273 * value. If the tree was created with the <code>SWT.VIRTUAL</code> style, | |
274 * these attributes are requested again as needed. | |
275 * | |
276 * @param index the index of the item to clear | |
277 * @param all <code>true</code> if all child items of the indexed item should be | |
278 * cleared recursively, and <code>false</code> otherwise | |
279 * | |
280 * @exception IllegalArgumentException <ul> | |
281 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
282 * </ul> | |
283 * @exception SWTException <ul> | |
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 SWT#VIRTUAL | |
289 * @see SWT#SetData | |
290 * | |
291 * @since 3.2 | |
292 */ | |
293 public void clear (int index, bool all) { | |
294 checkWidget (); | |
295 auto hwnd = parent.handle; | |
296 HANDLE hItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle); | |
297 if (hItem is null) error (SWT.ERROR_INVALID_RANGE); | |
298 hItem = parent.findItem (hItem, index); | |
299 if (hItem is null) error (SWT.ERROR_INVALID_RANGE); | |
300 TVITEM tvItem; | |
301 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM; | |
302 parent.clear (hItem, &tvItem); | |
303 if (all) { | |
304 hItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hItem); | |
305 parent.clearAll (hItem, &tvItem, all); | |
306 } | |
307 } | |
308 | |
309 /** | |
310 * Clears all the items in the receiver. The text, icon and other | |
311 * attributes of the items are set to their default values. If the | |
312 * tree was created with the <code>SWT.VIRTUAL</code> style, these | |
313 * attributes are requested again as needed. | |
314 * | |
315 * @param all <code>true</code> if all child items should be cleared | |
316 * recursively, and <code>false</code> otherwise | |
317 * | |
318 * @exception SWTException <ul> | |
319 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
320 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
321 * </ul> | |
322 * | |
323 * @see SWT#VIRTUAL | |
324 * @see SWT#SetData | |
325 * | |
326 * @since 3.2 | |
327 */ | |
328 public void clearAll (bool all) { | |
329 checkWidget (); | |
330 auto hwnd = parent.handle; | |
331 auto hItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle); | |
332 if (hItem is null) return; | |
333 TVITEM tvItem; | |
334 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM; | |
335 parent.clearAll (hItem, &tvItem, all); | |
336 } | |
337 | |
338 override void destroyWidget () { | |
339 TVITEM tvItem; | |
340 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM; | |
341 parent.releaseItem (handle, &tvItem, false); | |
342 parent.destroyItem (this, handle); | |
343 releaseHandle (); | |
344 } | |
345 | |
346 HFONT fontHandle (int index) { | |
347 if (cellFont !is null && cellFont [index] !is null) return cellFont [index].handle; | |
348 if (font !is null) return font.handle; | |
349 return cast(HFONT)-1; | |
350 } | |
351 | |
352 /** | |
353 * Returns the receiver's background color. | |
354 * | |
355 * @return the background color | |
356 * | |
357 * @exception SWTException <ul> | |
358 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
359 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
360 * </ul> | |
361 * | |
362 * @since 2.0 | |
363 * | |
364 */ | |
365 public Color getBackground () { | |
366 checkWidget (); | |
367 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
368 if (background is -1) return parent.getBackground (); | |
369 return Color.win32_new (display, background); | |
370 } | |
371 | |
372 /** | |
373 * Returns the background color at the given column index in the receiver. | |
374 * | |
375 * @param index the column index | |
376 * @return the background color | |
377 * | |
378 * @exception SWTException <ul> | |
379 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
380 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
381 * </ul> | |
382 * | |
383 * @since 3.1 | |
384 */ | |
385 public Color getBackground (int index) { | |
386 checkWidget (); | |
387 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
388 int count = Math.max (1, parent.getColumnCount ()); | |
389 if (0 > index || index > count - 1) return getBackground (); | |
390 int pixel = cellBackground !is null ? cellBackground [index] : -1; | |
391 return pixel is -1 ? getBackground () : Color.win32_new (display, pixel); | |
392 } | |
393 | |
394 /** | |
395 * Returns a rectangle describing the receiver's size and location | |
396 * relative to its parent. | |
397 * | |
398 * @return the receiver's bounding rectangle | |
399 * | |
400 * @exception SWTException <ul> | |
401 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
402 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
403 * </ul> | |
404 */ | |
405 public Rectangle getBounds () { | |
406 checkWidget (); | |
407 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
408 RECT* rect = getBounds (0, true, false, false); | |
409 int width = rect.right - rect.left, height = rect.bottom - rect.top; | |
410 return new Rectangle (rect.left, rect.top, width, height); | |
411 } | |
412 | |
413 /** | |
414 * Returns a rectangle describing the receiver's size and location | |
415 * relative to its parent at a column in the tree. | |
416 * | |
417 * @param index the index that specifies the column | |
418 * @return the receiver's bounding column rectangle | |
419 * | |
420 * @exception SWTException <ul> | |
421 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
422 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
423 * </ul> | |
424 * | |
425 * @since 3.1 | |
426 */ | |
427 public Rectangle getBounds (int index) { | |
428 checkWidget(); | |
429 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
430 RECT* rect = getBounds (index, true, true, true); | |
431 int width = rect.right - rect.left, height = rect.bottom - rect.top; | |
432 return new Rectangle (rect.left, rect.top, width, height); | |
433 } | |
434 | |
435 RECT* getBounds (int index, bool getText, bool getImage, bool fullText) { | |
436 return getBounds (index, getText, getImage, fullText, false, true, null); | |
437 } | |
438 | |
439 //TODO - take into account grid (add bool arg) to damage less during redraw | |
440 RECT* getBounds (int index, bool getText, bool getImage, bool fullText, bool fullImage, bool clip, HDC hDC) { | |
441 if (!getText && !getImage) return new RECT(); | |
442 auto hwnd = parent.handle; | |
443 if ((parent.style & SWT.VIRTUAL) is 0 && !cached && !parent.painted) { | |
444 TVITEM tvItem; | |
445 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_TEXT; | |
446 tvItem.hItem = cast(HTREEITEM)handle; | |
447 tvItem.pszText = OS.LPSTR_TEXTCALLBACK; | |
448 parent.ignoreCustomDraw = true; | |
449 OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, &tvItem); | |
450 parent.ignoreCustomDraw = false; | |
451 } | |
452 bool firstColumn = index is 0; | |
453 int columnCount = 0; | |
454 auto hwndHeader = parent.hwndHeader; | |
455 if (hwndHeader !is null) { | |
456 columnCount = parent.columnCount; | |
457 firstColumn = index is OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, 0, 0); | |
458 } | |
459 RECT* rect = new RECT(); | |
460 if (firstColumn) { | |
461 bool full = columnCount is 0 && getText && getImage && fullText && fullImage; | |
462 if (!OS.TreeView_GetItemRect (hwnd, cast(HTREEITEM)handle, rect, !full)) { | |
463 return new RECT(); | |
464 } | |
465 if (getImage && !fullImage) { | |
466 if (OS.SendMessage (hwnd, OS.TVM_GETIMAGELIST, OS.TVSIL_NORMAL, 0) !is 0) { | |
467 Point size = parent.getImageSize (); | |
468 rect.left -= size.x + Tree.INSET; | |
469 if (!getText) rect.right = rect.left + size.x; | |
470 } else { | |
471 if (!getText) rect.right = rect.left; | |
472 } | |
473 } | |
474 if (fullText || fullImage || clip) { | |
475 if (hwndHeader !is null) { | |
476 RECT* headerRect = new RECT(); | |
477 if (columnCount !is 0) { | |
478 if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, cast(int) headerRect) is 0) { | |
479 return new RECT(); | |
480 } | |
481 } else { | |
482 headerRect.right = parent.scrollWidth; | |
483 if (headerRect.right is 0) headerRect = rect; | |
484 } | |
485 if (fullText && clip) rect.right = headerRect.right; | |
486 if (fullImage) rect.left = headerRect.left; | |
487 if (clip && headerRect.right < rect.right) { | |
488 rect.right = headerRect.right; | |
489 } | |
490 } | |
491 } | |
492 } else { | |
493 if (!(0 <= index && index < columnCount)) return new RECT(); | |
494 RECT* headerRect = new RECT(); | |
495 if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, cast(int) headerRect) is 0) { | |
496 return new RECT(); | |
497 } | |
498 if (!OS.TreeView_GetItemRect (hwnd, cast(HTREEITEM)handle, rect, false)) { | |
499 return new RECT(); | |
500 } | |
501 rect.left = headerRect.left; | |
502 if (fullText && getImage && clip) { | |
503 rect.right = headerRect.right; | |
504 } else { | |
505 rect.right = headerRect.left; | |
506 Image image = null; | |
507 if (index is 0) { | |
508 image = this.image; | |
509 } else { | |
510 if (images !is null) image = images [index]; | |
511 } | |
512 if (image !is null) { | |
513 Point size = parent.getImageSize (); | |
514 rect.right += size.x; | |
515 } | |
516 if (getText) { | |
517 if (fullText && clip) { | |
518 rect.left = rect.right + Tree.INSET; | |
519 rect.right = headerRect.right; | |
520 } else { | |
521 String string = index is 0 ? text : strings !is null ? strings [index] : null; | |
522 if (string !is null) { | |
523 RECT* textRect = new RECT(); | |
524 TCHAR[] buffer = StrToTCHARs (parent.getCodePage (), string, false); | |
525 int flags = OS.DT_NOPREFIX | OS.DT_SINGLELINE | OS.DT_CALCRECT; | |
526 auto hNewDC = hDC; | |
527 HFONT hFont; | |
528 if (hDC is null) { | |
529 hNewDC = OS.GetDC (hwnd); | |
530 hFont = fontHandle (index); | |
531 if (hFont is cast(HFONT)-1) hFont = cast(HFONT) OS.SendMessage (hwnd, OS.WM_GETFONT, 0, 0); | |
532 hFont = OS.SelectObject (hNewDC, hFont); | |
533 } | |
534 OS.DrawText (hNewDC, buffer.ptr, buffer.length, textRect, flags); | |
535 if (hDC is null) { | |
536 OS.SelectObject (hNewDC, hFont); | |
537 OS.ReleaseDC (hwnd, hNewDC); | |
538 } | |
539 if (getImage) { | |
540 rect.right += textRect.right - textRect.left + Tree.INSET * 3; | |
541 } else { | |
542 rect.left = rect.right + Tree.INSET; | |
543 rect.right = rect.left + (textRect.right - textRect.left) + Tree.INSET; | |
544 } | |
545 } | |
546 } | |
547 } | |
548 if (clip && headerRect.right < rect.right) { | |
549 rect.right = headerRect.right; | |
550 } | |
551 } | |
552 } | |
553 int gridWidth = parent.linesVisible && columnCount !is 0 ? Tree.GRID_WIDTH : 0; | |
554 if (getText || !getImage) { | |
555 rect.right = Math.max (rect.left, rect.right - gridWidth); | |
556 } | |
557 rect.bottom = Math.max (rect.top, rect.bottom - gridWidth); | |
558 return rect; | |
559 } | |
560 | |
561 /** | |
562 * Returns <code>true</code> if the receiver is checked, | |
563 * and false otherwise. When the parent does not have | |
564 * the <code>CHECK style, return false. | |
565 * <p> | |
566 * | |
567 * @return the checked state | |
568 * | |
569 * @exception SWTException <ul> | |
570 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
571 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
572 * </ul> | |
573 */ | |
574 public bool getChecked () { | |
575 checkWidget (); | |
576 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
577 if ((parent.style & SWT.CHECK) is 0) return false; | |
578 auto hwnd = parent.handle; | |
579 TVITEM tvItem; | |
580 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; | |
581 tvItem.stateMask = OS.TVIS_STATEIMAGEMASK; | |
582 tvItem.hItem = cast(HTREEITEM)handle; | |
583 int result = OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, &tvItem); | |
584 return (result !is 0) && (((tvItem.state >> 12) & 1) is 0); | |
585 } | |
586 | |
587 /** | |
588 * Returns <code>true</code> if the receiver is expanded, | |
589 * and false otherwise. | |
590 * <p> | |
591 * | |
592 * @return the expanded state | |
593 * | |
594 * @exception SWTException <ul> | |
595 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
596 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
597 * </ul> | |
598 */ | |
599 public bool getExpanded () { | |
600 checkWidget (); | |
601 auto hwnd = parent.handle; | |
602 int state = 0; | |
603 static if (OS.IsWinCE) { | |
604 TVITEM tvItem; | |
605 tvItem.hItem = handle; | |
606 tvItem.mask = OS.TVIF_STATE; | |
607 OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, &tvItem); | |
608 state = tvItem.state; | |
609 } else { | |
610 /* | |
611 * Bug in Windows. Despite the fact that TVM_GETITEMSTATE claims | |
612 * to return only the bits specified by the stateMask, when called | |
613 * with TVIS_EXPANDED, the entire state is returned. The fix is | |
614 * to explicitly check for the TVIS_EXPANDED bit. | |
615 */ | |
616 state = OS.SendMessage (hwnd, OS.TVM_GETITEMSTATE, handle, OS.TVIS_EXPANDED); | |
617 } | |
618 return (state & OS.TVIS_EXPANDED) !is 0; | |
619 } | |
620 | |
621 /** | |
622 * Returns the font that the receiver will use to paint textual information for this item. | |
623 * | |
624 * @return the receiver's font | |
625 * | |
626 * @exception SWTException <ul> | |
627 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
628 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
629 * </ul> | |
630 * | |
631 * @since 3.0 | |
632 */ | |
633 public Font getFont () { | |
634 checkWidget (); | |
635 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
636 return font !is null ? font : parent.getFont (); | |
637 } | |
638 | |
639 /** | |
640 * Returns the font that the receiver will use to paint textual information | |
641 * for the specified cell in this item. | |
642 * | |
643 * @param index the column index | |
644 * @return the receiver's font | |
645 * | |
646 * @exception SWTException <ul> | |
647 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
648 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
649 * </ul> | |
650 * | |
651 * @since 3.1 | |
652 */ | |
653 public Font getFont (int index) { | |
654 checkWidget (); | |
655 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
656 int count = Math.max (1, parent.getColumnCount ()); | |
657 if (0 > index || index > count -1) return getFont (); | |
658 if (cellFont is null || cellFont [index] is null) return getFont (); | |
659 return cellFont [index]; | |
660 } | |
661 | |
662 /** | |
663 * Returns the foreground color that the receiver will use to draw. | |
664 * | |
665 * @return the receiver's foreground color | |
666 * | |
667 * @exception SWTException <ul> | |
668 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
669 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
670 * </ul> | |
671 * | |
672 * @since 2.0 | |
673 * | |
674 */ | |
675 public Color getForeground () { | |
676 checkWidget (); | |
677 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
678 if (foreground is -1) return parent.getForeground (); | |
679 return Color.win32_new (display, foreground); | |
680 } | |
681 | |
682 /** | |
683 * | |
684 * Returns the foreground color at the given column index in the receiver. | |
685 * | |
686 * @param index the column index | |
687 * @return the foreground color | |
688 * | |
689 * @exception SWTException <ul> | |
690 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
691 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
692 * </ul> | |
693 * | |
694 * @since 3.1 | |
695 */ | |
696 public Color getForeground (int index) { | |
697 checkWidget (); | |
698 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
699 int count = Math.max (1, parent.getColumnCount ()); | |
700 if (0 > index || index > count -1) return getForeground (); | |
701 int pixel = cellForeground !is null ? cellForeground [index] : -1; | |
702 return pixel is -1 ? getForeground () : Color.win32_new (display, pixel); | |
703 } | |
704 | |
705 /** | |
706 * Returns <code>true</code> if the receiver is grayed, | |
707 * and false otherwise. When the parent does not have | |
708 * the <code>CHECK style, return false. | |
709 * <p> | |
710 * | |
711 * @return the grayed state of the checkbox | |
712 * | |
713 * @exception SWTException <ul> | |
714 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
715 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
716 * </ul> | |
717 */ | |
718 public bool getGrayed () { | |
719 checkWidget (); | |
720 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
721 if ((parent.style & SWT.CHECK) is 0) return false; | |
722 auto hwnd = parent.handle; | |
723 TVITEM tvItem; | |
724 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; | |
725 tvItem.stateMask = OS.TVIS_STATEIMAGEMASK; | |
726 tvItem.hItem = cast(HTREEITEM)handle; | |
727 int result = OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, &tvItem); | |
728 return (result !is 0) && ((tvItem.state >> 12) > 2); | |
729 } | |
730 | |
731 /** | |
732 * Returns the item at the given, zero-relative index in the | |
733 * receiver. Throws an exception if the index is out of range. | |
734 * | |
735 * @param index the index of the item to return | |
736 * @return the item at the given index | |
737 * | |
738 * @exception IllegalArgumentException <ul> | |
739 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
740 * </ul> | |
741 * @exception SWTException <ul> | |
742 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
743 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
744 * </ul> | |
745 * | |
746 * @since 3.1 | |
747 */ | |
748 public TreeItem getItem (int index) { | |
749 checkWidget (); | |
750 if (index < 0) error (SWT.ERROR_INVALID_RANGE); | |
751 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
752 auto hwnd = parent.handle; | |
753 auto hFirstItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle); | |
754 if (hFirstItem is null) error (SWT.ERROR_INVALID_RANGE); | |
755 auto hItem = parent.findItem (hFirstItem, index); | |
756 if (hItem is null) error (SWT.ERROR_INVALID_RANGE); | |
757 return parent._getItem (hItem); | |
758 } | |
759 | |
760 /** | |
761 * Returns the number of items contained in the receiver | |
762 * that are direct item children of the receiver. | |
763 * | |
764 * @return the number of items | |
765 * | |
766 * @exception SWTException <ul> | |
767 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
768 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
769 * </ul> | |
770 */ | |
771 public int getItemCount () { | |
772 checkWidget (); | |
773 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
774 auto hwnd = parent.handle; | |
775 auto hItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle); | |
776 if (hItem is null) return 0; | |
777 return parent.getItemCount (hItem); | |
778 } | |
779 | |
780 /** | |
781 * Returns a (possibly empty) array of <code>TreeItem</code>s which | |
782 * are the direct item children of the receiver. | |
783 * <p> | |
784 * Note: This is not the actual structure used by the receiver | |
785 * to maintain its list of items, so modifying the array will | |
786 * not affect the receiver. | |
787 * </p> | |
788 * | |
789 * @return the receiver's items | |
790 * | |
791 * @exception SWTException <ul> | |
792 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
793 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
794 * </ul> | |
795 */ | |
796 public TreeItem [] getItems () { | |
797 checkWidget (); | |
798 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
799 auto hwnd = parent.handle; | |
800 auto hItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle); | |
801 if (hItem is null) return null; | |
802 return parent.getItems (hItem); | |
803 } | |
804 | |
805 override public Image getImage () { | |
806 checkWidget(); | |
807 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
808 return super.getImage (); | |
809 } | |
810 | |
811 /** | |
812 * Returns the image stored at the given column index in the receiver, | |
813 * or null if the image has not been set or if the column does not exist. | |
814 * | |
815 * @param index the column index | |
816 * @return the image stored at the given column index in the receiver | |
817 * | |
818 * @exception SWTException <ul> | |
819 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
820 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
821 * </ul> | |
822 * | |
823 * @since 3.1 | |
824 */ | |
825 public Image getImage (int index) { | |
826 checkWidget(); | |
827 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
828 if (index is 0) return getImage (); | |
829 if (images !is null) { | |
830 if (0 <= index && index < images.length) return images [index]; | |
831 } | |
832 return null; | |
833 } | |
834 | |
835 /** | |
836 * Returns a rectangle describing the size and location | |
837 * relative to its parent of an image at a column in the | |
838 * tree. | |
839 * | |
840 * @param index the index that specifies the column | |
841 * @return the receiver's bounding image rectangle | |
842 * | |
843 * @exception SWTException <ul> | |
844 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
845 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
846 * </ul> | |
847 * | |
848 * @since 3.1 | |
849 */ | |
850 public Rectangle getImageBounds (int index) { | |
851 checkWidget(); | |
852 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
853 RECT* rect = getBounds (index, false, true, false); | |
854 int width = rect.right - rect.left, height = rect.bottom - rect.top; | |
855 return new Rectangle (rect.left, rect.top, width, height); | |
856 } | |
857 | |
858 /** | |
859 * Returns the receiver's parent, which must be a <code>Tree</code>. | |
860 * | |
861 * @return the receiver's parent | |
862 * | |
863 * @exception SWTException <ul> | |
864 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
865 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
866 * </ul> | |
867 */ | |
868 public Tree getParent () { | |
869 checkWidget (); | |
870 return parent; | |
871 } | |
872 | |
873 /** | |
874 * Returns the receiver's parent item, which must be a | |
875 * <code>TreeItem</code> or null when the receiver is a | |
876 * root. | |
877 * | |
878 * @return the receiver's parent item | |
879 * | |
880 * @exception SWTException <ul> | |
881 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
882 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
883 * </ul> | |
884 */ | |
885 public TreeItem getParentItem () { | |
886 checkWidget (); | |
887 auto hwnd = parent.handle; | |
888 auto hItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_PARENT, handle); | |
889 return hItem !is null ? parent._getItem (hItem) : null; | |
890 } | |
891 | |
892 override public String getText () { | |
893 checkWidget(); | |
894 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
895 return super.getText (); | |
896 } | |
897 | |
898 /** | |
899 * Returns the text stored at the given column index in the receiver, | |
900 * or empty string if the text has not been set. | |
901 * | |
902 * @param index the column index | |
903 * @return the text stored at the given column index in the receiver | |
904 * | |
905 * @exception SWTException <ul> | |
906 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
907 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
908 * </ul> | |
909 * | |
910 * @since 3.1 | |
911 */ | |
912 public String getText (int index) { | |
913 checkWidget(); | |
914 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
915 if (index is 0) return getText (); | |
916 if (strings !is null) { | |
917 if (0 <= index && index < strings.length) { | |
918 String string = strings [index]; | |
919 return string !is null ? string : ""; | |
920 } | |
921 } | |
922 return ""; | |
923 } | |
924 | |
925 /** | |
926 * Returns a rectangle describing the size and location | |
927 * relative to its parent of the text at a column in the | |
928 * tree. | |
929 * | |
930 * @param index the index that specifies the column | |
931 * @return the receiver's bounding text rectangle | |
932 * | |
933 * @exception SWTException <ul> | |
934 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
935 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
936 * </ul> | |
937 * | |
938 * @since 3.3 | |
939 */ | |
940 public Rectangle getTextBounds (int index) { | |
941 checkWidget(); | |
942 if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); | |
943 RECT* rect = getBounds (index, true, false, true); | |
944 if (index is 0) rect.left += Tree.INSET - 1; | |
945 rect.left = Math.min (rect.left, rect.right); | |
946 rect.right = rect.right - Tree.INSET; | |
947 int width = Math.max (0, rect.right - rect.left); | |
948 int height = Math.max (0, rect.bottom - rect.top); | |
949 return new Rectangle (rect.left, rect.top, width, height); | |
950 } | |
951 | |
952 /** | |
953 * Searches the receiver's list starting at the first item | |
954 * (index 0) until an item is found that is equal to the | |
955 * argument, and returns the index of that item. If no item | |
956 * is found, returns -1. | |
957 * | |
958 * @param item the search item | |
959 * @return the index of the item | |
960 * | |
961 * @exception IllegalArgumentException <ul> | |
962 * <li>ERROR_NULL_ARGUMENT - if the item is null</li> | |
963 * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li> | |
964 * </ul> | |
965 * @exception SWTException <ul> | |
966 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
967 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
968 * </ul> | |
969 * | |
970 * @since 3.1 | |
971 */ | |
972 public int indexOf (TreeItem item) { | |
973 checkWidget (); | |
974 if (item is null) error (SWT.ERROR_NULL_ARGUMENT); | |
975 if (item.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT); | |
976 auto hwnd = parent.handle; | |
977 auto hItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle); | |
978 return hItem is null ? -1 : parent.findIndex (hItem, item.handle); | |
979 } | |
980 | |
981 void redraw () { | |
982 if (parent.currentItem is this || parent.drawCount !is 0) return; | |
983 auto hwnd = parent.handle; | |
984 if (!OS.IsWindowVisible (hwnd)) return; | |
985 /* | |
986 * When there are no columns and the tree is not | |
987 * full selection, redraw only the text. This is | |
988 * an optimization to reduce flashing. | |
989 */ | |
990 bool full = (parent.style & (SWT.FULL_SELECTION | SWT.VIRTUAL)) !is 0; | |
991 if (!full) { | |
992 full = parent.columnCount !is 0; | |
993 if (!full) { | |
994 if (parent.hooks (SWT.EraseItem) || parent.hooks (SWT.PaintItem)) { | |
995 full = true; | |
996 } | |
997 } | |
998 } | |
999 RECT rect; | |
1000 if (OS.TreeView_GetItemRect (hwnd, cast(HTREEITEM)handle, &rect, !full)) { | |
1001 OS.InvalidateRect (hwnd, &rect, true); | |
1002 } | |
1003 } | |
1004 | |
1005 void redraw (int column, bool drawText, bool drawImage) { | |
1006 if (parent.currentItem is this || parent.drawCount !is 0) return; | |
1007 auto hwnd = parent.handle; | |
1008 if (!OS.IsWindowVisible (hwnd)) return; | |
1009 bool fullImage = column is 0 && drawText && drawImage; | |
1010 RECT* rect = getBounds (column, drawText, drawImage, true, fullImage, true, null); | |
1011 OS.InvalidateRect (hwnd, rect, true); | |
1012 } | |
1013 | |
1014 override void releaseChildren (bool destroy) { | |
1015 if (destroy) { | |
1016 TVITEM tvItem; | |
1017 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM; | |
1018 parent.releaseItems (handle, &tvItem); | |
1019 } | |
1020 super.releaseChildren (destroy); | |
1021 } | |
1022 | |
1023 override void releaseHandle () { | |
1024 super.releaseHandle (); | |
1025 handle = null; | |
1026 parent = null; | |
1027 } | |
1028 | |
1029 override void releaseWidget () { | |
1030 super.releaseWidget (); | |
1031 strings = null; | |
1032 images = null; | |
1033 cellBackground = cellForeground = null; | |
1034 cellFont = null; | |
1035 } | |
1036 | |
1037 /** | |
1038 * Removes all of the items from the receiver. | |
1039 * <p> | |
1040 * @exception SWTException <ul> | |
1041 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1042 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1043 * </ul> | |
1044 * | |
1045 * @since 3.1 | |
1046 */ | |
1047 public void removeAll () { | |
1048 checkWidget (); | |
1049 auto hwnd = parent.handle; | |
1050 TVITEM tvItem; | |
1051 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM; | |
1052 tvItem.hItem = cast(HTREEITEM) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, cast(int)handle); | |
1053 while (tvItem.hItem !is null) { | |
1054 OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, cast(int)&tvItem); | |
1055 TreeItem item = tvItem.lParam !is -1 ? parent.items [tvItem.lParam] : null; | |
1056 if (item !is null && !item.isDisposed ()) { | |
1057 item.dispose (); | |
1058 } else { | |
1059 parent.releaseItem (tvItem.hItem, &tvItem, false); | |
1060 parent.destroyItem (null, tvItem.hItem); | |
1061 } | |
1062 tvItem.hItem = cast(HTREEITEM) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, cast(int)handle); | |
1063 } | |
1064 } | |
1065 | |
1066 /** | |
1067 * Sets the receiver's background color to the color specified | |
1068 * by the argument, or to the default system color for the item | |
1069 * if the argument is null. | |
1070 * | |
1071 * @param color the new color (or null) | |
1072 * | |
1073 * @exception IllegalArgumentException <ul> | |
1074 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
1075 * </ul> | |
1076 * @exception SWTException <ul> | |
1077 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1078 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1079 * </ul> | |
1080 * | |
1081 * @since 2.0 | |
1082 * | |
1083 */ | |
1084 public void setBackground (Color color) { | |
1085 checkWidget (); | |
1086 if (color !is null && color.isDisposed ()) { | |
1087 SWT.error (SWT.ERROR_INVALID_ARGUMENT); | |
1088 } | |
1089 int pixel = -1; | |
1090 if (color !is null) { | |
1091 parent.customDraw = true; | |
1092 pixel = color.handle; | |
1093 } | |
1094 if (background is pixel) return; | |
1095 background = pixel; | |
1096 if ((parent.style & SWT.VIRTUAL) !is 0) cached = true; | |
1097 redraw (); | |
1098 } | |
1099 | |
1100 /** | |
1101 * Sets the background color at the given column index in the receiver | |
1102 * to the color specified by the argument, or to the default system color for the item | |
1103 * if the argument is null. | |
1104 * | |
1105 * @param index the column index | |
1106 * @param color the new color (or null) | |
1107 * | |
1108 * @exception IllegalArgumentException <ul> | |
1109 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
1110 * </ul> | |
1111 * @exception SWTException <ul> | |
1112 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1113 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1114 * </ul> | |
1115 * | |
1116 * @since 3.1 | |
1117 * | |
1118 */ | |
1119 public void setBackground (int index, Color color) { | |
1120 checkWidget (); | |
1121 if (color !is null && color.isDisposed ()) { | |
1122 SWT.error (SWT.ERROR_INVALID_ARGUMENT); | |
1123 } | |
1124 int count = Math.max (1, parent.getColumnCount ()); | |
1125 if (0 > index || index > count - 1) return; | |
1126 int pixel = -1; | |
1127 if (color !is null) { | |
1128 parent.customDraw = true; | |
1129 pixel = color.handle; | |
1130 } | |
1131 if (cellBackground is null) { | |
1132 cellBackground = new int [count]; | |
1133 for (int i = 0; i < count; i++) { | |
1134 cellBackground [i] = -1; | |
1135 } | |
1136 } | |
1137 if (cellBackground [index] is pixel) return; | |
1138 cellBackground [index] = pixel; | |
1139 if ((parent.style & SWT.VIRTUAL) !is 0) cached = true; | |
1140 redraw (index, true, true); | |
1141 } | |
1142 | |
1143 /** | |
1144 * Sets the checked state of the receiver. | |
1145 * <p> | |
1146 * | |
1147 * @param checked the new checked state | |
1148 * | |
1149 * @exception SWTException <ul> | |
1150 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1151 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1152 * </ul> | |
1153 */ | |
1154 public void setChecked (bool checked) { | |
1155 checkWidget (); | |
1156 if ((parent.style & SWT.CHECK) is 0) return; | |
1157 auto hwnd = parent.handle; | |
1158 TVITEM tvItem; | |
1159 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; | |
1160 tvItem.stateMask = OS.TVIS_STATEIMAGEMASK; | |
1161 tvItem.hItem = cast(HTREEITEM)handle; | |
1162 OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, &tvItem); | |
1163 int state = tvItem.state >> 12; | |
1164 if (checked) { | |
1165 if ((state & 0x1) !is 0) state++; | |
1166 } else { | |
1167 if ((state & 0x1) is 0) --state; | |
1168 } | |
1169 state <<= 12; | |
1170 if (tvItem.state is state) return; | |
1171 if ((parent.style & SWT.VIRTUAL) !is 0) cached = true; | |
1172 tvItem.state = state; | |
1173 OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, &tvItem); | |
1174 /* | |
1175 * Bug in Windows. When TVM_SETITEM is used to set | |
1176 * the state image of an item inside TVN_GETDISPINFO, | |
1177 * the new state is not redrawn. The fix is to force | |
1178 * a redraw. | |
1179 */ | |
1180 if ((parent.style & SWT.VIRTUAL) !is 0) { | |
1181 if (parent.currentItem is this && OS.IsWindowVisible (hwnd)) { | |
1182 RECT rect; | |
1183 if (OS.TreeView_GetItemRect (hwnd, cast(HTREEITEM)handle, &rect, false)) { | |
1184 OS.InvalidateRect (hwnd, &rect, true); | |
1185 } | |
1186 } | |
1187 } | |
1188 } | |
1189 | |
1190 /** | |
1191 * Sets the expanded state of the receiver. | |
1192 * <p> | |
1193 * | |
1194 * @param expanded the new expanded state | |
1195 * | |
1196 * @exception SWTException <ul> | |
1197 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1198 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1199 * </ul> | |
1200 */ | |
1201 public void setExpanded (bool expanded) { | |
1202 checkWidget (); | |
1203 | |
1204 /* Do nothing when the item is a leaf or already expanded */ | |
1205 auto hwnd = parent.handle; | |
1206 if (OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle) is 0) { | |
1207 return; | |
1208 } | |
1209 int state = 0; | |
1210 static if (OS.IsWinCE) { | |
1211 TVITEM tvItem; | |
1212 tvItem.hItem = handle; | |
1213 tvItem.mask = OS.TVIF_STATE; | |
1214 OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, &tvItem); | |
1215 state = tvItem.state; | |
1216 } else { | |
1217 /* | |
1218 * Bug in Windows. Despite the fact that TVM_GETITEMSTATE claims | |
1219 * to return only the bits specified by the stateMask, when called | |
1220 * with TVIS_EXPANDED, the entire state is returned. The fix is | |
1221 * to explicitly check for the TVIS_EXPANDED bit. | |
1222 */ | |
1223 state = OS.SendMessage (hwnd, OS.TVM_GETITEMSTATE, handle, OS.TVIS_EXPANDED); | |
1224 } | |
1225 if (((state & OS.TVIS_EXPANDED) !is 0) is expanded) return; | |
1226 | |
1227 /* | |
1228 * Feature in Windows. When TVM_EXPAND is used to expand | |
1229 * an item, the widget scrolls to show the item and the | |
1230 * newly expanded items. While not strictly incorrect, | |
1231 * this means that application code that expands tree items | |
1232 * in a background thread can scroll the widget while the | |
1233 * user is interacting with it. The fix is to remember | |
1234 * the top item and the bounds of every tree item, turn | |
1235 * redraw off, expand the item, scroll back to the top | |
1236 * item. If none of the rectangles have moved, then | |
1237 * it is safe to turn redraw back on without redrawing | |
1238 * the control. | |
1239 */ | |
1240 RECT oldRect; | |
1241 RECT [] rects = null; | |
1242 SCROLLINFO* oldInfo; | |
1243 int count = 0; | |
1244 HANDLE hBottomItem; | |
1245 bool redraw = false, noScroll = true; | |
1246 HANDLE hTopItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0); | |
1247 if (noScroll && hTopItem !is null) { | |
1248 oldInfo = new SCROLLINFO (); | |
1249 oldInfo.cbSize = SCROLLINFO.sizeof; | |
1250 oldInfo.fMask = OS.SIF_ALL; | |
1251 if (!OS.GetScrollInfo (hwnd, OS.SB_HORZ, oldInfo)) { | |
1252 oldInfo = null; | |
1253 } | |
1254 if (parent.drawCount is 0 && OS.IsWindowVisible (hwnd)) { | |
1255 bool noAnimate = true; | |
1256 count = OS.SendMessage (hwnd, OS.TVM_GETVISIBLECOUNT, 0, 0); | |
1257 rects = new RECT [count + 1]; | |
1258 HANDLE hItem = hTopItem; | |
1259 int index = 0; | |
1260 while (hItem !is null && (noAnimate || hItem !is handle) && index < count) { | |
1261 RECT rect; | |
1262 if (OS.TreeView_GetItemRect (hwnd, cast(HTREEITEM)hItem, &rect, true)) { | |
1263 rects [index++] = rect; | |
1264 } | |
1265 hItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, cast(int) &hItem); | |
1266 } | |
1267 if (noAnimate || hItem !is handle) { | |
1268 redraw = true; | |
1269 count = index; | |
1270 hBottomItem = hItem; | |
1271 //oldRect = new RECT (); | |
1272 OS.GetClientRect (hwnd, &oldRect); | |
1273 auto topHandle = parent.topHandle (); | |
1274 OS.UpdateWindow (topHandle); | |
1275 OS.DefWindowProc (topHandle, OS.WM_SETREDRAW, 0, 0); | |
1276 if (hwnd !is topHandle) { | |
1277 OS.UpdateWindow (hwnd); | |
1278 OS.DefWindowProc (hwnd, OS.WM_SETREDRAW, 0, 0); | |
1279 } | |
1280 /* | |
1281 * This code is intentionally commented. | |
1282 */ | |
1283 // OS.SendMessage (hwnd, OS.WM_SETREDRAW, 0, 0); | |
1284 } | |
1285 } | |
1286 } | |
1287 | |
1288 /* | |
1289 * Feature in Windows. When the user collapses the root | |
1290 * of a subtree that has the focus item, Windows moves | |
1291 * the selection to the root of the subtree and issues | |
1292 * a TVN_SELCHANGED to inform the programmer that the | |
1293 * selection has changed. When the programmer collapses | |
1294 * the same subtree using TVM_EXPAND, Windows does not | |
1295 * send the selection changed notification. This is not | |
1296 * strictly wrong but is inconsistent. The fix is to | |
1297 * check whether the selection has changed and issue | |
1298 * the event. | |
1299 */ | |
1300 auto hOldItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | |
1301 | |
1302 /* Expand or collapse the item */ | |
1303 parent.ignoreExpand = true; | |
1304 OS.SendMessage (hwnd, OS.TVM_EXPAND, expanded ? OS.TVE_EXPAND : OS.TVE_COLLAPSE, handle); | |
1305 parent.ignoreExpand = false; | |
1306 | |
1307 /* Scroll back to the top item */ | |
1308 if (noScroll && hTopItem !is null) { | |
1309 bool collapsed = false; | |
1310 if (!expanded) { | |
1311 RECT rect; | |
1312 while (hTopItem !is null && !OS.TreeView_GetItemRect (hwnd, cast(HTREEITEM)hTopItem, &rect, false)) { | |
1313 hTopItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_PARENT, hTopItem); | |
1314 collapsed = true; | |
1315 } | |
1316 } | |
1317 bool scrolled = true; | |
1318 if (hTopItem !is null) { | |
1319 OS.SendMessage (hwnd, OS.TVM_SELECTITEM, OS.TVGN_FIRSTVISIBLE, hTopItem); | |
1320 scrolled = hTopItem !is cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0); | |
1321 } | |
1322 if (!collapsed && !scrolled && oldInfo !is null ) { | |
1323 SCROLLINFO newInfo; | |
1324 newInfo.cbSize = SCROLLINFO.sizeof; | |
1325 newInfo.fMask = OS.SIF_ALL; | |
1326 if (OS.GetScrollInfo (hwnd, OS.SB_HORZ, &newInfo)) { | |
1327 if (oldInfo.nPos !is newInfo.nPos) { | |
1328 int /*long*/ lParam = OS.MAKELPARAM (OS.SB_THUMBPOSITION, oldInfo.nPos); | |
1329 OS.SendMessage (hwnd, OS.WM_HSCROLL, lParam, 0); | |
1330 } | |
1331 } | |
1332 } | |
1333 if (redraw) { | |
1334 bool fixScroll = false; | |
1335 if (!collapsed && !scrolled) { | |
1336 RECT newRect; | |
1337 OS.GetClientRect (hwnd, &newRect); | |
1338 if (OS.EqualRect (&oldRect, &newRect)) { | |
1339 HANDLE hItem = hTopItem; | |
1340 int index = 0; | |
1341 while (hItem !is null && index < count) { | |
1342 RECT rect; | |
1343 if (OS.TreeView_GetItemRect (hwnd, cast(HTREEITEM)hItem, &rect, true)) { | |
1344 if (!OS.EqualRect (&rect, & rects [index])) { | |
1345 break; | |
1346 } | |
1347 } | |
1348 hItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, hItem); | |
1349 index++; | |
1350 } | |
1351 fixScroll = index is count && hItem is hBottomItem; | |
1352 } | |
1353 } | |
1354 auto topHandle = parent.topHandle (); | |
1355 OS.DefWindowProc (topHandle, OS.WM_SETREDRAW, 1, 0); | |
1356 if (hwnd !is topHandle) { | |
1357 OS.DefWindowProc (hwnd, OS.WM_SETREDRAW, 1, 0); | |
1358 } | |
1359 /* | |
1360 * This code is intentionally commented. | |
1361 */ | |
1362 // OS.SendMessage (hwnd, OS.WM_SETREDRAW, 1, 0); | |
1363 if (fixScroll) { | |
1364 parent.updateScrollBar (); | |
1365 SCROLLINFO info; | |
1366 info.cbSize = SCROLLINFO.sizeof; | |
1367 info.fMask = OS.SIF_ALL; | |
1368 if (OS.GetScrollInfo (hwnd, OS.SB_VERT, &info)) { | |
1369 OS.SetScrollInfo (hwnd, OS.SB_VERT, &info, true); | |
1370 } | |
1371 if (handle is hBottomItem) { | |
1372 RECT rect; | |
1373 if (OS.TreeView_GetItemRect (hwnd, cast(HTREEITEM)hBottomItem, &rect, false)) { | |
1374 OS.InvalidateRect (hwnd, &rect, true); | |
1375 } | |
1376 } | |
1377 } else { | |
1378 static if (OS.IsWinCE) { | |
1379 OS.InvalidateRect (topHandle, null, true); | |
1380 if (hwnd !is topHandle) OS.InvalidateRect (hwnd, null, true); | |
1381 } else { | |
1382 int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE | OS.RDW_ALLCHILDREN; | |
1383 OS.RedrawWindow (topHandle, null, null, flags); | |
1384 } | |
1385 } | |
1386 } | |
1387 } | |
1388 | |
1389 /* Check for a selection event */ | |
1390 auto hNewItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | |
1391 if (hNewItem !is hOldItem) { | |
1392 Event event = new Event (); | |
1393 if (hNewItem !is null) { | |
1394 event.item = parent._getItem (hNewItem); | |
1395 parent.hAnchor = hNewItem; | |
1396 } | |
1397 parent.sendEvent (SWT.Selection, event); | |
1398 } | |
1399 } | |
1400 | |
1401 /** | |
1402 * Sets the font that the receiver will use to paint textual information | |
1403 * for this item to the font specified by the argument, or to the default font | |
1404 * for that kind of control if the argument is null. | |
1405 * | |
1406 * @param font the new font (or null) | |
1407 * | |
1408 * @exception IllegalArgumentException <ul> | |
1409 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
1410 * </ul> | |
1411 * @exception SWTException <ul> | |
1412 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1413 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1414 * </ul> | |
1415 * | |
1416 * @since 3.0 | |
1417 */ | |
1418 public void setFont (Font font){ | |
1419 checkWidget (); | |
1420 if (font !is null && font.isDisposed ()) { | |
1421 SWT.error (SWT.ERROR_INVALID_ARGUMENT); | |
1422 } | |
1423 Font oldFont = this.font; | |
1424 if (oldFont is font) return; | |
1425 this.font = font; | |
1426 if (oldFont !is null && oldFont.opEquals (font)) return; | |
1427 if (font !is null) parent.customDraw = true; | |
1428 if ((parent.style & SWT.VIRTUAL) !is 0) cached = true; | |
1429 /* | |
1430 * Bug in Windows. When the font is changed for an item, | |
1431 * the bounds for the item are not updated, causing the text | |
1432 * to be clipped. The fix is to reset the text, causing | |
1433 * Windows to compute the new bounds using the new font. | |
1434 */ | |
1435 if ((parent.style & SWT.VIRTUAL) is 0 && !cached && !parent.painted) { | |
1436 return; | |
1437 } | |
1438 auto hwnd = parent.handle; | |
1439 TVITEM tvItem; | |
1440 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_TEXT; | |
1441 tvItem.hItem = cast(HTREEITEM)handle; | |
1442 tvItem.pszText = OS.LPSTR_TEXTCALLBACK; | |
1443 OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, &tvItem); | |
1444 } | |
1445 | |
1446 | |
1447 /** | |
1448 * Sets the font that the receiver will use to paint textual information | |
1449 * for the specified cell in this item to the font specified by the | |
1450 * argument, or to the default font for that kind of control if the | |
1451 * argument is null. | |
1452 * | |
1453 * @param index the column index | |
1454 * @param font the new font (or null) | |
1455 * | |
1456 * @exception IllegalArgumentException <ul> | |
1457 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
1458 * </ul> | |
1459 * @exception SWTException <ul> | |
1460 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1461 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1462 * </ul> | |
1463 * | |
1464 * @since 3.1 | |
1465 */ | |
1466 public void setFont (int index, Font font) { | |
1467 checkWidget (); | |
1468 if (font !is null && font.isDisposed ()) { | |
1469 SWT.error (SWT.ERROR_INVALID_ARGUMENT); | |
1470 } | |
1471 int count = Math.max (1, parent.getColumnCount ()); | |
1472 if (0 > index || index > count - 1) return; | |
1473 if (cellFont is null) { | |
1474 if (font is null) return; | |
1475 cellFont = new Font [count]; | |
1476 } | |
1477 Font oldFont = cellFont [index]; | |
1478 if (oldFont is font) return; | |
1479 cellFont [index] = font; | |
1480 if (oldFont !is null && oldFont.opEquals (font)) return; | |
1481 if (font !is null) parent.customDraw = true; | |
1482 if ((parent.style & SWT.VIRTUAL) !is 0) cached = true; | |
1483 /* | |
1484 * Bug in Windows. When the font is changed for an item, | |
1485 * the bounds for the item are not updated, causing the text | |
1486 * to be clipped. The fix is to reset the text, causing | |
1487 * Windows to compute the new bounds using the new font. | |
1488 */ | |
1489 if (index is 0) { | |
1490 if ((parent.style & SWT.VIRTUAL) is 0 && !cached && !parent.painted) { | |
1491 return; | |
1492 } | |
1493 auto hwnd = parent.handle; | |
1494 TVITEM tvItem; | |
1495 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_TEXT; | |
1496 tvItem.hItem = cast(HTREEITEM)handle; | |
1497 tvItem.pszText = OS.LPSTR_TEXTCALLBACK; | |
1498 OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, &tvItem); | |
1499 } else { | |
1500 redraw (index, true, false); | |
1501 } | |
1502 } | |
1503 | |
1504 /** | |
1505 * Sets the receiver's foreground color to the color specified | |
1506 * by the argument, or to the default system color for the item | |
1507 * if the argument is null. | |
1508 * | |
1509 * @param color the new color (or null) | |
1510 * | |
1511 * @since 2.0 | |
1512 * | |
1513 * @exception IllegalArgumentException <ul> | |
1514 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
1515 * </ul> | |
1516 * @exception SWTException <ul> | |
1517 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1518 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1519 * </ul> | |
1520 * | |
1521 * @since 2.0 | |
1522 * | |
1523 */ | |
1524 public void setForeground (Color color) { | |
1525 checkWidget (); | |
1526 if (color !is null && color.isDisposed ()) { | |
1527 SWT.error (SWT.ERROR_INVALID_ARGUMENT); | |
1528 } | |
1529 int pixel = -1; | |
1530 if (color !is null) { | |
1531 parent.customDraw = true; | |
1532 pixel = color.handle; | |
1533 } | |
1534 if (foreground is pixel) return; | |
1535 foreground = pixel; | |
1536 if ((parent.style & SWT.VIRTUAL) !is 0) cached = true; | |
1537 redraw (); | |
1538 } | |
1539 | |
1540 /** | |
1541 * Sets the foreground color at the given column index in the receiver | |
1542 * to the color specified by the argument, or to the default system color for the item | |
1543 * if the argument is null. | |
1544 * | |
1545 * @param index the column index | |
1546 * @param color the new color (or null) | |
1547 * | |
1548 * @exception IllegalArgumentException <ul> | |
1549 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
1550 * </ul> | |
1551 * @exception SWTException <ul> | |
1552 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1553 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1554 * </ul> | |
1555 * | |
1556 * @since 3.1 | |
1557 * | |
1558 */ | |
1559 public void setForeground (int index, Color color){ | |
1560 checkWidget (); | |
1561 if (color !is null && color.isDisposed ()) { | |
1562 SWT.error (SWT.ERROR_INVALID_ARGUMENT); | |
1563 } | |
1564 int count = Math.max (1, parent.getColumnCount ()); | |
1565 if (0 > index || index > count - 1) return; | |
1566 int pixel = -1; | |
1567 if (color !is null) { | |
1568 parent.customDraw = true; | |
1569 pixel = color.handle; | |
1570 } | |
1571 if (cellForeground is null) { | |
1572 cellForeground = new int [count]; | |
1573 for (int i = 0; i < count; i++) { | |
1574 cellForeground [i] = -1; | |
1575 } | |
1576 } | |
1577 if (cellForeground [index] is pixel) return; | |
1578 cellForeground [index] = pixel; | |
1579 if ((parent.style & SWT.VIRTUAL) !is 0) cached = true; | |
1580 redraw (index, true, false); | |
1581 } | |
1582 | |
1583 /** | |
1584 * Sets the grayed state of the checkbox for this item. This state change | |
1585 * only applies if the Tree was created with the SWT.CHECK style. | |
1586 * | |
1587 * @param grayed the new grayed state of the checkbox | |
1588 * | |
1589 * @exception SWTException <ul> | |
1590 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1591 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1592 * </ul> | |
1593 */ | |
1594 public void setGrayed (bool grayed) { | |
1595 checkWidget (); | |
1596 if ((parent.style & SWT.CHECK) is 0) return; | |
1597 auto hwnd = parent.handle; | |
1598 TVITEM tvItem; | |
1599 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; | |
1600 tvItem.stateMask = OS.TVIS_STATEIMAGEMASK; | |
1601 tvItem.hItem = cast(HTREEITEM)handle; | |
1602 OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, &tvItem); | |
1603 int state = tvItem.state >> 12; | |
1604 if (grayed) { | |
1605 if (state <= 2) state +=2; | |
1606 } else { | |
1607 if (state > 2) state -=2; | |
1608 } | |
1609 state <<= 12; | |
1610 if (tvItem.state is state) return; | |
1611 if ((parent.style & SWT.VIRTUAL) !is 0) cached = true; | |
1612 tvItem.state = state; | |
1613 OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, &tvItem); | |
1614 /* | |
1615 * Bug in Windows. When TVM_SETITEM is used to set | |
1616 * the state image of an item inside TVN_GETDISPINFO, | |
1617 * the new state is not redrawn. The fix is to force | |
1618 * a redraw. | |
1619 */ | |
1620 if ((parent.style & SWT.VIRTUAL) !is 0) { | |
1621 if (parent.currentItem is this && OS.IsWindowVisible (hwnd)) { | |
1622 RECT rect; | |
1623 if (OS.TreeView_GetItemRect (hwnd, cast(HTREEITEM)handle, &rect, false)) { | |
1624 OS.InvalidateRect (hwnd, &rect, true); | |
1625 } | |
1626 } | |
1627 } | |
1628 } | |
1629 | |
1630 /** | |
1631 * Sets the image for multiple columns in the tree. | |
1632 * | |
1633 * @param images the array of new images | |
1634 * | |
1635 * @exception IllegalArgumentException <ul> | |
1636 * <li>ERROR_INVALID_ARGUMENT - if one of the images has been disposed</li> | |
1637 * </ul> | |
1638 * @exception SWTException <ul> | |
1639 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1640 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1641 * </ul> | |
1642 * | |
1643 * @since 3.1 | |
1644 */ | |
1645 public void setImage (Image [] images) { | |
1646 checkWidget(); | |
1647 // SWT extension; allow null array | |
1648 //if (images is null) error (SWT.ERROR_NULL_ARGUMENT); | |
1649 for (int i=0; i<images.length; i++) { | |
1650 setImage (i, images [i]); | |
1651 } | |
1652 } | |
1653 | |
1654 /** | |
1655 * Sets the receiver's image at a column. | |
1656 * | |
1657 * @param index the column index | |
1658 * @param image the new image | |
1659 * | |
1660 * @exception IllegalArgumentException <ul> | |
1661 * <li>ERROR_INVALID_ARGUMENT - if the image 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 (int index, Image image) { | |
1671 checkWidget(); | |
1672 if (image !is null && image.isDisposed ()) { | |
1673 error(SWT.ERROR_INVALID_ARGUMENT); | |
1674 } | |
1675 Image oldImage = null; | |
1676 if (index is 0) { | |
1677 if (image !is null && image.type is SWT.ICON) { | |
1678 if (image==/*eq*/this.image) return; | |
1679 } | |
1680 oldImage = this.image; | |
1681 super.setImage (image); | |
1682 } | |
1683 int count = Math.max (1, parent.getColumnCount ()); | |
1684 if (0 > index || index > count - 1) return; | |
1685 if (images is null && index !is 0) { | |
1686 images = new Image [count]; | |
1687 images [0] = image; | |
1688 } | |
1689 if (images !is null) { | |
1690 if (image !is null && image.type is SWT.ICON) { | |
1691 if (image==/*eq*/images [index]) return; | |
1692 } | |
1693 oldImage = images [index]; | |
1694 images [index] = image; | |
1695 } | |
1696 if ((parent.style & SWT.VIRTUAL) !is 0) cached = true; | |
1697 | |
1698 /* Ensure that the image list is created */ | |
1699 //TODO - items that are not in column zero don't need to be in the image list | |
1700 parent.imageIndex (image, index); | |
1701 | |
1702 if (index is 0) { | |
1703 if ((parent.style & SWT.VIRTUAL) is 0 &&!cached && !parent.painted) { | |
1704 return; | |
1705 } | |
1706 auto hwnd = parent.handle; | |
1707 TVITEM tvItem; | |
1708 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_IMAGE | OS.TVIF_SELECTEDIMAGE; | |
1709 tvItem.hItem = cast(HTREEITEM)handle; | |
1710 tvItem.iImage = tvItem.iSelectedImage = OS.I_IMAGECALLBACK; | |
1711 /* | |
1712 * Bug in Windows. When I_IMAGECALLBACK is used with TVM_SETITEM | |
1713 * to indicate that an image has changed, Windows does not draw | |
1714 * the new image. The fix is to use LPSTR_TEXTCALLBACK to force | |
1715 * Windows to ask for the text, causing Windows to ask for both. | |
1716 */ | |
1717 tvItem.mask |= OS.TVIF_TEXT; | |
1718 tvItem.pszText = OS.LPSTR_TEXTCALLBACK; | |
1719 OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, &tvItem); | |
1720 } else { | |
1721 bool drawText = (image is null && oldImage !is null) || (image !is null && oldImage is null); | |
1722 redraw (index, drawText, true); | |
1723 } | |
1724 } | |
1725 | |
1726 override public void setImage (Image image) { | |
1727 checkWidget (); | |
1728 setImage (0, image); | |
1729 } | |
1730 | |
1731 /** | |
1732 * Sets the number of child items contained in the receiver. | |
1733 * | |
1734 * @param count the number of items | |
1735 * | |
1736 * @exception SWTException <ul> | |
1737 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1738 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1739 * </ul> | |
1740 * | |
1741 * @since 3.2 | |
1742 */ | |
1743 public void setItemCount (int count) { | |
1744 checkWidget (); | |
1745 count = Math.max (0, count); | |
1746 auto hwnd = parent.handle; | |
1747 auto hItem = cast(HANDLE) OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle); | |
1748 parent.setItemCount (count, handle, hItem); | |
1749 } | |
1750 | |
1751 /** | |
1752 * Sets the text for multiple columns in the tree. | |
1753 * | |
1754 * @param strings the array of new strings | |
1755 * | |
1756 * @exception SWTException <ul> | |
1757 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1758 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1759 * </ul> | |
1760 * | |
1761 * @since 3.1 | |
1762 */ | |
1763 public void setText (String[] strings) { | |
1764 checkWidget(); | |
1765 // SWT extension: allow null array | |
1766 //if (strings is null) error (SWT.ERROR_NULL_ARGUMENT); | |
1767 for (int i=0; i<strings.length; i++) { | |
1768 String string = strings [i]; | |
1769 if (string !is null) setText (i, string); | |
1770 } | |
1771 } | |
1772 | |
1773 /** | |
1774 * Sets the receiver's text at a column | |
1775 * | |
1776 * @param index the column index | |
1777 * @param string the new text | |
1778 * | |
1779 * @exception SWTException <ul> | |
1780 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1781 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1782 * </ul> | |
1783 * | |
1784 * @since 3.1 | |
1785 */ | |
1786 public void setText (int index, String string) { | |
1787 checkWidget(); | |
1788 // SWT extension: allow null string | |
1789 //if (string is null) error (SWT.ERROR_NULL_ARGUMENT); | |
1790 if (index is 0) { | |
1791 if (string==/*eq*/text) return; | |
1792 super.setText (string); | |
1793 } | |
1794 int count = Math.max (1, parent.getColumnCount ()); | |
1795 if (0 > index || index > count - 1) return; | |
1796 if (strings is null && index !is 0) { | |
1797 strings = new String [count]; | |
1798 strings [0] = text; | |
1799 } | |
1800 if (strings !is null) { | |
1801 if (string==/*eq*/strings [index]) return; | |
1802 strings [index] = string; | |
1803 } | |
1804 if ((parent.style & SWT.VIRTUAL) !is 0) cached = true; | |
1805 if (index is 0) { | |
1806 if ((parent.style & SWT.VIRTUAL) is 0 && !cached && !parent.painted) { | |
1807 return; | |
1808 } | |
1809 auto hwnd = parent.handle; | |
1810 TVITEM tvItem; | |
1811 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_TEXT; | |
1812 tvItem.hItem = cast(HTREEITEM)handle; | |
1813 tvItem.pszText = OS.LPSTR_TEXTCALLBACK; | |
1814 OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, &tvItem); | |
1815 } else { | |
1816 redraw (index, true, false); | |
1817 } | |
1818 } | |
1819 | |
1820 override public void setText (String string) { | |
1821 checkWidget(); | |
1822 setText (0, string); | |
1823 } | |
1824 | |
1825 /*public*/ void sort () { | |
1826 checkWidget (); | |
1827 if ((parent.style & SWT.VIRTUAL) !is 0) return; | |
1828 parent.sort (handle, false); | |
1829 } | |
1830 | |
1831 } | |
1832 |