comparison dwt/widgets/ToolTip.d @ 37:642f460a0908

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