Mercurial > projects > dwt-mac
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 } |