comparison dwt/widgets/ToolTip.d @ 0:380af2bdd8e5

Upload of whole dwt tree
author Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com>
date Sat, 09 Aug 2008 17:00:02 +0200
parents
children 649b8e223d5a
comparison
equal deleted inserted replaced
-1:000000000000 0:380af2bdd8e5
1 /*******************************************************************************
2 * Copyright (c) 2000, 2007 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 module dwt.widgets.ToolTip;
12
13 import dwt.dwthelper.utils;
14
15
16 import dwt.DWT;
17 import dwt.DWTException;
18 import dwt.events.SelectionEvent;
19 import dwt.events.SelectionListener;
20 import dwt.graphics.Color;
21 import dwt.graphics.Font;
22 import dwt.graphics.FontData;
23 import dwt.graphics.GC;
24 import dwt.graphics.Image;
25 import dwt.graphics.Point;
26 import dwt.graphics.Rectangle;
27 import dwt.graphics.Region;
28 import dwt.graphics.TextLayout;
29 import dwt.graphics.TextStyle;
30
31 /**
32 * Instances of this class represent popup windows that are used
33 * to inform or warn the user.
34 * <p>
35 * <dl>
36 * <dt><b>Styles:</b></dt>
37 * <dd>BALLOON, ICON_ERROR, ICON_INFORMATION, ICON_WARNING</dd>
38 * <dt><b>Events:</b></dt>
39 * <dd>Selection</dd>
40 * </dl>
41 * </p><p>
42 * Note: Only one of the styles ICON_ERROR, ICON_INFORMATION,
43 * and ICON_WARNING may be specified.
44 * </p><p>
45 * IMPORTANT: This class is intended to be subclassed <em>only</em>
46 * within the DWT implementation.
47 * </p>
48 *
49 * @since 3.2
50 */
51 public class ToolTip extends Widget {
52 Shell parent, tip;
53 TrayItem item;
54 int x, y;
55 int [] borderPolygon;
56 bool spikeAbove, autohide;
57 Listener listener;
58 TextLayout layoutText, layoutMessage;
59 Region region;
60 Font boldFont;
61 Runnable runnable;
62
63 static final int BORDER = 5;
64 static final int PADDING = 5;
65 static final int INSET = 4;
66 static final int TIP_HEIGHT = 20;
67 static final int IMAGE_SIZE = 16;
68 static final int DELAY = 10000;
69
70 /**
71 * Constructs a new instance of this class given its parent
72 * and a style value describing its behavior and appearance.
73 * <p>
74 * The style value is either one of the style constants defined in
75 * class <code>DWT</code> which is applicable to instances of this
76 * class, or must be built by <em>bitwise OR</em>'ing together
77 * (that is, using the <code>int</code> "|" operator) two or more
78 * of those <code>DWT</code> style constants. The class description
79 * lists the style constants that are applicable to the class.
80 * Style bits are also inherited from superclasses.
81 * </p>
82 *
83 * @param parent a composite control which will be the parent of the new instance (cannot be null)
84 * @param style the style of control to construct
85 *
86 * @exception IllegalArgumentException <ul>
87 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
88 * </ul>
89 * @exception DWTException <ul>
90 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
91 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
92 * </ul>
93 *
94 * @see DWT#ICON_ERROR
95 * @see DWT#ICON_INFORMATION
96 * @see DWT#ICON_WARNING
97 * @see Widget#checkSubclass
98 * @see Widget#getStyle
99 */
100 public ToolTip (Shell parent, int style) {
101 super (parent, checkStyle (style));
102 this.parent = parent;
103 this.autohide = true;
104 x = y = -1;
105 Display display = getDisplay ();
106 tip = new Shell (parent, DWT.ON_TOP | DWT.NO_TRIM);
107 Color background = display.getSystemColor (DWT.COLOR_INFO_BACKGROUND);
108 tip.setBackground (background);
109 listener = new Listener () {
110 public void handleEvent (Event event) {
111 switch (event.type) {
112 case DWT.Dispose: onDispose (event); break;
113 case DWT.Paint: onPaint (event); break;
114 case DWT.MouseDown: onMouseDown (event); break;
115 }
116 }
117 };
118 addListener (DWT.Dispose, listener);
119 tip.addListener (DWT.Paint, listener);
120 tip.addListener (DWT.MouseDown, listener);
121 }
122
123 static int checkStyle (int style) {
124 int mask = DWT.ICON_ERROR | DWT.ICON_INFORMATION | DWT.ICON_WARNING;
125 if ((style & mask) is 0) return style;
126 return checkBits (style, DWT.ICON_INFORMATION, DWT.ICON_WARNING, DWT.ICON_ERROR, 0, 0, 0);
127 }
128
129 /**
130 * Adds the listener to the collection of listeners who will
131 * be notified when the receiver is selected by the user, by sending
132 * it one of the messages defined in the <code>SelectionListener</code>
133 * interface.
134 * <p>
135 * <code>widgetSelected</code> is called when the receiver is selected.
136 * <code>widgetDefaultSelected</code> is not called.
137 * </p>
138 *
139 * @param listener the listener which should be notified when the receiver is selected by the user
140 *
141 * @exception IllegalArgumentException <ul>
142 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
143 * </ul>
144 * @exception DWTException <ul>
145 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
146 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
147 * </ul>
148 *
149 * @see SelectionListener
150 * @see #removeSelectionListener
151 * @see SelectionEvent
152 */
153 public void addSelectionListener (SelectionListener listener) {
154 checkWidget ();
155 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
156 TypedListener typedListener = new TypedListener (listener);
157 addListener (DWT.Selection,typedListener);
158 addListener (DWT.DefaultSelection,typedListener);
159 }
160
161 void configure () {
162 Display display = parent.getDisplay ();
163 int x = this.x;
164 int y = this.y;
165 if (x is -1 || y is -1) {
166 Point point = display.getCursorLocation ();
167 x = point.x;
168 y = point.y;
169 }
170 Monitor monitor = parent.getMonitor ();
171 Rectangle dest = monitor.getBounds ();
172 Point size = getSize (dest.width / 4);
173 int w = size.x;
174 int h = size.y;
175 int t = (style & DWT.BALLOON) !is 0 ? TIP_HEIGHT : 0;
176 int i = (style & DWT.BALLOON) !is 0 ? 16 : 0;
177 tip.setSize (w, h + t);
178 int [] polyline;
179 spikeAbove = dest.height >= y + size.y + t;
180 if (dest.width >= x + size.x) {
181 if (dest.height >= y + size.y + t) {
182 polyline = new int [] {
183 0, 5+t, 1, 5+t, 1, 3+t, 3, 1+t, 5, 1+t, 5, t,
184 16, t, 16, 0, 35, t,
185 w-5, t, w-5, 1+t, w-3, 1+t, w-1, 3+t, w-1, 5+t, w, 5+t,
186 w, h-5+t, w-1, h-5+t, w-1, h-3+t, w-2, h-3+t, w-2, h-2+t, w-3, h-2+t, w-3, h-1+t, w-5, h-1+t, w-5, h+t,
187 5, h+t, 5, h-1+t, 3, h-1+t, 3, h-2+t, 2, h-2+t, 2, h-3+t, 1, h-3+t, 1, h-5+t, 0, h-5+t,
188 0, 5+t};
189 borderPolygon = new int[] {
190 0, 5+t, 1, 4+t, 1, 3+t, 3, 1+t, 4, 1+t, 5, t,
191 16, t, 16, 1, 35, t,
192 w-6, 0+t, w-5, 1+t, w-4, 1+t, w-2, 3+t, w-2, 4+t, w-1, 5+t,
193 w-1, h-6+t, w-2, h-5+t, w-2, h-4+t, w-4, h-2+t, w-5, h-2+t, w-6, h-1+t,
194 5, h-1+t, 4, h-2+t, 3, h-2+t, 1, h-4+t, 1, h-5+t, 0, h-6+t,
195 0, 5+t};
196 tip.setLocation (Math.max (0, x - i), y);
197 } else {
198 polyline = new int [] {
199 0, 5, 1, 5, 1, 3, 3, 1, 5, 1, 5, 0,
200 w-5, 0, w-5, 1, w-3, 1, w-1, 3, w-1, 5, w, 5,
201 w, h-5, w-1, h-5, w-1, h-3, w-2, h-3, w-2, h-2, w-3, h-2, w-3, h-1, w-5, h-1, w-5, h,
202 35, h, 16, h+t, 16, h,
203 5, h, 5, h-1, 3, h-1, 3, h-2, 2, h-2, 2, h-3, 1, h-3, 1, h-5, 0, h-5,
204 0, 5};
205 borderPolygon = new int[] {
206 0, 5, 1, 4, 1, 3, 3, 1, 4, 1, 5, 0,
207 w-6, 0, w-5, 1, w-4, 1, w-2, 3, w-2, 4, w-1, 5,
208 w-1, h-6, w-2, h-5, w-2, h-4, w-4, h-2, w-5, h-2, w-6, h-1,
209 36, h-1, 16, h+t-1, 16, h-1,
210 5, h-1, 4, h-2, 3, h-2, 1, h-4, 1, h-5, 0, h-6,
211 0, 5};
212 tip.setLocation (Math.max (0, x - i), y - size.y - t);
213 }
214 } else {
215 if (dest.height >= y + size.y + t) {
216 polyline = new int [] {
217 0, 5+t, 1, 5+t, 1, 3+t, 3, 1+t, 5, 1+t, 5, t,
218 w-35, t, w-16, 0, w-16, t,
219 w-5, t, w-5, 1+t, w-3, 1+t, w-1, 3+t, w-1, 5+t, w, 5+t,
220 w, h-5+t, w-1, h-5+t, w-1, h-3+t, w-2, h-3+t, w-2, h-2+t, w-3, h-2+t, w-3, h-1+t, w-5, h-1+t, w-5, h+t,
221 5, h+t, 5, h-1+t, 3, h-1+t, 3, h-2+t, 2, h-2+t, 2, h-3+t, 1, h-3+t, 1, h-5+t, 0, h-5+t,
222 0, 5+t};
223 borderPolygon = new int[] {
224 0, 5+t, 1, 4+t, 1, 3+t, 3, 1+t, 4, 1+t, 5, t,
225 w-35, t, w-17, 2, w-17, t,
226 w-6, t, w-5, 1+t, w-4, 1+t, w-2, 3+t, w-2, 4+t, w-1, 5+t,
227 w-1, h-6+t, w-2, h-5+t, w-2, h-4+t, w-4, h-2+t, w-5, h-2+t, w-6, h-1+t,
228 5, h-1+t, 4, h-2+t, 3, h-2+t, 1, h-4+t, 1, h-5+t, 0, h-6+t,
229 0, 5+t};
230 tip.setLocation (Math.min (dest.width - size.x, x - size.x + i), y);
231 } else {
232 polyline = new int [] {
233 0, 5, 1, 5, 1, 3, 3, 1, 5, 1, 5, 0,
234 w-5, 0, w-5, 1, w-3, 1, w-1, 3, w-1, 5, w, 5,
235 w, h-5, w-1, h-5, w-1, h-3, w-2, h-3, w-2, h-2, w-3, h-2, w-3, h-1, w-5, h-1, w-5, h,
236 w-16, h, w-16, h+t, w-35, h,
237 5, h, 5, h-1, 3, h-1, 3, h-2, 2, h-2, 2, h-3, 1, h-3, 1, h-5, 0, h-5,
238 0, 5};
239 borderPolygon = new int[] {
240 0, 5, 1, 4, 1, 3, 3, 1, 4, 1, 5, 0,
241 w-6, 0, w-5, 1, w-4, 1, w-2, 3, w-2, 4, w-1, 5,
242 w-1, h-6, w-2, h-5, w-2, h-4, w-4, h-2, w-5, h-2, w-6, h-1,
243 w-17, h-1, w-17, h+t-2, w-36, h-1,
244 5, h-1, 4, h-2, 3, h-2, 1, h-4, 1, h-5, 0, h-6,
245 0, 5};
246 tip.setLocation (Math.min (dest.width - size.x, x - size.x + i), y - size.y - t);
247 }
248 }
249 if ((style & DWT.BALLOON) !is 0) {
250 if (region !is null) region.dispose ();
251 region = new Region (display);
252 region.add (polyline);
253 tip.setRegion (region);
254 }
255 }
256
257 /**
258 * Returns <code>true</code> if the receiver is automatically
259 * hidden by the platform, and <code>false</code> otherwise.
260 *
261 * @return the receiver's auto hide state
262 *
263 * @exception DWTException <ul>
264 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
265 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
266 * </ul>
267 *
268 */
269 public bool getAutoHide () {
270 checkWidget ();
271 return autohide;
272 }
273
274 Point getSize (int maxWidth) {
275 int textWidth = 0, messageWidth = 0;
276 if (layoutText !is null) {
277 layoutText.setWidth (-1);
278 textWidth = layoutText.getBounds ().width;
279 }
280 if (layoutMessage !is null) {
281 layoutMessage.setWidth (-1);
282 messageWidth = layoutMessage.getBounds ().width;
283 }
284 int messageTrim = 2 * INSET + 2 * BORDER + 2 * PADDING;
285 bool hasImage = layoutText !is null && (style & DWT.BALLOON) !is 0 && (style & (DWT.ICON_ERROR | DWT.ICON_INFORMATION | DWT.ICON_WARNING)) !is 0;
286 int textTrim = messageTrim + (hasImage ? IMAGE_SIZE : 0);
287 int width = Math.min (maxWidth, Math.max (textWidth + textTrim, messageWidth + messageTrim));
288 int textHeight = 0, messageHeight = 0;
289 if (layoutText !is null) {
290 layoutText.setWidth (maxWidth - textTrim);
291 textHeight = layoutText.getBounds ().height;
292 }
293 if (layoutMessage !is null) {
294 layoutMessage.setWidth (maxWidth - messageTrim);
295 messageHeight = layoutMessage.getBounds ().height;
296 }
297 int height = 2 * BORDER + 2 * PADDING + messageHeight;
298 if (layoutText !is null) height += Math.max (IMAGE_SIZE, textHeight) + 2 * PADDING;
299 return new Point (width, height);
300 }
301
302 /**
303 * Returns the receiver's message, which will be an empty
304 * string if it has never been set.
305 *
306 * @return the receiver's message
307 *
308 * @exception DWTException <ul>
309 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
310 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
311 * </ul>
312 */
313 public String getMessage () {
314 checkWidget ();
315 return layoutMessage !is null ? layoutMessage.getText() : "";
316 }
317
318 /**
319 * Returns the receiver's parent, which must be a <code>Shell</code>.
320 *
321 * @return the receiver's parent
322 *
323 * @exception DWTException <ul>
324 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
325 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
326 * </ul>
327 */
328 public Shell getParent () {
329 checkWidget ();
330 return parent;
331 }
332
333 /**
334 * Returns the receiver's text, which will be an empty
335 * string if it has never been set.
336 *
337 * @return the receiver's text
338 *
339 * @exception DWTException <ul>
340 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
341 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
342 * </ul>
343 */
344 public String getText () {
345 checkWidget ();
346 return layoutText !is null ? layoutText.getText() : "";
347 }
348
349 /**
350 * Returns <code>true</code> if the receiver is visible, and
351 * <code>false</code> otherwise.
352 * <p>
353 * If one of the receiver's ancestors is not visible or some
354 * other condition makes the receiver not visible, this method
355 * may still indicate that it is considered visible even though
356 * it may not actually be showing.
357 * </p>
358 *
359 * @return the receiver's visibility state
360 *
361 * @exception DWTException <ul>
362 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
363 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
364 * </ul>
365 */
366 public bool getVisible () {
367 checkWidget ();
368 return tip.getVisible ();
369 }
370
371 /**
372 * Returns <code>true</code> if the receiver is visible and all
373 * of the receiver's ancestors are visible and <code>false</code>
374 * otherwise.
375 *
376 * @return the receiver's visibility state
377 *
378 * @exception DWTException <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 * @see #getVisible
384 */
385 public bool isVisible () {
386 checkWidget ();
387 return getVisible ();
388 }
389
390 void onDispose (Event event) {
391 removeListener (DWT.Dispose, listener);
392 notifyListeners (DWT.Dispose, event);
393 event.type = DWT.None;
394
395 if (runnable !is null) {
396 Display display = getDisplay ();
397 display.timerExec (-1, runnable);
398 }
399 runnable = null;
400 tip.dispose ();
401 tip = null;
402 if (region !is null) region.dispose ();
403 region = null;
404 if (layoutText !is null) layoutText.dispose ();
405 layoutText = null;
406 if (layoutMessage !is null) layoutMessage.dispose ();
407 layoutMessage = null;
408 if (boldFont !is null) boldFont.dispose ();
409 boldFont = null;
410 borderPolygon = null;
411 }
412
413 void onMouseDown (Event event) {
414 notifyListeners (DWT.Selection, new Event ());
415 setVisible (false);
416 }
417
418 void onPaint (Event event) {
419 GC gc = event.gc;
420 int x = BORDER + PADDING;
421 int y = BORDER + PADDING;
422 if ((style & DWT.BALLOON) !is 0) {
423 if (spikeAbove) y += TIP_HEIGHT;
424 gc.drawPolygon (borderPolygon);
425 } else {
426 Rectangle rect = tip.getClientArea ();
427 gc.drawRectangle(rect.x, rect.y, rect.width - 1, rect.height -1);
428 }
429 if (layoutText !is null) {
430 int id = style & (DWT.ICON_ERROR | DWT.ICON_INFORMATION | DWT.ICON_WARNING);
431 if ((style & DWT.BALLOON) !is 0 && id !is 0) {
432 Display display = getDisplay ();
433 Image image = display.getSystemImage (id);
434 Rectangle rect = image.getBounds ();
435 gc.drawImage (image, 0, 0, rect.width, rect.height, x, y, IMAGE_SIZE, IMAGE_SIZE);
436 x += IMAGE_SIZE;
437 }
438 x += INSET;
439 layoutText.draw (gc, x, y);
440 y += 2 * PADDING + Math.max (IMAGE_SIZE, layoutText.getBounds ().height);
441 }
442 if (layoutMessage !is null) {
443 x = BORDER + PADDING + INSET;
444 layoutMessage.draw (gc, x, y);
445 }
446 }
447
448 /**
449 * Removes the listener from the collection of listeners who will
450 * be notified when the receiver is selected by the user.
451 *
452 * @param listener the listener which should no longer be notified
453 *
454 * @exception IllegalArgumentException <ul>
455 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
456 * </ul>
457 * @exception DWTException <ul>
458 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
459 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
460 * </ul>
461 *
462 * @see SelectionListener
463 * @see #addSelectionListener
464 */
465 public void removeSelectionListener (SelectionListener listener) {
466 checkWidget();
467 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
468 if (eventTable is null) return;
469 eventTable.unhook (DWT.Selection, listener);
470 eventTable.unhook (DWT.DefaultSelection,listener);
471 }
472
473 /**
474 * Makes the receiver hide automatically when <code>true</code>,
475 * and remain visible when <code>false</code>.
476 *
477 * @param autoHide the auto hide state
478 *
479 * @exception DWTException <ul>
480 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
481 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
482 * </ul>
483 *
484 * @see #getVisible
485 * @see #setVisible
486 */
487 public void setAutoHide (bool autohide) {
488 checkWidget ();
489 this.autohide = autohide;
490 //TODO - update when visible
491 }
492
493 /**
494 * Sets the location of the receiver, which must be a tooltip,
495 * to the point specified by the arguments which are relative
496 * to the display.
497 * <p>
498 * Note that this is different from most widgets where the
499 * location of the widget is relative to the parent.
500 * </p>
501 *
502 * @param x the new x coordinate for the receiver
503 * @param y the new y coordinate for the receiver
504 *
505 * @exception DWTException <ul>
506 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
507 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
508 * </ul>
509 */
510 public void setLocation (int x, int y) {
511 checkWidget ();
512 if (this.x is x && this.y is y) return;
513 this.x = x;
514 this.y = y;
515 if (tip.getVisible ()) configure ();
516 }
517
518 /**
519 * Sets the location of the receiver, which must be a tooltip,
520 * to the point specified by the argument which is relative
521 * to the display.
522 * <p>
523 * Note that this is different from most widgets where the
524 * location of the widget is relative to the parent.
525 * </p><p>
526 * Note that the platform window manager ultimately has control
527 * over the location of tooltips.
528 * </p>
529 *
530 * @param location the new location for the receiver
531 *
532 * @exception IllegalArgumentException <ul>
533 * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
534 * </ul>
535 * @exception DWTException <ul>
536 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
537 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
538 * </ul>
539 */
540 public void setLocation (Point location) {
541 checkWidget ();
542 if (location is null) DWT.error (DWT.ERROR_NULL_ARGUMENT);
543 setLocation (location.x, location.y);
544 }
545
546 /**
547 * Sets the receiver's message.
548 *
549 * @param string the new message
550 *
551 * @exception IllegalArgumentException <ul>
552 * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
553 * </ul>
554 * @exception DWTException <ul>
555 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
556 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
557 * </ul>
558 */
559 public void setMessage (String string) {
560 checkWidget ();
561 if (string is null) error (DWT.ERROR_NULL_ARGUMENT);
562 if (layoutMessage !is null) layoutMessage.dispose();
563 layoutMessage = null;
564 if (string.length () !is 0) {
565 Display display = getDisplay ();
566 layoutMessage = new TextLayout (display);
567 layoutMessage.setText (string);
568 }
569 if (tip.getVisible ()) configure ();
570 }
571
572 /**
573 * Sets the receiver's text.
574 *
575 * @param string the new text
576 *
577 * @exception IllegalArgumentException <ul>
578 * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
579 * </ul>
580 * @exception DWTException <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 void setText (String string) {
586 checkWidget ();
587 if (string is null) error (DWT.ERROR_NULL_ARGUMENT);
588 if (layoutText !is null) layoutText.dispose ();
589 layoutText = null;
590 if (boldFont !is null) boldFont.dispose ();
591 boldFont = null;
592 if (string.length () !is 0) {
593 Display display = getDisplay ();
594 layoutText = new TextLayout (display);
595 layoutText.setText (string);
596 Font font = display.getSystemFont ();
597 FontData data = font.getFontData () [0];
598 boldFont = new Font (display, data.getName (), data.getHeight (), DWT.BOLD);
599 TextStyle style = new TextStyle (boldFont, null, null);
600 layoutText.setStyle (style, 0, string.length ());
601 }
602 if (tip.getVisible ()) configure ();
603 }
604
605 /**
606 * Marks the receiver as visible if the argument is <code>true</code>,
607 * and marks it invisible otherwise.
608 * <p>
609 * If one of the receiver's ancestors is not visible or some
610 * other condition makes the receiver not visible, marking
611 * it visible may not actually cause it to be displayed.
612 * </p>
613 *
614 * @param visible the new visibility state
615 *
616 * @exception DWTException <ul>
617 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
618 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
619 * </ul>
620 */
621 public void setVisible (bool visible) {
622 if (visible) configure ();
623 tip.setVisible (visible);
624 Display display = getDisplay ();
625 if (runnable !is null) display.timerExec (-1, runnable);
626 runnable = null;
627 if (autohide && visible) {
628 runnable = new Runnable () {
629 public void run () {
630 if (!isDisposed ()) setVisible (false);
631 }
632 };
633 display.timerExec(DELAY, runnable);
634 }
635 }
636
637 }