comparison dwt/widgets/Button.d @ 45:d8635bb48c7c

Merge with SWT 3.5
author Jacob Carlborg <doob@me.com>
date Mon, 01 Dec 2008 17:07:00 +0100
parents 642f460a0908
children cfa563df4fdd
comparison
equal deleted inserted replaced
44:ca5e494f2bbf 45:d8635bb48c7c
1 /******************************************************************************* 1 /*******************************************************************************
2 * Copyright (c) 2000, 2007 IBM Corporation and others. 2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials 3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0 4 * are made available under the terms of the Eclipse Public License v1.0
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 * 10 *
11 * Port to the D programming language: 11 * Port to the D programming language:
12 * Jacob Carlborg <jacob.carlborg@gmail.com> 12 * Jacob Carlborg <doob@me.com>
13 *******************************************************************************/ 13 *******************************************************************************/
14 module dwt.widgets.Button; 14 module dwt.widgets.Button;
15 15
16 16
17 import dwt.DWT; 17 import dwt.DWT;
18 import dwt.DWTException; 18 import dwt.DWTException;
19 import dwt.accessibility.ACC;
19 import dwt.events.SelectionEvent; 20 import dwt.events.SelectionEvent;
20 import dwt.events.SelectionListener; 21 import dwt.events.SelectionListener;
21 import dwt.graphics.Image; 22 import dwt.graphics.Image;
23 import dwt.graphics.Point;
24 import dwt.internal.cocoa.NSAffineTransform;
22 import dwt.internal.cocoa.NSAttributedString; 25 import dwt.internal.cocoa.NSAttributedString;
26 import dwt.internal.cocoa.NSBezierPath;
23 import dwt.internal.cocoa.NSButton; 27 import dwt.internal.cocoa.NSButton;
24 import dwt.internal.cocoa.NSButtonCell; 28 import dwt.internal.cocoa.NSButtonCell;
25 import dwt.internal.cocoa.NSColor; 29 import dwt.internal.cocoa.NSColor;
30 import dwt.internal.cocoa.NSControl;
26 import dwt.internal.cocoa.NSEvent; 31 import dwt.internal.cocoa.NSEvent;
32 import dwt.internal.cocoa.NSFont;
33 import dwt.internal.cocoa.NSGraphicsContext;
27 import dwt.internal.cocoa.NSMutableDictionary; 34 import dwt.internal.cocoa.NSMutableDictionary;
28 import dwt.internal.cocoa.NSMutableParagraphStyle; 35 import dwt.internal.cocoa.NSMutableParagraphStyle;
36 import dwt.internal.cocoa.NSPoint;
29 import dwt.internal.cocoa.NSRect; 37 import dwt.internal.cocoa.NSRect;
30 import dwt.internal.cocoa.NSString; 38 import dwt.internal.cocoa.NSString;
31 import dwt.internal.cocoa.OS; 39 import dwt.internal.cocoa.OS;
32 import dwt.internal.cocoa.SWTButton; 40 import dwt.internal.cocoa.SWTButton;
41 import dwt.internal.cocoa.id;
33 42
34 import dwt.dwthelper.utils; 43 import dwt.dwthelper.utils;
35 import dwt.internal.cocoa.CGFloat; 44 import dwt.internal.cocoa.CGFloat;
36 import dwt.internal.cocoa.NSCell; 45 import dwt.internal.cocoa.NSCell;
37 import dwt.internal.cocoa.NSInteger; 46 import dwt.internal.cocoa.NSInteger;
61 * when the ARROW style is specified. 70 * when the ARROW style is specified.
62 * </p><p> 71 * </p><p>
63 * IMPORTANT: This class is intended to be subclassed <em>only</em> 72 * IMPORTANT: This class is intended to be subclassed <em>only</em>
64 * within the DWT implementation. 73 * within the DWT implementation.
65 * </p> 74 * </p>
75 *
76 * @see <a href="http://www.eclipse.org/swt/snippets/#button">Button snippets</a>
77 * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: ControlExample</a>
78 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
66 */ 79 */
67 public class Button : Control { 80 public class Button : Control {
68 String text = ""; 81 String text = "";
69 Image image; 82 Image image;
70 bool grayed; 83 bool grayed;
107 */ 120 */
108 public this (Composite parent, int style) { 121 public this (Composite parent, int style) {
109 super (parent, checkStyle (style)); 122 super (parent, checkStyle (style));
110 } 123 }
111 124
125 int accessibilityAttributeValue (int /*long*/ id, int /*long*/ sel, int /*long*/ arg0) {
126 NSString nsAttributeName = new NSString(arg0);
127
128 if (accessible !is null) {
129 id returnObject = accessible.internal_accessibilityAttributeValue(nsAttributeName, ACC.CHILDID_SELF);
130 if (returnObject !is null) return returnObject.id;
131 }
132
133 if (nsAttributeName.isEqualToString (OS.NSAccessibilityRoleAttribute) || nsAttributeName.isEqualToString (OS.NSAccessibilityRoleDescriptionAttribute)) {
134 NSString role = null;
135
136 if ((style & DWT.RADIO) !is 0) {
137 role = OS.NSAccessibilityRadioButtonRole;
138 } else if ((style & DWT.ARROW) !is 0) {
139 role = OS.NSAccessibilityButtonRole;
140 }
141
142 if (role !is null) {
143 if (nsAttributeName.isEqualToString (OS.NSAccessibilityRoleAttribute))
144 return role.id;
145 else {
146 int roleDescription = OS.NSAccessibilityRoleDescription(role.id, 0);
147 return roleDescription;
148 }
149 }
150 }
151
152 return super.accessibilityAttributeValue(id, sel, arg0);
153 }
154
155
112 /** 156 /**
113 * Adds the listener to the collection of listeners who will 157 * Adds the listener to the collection of listeners who will
114 * be notified when the control is selected by the user, by sending 158 * be notified when the control is selected by the user, by sending
115 * it one of the messages defined in the <code>SelectionListener</code> 159 * it one of the messages defined in the <code>SelectionListener</code>
116 * interface. 160 * interface.
158 202
159 void click () { 203 void click () {
160 postEvent (DWT.Selection); 204 postEvent (DWT.Selection);
161 } 205 }
162 206
207 public Point computeSize (int wHint, int hHint, bool changed) {
208 checkWidget();
209 if ((style & DWT.ARROW) !is 0) {
210 // TODO use some OS metric instead of hardcoded values
211 int width = wHint !is DWT.DEFAULT ? wHint : 23;
212 int height = hHint !is DWT.DEFAULT ? hHint : 23;
213 return new Point (width, height);
214 }
215 return super.computeSize(wHint, hHint, changed);
216 }
217
163 NSAttributedString createString() { 218 NSAttributedString createString() {
164 NSMutableDictionary dict = NSMutableDictionary.dictionaryWithCapacity(4); 219 NSMutableDictionary dict = NSMutableDictionary.dictionaryWithCapacity(4);
165 if (foreground !is null) { 220 if (foreground !is null) {
166 NSColor color = NSColor.colorWithDeviceRed(cast(CGFloat) foreground.handle[0], cast(CGFloat) foreground.handle[1], cast(CGFloat) foreground.handle[2], 1); 221 NSColor color = NSColor.colorWithDeviceRed(cast(CGFloat) foreground.handle[0], cast(CGFloat) foreground.handle[1], cast(CGFloat) foreground.handle[2], 1);
167 dict.setObject(color, OS.NSForegroundColorAttributeName()); 222 dict.setObject(color, OS.NSForegroundColorAttributeName);
168 } 223 }
169 if (font !is null) { 224
170 dict.setObject(font.handle, OS.NSFontAttributeName()); 225 dict.setObject(getFont().handle, OS.NSFontAttributeName);
171 } 226
172 NSTextAlignment alignment; 227 NSTextAlignment alignment;
173 if ((style & DWT.CENTER) !is 0) { 228 if ((style & DWT.CENTER) !is 0) {
174 alignment = NSCenterTextAlignment; 229 alignment = NSCenterTextAlignment;
175 } else if ((style & DWT.LEFT) !is 0) { 230 } else if ((style & DWT.LEFT) !is 0) {
176 alignment = NSLeftTextAlignment; 231 alignment = NSLeftTextAlignment;
178 alignment = NSRightTextAlignment; 233 alignment = NSRightTextAlignment;
179 } 234 }
180 NSMutableParagraphStyle pStyle = cast(NSMutableParagraphStyle)(new NSMutableParagraphStyle()).alloc().init(); 235 NSMutableParagraphStyle pStyle = cast(NSMutableParagraphStyle)(new NSMutableParagraphStyle()).alloc().init();
181 pStyle.autorelease(); 236 pStyle.autorelease();
182 pStyle.setAlignment(alignment); 237 pStyle.setAlignment(alignment);
183 dict.setObject(pStyle, OS.NSParagraphStyleAttributeName()); 238 dict.setObject(pStyle, OS.NSParagraphStyleAttributeName);
184 char [] chars = new char [text.length ()]; 239 char [] chars = new char [text.length ()];
185 text.getChars (0, chars.length, chars, 0); 240 text.getChars (0, chars.length, chars, 0);
186 NSUInteger length = fixMnemonic (chars); 241 NSUInteger length = fixMnemonic (chars);
187 NSString str = NSString.stringWithCharacters(chars.toString16().ptr, length); 242 NSString str = NSString.stringWithCharacters(chars.toString16().ptr, length);
188 NSAttributedString attribStr = (cast(NSAttributedString)(new NSAttributedString()).alloc()).initWithString_attributes_(str, dict); 243 NSAttributedString attribStr = (cast(NSAttributedString)(new NSAttributedString()).alloc()).initWithString(str, dict);
189 attribStr.autorelease(); 244 attribStr.autorelease();
190 return attribStr; 245 return attribStr;
191 } 246 }
192 247
193 void createHandle () { 248 void createHandle () {
194 NSButton widget = cast(NSButton)(new SWTButton()).alloc(); 249 NSButton widget = cast(NSButton)(new SWTButton()).alloc();
195 widget.initWithFrame(NSRect()); 250 widget.initWithFrame(NSRect());
196 NSButtonType type = NSMomentaryPushButton; 251 NSButtonType type = NSMomentaryLightButton;
197 if ((style & DWT.PUSH) !is 0) { 252 if ((style & DWT.PUSH) !is 0) {
198 widget.setBezelStyle(NSRoundedBezelStyle); 253 if ((style & DWT.FLAT) !is 0) {
254 widget.setBezelStyle(OS.NSShadowlessSquareBezelStyle);
255 // if ((style & DWT.BORDER) is 0) widget.setShowsBorderOnlyWhileMouseInside(true);
256 } else {
257 widget.setBezelStyle(OS.NSRoundedBezelStyle);
258 }
199 } else if ((style & DWT.CHECK) !is 0) { 259 } else if ((style & DWT.CHECK) !is 0) {
200 type = NSSwitchButton; 260 type = NSSwitchButton;
201 widget.setAllowsMixedState (true); 261 widget.setAllowsMixedState (true);
202 } else if ((style & DWT.RADIO) !is 0) { 262 } else if ((style & DWT.RADIO) !is 0) {
203 type = NSRadioButton; 263 type = NSRadioButton;
204 } else if ((style & DWT.TOGGLE) !is 0) { 264 } else if ((style & DWT.TOGGLE) !is 0) {
205 type = NSPushOnPushOffButton; 265 type = NSPushOnPushOffButton;
206 widget.setBezelStyle(NSRegularSquareBezelStyle); 266 widget.setBezelStyle(NSRegularSquareBezelStyle);
267 widget.setBezelStyle(OS.NSShadowlessSquareBezelStyle);
268 // if ((style & DWT.BORDER) is 0) widget.setShowsBorderOnlyWhileMouseInside(true);
269 } else {
270 widget.setBezelStyle(OS.NSRoundedBezelStyle);
271 }
207 } else if ((style & DWT.ARROW) !is 0) { 272 } else if ((style & DWT.ARROW) !is 0) {
208 widget.setBezelStyle(NSRoundedDisclosureBezelStyle); 273 widget.setBezelStyle(NSRegularSquareBezelStyle);
209 } 274 }
210 widget.setButtonType(type); 275 widget.setButtonType(type);
211 widget.setTitle(NSString.stringWith("")); 276 widget.setTitle(NSString.stringWith(""));
212 widget.setImagePosition(NSImageLeft); 277 widget.setImagePosition(NSImageLeft);
213 widget.setTarget(widget); 278 widget.setTarget(widget);
214 widget.setAction(OS.sel_sendSelection); 279 widget.setAction(OS.sel_sendSelection);
215 widget.setTag(jniRef); 280 view = widget;
216 view = widget;
217 parent.contentView().addSubview_(widget);
218 _setAlignment(style); 281 _setAlignment(style);
282 }
283
284 void deregister () {
285 super.deregister ();
286 display.removeWidget(((NSControl)view).cell());
287 }
288
289 void drawWidget (int /*long*/ id, NSRect rect) {
290 if ((style & DWT.ARROW) !is 0) {
291 NSRect frame = view.frame();
292 int arrowSize = Math.min((int)frame.height, (int)frame.width) / 2;
293 NSGraphicsContext context = NSGraphicsContext.currentContext();
294 context.saveGraphicsState();
295 NSPoint p1 = new NSPoint();
296 p1.x = (float)Math.floor(-arrowSize / 2);
297 p1.y = (float)Math.floor(-arrowSize / 2);
298 NSPoint p2 = new NSPoint();
299 p2.x = (float)Math.ceil(arrowSize / 2);
300 p2.y = p1.y;
301 NSPoint p3 = new NSPoint();
302 p3.y = (float)Math.ceil(arrowSize / 2);
303
304 NSBezierPath path = NSBezierPath.bezierPath();
305 path.moveToPoint(p1);
306 path.lineToPoint(p2);
307 path.lineToPoint(p3);
308 path.closePath();
309
310 NSAffineTransform transform = NSAffineTransform.transform();
311 if ((style & DWT.LEFT) !is 0) {
312 transform.rotateByDegrees(90);
313 } else if ((style & DWT.UP) !is 0) {
314 transform.rotateByDegrees(180);
315 } else if ((style & DWT.RIGHT) !is 0) {
316 transform.rotateByDegrees(-90);
317 }
318 path.transformUsingAffineTransform(transform);
319 transform = NSAffineTransform.transform();
320 transform.translateXBy(frame.width / 2, frame.height / 2);
321 path.transformUsingAffineTransform(transform);
322
323 NSColor color = isEnabled() ? NSColor.blackColor() : NSColor.disabledControlTextColor();
324 color.set();
325 path.fill();
326 context.restoreGraphicsState();
327 }
328 super.drawWidget (id, rect);
219 } 329 }
220 330
221 /** 331 /**
222 * Returns a value which describes the position of the 332 * Returns a value which describes the position of the
223 * text or image in the receiver. The value will be one of 333 * text or image in the receiver. The value will be one of
247 if ((style & DWT.CENTER) !is 0) return DWT.CENTER; 357 if ((style & DWT.CENTER) !is 0) return DWT.CENTER;
248 if ((style & DWT.RIGHT) !is 0) return DWT.RIGHT; 358 if ((style & DWT.RIGHT) !is 0) return DWT.RIGHT;
249 return DWT.LEFT; 359 return DWT.LEFT;
250 } 360 }
251 361
362 /**
363 * Returns <code>true</code> if the receiver is grayed,
364 * and false otherwise. When the widget does not have
365 * the <code>CHECK</code> style, return false.
366 *
367 * @return the grayed state of the checkbox
368 *
369 * @exception DWTException <ul>
370 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
371 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
372 * </ul>
373 *
374 * @since 3.4
375 */
252 public bool getGrayed() { 376 public bool getGrayed() {
253 checkWidget (); 377 checkWidget ();
254 if ((style &DWT.CHECK) !is 0) return false; 378 if ((style &DWT.CHECK) !is 0) return false;
255 return grayed; 379 return grayed;
256 } 380 }
311 * </ul> 435 * </ul>
312 */ 436 */
313 public String getText () { 437 public String getText () {
314 checkWidget (); 438 checkWidget ();
315 return text; 439 return text;
440 }
441
442 void register() {
443 super.register();
444 display.addWidget(((NSControl)view).cell(), this);
316 } 445 }
317 446
318 void releaseWidget () { 447 void releaseWidget () {
319 super.releaseWidget (); 448 super.releaseWidget ();
320 image = null; 449 image = null;
468 cell.setBackgroundColor(nsColor); 597 cell.setBackgroundColor(nsColor);
469 } 598 }
470 599
471 void setDefault (bool value) { 600 void setDefault (bool value) {
472 if ((style & DWT.PUSH) is 0) return; 601 if ((style & DWT.PUSH) is 0) return;
473 // int window = OS.GetControlOwner (handle); 602 // NSWindow window = view.window();
474 // OS.SetWindowDefaultButton (window, value ? handle : 0); 603 // NSButtonCell cell = null;
604 // if (value) {
605 // cell = new NSButtonCell(((NSButton)view).cell());
606 // }
607 // window.setDefaultButtonCell(cell);
608 }
609
610 void setFont (NSFont font) {
611 if (text !is null) {
612 ((NSButton)view).setAttributedTitle(createString());
613 }
475 } 614 }
476 615
477 void setForeground (float [] color) { 616 void setForeground (float [] color) {
478 (cast(NSButton)view).setAttributedTitle(createString()); 617 (cast(NSButton)view).setAttributedTitle(createString());
479 } 618 }
480 619
620 /**
621 * Sets the grayed state of the receiver. This state change
622 * only applies if the control was created with the DWT.CHECK
623 * style.
624 *
625 * @param grayed the new grayed 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 * @since 3.4
633 */
481 public void setGrayed(bool grayed) { 634 public void setGrayed(bool grayed) {
482 checkWidget (); 635 checkWidget ();
483 if ((style & DWT.CHECK) is 0) return; 636 if ((style & DWT.CHECK) is 0) return;
484 bool checked = getSelection (); 637 bool checked = getSelection ();
485 this.grayed = grayed; 638 this.grayed = grayed;
511 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 664 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
512 * </ul> 665 * </ul>
513 */ 666 */
514 public void setImage (Image image) { 667 public void setImage (Image image) {
515 checkWidget(); 668 checkWidget();
516 if ((style & DWT.ARROW) !is 0) return;
517 if (image !is null && image.isDisposed ()) { 669 if (image !is null && image.isDisposed ()) {
518 error (DWT.ERROR_INVALID_ARGUMENT); 670 error (DWT.ERROR_INVALID_ARGUMENT);
519 } 671 }
672 if ((style & DWT.ARROW) !is 0) return;
520 this.image = image; 673 this.image = image;
521 (cast(NSButton)view).setImage(image.handle); 674 (cast(NSButton)view).setImage(image !is null ? image.handle : null);
522 } 675 }
523 676
524 bool setRadioSelection (bool value){ 677 bool setRadioSelection (bool value){
525 if ((style & DWT.RADIO) is 0) return false; 678 if ((style & DWT.RADIO) is 0) return false;
526 if (getSelection () !is value) { 679 if (getSelection () !is value) {
595 (cast(NSButton)view).setAttributedTitle(createString()); 748 (cast(NSButton)view).setAttributedTitle(createString());
596 } 749 }
597 750
598 int traversalCode (int key, NSEvent theEvent) { 751 int traversalCode (int key, NSEvent theEvent) {
599 int code = super.traversalCode (key, theEvent); 752 int code = super.traversalCode (key, theEvent);
753 if ((style & DWT.ARROW) !is 0) code &= ~(DWT.TRAVERSE_TAB_NEXT | DWT.TRAVERSE_TAB_PREVIOUS);
600 if ((style & DWT.RADIO) !is 0) code |= DWT.TRAVERSE_ARROW_NEXT | DWT.TRAVERSE_ARROW_PREVIOUS; 754 if ((style & DWT.RADIO) !is 0) code |= DWT.TRAVERSE_ARROW_NEXT | DWT.TRAVERSE_ARROW_PREVIOUS;
601 return code; 755 return code;
602 } 756 }
603 757
604 } 758 }