comparison dwt/widgets/Button.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.Button;
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.Image;
21 import dwt.internal.cocoa.NSAttributedString;
22 import dwt.internal.cocoa.NSButton;
23 import dwt.internal.cocoa.NSButtonCell;
24 import dwt.internal.cocoa.NSColor;
25 import dwt.internal.cocoa.NSEvent;
26 import dwt.internal.cocoa.NSMutableDictionary;
27 import dwt.internal.cocoa.NSMutableParagraphStyle;
28 import dwt.internal.cocoa.NSRect;
29 import dwt.internal.cocoa.NSString;
30 import dwt.internal.cocoa.OS;
31 import dwt.internal.cocoa.SWTButton;
32
33 /**
34 * Instances of this class represent a selectable user interface object that
35 * issues notification when pressed and released.
36 * <dl>
37 * <dt><b>Styles:</b></dt>
38 * <dd>ARROW, CHECK, PUSH, RADIO, TOGGLE, FLAT</dd>
39 * <dd>UP, DOWN, LEFT, RIGHT, CENTER</dd>
40 * <dt><b>Events:</b></dt>
41 * <dd>Selection</dd>
42 * </dl>
43 * <p>
44 * Note: Only one of the styles ARROW, CHECK, PUSH, RADIO, and TOGGLE
45 * may be specified.
46 * </p><p>
47 * Note: Only one of the styles LEFT, RIGHT, and CENTER may be specified.
48 * </p><p>
49 * Note: Only one of the styles UP, DOWN, LEFT, and RIGHT may be specified
50 * when the ARROW style is specified.
51 * </p><p>
52 * IMPORTANT: This class is intended to be subclassed <em>only</em>
53 * within the DWT implementation.
54 * </p>
55 */
56 public class Button extends Control {
57 String text = "";
58 Image image;
59 bool grayed;
60
61 /**
62 * Constructs a new instance of this class given its parent
63 * and a style value describing its behavior and appearance.
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#ARROW
86 * @see DWT#CHECK
87 * @see DWT#PUSH
88 * @see DWT#RADIO
89 * @see DWT#TOGGLE
90 * @see DWT#FLAT
91 * @see DWT#LEFT
92 * @see DWT#RIGHT
93 * @see DWT#CENTER
94 * @see Widget#checkSubclass
95 * @see Widget#getStyle
96 */
97 public Button (Composite parent, int style) {
98 super (parent, checkStyle (style));
99 }
100
101 /**
102 * Adds the listener to the collection of listeners who will
103 * be notified when the control is selected by the user, by sending
104 * it one of the messages defined in the <code>SelectionListener</code>
105 * interface.
106 * <p>
107 * <code>widgetSelected</code> is called when the control is selected by the user.
108 * <code>widgetDefaultSelected</code> is not called.
109 * </p>
110 *
111 * @param listener the listener which should be notified
112 *
113 * @exception IllegalArgumentException <ul>
114 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
115 * </ul>
116 * @exception DWTException <ul>
117 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
118 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
119 * </ul>
120 *
121 * @see SelectionListener
122 * @see #removeSelectionListener
123 * @see SelectionEvent
124 */
125 public void addSelectionListener(SelectionListener listener) {
126 checkWidget();
127 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
128 TypedListener typedListener = new TypedListener(listener);
129 addListener(DWT.Selection,typedListener);
130 addListener(DWT.DefaultSelection,typedListener);
131 }
132
133 static int checkStyle (int style) {
134 style = checkBits (style, DWT.PUSH, DWT.ARROW, DWT.CHECK, DWT.RADIO, DWT.TOGGLE, 0);
135 if ((style & (DWT.PUSH | DWT.TOGGLE)) !is 0) {
136 return checkBits (style, DWT.CENTER, DWT.LEFT, DWT.RIGHT, 0, 0, 0);
137 }
138 if ((style & (DWT.CHECK | DWT.RADIO)) !is 0) {
139 return checkBits (style, DWT.LEFT, DWT.RIGHT, DWT.CENTER, 0, 0, 0);
140 }
141 if ((style & DWT.ARROW) !is 0) {
142 style |= DWT.NO_FOCUS;
143 return checkBits (style, DWT.UP, DWT.DOWN, DWT.LEFT, DWT.RIGHT, 0, 0);
144 }
145 return style;
146 }
147
148 void click () {
149 postEvent (DWT.Selection);
150 }
151
152 NSAttributedString createString() {
153 NSMutableDictionary dict = NSMutableDictionary.dictionaryWithCapacity(4);
154 if (foreground !is null) {
155 NSColor color = NSColor.colorWithDeviceRed(foreground.handle[0], foreground.handle[1], foreground.handle[2], 1);
156 dict.setObject(color, OS.NSForegroundColorAttributeName());
157 }
158 if (font !is null) {
159 dict.setObject(font.handle, OS.NSFontAttributeName());
160 }
161 int alignment;
162 if ((style & DWT.CENTER) !is 0) {
163 alignment = OS.NSCenterTextAlignment;
164 } else if ((style & DWT.LEFT) !is 0) {
165 alignment = OS.NSLeftTextAlignment;
166 } else {
167 alignment = OS.NSRightTextAlignment;
168 }
169 NSMutableParagraphStyle pStyle = (NSMutableParagraphStyle)new NSMutableParagraphStyle().alloc().init();
170 pStyle.autorelease();
171 pStyle.setAlignment(alignment);
172 dict.setObject(pStyle, OS.NSParagraphStyleAttributeName());
173 char [] chars = new char [text.length ()];
174 text.getChars (0, chars.length, chars, 0);
175 int length = fixMnemonic (chars);
176 NSString str = NSString.stringWithCharacters(chars, length);
177 NSAttributedString attribStr = ((NSAttributedString)new NSAttributedString().alloc()).initWithString_attributes_(str, dict);
178 attribStr.autorelease();
179 return attribStr;
180 }
181
182 void createHandle () {
183 NSButton widget = (NSButton)new SWTButton().alloc();
184 widget.initWithFrame(new NSRect());
185 int type = OS.NSMomentaryPushButton;
186 if ((style & DWT.PUSH) !is 0) {
187 widget.setBezelStyle(OS.NSRoundedBezelStyle);
188 } else if ((style & DWT.CHECK) !is 0) {
189 type = OS.NSSwitchButton;
190 widget.setAllowsMixedState (true);
191 } else if ((style & DWT.RADIO) !is 0) {
192 type = OS.NSRadioButton;
193 } else if ((style & DWT.TOGGLE) !is 0) {
194 type = OS.NSPushOnPushOffButton;
195 widget.setBezelStyle(OS.NSRegularSquareBezelStyle);
196 } else if ((style & DWT.ARROW) !is 0) {
197 widget.setBezelStyle(OS.NSRoundedDisclosureBezelStyle);
198 }
199 widget.setButtonType(type);
200 widget.setTitle(NSString.stringWith(""));
201 widget.setImagePosition(OS.NSImageLeft);
202 widget.setTarget(widget);
203 widget.setAction(OS.sel_sendSelection);
204 widget.setTag(jniRef);
205 view = widget;
206 parent.contentView().addSubview_(widget);
207 _setAlignment(style);
208 }
209
210 /**
211 * Returns a value which describes the position of the
212 * text or image in the receiver. The value will be one of
213 * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>
214 * unless the receiver is an <code>ARROW</code> button, in
215 * which case, the alignment will indicate the direction of
216 * the arrow (one of <code>LEFT</code>, <code>RIGHT</code>,
217 * <code>UP</code> or <code>DOWN</code>).
218 *
219 * @return the alignment
220 *
221 * @exception DWTException <ul>
222 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
223 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
224 * </ul>
225 */
226 public int getAlignment () {
227 checkWidget ();
228 if ((style & DWT.ARROW) !is 0) {
229 if ((style & DWT.UP) !is 0) return DWT.UP;
230 if ((style & DWT.DOWN) !is 0) return DWT.DOWN;
231 if ((style & DWT.LEFT) !is 0) return DWT.LEFT;
232 if ((style & DWT.RIGHT) !is 0) return DWT.RIGHT;
233 return DWT.UP;
234 }
235 if ((style & DWT.LEFT) !is 0) return DWT.LEFT;
236 if ((style & DWT.CENTER) !is 0) return DWT.CENTER;
237 if ((style & DWT.RIGHT) !is 0) return DWT.RIGHT;
238 return DWT.LEFT;
239 }
240
241 public bool getGrayed() {
242 checkWidget ();
243 if ((style &DWT.CHECK) !is 0) return false;
244 return grayed;
245 }
246
247 /**
248 * Returns the receiver's image if it has one, or null
249 * if it does not.
250 *
251 * @return the receiver's image
252 *
253 * @exception DWTException <ul>
254 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
255 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
256 * </ul>
257 */
258 public Image getImage () {
259 checkWidget();
260 return image;
261 }
262
263 String getNameText () {
264 return getText ();
265 }
266
267 /**
268 * Returns <code>true</code> if the receiver is selected,
269 * and false otherwise.
270 * <p>
271 * When the receiver is of type <code>CHECK</code> or <code>RADIO</code>,
272 * it is selected when it is checked. When it is of type <code>TOGGLE</code>,
273 * it is selected when it is pushed in. If the receiver is of any other type,
274 * this method returns false.
275 *
276 * @return the selection state
277 *
278 * @exception DWTException <ul>
279 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
280 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
281 * </ul>
282 */
283 public bool getSelection () {
284 checkWidget ();
285 if ((style & (DWT.CHECK | DWT.RADIO | DWT.TOGGLE)) is 0) return false;
286 if ((style & DWT.CHECK) !is 0 && grayed) return ((NSButton)view).state() is OS.NSMixedState;
287 return ((NSButton)view).state() is OS.NSOnState;
288 }
289
290 /**
291 * Returns the receiver's text, which will be an empty
292 * string if it has never been set or if the receiver is
293 * an <code>ARROW</code> button.
294 *
295 * @return the receiver's text
296 *
297 * @exception DWTException <ul>
298 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
299 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
300 * </ul>
301 */
302 public String getText () {
303 checkWidget ();
304 return text;
305 }
306
307 void releaseWidget () {
308 super.releaseWidget ();
309 image = null;
310 text = null;
311 }
312
313 /**
314 * Removes the listener from the collection of listeners who will
315 * be notified when the control is selected by the user.
316 *
317 * @param listener the listener which should no longer be notified
318 *
319 * @exception IllegalArgumentException <ul>
320 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
321 * </ul>
322 * @exception DWTException <ul>
323 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
324 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
325 * </ul>
326 *
327 * @see SelectionListener
328 * @see #addSelectionListener
329 */
330 public void removeSelectionListener(SelectionListener listener) {
331 checkWidget();
332 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
333 if (eventTable is null) return;
334 eventTable.unhook(DWT.Selection, listener);
335 eventTable.unhook(DWT.DefaultSelection,listener);
336 }
337
338 void selectRadio () {
339 /*
340 * This code is intentionally commented. When two groups
341 * of radio buttons with the same parent are separated by
342 * another control, the correct behavior should be that
343 * the two groups act independently. This is consistent
344 * with radio tool and menu items. The commented code
345 * implements this behavior.
346 */
347 // int index = 0;
348 // Control [] children = parent._getChildren ();
349 // while (index < children.length && children [index] !is this) index++;
350 // int i = index - 1;
351 // while (i >= 0 && children [i].setRadioSelection (false)) --i;
352 // int j = index + 1;
353 // while (j < children.length && children [j].setRadioSelection (false)) j++;
354 // setSelection (true);
355 Control [] children = parent._getChildren ();
356 for (int i=0; i<children.length; i++) {
357 Control child = children [i];
358 if (this !is child) child.setRadioSelection (false);
359 }
360 setSelection (true);
361 }
362
363 void sendSelection () {
364 if ((style & DWT.RADIO) !is 0) {
365 if ((parent.getStyle () & DWT.NO_RADIO_GROUP) is 0) {
366 selectRadio ();
367 }
368 }
369 if ((style & DWT.CHECK) !is 0) {
370 if (grayed && ((NSButton)view).state() is OS.NSOnState) {
371 ((NSButton)view).setState(OS.NSOffState);
372 }
373 if (!grayed && ((NSButton)view).state() is OS.NSMixedState) {
374 ((NSButton)view).setState(OS.NSOnState);
375 }
376 }
377 postEvent (DWT.Selection);
378 }
379
380
381 /**
382 * Controls how text, images and arrows will be displayed
383 * in the receiver. The argument should be one of
384 * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>
385 * unless the receiver is an <code>ARROW</code> button, in
386 * which case, the argument indicates the direction of
387 * the arrow (one of <code>LEFT</code>, <code>RIGHT</code>,
388 * <code>UP</code> or <code>DOWN</code>).
389 *
390 * @param alignment the new alignment
391 *
392 * @exception DWTException <ul>
393 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
394 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
395 * </ul>
396 */
397 public void setAlignment (int alignment) {
398 checkWidget ();
399 _setAlignment (alignment);
400 redraw ();
401 }
402
403 void _setAlignment (int alignment) {
404 if ((style & DWT.ARROW) !is 0) {
405 if ((style & (DWT.UP | DWT.DOWN | DWT.LEFT | DWT.RIGHT)) is 0) return;
406 style &= ~(DWT.UP | DWT.DOWN | DWT.LEFT | DWT.RIGHT);
407 style |= alignment & (DWT.UP | DWT.DOWN | DWT.LEFT | DWT.RIGHT);
408 // int orientation = OS.kThemeDisclosureRight;
409 // if ((style & DWT.UP) !is 0) orientation = OS.kThemeDisclosureDown;
410 // if ((style & DWT.DOWN) !is 0) orientation = OS.kThemeDisclosureDown;
411 // if ((style & DWT.LEFT) !is 0) orientation = OS.kThemeDisclosureLeft;
412 // OS.SetControl32BitValue (handle, orientation);
413 return;
414 }
415 if ((alignment & (DWT.LEFT | DWT.RIGHT | DWT.CENTER)) is 0) return;
416 style &= ~(DWT.LEFT | DWT.RIGHT | DWT.CENTER);
417 style |= alignment & (DWT.LEFT | DWT.RIGHT | DWT.CENTER);
418 /* text is still null when this is called from createHandle() */
419 if (text !is null) {
420 ((NSButton)view).setAttributedTitle(createString());
421 }
422 // /* Alignment not honoured when image and text is visible */
423 // bool bothVisible = text !is null && text.length () > 0 && image !is null;
424 // if (bothVisible) {
425 // if ((style & (DWT.RADIO | DWT.CHECK)) !is 0) alignment = DWT.LEFT;
426 // if ((style & (DWT.PUSH | DWT.TOGGLE)) !is 0) alignment = DWT.CENTER;
427 // }
428 // int textAlignment = 0;
429 // int graphicAlignment = 0;
430 // if ((alignment & DWT.LEFT) !is 0) {
431 // textAlignment = OS.kControlBevelButtonAlignTextFlushLeft;
432 // graphicAlignment = OS.kControlBevelButtonAlignLeft;
433 // }
434 // if ((alignment & DWT.CENTER) !is 0) {
435 // textAlignment = OS.kControlBevelButtonAlignTextCenter;
436 // graphicAlignment = OS.kControlBevelButtonAlignCenter;
437 // }
438 // if ((alignment & DWT.RIGHT) !is 0) {
439 // textAlignment = OS.kControlBevelButtonAlignTextFlushRight;
440 // graphicAlignment = OS.kControlBevelButtonAlignRight;
441 // }
442 // OS.SetControlData (handle, OS.kControlEntireControl, OS.kControlBevelButtonTextAlignTag, 2, new short [] {(short)textAlignment});
443 // OS.SetControlData (handle, OS.kControlEntireControl, OS.kControlBevelButtonGraphicAlignTag, 2, new short [] {(short)graphicAlignment});
444 // if (bothVisible) {
445 // OS.SetControlData (handle, OS.kControlEntireControl, OS.kControlBevelButtonTextPlaceTag, 2, new short [] {(short)OS.kControlBevelButtonPlaceToRightOfGraphic});
446 // }
447 }
448
449 void setBackground (float [] color) {
450 NSColor nsColor;
451 if (color is null) {
452 return; // TODO set to OS default
453 } else {
454 nsColor = NSColor.colorWithDeviceRed(color[0], color[1], color[2], 1);
455 }
456 NSButtonCell cell = new NSButtonCell(((NSButton)view).cell());
457 cell.setBackgroundColor(nsColor);
458 }
459
460 void setDefault (bool value) {
461 if ((style & DWT.PUSH) is 0) return;
462 // int window = OS.GetControlOwner (handle);
463 // OS.SetWindowDefaultButton (window, value ? handle : 0);
464 }
465
466 void setForeground (float [] color) {
467 ((NSButton)view).setAttributedTitle(createString());
468 }
469
470 public void setGrayed(bool grayed) {
471 checkWidget ();
472 if ((style & DWT.CHECK) is 0) return;
473 bool checked = getSelection ();
474 this.grayed = grayed;
475 if (checked) {
476 if (grayed) {
477 ((NSButton) view).setState (OS.NSMixedState);
478 } else {
479 ((NSButton) view).setState (OS.NSOnState);
480 }
481 }
482 }
483
484 /**
485 * Sets the receiver's image to the argument, which may be
486 * <code>null</code> indicating that no image should be displayed.
487 * <p>
488 * Note that a Button can display an image and text simultaneously
489 * on Windows (starting with XP), GTK+ and OSX. On other platforms,
490 * a Button that has an image and text set into it will display the
491 * image or text that was set most recently.
492 * </p>
493 * @param image the image to display on the receiver (may be <code>null</code>)
494 *
495 * @exception IllegalArgumentException <ul>
496 * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
497 * </ul>
498 * @exception DWTException <ul>
499 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
500 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
501 * </ul>
502 */
503 public void setImage (Image image) {
504 checkWidget();
505 if ((style & DWT.ARROW) !is 0) return;
506 if (image !is null && image.isDisposed ()) {
507 error (DWT.ERROR_INVALID_ARGUMENT);
508 }
509 this.image = image;
510 ((NSButton)view).setImage(image.handle);
511 }
512
513 bool setRadioSelection (bool value){
514 if ((style & DWT.RADIO) is 0) return false;
515 if (getSelection () !is value) {
516 setSelection (value);
517 postEvent (DWT.Selection);
518 }
519 return true;
520 }
521
522 /**
523 * Sets the selection state of the receiver, if it is of type <code>CHECK</code>,
524 * <code>RADIO</code>, or <code>TOGGLE</code>.
525 *
526 * <p>
527 * When the receiver is of type <code>CHECK</code> or <code>RADIO</code>,
528 * it is selected when it is checked. When it is of type <code>TOGGLE</code>,
529 * it is selected when it is pushed in.
530 *
531 * @param selected the new selection state
532 *
533 * @exception DWTException <ul>
534 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
535 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
536 * </ul>
537 */
538 public void setSelection (bool selected) {
539 checkWidget();
540 if ((style & (DWT.CHECK | DWT.RADIO | DWT.TOGGLE)) is 0) return;
541 if (grayed) {
542 ((NSButton)view).setState (selected ? OS.NSMixedState : OS.NSOffState);
543 } else {
544 ((NSButton)view).setState (selected ? OS.NSOnState : OS.NSOffState);
545 }
546 }
547
548 /**
549 * Sets the receiver's text.
550 * <p>
551 * This method sets the button label. The label may include
552 * the mnemonic character but must not contain line delimiters.
553 * </p>
554 * <p>
555 * Mnemonics are indicated by an '&amp;' that causes the next
556 * character to be the mnemonic. When the user presses a
557 * key sequence that matches the mnemonic, a selection
558 * event occurs. On most platforms, the mnemonic appears
559 * underlined but may be emphasized in a platform specific
560 * manner. The mnemonic indicator character '&amp;' can be
561 * escaped by doubling it in the string, causing a single
562 * '&amp;' to be displayed.
563 * </p><p>
564 * Note that a Button can display an image and text simultaneously
565 * on Windows (starting with XP), GTK+ and OSX. On other platforms,
566 * a Button that has an image and text set into it will display the
567 * image or text that was set most recently.
568 * </p>
569 * @param string the new text
570 *
571 * @exception IllegalArgumentException <ul>
572 * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
573 * </ul>
574 * @exception DWTException <ul>
575 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
576 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
577 * </ul>
578 */
579 public void setText (String string) {
580 checkWidget();
581 if (string is null) error (DWT.ERROR_NULL_ARGUMENT);
582 if ((style & DWT.ARROW) !is 0) return;
583 text = string;
584 ((NSButton)view).setAttributedTitle(createString());
585 }
586
587 int traversalCode (int key, NSEvent theEvent) {
588 int code = super.traversalCode (key, theEvent);
589 if ((style & DWT.RADIO) !is 0) code |= DWT.TRAVERSE_ARROW_NEXT | DWT.TRAVERSE_ARROW_PREVIOUS;
590 return code;
591 }
592
593 }