comparison dwt/widgets/TrayItem.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.TrayItem;
12
13 import dwt.dwthelper.utils;
14
15
16 import dwt.DWT;
17 import dwt.DWTException;
18 import dwt.events.MenuDetectListener;
19 import dwt.events.SelectionEvent;
20 import dwt.events.SelectionListener;
21 import dwt.graphics.Image;
22 import dwt.graphics.Point;
23 import dwt.internal.cocoa.NSEvent;
24 import dwt.internal.cocoa.NSImageView;
25 import dwt.internal.cocoa.NSPoint;
26 import dwt.internal.cocoa.NSRect;
27 import dwt.internal.cocoa.NSStatusBar;
28 import dwt.internal.cocoa.NSStatusItem;
29 import dwt.internal.cocoa.NSString;
30 import dwt.internal.cocoa.OS;
31 import dwt.internal.cocoa.SWTImageView;
32
33 /**
34 * Instances of this class represent icons that can be placed on the
35 * system tray or task bar status area.
36 * <p>
37 * <dl>
38 * <dt><b>Styles:</b></dt>
39 * <dd>(none)</dd>
40 * <dt><b>Events:</b></dt>
41 * <dd>DefaultSelection, MenuDetect, Selection</dd>
42 * </dl>
43 * </p><p>
44 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
45 * </p>
46 *
47 * @since 3.0
48 */
49 public class TrayItem extends Item {
50 Tray parent;
51 ToolTip toolTip;
52 String toolTipText;
53 bool visible = true, highlight;
54 NSStatusItem item;
55 NSImageView view;
56
57 static final float BORDER = 8f;
58
59 /**
60 * Constructs a new instance of this class given its parent
61 * (which must be a <code>Tray</code>) and a style value
62 * describing its behavior and appearance. The item is added
63 * to the end of the items maintained by its parent.
64 * <p>
65 * The style value is either one of the style constants defined in
66 * class <code>DWT</code> which is applicable to instances of this
67 * class, or must be built by <em>bitwise OR</em>'ing together
68 * (that is, using the <code>int</code> "|" operator) two or more
69 * of those <code>DWT</code> style constants. The class description
70 * lists the style constants that are applicable to the class.
71 * Style bits are also inherited from superclasses.
72 * </p>
73 *
74 * @param parent a composite control which will be the parent of the new instance (cannot be null)
75 * @param style the style of control to construct
76 *
77 * @exception IllegalArgumentException <ul>
78 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
79 * </ul>
80 * @exception DWTException <ul>
81 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
82 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
83 * </ul>
84 *
85 * @see DWT
86 * @see Widget#checkSubclass
87 * @see Widget#getStyle
88 */
89 public TrayItem (Tray parent, int style) {
90 super (parent, style);
91 this.parent = parent;
92 parent.createItem (this, parent.getItemCount ());
93 createWidget ();
94 }
95
96 /**
97 * Adds the listener to the collection of listeners who will
98 * be notified when the platform-specific context menu trigger
99 * has occurred, by sending it one of the messages defined in
100 * the <code>MenuDetectListener</code> interface.
101 *
102 * @param listener the listener which should be notified
103 *
104 * @exception IllegalArgumentException <ul>
105 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
106 * </ul>
107 * @exception DWTException <ul>
108 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
109 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
110 * </ul>
111 *
112 * @see MenuDetectListener
113 * @see #removeMenuDetectListener
114 *
115 * @since 3.3
116 */
117 public void addMenuDetectListener (MenuDetectListener listener) {
118 checkWidget ();
119 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
120 TypedListener typedListener = new TypedListener (listener);
121 addListener (DWT.MenuDetect, typedListener);
122 }
123
124 /**
125 * Adds the listener to the collection of listeners who will
126 * be notified when the receiver is selected by the user, by sending
127 * it one of the messages defined in the <code>SelectionListener</code>
128 * interface.
129 * <p>
130 * <code>widgetSelected</code> is called when the receiver is selected
131 * <code>widgetDefaultSelected</code> is called when the receiver is double-clicked
132 * </p>
133 *
134 * @param listener the listener which should be notified when the receiver is selected by the user
135 *
136 * @exception IllegalArgumentException <ul>
137 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
138 * </ul>
139 * @exception DWTException <ul>
140 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
141 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
142 * </ul>
143 *
144 * @see SelectionListener
145 * @see #removeSelectionListener
146 * @see SelectionEvent
147 */
148 public void addSelectionListener(SelectionListener listener) {
149 checkWidget ();
150 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
151 TypedListener typedListener = new TypedListener (listener);
152 addListener (DWT.Selection,typedListener);
153 addListener (DWT.DefaultSelection,typedListener);
154 }
155
156 protected void checkSubclass () {
157 if (!isValidSubclass ()) error (DWT.ERROR_INVALID_SUBCLASS);
158 }
159
160 void createWidget () {
161 NSStatusBar statusBar = NSStatusBar.systemStatusBar();
162 item = statusBar.statusItemWithLength(0);
163 if (item is null) error (DWT.ERROR_NO_HANDLES);
164 item.retain();
165 item.setHighlightMode(true);
166 NSRect rect = new NSRect();
167 view = (NSImageView)new SWTImageView().alloc();
168 if (view is null) error (DWT.ERROR_NO_HANDLES);
169 view.initWithFrame(rect);
170 item.setView(view);
171 createJNIRef();
172 view.setTag(jniRef);
173 }
174
175 void destroyWidget () {
176 parent.destroyItem (this);
177 releaseHandle ();
178 }
179
180 Point getLocation () {
181 NSRect rect = view.frame();
182 NSRect windowRect = view.window().frame();
183 NSPoint pt = new NSPoint();
184 pt.x = rect.width / 2;
185 pt.y = rect.height;
186 pt = view.convertPoint_fromView_(pt, null);
187 pt.x += windowRect.x;
188 return new Point ((int)pt.x, (int)pt.y);
189 }
190
191 /**
192 * Returns the receiver's parent, which must be a <code>Tray</code>.
193 *
194 * @return the receiver's parent
195 *
196 * @exception DWTException <ul>
197 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
198 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
199 * </ul>
200 *
201 * @since 3.2
202 */
203 public Tray getParent () {
204 checkWidget ();
205 return parent;
206 }
207
208 /**
209 * Returns the receiver's tool tip, or null if it has
210 * not been set.
211 *
212 * @return the receiver's tool tip text
213 *
214 * @exception DWTException <ul>
215 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
216 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
217 * </ul>
218 *
219 * @since 3.2
220 */
221 public ToolTip getToolTip () {
222 checkWidget ();
223 return toolTip;
224 }
225
226 /**
227 * Returns the receiver's tool tip text, or null if it has
228 * not been set.
229 *
230 * @return the receiver's tool tip text
231 *
232 * @exception DWTException <ul>
233 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
234 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
235 * </ul>
236 */
237 public String getToolTipText () {
238 checkWidget ();
239 return toolTipText;
240 }
241
242 /**
243 * Returns <code>true</code> if the receiver is visible and
244 * <code>false</code> otherwise.
245 *
246 * @return the receiver's visibility
247 *
248 * @exception DWTException <ul>
249 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
250 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
251 * </ul>
252 */
253 public bool getVisible () {
254 checkWidget ();
255 return visible;
256 }
257
258 void releaseHandle () {
259 super.releaseHandle ();
260 parent = null;
261 if (item !is null) item.release();
262 if (view !is null) {
263 view.setTag(-1);
264 view.release();
265 }
266 item = null;
267 view = null;
268 }
269
270 void releaseWidget () {
271 super.releaseWidget ();
272 NSStatusBar statusBar = NSStatusBar.systemStatusBar();
273 statusBar.removeStatusItem(item);
274 }
275
276 /**
277 * Removes the listener from the collection of listeners who will
278 * be notified when the platform-specific context menu trigger has
279 * occurred.
280 *
281 * @param listener the listener which should no longer be notified
282 *
283 * @exception IllegalArgumentException <ul>
284 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
285 * </ul>
286 * @exception DWTException <ul>
287 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
288 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
289 * </ul>
290 *
291 * @see MenuDetectListener
292 * @see #addMenuDetectListener
293 *
294 * @since 3.3
295 */
296 public void removeMenuDetectListener (MenuDetectListener listener) {
297 checkWidget ();
298 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
299 if (eventTable is null) return;
300 eventTable.unhook (DWT.MenuDetect, listener);
301 }
302
303 /**
304 * Removes the listener from the collection of listeners who will
305 * be notified when the receiver is selected by the user.
306 *
307 * @param listener the listener which should no longer be notified
308 *
309 * @exception IllegalArgumentException <ul>
310 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
311 * </ul>
312 * @exception DWTException <ul>
313 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
314 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
315 * </ul>
316 *
317 * @see SelectionListener
318 * @see #addSelectionListener
319 */
320 public void removeSelectionListener (SelectionListener listener) {
321 checkWidget ();
322 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
323 if (eventTable is null) return;
324 eventTable.unhook (DWT.Selection, listener);
325 eventTable.unhook (DWT.DefaultSelection,listener);
326 }
327
328 /**
329 * Sets the receiver's image.
330 *
331 * @param image the new image
332 *
333 * @exception IllegalArgumentException <ul>
334 * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
335 * </ul>
336 * @exception DWTException <ul>
337 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
338 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
339 * </ul>
340 */
341 public void setImage (Image image) {
342 checkWidget ();
343 if (image !is null && image.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT);
344 super.setImage (image);
345 view.setImage(image !is null ? image.handle : null);
346 float width = image !is null && visible ? image.handle.size().width + BORDER : 0;
347 item.setLength(width);
348 }
349
350 /**
351 * Sets the receiver's tool tip to the argument, which
352 * may be null indicating that no tool tip should be shown.
353 *
354 * @param toolTip the new tool tip (or null)
355 *
356 * @exception DWTException <ul>
357 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
358 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
359 * </ul>
360 *
361 * @since 3.2
362 */
363 public void setToolTip (ToolTip toolTip) {
364 checkWidget ();
365 ToolTip oldTip = this.toolTip, newTip = toolTip;
366 if (oldTip !is null) oldTip.item = null;
367 this.toolTip = newTip;
368 if (newTip !is null) newTip.item = this;
369 }
370
371 /**
372 * Sets the receiver's tool tip text to the argument, which
373 * may be null indicating that no tool tip text should be shown.
374 *
375 * @param value the new tool tip text (or null)
376 *
377 * @exception DWTException <ul>
378 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
379 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
380 * </ul>
381 */
382 public void setToolTipText (String string) {
383 checkWidget ();
384 toolTipText = string;
385 _setToolTipText (string);
386 }
387
388 void _setToolTipText (String string) {
389 NSString str = null;
390 if (string !is null) str = NSString.stringWith(string);
391 view.setToolTip(str);
392 }
393
394 /**
395 * Makes the receiver visible if the argument is <code>true</code>,
396 * and makes it invisible otherwise.
397 *
398 * @param visible the new visibility state
399 *
400 * @exception DWTException <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 void setVisible (bool visible) {
406 checkWidget ();
407 if (this.visible is visible) return;
408 if (visible) {
409 sendEvent (DWT.Show);
410 if (isDisposed ()) return;
411 }
412 this.visible = visible;
413 float width = image !is null && visible ? image.handle.size().width + BORDER : 0;
414 item.setLength(width);
415 if (!visible) sendEvent (DWT.Hide);
416 }
417
418 void showMenu () {
419 _setToolTipText (null);
420 sendEvent (DWT.MenuDetect);
421 if (isDisposed ()) return;
422 // display.runPopups ();
423 if (isDisposed ()) return;
424 _setToolTipText (toolTipText);
425 }
426
427 void mouseDown(int event) {
428 NSEvent nsEvent = new NSEvent(event);
429 int mask = nsEvent.modifierFlags() & OS.NSDeviceIndependentModifierFlagsMask;
430 if (mask is OS.NSControlKeyMask) {
431 showMenu();
432 } else {
433 highlight = true;
434 view.setNeedsDisplay(true);
435 int clickCount = nsEvent.clickCount();
436 postEvent(clickCount is 2 ? DWT.DefaultSelection : DWT.Selection);
437 }
438 }
439
440 void mouseUp(int event) {
441 highlight = false;
442 view.setNeedsDisplay(true);
443 }
444
445 void rightMouseDown(int event) {
446 showMenu();
447 }
448
449 void drawRect(int id, NSRect rect) {
450 item.drawStatusBarBackgroundInRect(rect, highlight);
451 super.drawRect(id, rect);
452 }
453 }