Mercurial > projects > dwt-mac
view dwt/widgets/Control.d @ 145:1324fd764db4
Fixes #26
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Sat, 06 Jun 2009 23:02:40 +0200 |
parents | 52d360200ae4 |
children | e91dcbf77cc7 |
line wrap: on
line source
/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * * Port to the D programming language: * Jacob Carlborg <doob@me.com> *******************************************************************************/ module dwt.widgets.Control; import dwt.DWT; import dwt.DWTException; import dwt.accessibility.ACC; import dwt.accessibility.Accessible; import dwt.events.ControlListener; import dwt.events.DragDetectListener; import dwt.events.FocusListener; import dwt.events.HelpListener; import dwt.events.KeyListener; import dwt.events.MenuDetectListener; import dwt.events.MouseEvent; import dwt.events.MouseListener; import dwt.events.MouseMoveListener; import dwt.events.MouseTrackListener; import dwt.events.MouseWheelListener; import dwt.events.PaintListener; import dwt.events.TraverseListener; import dwt.graphics.Color; import dwt.graphics.Cursor; import dwt.graphics.Drawable; import dwt.graphics.Font; import dwt.graphics.GC; import dwt.graphics.GCData; import dwt.graphics.Image; import dwt.graphics.Point; import dwt.graphics.Rectangle; import dwt.graphics.Region; import dwt.internal.cocoa.NSApplication; import dwt.internal.cocoa.NSArray; import dwt.internal.cocoa.NSAttributedString; import dwt.internal.cocoa.NSBezierPath; import dwt.internal.cocoa.NSColor; import dwt.internal.cocoa.NSControl; import dwt.internal.cocoa.NSDate; import dwt.internal.cocoa.NSEvent; import dwt.internal.cocoa.NSFont; import dwt.internal.cocoa.NSGraphicsContext; import dwt.internal.cocoa.NSInputManager; import dwt.internal.cocoa.NSMutableArray; import dwt.internal.cocoa.NSPoint; import dwt.internal.cocoa.NSRect; import dwt.internal.cocoa.NSSize; import dwt.internal.cocoa.NSString; import dwt.internal.cocoa.NSView; import dwt.internal.cocoa.OS; import cocoa = dwt.internal.cocoa.id; import tango.core.Thread; import dwt.dwthelper.utils; import dwt.dwthelper.System; import Carbon = dwt.internal.c.Carbon; import dwt.internal.objc.cocoa.Cocoa; import objc = dwt.internal.objc.runtime; import dwt.widgets.Composite; import dwt.widgets.Decorations; import dwt.widgets.Display; import dwt.widgets.Event; import dwt.widgets.Listener; import dwt.widgets.Menu; import dwt.widgets.Monitor; import dwt.widgets.Shell; import dwt.widgets.TypedListener; import dwt.widgets.Widget; /** * Control is the abstract superclass of all windowed user interface classes. * <p> * <dl> * <dt><b>Styles:</b> * <dd>BORDER</dd> * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd> * <dt><b>Events:</b> * <dd>DragDetect, FocusIn, FocusOut, Help, KeyDown, KeyUp, MenuDetect, MouseDoubleClick, MouseDown, MouseEnter, * MouseExit, MouseHover, MouseUp, MouseMove, Move, Paint, Resize, Traverse</dd> * </dl> * </p><p> * Only one of LEFT_TO_RIGHT or RIGHT_TO_LEFT may be specified. * </p><p> * IMPORTANT: This class is intended to be subclassed <em>only</em> * within the DWT implementation. * </p> * * @see <a href="http://www.eclipse.org/swt/snippets/#control">Control snippets</a> * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: ControlExample</a> * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> */ public abstract class Control : Widget , Drawable { alias Widget.setInputState setInputState; /** * the handle to the OS resource * (Warning: This field is platform dependent) * <p> * <b>IMPORTANT:</b> This field is <em>not</em> part of the DWT * public API. It is marked public only so that it can be shared * within the packages provided by DWT. It is not available on all * platforms and should never be accessed from application code. * </p> */ public NSView view; Composite parent; String toolTipText; Object layoutData; int drawCount; // int visibleRgn; Menu menu; Color foreground, background; Image backgroundImage; Font font; Cursor cursor; Region region; // GCData gcs[]; Accessible accessible; // static final String RESET_VISIBLE_REGION = "dwt.internal.resetVisibleRegion"; this () { /* Do nothing */ } /** * Constructs a new instance of this class given its parent * and a style value describing its behavior and appearance. * <p> * The style value is either one of the style constants defined in * class <code>DWT</code> which is applicable to instances of this * class, or must be built by <em>bitwise OR</em>'ing together * (that is, using the <code>int</code> "|" operator) two or more * of those <code>DWT</code> style constants. The class description * lists the style constants that are applicable to the class. * Style bits are also inherited from superclasses. * </p> * * @param parent a composite control which will be the parent of the new instance (cannot be null) * @param style the style of control to construct * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> * </ul> * * @see DWT#BORDER * @see Widget#checkSubclass * @see Widget#getStyle */ public this (Composite parent, int style) { super (parent, style); this.parent = parent; createWidget (); } objc.id accessibilityActionNames(objc.id id, objc.SEL sel) { if (accessible !is null) { NSArray returnValue = accessible.internal_accessibilityActionNames(ACC.CHILDID_SELF); if (returnValue !is null) return returnValue.id; } return super.accessibilityActionNames(id, sel); } objc.id accessibilityAttributeNames(objc.id id, objc.SEL sel) { if (id is view.id || (cast(NSControl)view && (cast(NSControl)view).cell() !is null && (cast(NSControl)view).cell().id is id)) { if (accessible !is null) { // First, see if the accessible is going to define a set of attributes for the control. // If it does, return that. NSArray returnValue = accessible.internal_accessibilityAttributeNames(ACC.CHILDID_SELF); if (returnValue !is null) return returnValue.id; // If not, see if it will override or augment the standard list. // Help, title, and description can be overridden. NSMutableArray extraAttributes = NSMutableArray.arrayWithCapacity(3); extraAttributes.addObject(OS.NSAccessibilityHelpAttribute); extraAttributes.addObject(OS.NSAccessibilityDescriptionAttribute); extraAttributes.addObject(OS.NSAccessibilityTitleAttribute); for (int i = extraAttributes.count() - 1; i >= 0; i--) { NSString attribute = new NSString(extraAttributes.objectAtIndex(i).id); if (accessible.internal_accessibilityAttributeValue(attribute, ACC.CHILDID_SELF) is null) { extraAttributes.removeObjectAtIndex(i); } } if (extraAttributes.count() > 0) { objc.id superResult = super.accessibilityAttributeNames(id, sel); NSArray baseAttributes = new NSArray(superResult); NSMutableArray mutableAttributes = NSMutableArray.arrayWithCapacity(baseAttributes.count() + 1); mutableAttributes.addObjectsFromArray(baseAttributes); for (int i = 0; i < extraAttributes.count(); i++) { cocoa.id currAttribute = extraAttributes.objectAtIndex(i); if (!mutableAttributes.containsObject(currAttribute)) { mutableAttributes.addObject(currAttribute); } } return mutableAttributes.id; } } } return super.accessibilityAttributeNames(id, sel); } objc.id accessibilityParameterizedAttributeNames(objc.id id, objc.SEL sel) { if (id is view.id || (cast(NSControl)view && (cast(NSControl)view).cell() !is null && (cast(NSControl)view).cell().id is id)) { if (accessible !is null) { NSArray returnValue = accessible.internal_accessibilityParameterizedAttributeNames(ACC.CHILDID_SELF); if (returnValue !is null) return returnValue.id; } } return super.accessibilityParameterizedAttributeNames(id, sel); } bool accessibilityIsAttributeSettable(objc.id id, objc.SEL sel, objc.id arg0) { // TODO: Carbon didn't support setting attributes, so for now Cocoa doesn't as well. // NSString attribute = new NSString(arg0); // // if (accessible !is null) { // return accessible.accessibilityIsAttributeSettable(attribute, ACC.CHILDID_SELF); // } // // return super.accessibilityIsAttributeSettable(id, sel, arg0); return false; } objc.id accessibilityFocusedUIElement(objc.id id, objc.SEL sel) { cocoa.id returnValue = null; if (id is view.id || (cast(NSControl)view && (cast(NSControl)view).cell() !is null && (cast(NSControl)view).cell().id is id)) { if (accessible !is null) { returnValue = accessible.internal_accessibilityFocusedUIElement(ACC.CHILDID_SELF); } } // If we had an accessible and it didn't handle the attribute request, let the // superclass handle it. if (returnValue is null) return super.accessibilityFocusedUIElement(id, sel); else return returnValue.id; } objc.id accessibilityHitTest(objc.id id, objc.SEL sel, NSPoint point) { cocoa.id returnValue = null; if (id is view.id || (cast(NSControl)view && (cast(NSControl)view).cell() !is null && (cast(NSControl)view).cell().id is id)) { if (accessible !is null) { returnValue = accessible.internal_accessibilityHitTest(point, ACC.CHILDID_SELF); } } // If we had an accessible and it didn't handle the attribute request, let the // superclass handle it. if (returnValue is null) return super.accessibilityHitTest(id, sel, point); else return returnValue.id; } objc.id accessibilityAttributeValue(objc.id id, objc.SEL sel, objc.id arg0) { NSString attribute = new NSString(arg0); objc.id returnValue = null; cocoa.id returnObject = null; if (accessible !is null) { returnObject = accessible.internal_accessibilityAttributeValue(attribute, ACC.CHILDID_SELF); } // If we had an accessible and it didn't handle the attribute request, let the // superclass handle it. if (returnObject is null) { returnValue = super.accessibilityAttributeValue(id, sel, arg0); } else { returnValue = returnObject.id; } return returnValue; } objc.id accessibilityAttributeValue_forParameter(objc.id id, objc.SEL sel, objc.id arg0, objc.id arg1) { NSString attribute = new NSString(arg0); cocoa.id returnValue = null; if (accessible !is null) { cocoa.id parameter = new cocoa.id(arg1); returnValue = accessible.internal_accessibilityAttributeValue_forParameter(attribute, parameter, ACC.CHILDID_SELF); } // If we had an accessible and it didn't handle the attribute request, let the // superclass handle it. if (returnValue is null) return super.accessibilityAttributeValue_forParameter(id, sel, arg0, arg1); else return returnValue.id; } /** * Adds the listener to the collection of listeners who will * be notified when the control is moved or resized, by sending * it one of the messages defined in the <code>ControlListener</code> * interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see ControlListener * @see #removeControlListener */ public void addControlListener(ControlListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); TypedListener typedListener = new TypedListener (listener); addListener (DWT.Resize,typedListener); addListener (DWT.Move,typedListener); } /** * Adds the listener to the collection of listeners who will * be notified when a drag gesture occurs, by sending it * one of the messages defined in the <code>DragDetectListener</code> * interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see DragDetectListener * @see #removeDragDetectListener * * @since 3.3 */ public void addDragDetectListener (DragDetectListener listener) { checkWidget (); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); TypedListener typedListener = new TypedListener (listener); addListener (DWT.DragDetect,typedListener); } /** * Adds the listener to the collection of listeners who will * be notified when the control gains or loses focus, by sending * it one of the messages defined in the <code>FocusListener</code> * interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see FocusListener * @see #removeFocusListener */ public void addFocusListener(FocusListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); TypedListener typedListener = new TypedListener (listener); addListener(DWT.FocusIn,typedListener); addListener(DWT.FocusOut,typedListener); } /** * Adds the listener to the collection of listeners who will * be notified when help events are generated for the control, * by sending it one of the messages defined in the * <code>HelpListener</code> interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see HelpListener * @see #removeHelpListener */ public void addHelpListener (HelpListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); TypedListener typedListener = new TypedListener (listener); addListener (DWT.Help, typedListener); } /** * Adds the listener to the collection of listeners who will * be notified when keys are pressed and released on the system keyboard, by sending * it one of the messages defined in the <code>KeyListener</code> * interface. * <p> * When a key listener is added to a control, the control * will take part in widget traversal. By default, all * traversal keys (such as the tab key and so on) are * delivered to the control. In order for a control to take * part in traversal, it should listen for traversal events. * Otherwise, the user can traverse into a control but not * out. Note that native controls such as table and tree * implement key traversal in the operating system. It is * not necessary to add traversal listeners for these controls, * unless you want to override the default traversal. * </p> * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see KeyListener * @see #removeKeyListener */ public void addKeyListener(KeyListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); TypedListener typedListener = new TypedListener (listener); addListener(DWT.KeyUp,typedListener); addListener(DWT.KeyDown,typedListener); } /** * Adds the listener to the collection of listeners who will * be notified when the platform-specific context menu trigger * has occurred, by sending it one of the messages defined in * the <code>MenuDetectListener</code> interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see MenuDetectListener * @see #removeMenuDetectListener * * @since 3.3 */ public void addMenuDetectListener (MenuDetectListener listener) { checkWidget (); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); TypedListener typedListener = new TypedListener (listener); addListener (DWT.MenuDetect, typedListener); } /** * Adds the listener to the collection of listeners who will * be notified when mouse buttons are pressed and released, by sending * it one of the messages defined in the <code>MouseListener</code> * interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see MouseListener * @see #removeMouseListener */ public void addMouseListener(MouseListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); TypedListener typedListener = new TypedListener (listener); addListener(DWT.MouseDown,typedListener); addListener(DWT.MouseUp,typedListener); addListener(DWT.MouseDoubleClick,typedListener); } /** * Adds the listener to the collection of listeners who will * be notified when the mouse passes or hovers over controls, by sending * it one of the messages defined in the <code>MouseTrackListener</code> * interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see MouseTrackListener * @see #removeMouseTrackListener */ public void addMouseTrackListener (MouseTrackListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); TypedListener typedListener = new TypedListener (listener); addListener (DWT.MouseEnter,typedListener); addListener (DWT.MouseExit,typedListener); addListener (DWT.MouseHover,typedListener); } /** * Adds the listener to the collection of listeners who will * be notified when the mouse moves, by sending it one of the * messages defined in the <code>MouseMoveListener</code> * interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see MouseMoveListener * @see #removeMouseMoveListener */ public void addMouseMoveListener(MouseMoveListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); TypedListener typedListener = new TypedListener (listener); addListener(DWT.MouseMove,typedListener); } /** * Adds the listener to the collection of listeners who will * be notified when the mouse wheel is scrolled, by sending * it one of the messages defined in the * <code>MouseWheelListener</code> interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see MouseWheelListener * @see #removeMouseWheelListener * * @since 3.3 */ public void addMouseWheelListener (MouseWheelListener listener) { checkWidget (); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); TypedListener typedListener = new TypedListener (listener); addListener (DWT.MouseWheel, typedListener); } /** * Adds the listener to the collection of listeners who will * be notified when the receiver needs to be painted, by sending it * one of the messages defined in the <code>PaintListener</code> * interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see PaintListener * @see #removePaintListener */ public void addPaintListener(PaintListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); TypedListener typedListener = new TypedListener (listener); addListener(DWT.Paint,typedListener); } /** * Adds the listener to the collection of listeners who will * be notified when traversal events occur, by sending it * one of the messages defined in the <code>TraverseListener</code> * interface. * * @param listener the listener which should be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see TraverseListener * @see #removeTraverseListener */ public void addTraverseListener (TraverseListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); TypedListener typedListener = new TypedListener (listener); addListener (DWT.Traverse,typedListener); } void checkBackground () { Shell shell = getShell (); if (this is shell) return; state &= ~PARENT_BACKGROUND; Composite composite = parent; do { int mode = composite.backgroundMode; if (mode !is 0) { if (mode is DWT.INHERIT_DEFAULT) { Control control = this; do { if ((control.state & THEME_BACKGROUND) is 0) { return; } control = control.parent; } while (control !is composite); } state |= PARENT_BACKGROUND; return; } if (composite is shell) break; composite = composite.parent; } while (true); } void checkBuffered () { style |= DWT.DOUBLE_BUFFERED; } /** * Returns the preferred size of the receiver. * <p> * The <em>preferred size</em> of a control is the size that it would * best be displayed at. The width hint and height hint arguments * allow the caller to ask a control questions such as "Given a particular * width, how high does the control need to be to show all of the contents?" * To indicate that the caller does not wish to constrain a particular * dimension, the constant <code>DWT.DEFAULT</code> is passed for the hint. * </p> * * @param wHint the width hint (can be <code>DWT.DEFAULT</code>) * @param hHint the height hint (can be <code>DWT.DEFAULT</code>) * @return the preferred size of the control * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see Layout * @see #getBorderWidth * @see #getBounds * @see #getSize * @see #pack(bool) * @see "computeTrim, getClientArea for controls that implement them" */ public Point computeSize (int wHint, int hHint) { return computeSize (wHint, hHint, true); } /** * Returns the preferred size of the receiver. * <p> * The <em>preferred size</em> of a control is the size that it would * best be displayed at. The width hint and height hint arguments * allow the caller to ask a control questions such as "Given a particular * width, how high does the control need to be to show all of the contents?" * To indicate that the caller does not wish to constrain a particular * dimension, the constant <code>DWT.DEFAULT</code> is passed for the hint. * </p><p> * If the changed flag is <code>true</code>, it indicates that the receiver's * <em>contents</em> have changed, therefore any caches that a layout manager * containing the control may have been keeping need to be flushed. When the * control is resized, the changed flag will be <code>false</code>, so layout * manager caches can be retained. * </p> * * @param wHint the width hint (can be <code>DWT.DEFAULT</code>) * @param hHint the height hint (can be <code>DWT.DEFAULT</code>) * @param changed <code>true</code> if the control's contents have changed, and <code>false</code> otherwise * @return the preferred size of the control. * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see Layout * @see #getBorderWidth * @see #getBounds * @see #getSize * @see #pack(bool) * @see "computeTrim, getClientArea for controls that implement them" */ public Point computeSize (int wHint, int hHint, bool changed) { checkWidget(); int width = DEFAULT_WIDTH; int height = DEFAULT_HEIGHT; if (cast(NSControl) topView()) { NSRect oldRect = topView().frame(); (cast(NSControl)topView()).sizeToFit(); NSRect newRect = topView().frame(); topView().setFrame (oldRect); width = cast(int) newRect.width; height = cast(int)newRect.height; } int border = getBorderWidth (); if (wHint !is DWT.DEFAULT) { width = wHint; width += border * 2; } if (hHint !is DWT.DEFAULT) { height = hHint; height += border * 2; } return new Point (width, height); } Control computeTabGroup () { if (isTabGroup()) return this; return parent.computeTabGroup (); } Control[] computeTabList() { if (isTabGroup()) { if (getVisible() && getEnabled()) { return [this]; } } return new Control[0]; } Control computeTabRoot () { Control[] tabList = parent._getTabList(); if (tabList !is null) { int index = 0; while (index < tabList.length) { if (tabList [index] is this) break; index++; } if (index is tabList.length) { if (isTabGroup ()) return this; } } return parent.computeTabRoot (); } NSView contentView () { return view; } void createWidget () { state |= DRAG_DETECT; checkOrientation (parent); super.createWidget (); checkBackground (); checkBuffered (); setDefaultFont (); setZOrder (); } Color defaultBackground () { return display.getSystemColor (DWT.COLOR_WIDGET_BACKGROUND); } Font defaultFont () { //TODO - Controls only, does this leak? if (cast(NSControl) view) { NSFont nsFont = (cast(NSControl)view).font (); if (nsFont !is null) { return Font.cocoa_new (display, nsFont); } } return display.getSystemFont (); } Color defaultForeground () { return display.getSystemColor (DWT.COLOR_WIDGET_FOREGROUND); } void deregister () { super.deregister (); display.removeWidget (view); } void destroyWidget () { NSView view = topView (); view.removeFromSuperview (); releaseHandle (); } void doCommandBySelector (objc.id id, objc.SEL sel, objc.SEL selector) { if (view.window ().firstResponder ().id is id) { NSEvent nsEvent = NSApplication.sharedApplication ().currentEvent (); if (nsEvent !is null && nsEvent.type () is OS.NSKeyDown) { // TODO is this workaround ok? /* * Feature in Cocoa. Pressing Alt+UpArrow invokes doCommandBySelector * twice, with selectors moveBackward and moveToBeginningOfParagraph * (Alt+DownArrow behaves similarly). In order to avoid sending * multiple events for these keys, do not send a KeyDown if the * selector is moveToBeginningOfParagraph or moveToEndOfParagraph. */ if (selector is OS.sel_moveToBeginningOfParagraph_|| selector is OS.sel_moveToEndOfParagraph_) return; bool [] consume = new bool [1]; if (translateTraversal (nsEvent.keyCode (), nsEvent, consume)) return; if (isDisposed ()) return; if (!sendKeyEvent (nsEvent, DWT.KeyDown)) return; if (consume [0]) return; } if ((state & CANVAS) !is 0) return; } super.doCommandBySelector (id, sel, selector); } /** * Detects a drag and drop gesture. This method is used * to detect a drag gesture when called from within a mouse * down listener. * * <p>By default, a drag is detected when the gesture * occurs anywhere within the client area of a control. * Some controls, such as tables and trees, override this * behavior. In addition to the operating system specific * drag gesture, they require the mouse to be inside an * item. Custom widget writers can use <code>setDragDetect</code> * to disable the default detection, listen for mouse down, * and then call <code>dragDetect()</code> from within the * listener to conditionally detect a drag. * </p> * * @param event the mouse down event * * @return <code>true</code> if the gesture occurred, and <code>false</code> otherwise. * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT when the event is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see DragDetectListener * @see #addDragDetectListener * * @see #getDragDetect * @see #setDragDetect * * @since 3.3 */ public bool dragDetect (Event event) { checkWidget (); if (event is null) error (DWT.ERROR_NULL_ARGUMENT); return dragDetect (); } /** * Detects a drag and drop gesture. This method is used * to detect a drag gesture when called from within a mouse * down listener. * * <p>By default, a drag is detected when the gesture * occurs anywhere within the client area of a control. * Some controls, such as tables and trees, override this * behavior. In addition to the operating system specific * drag gesture, they require the mouse to be inside an * item. Custom widget writers can use <code>setDragDetect</code> * to disable the default detection, listen for mouse down, * and then call <code>dragDetect()</code> from within the * listener to conditionally detect a drag. * </p> * * @param event the mouse down event * * @return <code>true</code> if the gesture occurred, and <code>false</code> otherwise. * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT when the event is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see DragDetectListener * @see #addDragDetectListener * * @see #getDragDetect * @see #setDragDetect * * @since 3.3 */ public bool dragDetect (MouseEvent event) { checkWidget (); if (event is null) error (DWT.ERROR_NULL_ARGUMENT); return dragDetect(); } bool dragDetect () { NSApplication application = NSApplication.sharedApplication(); NSEvent event = application.nextEventMatchingMask(OS.NSLeftMouseDraggedMask, NSDate.dateWithTimeIntervalSinceNow(0.2), OS.NSDefaultRunLoopMode, false); return (event !is null); } bool dragDetect (int x, int y, bool filter, bool [] consume) { return dragDetect(); } bool drawGripper (int x, int y, int width, int height, bool vertical) { return false; } void drawWidget (objc.id id, NSRect rect) { if (id !is view.id) return; if (!hooks (DWT.Paint) && !filters (DWT.Paint)) return; /* Send paint event */ GCData data = new GCData (); data.paintRectStruct = rect; data.paintRect = &data.paintRectStruct; GC gc = GC.cocoa_new (this, data); Event event = new Event (); event.gc = gc; event.x = cast(int)rect.x; event.y = cast(int)rect.y; event.width = cast(int)rect.width; event.height = cast(int)rect.height; sendEvent (DWT.Paint, event); event.gc = null; gc.dispose (); } void enableWidget (bool enabled) { if (cast(NSControl) view) { (cast(NSControl)view).setEnabled(enabled); } } void fillBackground (NSView view, NSGraphicsContext context, NSRect rect) { Control control = findBackgroundControl(); if (control is null) control = this; Image image = control.backgroundImage; if (image !is null && !image.isDisposed()) { context.saveGraphicsState(); NSColor.colorWithPatternImage(image.handle).setFill(); NSPoint phase = NSPoint(); NSView controlView = control.view; NSView contentView = controlView.window().contentView(); phase = controlView.convertPoint_toView_(phase, contentView); phase.y = contentView.bounds().height - phase.y; context.setPatternPhase(phase); NSBezierPath.fillRect(rect); context.restoreGraphicsState(); return; } Color background = control.getBackgroundColor (); if (background !is null && !background.isDisposed ()) { Carbon.CGFloat [] color = background.handle; context.saveGraphicsState(); NSColor.colorWithDeviceRed(color [0], color [1], color [2], getThemeAlpha()).setFill(); NSBezierPath.fillRect(rect); context.restoreGraphicsState(); return; } } Cursor findCursor () { if (cursor !is null) return cursor; return parent.findCursor (); } Control findBackgroundControl () { if (backgroundImage !is null || background !is null) return this; return (state & PARENT_BACKGROUND) !is 0 ? parent.findBackgroundControl () : null; } Menu [] findMenus (Control control) { if (menu !is null && this !is control) return [menu]; return new Menu [0]; } void fixChildren (Shell newShell, Shell oldShell, Decorations newDecorations, Decorations oldDecorations, Menu [] menus) { oldShell.fixShell (newShell, this); oldDecorations.fixDecorations (newDecorations, this, menus); } void fixFocus (Control focusControl) { Shell shell = getShell (); Control control = this; while (control !is shell && (control = control.parent) !is null) { if (control.setFocus ()) return; } shell.setSavedFocus (focusControl); // int window = OS.GetControlOwner (handle); // OS.ClearKeyboardFocus (window); } void flagsChanged (objc.id id, objc.SEL sel, objc.id theEvent) { if (view.window ().firstResponder ().id is id) { if ((state & SAFARI_EVENTS_FIX) is 0) { int mask = 0; NSEvent nsEvent = new NSEvent (theEvent); NSUInteger modifiers = nsEvent.modifierFlags (); int keyCode = Display.translateKey (nsEvent.keyCode ()); switch (keyCode) { case DWT.ALT: mask = OS.NSAlternateKeyMask; break; case DWT.CONTROL: mask = OS.NSControlKeyMask; break; case DWT.COMMAND: mask = OS.NSCommandKeyMask; break; case DWT.SHIFT: mask = OS.NSShiftKeyMask; break; case DWT.CAPS_LOCK: Event event = new Event(); event.keyCode = keyCode; setInputState (event, nsEvent, DWT.KeyDown); sendKeyEvent (DWT.KeyDown, event); setInputState (event, nsEvent, DWT.KeyUp); sendKeyEvent (DWT.KeyUp, event); break; default: } if (mask !is 0) { int type = (mask & modifiers) !is 0 ? DWT.KeyDown : DWT.KeyUp; Event event = new Event(); event.keyCode = keyCode; setInputState (event, nsEvent, type); if (!sendKeyEvent (type, event)) return; } } } super.flagsChanged (id, sel, theEvent); } NSView focusView () { return view; } /** * Forces the receiver to have the <em>keyboard focus</em>, causing * all keyboard events to be delivered to it. * * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to. * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #setFocus */ public bool forceFocus () { checkWidget(); Decorations shell = menuShell (); shell.setSavedFocus (this); if (!isEnabled () || !isVisible ()/* || !isActive ()*/) return false; if (isFocusControl ()) return true; shell.setSavedFocus (null); shell.bringToTop (false); if (isDisposed ()) return false; bool result = view.window ().makeFirstResponder (focusView ()); if (isDisposed ()) return false; shell.setSavedFocus (this); return result; } /** * Returns the accessible object for the receiver. * If this is the first time this object is requested, * then the object is created and returned. * * @return the accessible object * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see Accessible#addAccessibleListener * @see Accessible#addAccessibleControlListener * * @since 2.0 */ public Accessible getAccessible () { checkWidget (); if (accessible is null) accessible = new_Accessible (this); return accessible; } /** * Returns the receiver's background color. * * @return the background color * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Color getBackground () { checkWidget(); Control control = findBackgroundControl (); if (control is null) control = this; return control.getBackgroundColor (); } Color getBackgroundColor () { return background !is null ? background : defaultBackground (); } /** * Returns the receiver's background image. * * @return the background image * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 3.2 */ public Image getBackgroundImage () { checkWidget(); Control control = findBackgroundControl (); if (control is null) control = this; return control.backgroundImage; } /** * Returns the receiver's border width. * * @return the border width * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public int getBorderWidth () { checkWidget(); return 0; } /** * Returns a rectangle describing the receiver's size and location * relative to its parent (or its display if its parent is null), * unless the receiver is a shell. In this case, the location is * relative to the display. * * @return the receiver's bounding rectangle * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Rectangle getBounds () { checkWidget(); NSRect rect = topView().frame(); return new Rectangle(cast(int)rect.x, cast(int)rect.y, cast(int)rect.width, cast(int)rect.height); } /** * Returns <code>true</code> if the receiver is detecting * drag gestures, and <code>false</code> otherwise. * * @return the receiver's drag detect state * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 3.3 */ public bool getDragDetect () { checkWidget (); return (state & DRAG_DETECT) !is 0; } NSBezierPath getClipping() { return parent.getClipping (); } /** * Returns the receiver's cursor, or null if it has not been set. * <p> * When the mouse pointer passes over a control its appearance * is changed to match the control's cursor. * </p> * * @return the receiver's cursor or <code>null</code> * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 3.3 */ public Cursor getCursor () { checkWidget(); return cursor; } /** * Returns <code>true</code> if the receiver is enabled, and * <code>false</code> otherwise. A disabled control is typically * not selectable from the user interface and draws with an * inactive or "grayed" look. * * @return the receiver's enabled state * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #isEnabled */ public bool getEnabled () { checkWidget(); return (state & DISABLED) is 0; } /** * Returns the font that the receiver will use to paint textual information. * * @return the receiver's font * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Font getFont () { checkWidget(); return font !is null ? font : defaultFont (); } /** * Returns the foreground color that the receiver will use to draw. * * @return the receiver's foreground color * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Color getForeground () { checkWidget(); return getForegroundColor (); } Color getForegroundColor () { return foreground !is null ? foreground: defaultForeground (); } /** * Returns layout data which is associated with the receiver. * * @return the receiver's layout data * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Object getLayoutData () { checkWidget(); return layoutData; } /** * Returns a point describing the receiver's location relative * to its parent (or its display if its parent is null), unless * the receiver is a shell. In this case, the point is * relative to the display. * * @return the receiver's location * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Point getLocation () { checkWidget(); NSRect rect = topView().frame(); return new Point(cast(int)rect.x, cast(int)rect.y); } /** * Returns the receiver's pop up menu if it has one, or null * if it does not. All controls may optionally have a pop up * menu that is displayed when the user requests one for * the control. The sequence of key strokes, button presses * and/or button releases that are used to request a pop up * menu is platform specific. * * @return the receiver's menu * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Menu getMenu () { checkWidget(); return menu; } int getMininumHeight () { return 0; } /** * Returns the receiver's monitor. * * @return the receiver's monitor * * @since 3.0 */ public dwt.widgets.Monitor.Monitor getMonitor () { checkWidget(); dwt.widgets.Monitor.Monitor [] monitors = display.getMonitors (); if (monitors.length is 1) return monitors [0]; int index = -1, value = -1; Rectangle bounds = getBounds (); if (this !is getShell ()) { bounds = display.map (this.parent, null, bounds); } for (int i=0; i<monitors.length; i++) { Rectangle rect = bounds.intersection (monitors [i].getBounds ()); int area = rect.width * rect.height; if (area > 0 && area > value) { index = i; value = area; } } if (index >= 0) return monitors [index]; int centerX = bounds.x + bounds.width / 2, centerY = bounds.y + bounds.height / 2; for (int i=0; i<monitors.length; i++) { Rectangle rect = monitors [i].getBounds (); int x = centerX < rect.x ? rect.x - centerX : centerX > rect.x + rect.width ? centerX - rect.x - rect.width : 0; int y = centerY < rect.y ? rect.y - centerY : centerY > rect.y + rect.height ? centerY - rect.y - rect.height : 0; int distance = x * x + y * y; if (index is -1 || distance < value) { index = i; value = distance; } } return monitors [index]; } /** * Returns the receiver's parent, which must be a <code>Composite</code> * or null when the receiver is a shell that was created with null or * a display for a parent. * * @return the receiver's parent * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Composite getParent () { checkWidget(); return parent; } Control [] getPath () { int count = 0; Shell shell = getShell (); Control control = this; while (control !is shell) { count++; control = control.parent; } control = this; Control [] result = new Control [count]; while (control !is shell) { result [--count] = control; control = control.parent; } return result; } /** * Returns the region that defines the shape of the control, * or null if the control has the default shape. * * @return the region that defines the shape of the shell (or null) * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 3.4 */ public Region getRegion () { checkWidget (); return region; } /** * Returns the receiver's shell. For all controls other than * shells, this simply returns the control's nearest ancestor * shell. Shells return themselves, even if they are children * of other shells. * * @return the receiver's shell * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #getParent */ public Shell getShell () { checkWidget(); return parent.getShell (); } /** * Returns a point describing the receiver's size. The * x coordinate of the result is the width of the receiver. * The y coordinate of the result is the height of the * receiver. * * @return the receiver's size * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Point getSize () { checkWidget(); NSRect rect = topView().frame(); return new Point(cast(int)rect.width, cast(int)rect.height); } float getThemeAlpha () { return 1 * parent.getThemeAlpha (); } /** * Returns the receiver's tool tip text, or null if it has * not been set. * * @return the receiver's tool tip text * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public String getToolTipText () { checkWidget(); return toolTipText; } /** * Returns <code>true</code> if the receiver is visible, and * <code>false</code> otherwise. * <p> * If one of the receiver's ancestors is not visible or some * other condition makes the receiver not visible, this method * may still indicate that it is considered visible even though * it may not actually be showing. * </p> * * @return the receiver's visibility state * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public bool getVisible () { checkWidget(); return (state & HIDDEN) is 0; } bool hasBorder () { return (style & DWT.BORDER) !is 0; } bool hasFocus () { return (view.window().firstResponder().id is view.id); } objc.id hitTest (objc.id id, objc.SEL sel, NSPoint point) { if ((state & DISABLED) !is 0) return null; return super.hitTest(id, sel, point); } bool insertText (objc.id id, objc.SEL sel, objc.id string) { if (view.window ().firstResponder ().id is id) { NSEvent nsEvent = NSApplication.sharedApplication ().currentEvent (); if (nsEvent !is null && nsEvent.type () is OS.NSKeyDown) { NSString str = new NSString (string); if (str.isKindOfClass (cast(objc.Class)OS.objc_getClass ("NSAttributedString"))) { str = (new NSAttributedString (string)).string (); } NSUInteger length = str.length (); wchar[] buffer = new wchar [length]; str.getCharacters(buffer.ptr); for (int i = 0; i < buffer.length; i++) { Event event = new Event (); if (length is 1) setKeyState (event, DWT.KeyDown, nsEvent); event.character = buffer [i]; if (!sendKeyEvent (nsEvent, DWT.KeyDown)) return false; } } if ((state & CANVAS) !is 0) return true; } return super.insertText (id, sel, string); } /** * Invokes platform specific functionality to allocate a new GC handle. * <p> * <b>IMPORTANT:</b> This method is <em>not</em> part of the public * API for <code>Control</code>. It is marked public only so that it * can be shared within the packages provided by DWT. It is not * available on all platforms, and should never be called from * application code. * </p> * * @param data the platform specific GC data * @return the platform specific GC handle */ public objc.id internal_new_GC (GCData data) { checkWidget(); objc.id context = null; if (data !is null && data.paintRect !is null) { context = NSGraphicsContext.currentContext().id; } else { NSGraphicsContext graphicsContext = NSGraphicsContext.graphicsContextWithWindow (view.window ()); display.addContext (graphicsContext); context = graphicsContext.id; } if (data !is null) { int mask = DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT; if ((data.style & mask) is 0) { data.style |= style & (mask | DWT.MIRRORED); } data.device = display; data.thread = display.thread; data.view = view; data.foreground = getForegroundColor ().handle; Control control = findBackgroundControl (); if (control is null) control = this; data.background = control.getBackgroundColor ().handle; data.font = font !is null ? font : defaultFont (); } return context; } /** * Invokes platform specific functionality to dispose a GC handle. * <p> * <b>IMPORTANT:</b> This method is <em>not</em> part of the public * API for <code>Control</code>. It is marked public only so that it * can be shared within the packages provided by DWT. It is not * available on all platforms, and should never be called from * application code. * </p> * * @param hDC the platform specific GC handle * @param data the platform specific GC data */ public void internal_dispose_GC (objc.id context, GCData data) { checkWidget (); NSGraphicsContext graphicsContext = new NSGraphicsContext (context); display.removeContext (graphicsContext); if (data !is null) { if (data.paintRect !is null) { NSGraphicsContext.setCurrentContext (graphicsContext); } else { graphicsContext.flushGraphics (); } } } /** * Returns <code>true</code> if the receiver is enabled and all * ancestors up to and including the receiver's nearest ancestor * shell are enabled. Otherwise, <code>false</code> is returned. * A disabled control is typically not selectable from the user * interface and draws with an inactive or "grayed" look. * * @return the receiver's enabled state * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #getEnabled */ public bool isEnabled () { checkWidget(); return getEnabled () && parent.isEnabled (); } bool isEnabledCursor () { return isEnabled (); } bool isFocusAncestor (Control control) { while (control !is null && control !is this && !(cast(Shell) control)) { control = control.parent; } return control is this; } /** * Returns <code>true</code> if the receiver has the user-interface * focus, and <code>false</code> otherwise. * * @return the receiver's focus state * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public bool isFocusControl () { checkWidget(); return hasFocus (); } /** * Returns <code>true</code> if the underlying operating * system supports this reparenting, otherwise <code>false</code> * * @return <code>true</code> if the widget can be reparented, otherwise <code>false</code> * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public bool isReparentable () { checkWidget(); return true; } bool isShowing () { /* * This is not complete. Need to check if the * widget is obscurred by a parent or sibling. */ if (!isVisible ()) return false; Control control = this; while (control !is null) { Point size = control.getSize (); if (size.x is 0 || size.y is 0) { return false; } control = control.parent; } return true; } bool isTabGroup () { Control [] tabList = parent._getTabList (); if (tabList !is null) { for (int i=0; i<tabList.length; i++) { if (tabList [i] is this) return true; } } int code = traversalCode (0, null); if ((code & (DWT.TRAVERSE_ARROW_PREVIOUS | DWT.TRAVERSE_ARROW_NEXT)) !is 0) return false; return (code & (DWT.TRAVERSE_TAB_PREVIOUS | DWT.TRAVERSE_TAB_NEXT)) !is 0; } bool isTabItem () { Control [] tabList = parent._getTabList (); if (tabList !is null) { for (int i=0; i<tabList.length; i++) { if (tabList [i] is this) return false; } } int code = traversalCode (0, null); return (code & (DWT.TRAVERSE_ARROW_PREVIOUS | DWT.TRAVERSE_ARROW_NEXT)) !is 0; } bool isTrim (NSView view) { return false; } /** * Returns <code>true</code> if the receiver is visible and all * ancestors up to and including the receiver's nearest ancestor * shell are visible. Otherwise, <code>false</code> is returned. * * @return the receiver's visibility state * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #getVisible */ public bool isVisible () { checkWidget(); return getVisible () && parent.isVisible (); } void keyDown (objc.id id, objc.SEL sel, objc.id theEvent) { if (view.window ().firstResponder ().id is id) { bool textInput = OS.objc_msgSend (id, OS.sel_conformsToProtocol_, OS.objc_getProtocol ("NSTextInput")) !is null; if (!textInput) { NSEvent nsEvent = new NSEvent (theEvent); bool [] consume = new bool [1]; if (translateTraversal (nsEvent.keyCode (), nsEvent, consume)) return; if (isDisposed ()) return; if (!sendKeyEvent (nsEvent, DWT.KeyDown)) return; if (consume [0]) return; } } super.keyDown (id, sel, theEvent); } void keyUp (objc.id id, objc.SEL sel, objc.id theEvent) { if (view.window ().firstResponder ().id is id) { NSEvent nsEvent = new NSEvent (theEvent); if (!sendKeyEvent (nsEvent, DWT.KeyUp)) return; } super.keyUp (id, sel, theEvent); } void markLayout (bool changed, bool all) { /* Do nothing */ } objc.id menuForEvent (objc.id id, objc.SEL sel, objc.id theEvent) { NSPoint pt = NSEvent.mouseLocation(); pt.y = cast(int) (display.getPrimaryFrame().height - pt.y); int x = cast(int) pt.x; int y = cast(int) pt.y; Event event = new Event (); event.x = x; event.y = y; sendEvent (DWT.MenuDetect, event); if (!event.doit) return null; Menu menu = getMenu (); if (menu !is null && !menu.isDisposed ()) { if (x !is event.x || y !is event.y) { menu.setLocation (event.x, event.y); } return menu.nsMenu.id; } return super.menuForEvent (id, sel, theEvent); } Decorations menuShell () { return parent.menuShell (); } void scrollWheel (objc.id id, objc.SEL sel, objc.id theEvent) { if (id is view.id) { if (hooks (DWT.MouseWheel) || filters (DWT.MouseWheel)) { NSEvent nsEvent = new NSEvent(theEvent); if (nsEvent.deltaY() !is 0) { if (!sendMouseEvent(nsEvent, DWT.MouseWheel, true)) { return; } } } } super.scrollWheel(id, sel, theEvent); } void mouseDown(objc.id id, objc.SEL sel, objc.id theEvent) { Display display = this.display; display.trackingControl = this; super.mouseDown(id, sel, theEvent); display.trackingControl = null; } void moved () { sendEvent (DWT.Move); } /** * Moves the receiver above the specified control in the * drawing order. If the argument is null, then the receiver * is moved to the top of the drawing order. The control at * the top of the drawing order will not be covered by other * controls even if they occupy intersecting areas. * * @param control the sibling control (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see Control#moveBelow * @see Composite#getChildren */ public void moveAbove (Control control) { checkWidget(); if (control !is null) { if (control.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); if (parent !is control.parent) return; } setZOrder (control, true); } /** * Moves the receiver below the specified control in the * drawing order. If the argument is null, then the receiver * is moved to the bottom of the drawing order. The control at * the bottom of the drawing order will be covered by all other * controls which occupy intersecting areas. * * @param control the sibling control (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see Control#moveAbove * @see Composite#getChildren */ public void moveBelow (Control control) { checkWidget(); if (control !is null) { if (control.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); if (parent !is control.parent) return; } setZOrder (control, false); } Accessible new_Accessible (Control control) { return Accessible.internal_new_Accessible (this); } /** * Causes the receiver to be resized to its preferred size. * For a composite, this involves computing the preferred size * from its layout, if there is one. * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #computeSize(int, int, bool) */ public void pack () { checkWidget(); pack (true); } /** * Causes the receiver to be resized to its preferred size. * For a composite, this involves computing the preferred size * from its layout, if there is one. * <p> * If the changed flag is <code>true</code>, it indicates that the receiver's * <em>contents</em> have changed, therefore any caches that a layout manager * containing the control may have been keeping need to be flushed. When the * control is resized, the changed flag will be <code>false</code>, so layout * manager caches can be retained. * </p> * * @param changed whether or not the receiver's contents have changed * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #computeSize(int, int, bool) */ public void pack (bool changed) { checkWidget(); setSize (computeSize (DWT.DEFAULT, DWT.DEFAULT, changed)); } /** * Prints the receiver and all children. * * @param gc the gc where the drawing occurs * @return <code>true</code> if the operation was successful and <code>false</code> otherwise * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the gc is null</li> * <li>ERROR_INVALID_ARGUMENT - if the gc has been disposed</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 3.4 */ public bool print (GC gc) { checkWidget (); if (gc is null) error (DWT.ERROR_NULL_ARGUMENT); if (gc.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); // int [] outImage = new int [1]; // CGRect outFrame = new CGRect (); // if (OS.HIViewCreateOffscreenImage (handle, 0, outFrame, outImage) is OS.noErr) { // int width = OS.CGImageGetWidth (outImage [0]); // int height = OS.CGImageGetHeight (outImage [0]); // CGRect rect = new CGRect(); // rect.width = width; // rect.height = height; // //TODO - does not draw the browser (cocoa widgets?) // OS.HIViewDrawCGImage (gc.handle, rect, outImage [0]); // OS.CGImageRelease (outImage [0]); // } // return true; return false; } /** * Causes the entire bounds of the receiver to be marked * as needing to be redrawn. The next time a paint request * is processed, the control will be completely painted, * including the background. * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #update() * @see PaintListener * @see DWT#Paint * @see DWT#NO_BACKGROUND * @see DWT#NO_REDRAW_RESIZE * @see DWT#NO_MERGE_PAINTS * @see DWT#DOUBLE_BUFFERED */ public void redraw () { checkWidget(); view.setNeedsDisplay(true); } void redraw (bool children) { // checkWidget(); } /** * Causes the rectangular area of the receiver specified by * the arguments to be marked as needing to be redrawn. * The next time a paint request is processed, that area of * the receiver will be painted, including the background. * If the <code>all</code> flag is <code>true</code>, any * children of the receiver which intersect with the specified * area will also paint their intersecting areas. If the * <code>all</code> flag is <code>false</code>, the children * will not be painted. * * @param x the x coordinate of the area to draw * @param y the y coordinate of the area to draw * @param width the width of the area to draw * @param height the height of the area to draw * @param all <code>true</code> if children should redraw, and <code>false</code> otherwise * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #update() * @see PaintListener * @see DWT#Paint * @see DWT#NO_BACKGROUND * @see DWT#NO_REDRAW_RESIZE * @see DWT#NO_MERGE_PAINTS * @see DWT#DOUBLE_BUFFERED */ public void redraw (int x, int y, int width, int height, bool all) { checkWidget (); NSRect rect = NSRect(); rect.x = x; rect.y = y; rect.width = width; rect.height = height; view.setNeedsDisplayInRect(rect); } void register () { super.register (); display.addWidget (view, this); } void releaseHandle () { super.releaseHandle (); if (view !is null) view.release(); view = null; parent = null; } void releaseParent () { parent.removeControl (this); } void releaseWidget () { super.releaseWidget (); if (display.currentControl is this) { display.currentControl = null; display.timerExec(-1, display.hoverTimer); } if (display.grabControl is this) { display.grabControl = null; } if (menu !is null && !menu.isDisposed ()) { menu.dispose (); } menu = null; layoutData = null; if (accessible !is null) { accessible.internal_dispose_Accessible (); } accessible = null; region = null; } /** * Removes the listener from the collection of listeners who will * be notified when the control is moved or resized. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see ControlListener * @see #addControlListener */ public void removeControlListener (ControlListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; eventTable.unhook (DWT.Move, listener); eventTable.unhook (DWT.Resize, listener); } /** * Removes the listener from the collection of listeners who will * be notified when a drag gesture occurs. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see DragDetectListener * @see #addDragDetectListener * * @since 3.3 */ public void removeDragDetectListener(DragDetectListener listener) { checkWidget (); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; eventTable.unhook (DWT.DragDetect, listener); } /** * Removes the listener from the collection of listeners who will * be notified when the control gains or loses focus. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see FocusListener * @see #addFocusListener */ public void removeFocusListener(FocusListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; eventTable.unhook(DWT.FocusIn, listener); eventTable.unhook(DWT.FocusOut, listener); } /** * Removes the listener from the collection of listeners who will * be notified when the help events are generated for the control. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see HelpListener * @see #addHelpListener */ public void removeHelpListener (HelpListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; eventTable.unhook (DWT.Help, listener); } /** * Removes the listener from the collection of listeners who will * be notified when keys are pressed and released on the system keyboard. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see KeyListener * @see #addKeyListener */ public void removeKeyListener(KeyListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; eventTable.unhook(DWT.KeyUp, listener); eventTable.unhook(DWT.KeyDown, listener); } /** * Removes the listener from the collection of listeners who will * be notified when the platform-specific context menu trigger has * occurred. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see MenuDetectListener * @see #addMenuDetectListener * * @since 3.3 */ public void removeMenuDetectListener (MenuDetectListener listener) { checkWidget (); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; eventTable.unhook (DWT.MenuDetect, listener); } /** * Removes the listener from the collection of listeners who will * be notified when mouse buttons are pressed and released. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see MouseListener * @see #addMouseListener */ public void removeMouseListener(MouseListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; eventTable.unhook(DWT.MouseDown, listener); eventTable.unhook(DWT.MouseUp, listener); eventTable.unhook(DWT.MouseDoubleClick, listener); } /** * Removes the listener from the collection of listeners who will * be notified when the mouse moves. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see MouseMoveListener * @see #addMouseMoveListener */ public void removeMouseMoveListener(MouseMoveListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; eventTable.unhook(DWT.MouseMove, listener); } /** * Removes the listener from the collection of listeners who will * be notified when the mouse passes or hovers over controls. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see MouseTrackListener * @see #addMouseTrackListener */ public void removeMouseTrackListener(MouseTrackListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; eventTable.unhook (DWT.MouseEnter, listener); eventTable.unhook (DWT.MouseExit, listener); eventTable.unhook (DWT.MouseHover, listener); } /** * Removes the listener from the collection of listeners who will * be notified when the mouse wheel is scrolled. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see MouseWheelListener * @see #addMouseWheelListener * * @since 3.3 */ public void removeMouseWheelListener (MouseWheelListener listener) { checkWidget (); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; eventTable.unhook (DWT.MouseWheel, listener); } /** * Removes the listener from the collection of listeners who will * be notified when the receiver needs to be painted. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see PaintListener * @see #addPaintListener */ public void removePaintListener(PaintListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; eventTable.unhook(DWT.Paint, listener); } /** * Removes the listener from the collection of listeners who will * be notified when traversal events occur. * * @param listener the listener which should no longer be notified * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see TraverseListener * @see #addTraverseListener */ public void removeTraverseListener(TraverseListener listener) { checkWidget(); if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; eventTable.unhook (DWT.Traverse, listener); } void resized () { sendEvent (DWT.Resize); } bool sendDragEvent (int button, int stateMask, int x, int y) { Event event = new Event (); event.button = button; event.x = x; event.y = y; event.stateMask = stateMask; postEvent (DWT.DragDetect, event); return event.doit; } bool sendDragEvent (NSEvent nsEvent) { return sendMouseEvent(nsEvent, DWT.DragDetect, true); } void sendFocusEvent (int type, bool post) { Display display = this.display; Shell shell = getShell (); if (post) { postEvent (type); } else { sendEvent (type); } /* * It is possible that the shell may be * disposed at this point. If this happens * don't send the activate and deactivate * events. */ if (!shell.isDisposed ()) { switch (type) { case DWT.FocusIn: shell.setActiveControl (this); break; case DWT.FocusOut: if (shell !is display.getActiveShell ()) { shell.setActiveControl (null); } break; default: } } } bool sendMouseEvent (NSEvent nsEvent, int type, bool send) { NSInputManager manager = NSInputManager.currentInputManager (); if (manager !is null && manager.wantsToHandleMouseEvents ()) { if (manager.handleMouseEvent (nsEvent)) { return true; } } Shell shell = null; Event event = new Event (); switch (type) { case DWT.MouseDown: shell = getShell (); //FALL THROUGH case DWT.MouseUp: case DWT.MouseDoubleClick: int button = cast(int)/*64*/nsEvent.buttonNumber(); switch (button) { case 0: event.button = 1; break; case 1: event.button = 3; break; case 2: event.button = 2; break; case 3: event.button = 4; break; case 4: event.button = 5; break; default: } break; case DWT.MouseWheel: event.detail = DWT.SCROLL_LINE; Carbon.CGFloat delta = nsEvent.deltaY(); event.count = delta > 0 ? Math.max (1, cast(int)delta) : Math.min (-1, cast(int)delta); break; default: } if (event.button !is 0) event.count = cast(int)/*64*/nsEvent.clickCount(); NSPoint windowPoint; if (nsEvent is null || nsEvent.type() is OS.NSMouseMoved) { windowPoint = view.window().convertScreenToBase(NSEvent.mouseLocation()); } else { windowPoint = nsEvent.locationInWindow(); } NSPoint point = view.convertPoint_fromView_(windowPoint, null); event.x = cast(int) point.x; event.y = cast(int) point.y; setInputState (event, nsEvent, type); if (send) { sendEvent (type, event); if (isDisposed ()) return false; } else { postEvent (type, event); } if (shell !is null) shell.setActiveControl(this); return event.doit; } void setBackground () { // redrawWidget (handle, false); } /** * Sets the receiver's background color to the color specified * by the argument, or to the default system color for the control * if the argument is null. * <p> * Note: This operation is a hint and may be overridden by the platform. * For example, on Windows the background of a Button cannot be changed. * </p> * @param color the new color (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setBackground (Color color) { checkWidget(); if (color !is null) { if (color.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); } // if (equals (background, this.background)) return; this.background = color; setBackground (color !is null ? color.handle : null); view.setNeedsDisplay(true); } /** * Sets the receiver's background image to the image specified * by the argument, or to the default system color for the control * if the argument is null. The background image is tiled to fill * the available space. * <p> * Note: This operation is a hint and may be overridden by the platform. * For example, on Windows the background of a Button cannot be changed. * </p> * @param image the new image (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> * <li>ERROR_INVALID_ARGUMENT - if the argument is not a bitmap</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 3.2 */ public void setBackgroundImage (Image image) { checkWidget(); if (image !is null && image.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); if (image is backgroundImage) return; backgroundImage = image; // redrawWidget (handle, false); } void setBackground (Carbon.CGFloat [] color) { } void setBackground (int control, Carbon.CGFloat [] color) { // ControlFontStyleRec fontStyle = new ControlFontStyleRec (); // OS.GetControlData (control, cast(short) OS.kControlEntireControl, OS.kControlFontStyleTag, ControlFontStyleRec.sizeof, fontStyle, null); // if (color !is null) { // fontStyle.backColor_red = cast(short) (color [0] * 0xffff); // fontStyle.backColor_green = cast(short) (color [1] * 0xffff); // fontStyle.backColor_blue = cast(short) (color [2] * 0xffff); // fontStyle.flags |= OS.kControlUseBackColorMask; // } else { // fontStyle.flags &= ~OS.kControlUseBackColorMask; // } // OS.SetControlFontStyle (control, fontStyle); } /** * Sets the receiver's size and location to the rectangular * area specified by the arguments. The <code>x</code> and * <code>y</code> arguments are relative to the receiver's * parent (or its display if its parent is null), unless * the receiver is a shell. In this case, the <code>x</code> * and <code>y</code> arguments are relative to the display. * <p> * Note: Attempting to set the width or height of the * receiver to a negative number will cause that * value to be set to zero instead. * </p> * * @param x the new x coordinate for the receiver * @param y the new y coordinate for the receiver * @param width the new width for the receiver * @param height the new height for the receiver * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setBounds (int x, int y, int width, int height) { checkWidget(); setBounds (x, y, Math.max (0, width), Math.max (0, height), true, true); } void setBounds (int x, int y, int width, int height, bool move, bool resize) { NSView topView = topView(); if (move && resize) { NSRect rect = NSRect(); rect.x = x; rect.y = y; rect.width = width; rect.height = height; topView.setFrame (rect); } else if (move) { NSPoint point = NSPoint(); point.x = x; point.y = y; topView.setFrameOrigin(point); } else if (resize) { NSSize size = NSSize(); size.width = width; size.height = height; topView.setFrameSize(size); } } /** * Sets the receiver's size and location to the rectangular * area specified by the argument. The <code>x</code> and * <code>y</code> fields of the rectangle are relative to * the receiver's parent (or its display if its parent is null). * <p> * Note: Attempting to set the width or height of the * receiver to a negative number will cause that * value to be set to zero instead. * </p> * * @param rect the new bounds for the receiver * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setBounds (Rectangle rect) { checkWidget (); if (rect is null) error (DWT.ERROR_NULL_ARGUMENT); setBounds (rect.x, rect.y, Math.max (0, rect.width), Math.max (0, rect.height), true, true); } /** * If the argument is <code>true</code>, causes the receiver to have * all mouse events delivered to it until the method is called with * <code>false</code> as the argument. Note that on some platforms, * a mouse button must currently be down for capture to be assigned. * * @param capture <code>true</code> to capture the mouse, and <code>false</code> to release it * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setCapture (bool capture) { checkWidget(); } /** * Sets the receiver's cursor to the cursor specified by the * argument, or to the default cursor for that kind of control * if the argument is null. * <p> * When the mouse pointer passes over a control its appearance * is changed to match the control's cursor. * </p> * * @param cursor the new cursor (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setCursor (Cursor cursor) { checkWidget(); if (cursor !is null && cursor.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); this.cursor = cursor; if (!isEnabled()) return; display.setCursor (display.currentControl); } void setDefaultFont () { // if (display.smallFonts) setFontStyle (defaultFont ()); } /** * Sets the receiver's drag detect state. If the argument is * <code>true</code>, the receiver will detect drag gestures, * otherwise these gestures will be ignored. * * @param dragDetect the new drag detect state * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 3.3 */ public void setDragDetect (bool dragDetect) { checkWidget (); if (dragDetect) { state |= DRAG_DETECT; } else { state &= ~DRAG_DETECT; } } /** * Enables the receiver if the argument is <code>true</code>, * and disables it otherwise. A disabled control is typically * not selectable from the user interface and draws with an * inactive or "grayed" look. * * @param enabled the new enabled state * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setEnabled (bool enabled) { checkWidget(); if (((state & DISABLED) is 0) is enabled) return; Control control = null; bool fixFocus_ = false; if (!enabled) { control = display.getFocusControl (); fixFocus_ = isFocusAncestor (control); } if (enabled) { state &= ~DISABLED; } else { state |= DISABLED; } enableWidget (enabled); if (fixFocus_) fixFocus (control); } /** * Causes the receiver to have the <em>keyboard focus</em>, * such that all keyboard events will be delivered to it. Focus * reassignment will respect applicable platform constraints. * * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to. * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #forceFocus */ public bool setFocus () { checkWidget(); if ((style & DWT.NO_FOCUS) !is 0) return false; return forceFocus (); } /** * Sets the font that the receiver will use to paint textual information * to the font specified by the argument, or to the default font for that * kind of control if the argument is null. * * @param font the new font (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setFont (Font font) { checkWidget(); if (font !is null) { if (font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); } this.font = font; setFont (font !is null ? font.handle : defaultFont().handle); } void setFont (NSFont font) { //TODO - bad cast if (cast(NSControl) view) { (cast(NSControl)view).setFont(font); } } /** * Sets the receiver's foreground color to the color specified * by the argument, or to the default system color for the control * if the argument is null. * <p> * Note: This operation is a hint and may be overridden by the platform. * </p> * @param color the new color (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setForeground (Color color) { checkWidget(); if (color !is null) { if (color.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); } // if (equals (foreground, this.foreground)) return; this.foreground = color; setForeground (color !is null ? color.handle : null); view.setNeedsDisplay(true); } void setForeground (float [] color) { } void setForeground (int control, float [] color) { // ControlFontStyleRec fontStyle = new ControlFontStyleRec (); // OS.GetControlData (control, cast(short) OS.kControlEntireControl, OS.kControlFontStyleTag, ControlFontStyleRec.sizeof, fontStyle, null); // if (color !is null) { // fontStyle.foreColor_red = cast(short) (color [0] * 0xffff); // fontStyle.foreColor_green = cast(short) (color [1] * 0xffff); // fontStyle.foreColor_blue = cast(short) (color [2] * 0xffff); // fontStyle.flags |= OS.kControlUseForeColorMask; // } else { // fontStyle.flags &= ~OS.kControlUseForeColorMask; // } // OS.SetControlFontStyle (control, fontStyle); } void setFrameOrigin (objc.id id, objc.SEL sel, NSPoint point) { NSView topView = topView (); if (topView.id !is id) { super.setFrameOrigin(id, sel, point); return; } NSRect frame = topView.frame(); super.setFrameOrigin(id, sel, point); if (frame.x !is point.x || frame.y !is point.y) { moved (); } } void setFrameSize (objc.id id, objc.SEL sel, NSSize size) { NSView topView = topView (); if (topView.id !is id) { super.setFrameSize(id, sel, size); return; } NSRect frame = topView.frame(); super.setFrameSize(id, sel, size); if (frame.width !is size.width || frame.height !is size.height) { resized (); } } /** * Sets the layout data associated with the receiver to the argument. * * @param layoutData the new layout data for the receiver. * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setLayoutData (Object layoutData) { checkWidget(); this.layoutData = layoutData; } /** * Sets the receiver's location to the point specified by * the arguments which are relative to the receiver's * parent (or its display if its parent is null), unless * the receiver is a shell. In this case, the point is * relative to the display. * * @param x the new x coordinate for the receiver * @param y the new y coordinate for the receiver * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setLocation (int x, int y) { checkWidget(); setBounds (x, y, 0, 0, true, false); } /** * Sets the receiver's location to the point specified by * the arguments which are relative to the receiver's * parent (or its display if its parent is null), unless * the receiver is a shell. In this case, the point is * relative to the display. * * @param location the new location for the receiver * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setLocation (Point location) { checkWidget(); if (location is null) error (DWT.ERROR_NULL_ARGUMENT); setBounds (location.x, location.y, 0, 0, true, false); } /** * Sets the receiver's pop up menu to the argument. * All controls may optionally have a pop up * menu that is displayed when the user requests one for * the control. The sequence of key strokes, button presses * and/or button releases that are used to request a pop up * menu is platform specific. * <p> * Note: Disposing of a control that has a pop up menu will * dispose of the menu. To avoid this behavior, set the * menu to null before the control is disposed. * </p> * * @param menu the new pop up menu * * @exception IllegalArgumentException <ul> * <li>ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu</li> * <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li> * <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setMenu (Menu menu) { checkWidget(); if (menu !is null) { if (menu.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); if ((menu.style & DWT.POP_UP) is 0) { error (DWT.ERROR_MENU_NOT_POP_UP); } if (menu.parent !is menuShell ()) { error (DWT.ERROR_INVALID_PARENT); } } this.menu = menu; } /** * Changes the parent of the widget to be the one provided if * the underlying operating system supports this feature. * Returns <code>true</code> if the parent is successfully changed. * * @param parent the new parent for the control. * @return <code>true</code> if the parent is changed and <code>false</code> otherwise. * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> * <li>ERROR_NULL_ARGUMENT - if the parent is <code>null</code></li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public bool setParent (Composite parent) { checkWidget(); if (parent is null) error (DWT.ERROR_NULL_ARGUMENT); if (parent.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); if (this.parent is parent) return true; if (!isReparentable ()) return false; releaseParent (); Shell newShell = parent.getShell (), oldShell = getShell (); Decorations newDecorations = parent.menuShell (), oldDecorations = menuShell (); if (oldShell !is newShell || oldDecorations !is newDecorations) { Menu [] menus = oldShell.findMenus (this); fixChildren (newShell, oldShell, newDecorations, oldDecorations, menus); } NSView topView = topView (); topView.retain(); topView.removeFromSuperview(); parent.contentView().addSubview(topView, OS.NSWindowBelow, null); topView.release(); this.parent = parent; return true; } /** * If the argument is <code>false</code>, causes subsequent drawing * operations in the receiver to be ignored. No drawing of any kind * can occur in the receiver until the flag is set to true. * Graphics operations that occurred while the flag was * <code>false</code> are lost. When the flag is set to <code>true</code>, * the entire widget is marked as needing to be redrawn. Nested calls * to this method are stacked. * <p> * Note: This operation is a hint and may not be supported on some * platforms or for some widgets. * </p> * * @param redraw the new redraw state * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #redraw(int, int, int, int, bool) * @see #update() */ public void setRedraw (bool redraw) { checkWidget(); if (redraw) { if (--drawCount is 0) { // OS.HIViewSetDrawingEnabled (handle, true); // invalidateVisibleRegion (handle); // redrawWidget (handle, true); } } else { if (drawCount is 0) { // OS.HIViewSetDrawingEnabled (handle, false); // invalidateVisibleRegion (handle); } drawCount++; } } /** * Sets the shape of the control to the region specified * by the argument. When the argument is null, the * default shape of the control is restored. * * @param region the region that defines the shape of the control (or null) * * @exception IllegalArgumentException <ul> * <li>ERROR_INVALID_ARGUMENT - if the region has been disposed</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 3.4 */ public void setRegion (Region region) { checkWidget (); if (region !is null && region.isDisposed()) error (DWT.ERROR_INVALID_ARGUMENT); this.region = region; // redrawWidget (handle, true); } bool setRadioSelection (bool value){ return false; } /** * Sets the receiver's size to the point specified by the arguments. * <p> * Note: Attempting to set the width or height of the * receiver to a negative number will cause that * value to be set to zero instead. * </p> * * @param width the new width for the receiver * @param height the new height for the receiver * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setSize (int width, int height) { checkWidget(); setBounds (0, 0, Math.max (0, width), Math.max (0, height), false, true); } /** * Sets the receiver's size to the point specified by the argument. * <p> * Note: Attempting to set the width or height of the * receiver to a negative number will cause them to be * set to zero instead. * </p> * * @param size the new size for the receiver * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the point is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setSize (Point size) { checkWidget (); if (size is null) error (DWT.ERROR_NULL_ARGUMENT); setBounds (0, 0, Math.max (0, size.x), Math.max (0, size.y), false, true); } bool setTabGroupFocus () { return setTabItemFocus (); } bool setTabItemFocus () { if (!isShowing ()) return false; return forceFocus (); } /** * Sets the receiver's tool tip text to the argument, which * may be null indicating that no tool tip text should be shown. * * @param string the new tool tip text (or null) * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setToolTipText (String string) { checkWidget(); toolTipText = string; view.setToolTip(string !is null ? NSString.stringWith(string) : null); } /** * Marks the receiver as visible if the argument is <code>true</code>, * and marks it invisible otherwise. * <p> * If one of the receiver's ancestors is not visible or some * other condition makes the receiver not visible, marking * it visible may not actually cause it to be displayed. * </p> * * @param visible the new visibility state * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public void setVisible (bool visible) { checkWidget(); if (visible) { if ((state & HIDDEN) is 0) return; state &= ~HIDDEN; } else { if ((state & HIDDEN) !is 0) return; state |= HIDDEN; } if (visible) { /* * It is possible (but unlikely), that application * code could have disposed the widget in the show * event. If this happens, just return. */ sendEvent (DWT.Show); if (isDisposed ()) return; } /* * Feature in the Macintosh. If the receiver has focus, hiding * the receiver causes no control to have focus. Also, the focus * needs to be cleared from any TXNObject so that it stops blinking * the caret. The fix is to assign focus to the first ancestor * control that takes focus. If no control will take focus, clear * the focus control. */ Control control = null; bool fixFocus_ = false; if (!visible) { control = display.getFocusControl (); fixFocus_ = isFocusAncestor (control); } topView().setHidden(!visible); if (!visible) { /* * It is possible (but unlikely), that application * code could have disposed the widget in the show * event. If this happens, just return. */ sendEvent (DWT.Hide); if (isDisposed ()) return; } if (fixFocus_) fixFocus (control); } void setZOrder () { NSView topView = topView (); parent.contentView().addSubview(topView, OS.NSWindowBelow, null); } void setZOrder (Control control, bool above) { NSView otherView = control is null ? null : control.topView (); view.retain(); view.removeFromSuperview(); parent.contentView().addSubview(view, above ? OS.NSWindowAbove : OS.NSWindowBelow, otherView); view.release(); } void sort (int [] items) { /* Shell Sort from K&R, pg 108 */ int length = items.length; for (int gap=length/2; gap>0; gap/=2) { for (int i=gap; i<length; i++) { for (int j=i-gap; j>=0; j-=gap) { if (items [j] <= items [j + gap]) { int swap = items [j]; items [j] = items [j + gap]; items [j + gap] = swap; } } } } } /** * Returns a point which is the result of converting the * argument, which is specified in display relative coordinates, * to coordinates relative to the receiver. * <p> * @param x the x coordinate to be translated * @param y the y coordinate to be translated * @return the translated coordinates * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 2.1 */ public Point toControl (int x, int y) { checkWidget(); return display.map (null, this, x, y); } /** * Returns a point which is the result of converting the * argument, which is specified in display relative coordinates, * to coordinates relative to the receiver. * <p> * @param point the point to be translated (must not be null) * @return the translated coordinates * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the point is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Point toControl (Point point) { checkWidget(); if (point is null) error (DWT.ERROR_NULL_ARGUMENT); return toControl (point.x, point.y); } /** * Returns a point which is the result of converting the * argument, which is specified in coordinates relative to * the receiver, to display relative coordinates. * <p> * @param x the x coordinate to be translated * @param y the y coordinate to be translated * @return the translated coordinates * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 2.1 */ public Point toDisplay (int x, int y) { checkWidget(); return display.map (this, null, x, y); } /** * Returns a point which is the result of converting the * argument, which is specified in coordinates relative to * the receiver, to display relative coordinates. * <p> * @param point the point to be translated (must not be null) * @return the translated coordinates * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the point is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public Point toDisplay (Point point) { checkWidget(); if (point is null) error (DWT.ERROR_NULL_ARGUMENT); return toDisplay (point.x, point.y); } NSView topView () { return view; } bool translateTraversal (short key, NSEvent theEvent, bool [] consume) { int detail = DWT.TRAVERSE_NONE; int code = traversalCode (key, theEvent); bool all = false; switch (key) { case 53: /* Esc */ { all = true; detail = DWT.TRAVERSE_ESCAPE; break; } case 76: /* KP Enter */ case 36: /* Return */ { all = true; detail = DWT.TRAVERSE_RETURN; break; } case 48: /* Tab */ { NSUInteger modifiers = theEvent.modifierFlags (); bool next = (modifiers & OS.NSShiftKeyMask) is 0; detail = next ? DWT.TRAVERSE_TAB_NEXT : DWT.TRAVERSE_TAB_PREVIOUS; break; } case 126: /* Up arrow */ case 123: /* Left arrow */ case 125: /* Down arrow */ case 124: /* Right arrow */ { bool next = key is 125 /* Down arrow */ || key is 124 /* Right arrow */; detail = next ? DWT.TRAVERSE_ARROW_NEXT : DWT.TRAVERSE_ARROW_PREVIOUS; break; } case 116: /* Page up */ case 121: /* Page down */ { all = true; NSUInteger modifiers = theEvent.modifierFlags (); if ((modifiers & OS.NSControlKeyMask) is 0) return false; detail = key is 121 /* Page down */ ? DWT.TRAVERSE_PAGE_NEXT : DWT.TRAVERSE_PAGE_PREVIOUS; break; } default: return false; } Event event = new Event (); event.doit = consume [0] = (code & detail) !is 0; event.detail = detail; if (!setKeyState (event, DWT.Traverse, theEvent)) return false; Shell shell = getShell (); Control control = this; do { if (control.traverse (event)) return true; if (!event.doit && control.hooks (DWT.Traverse)) { return false; } if (control is shell) return false; control = control.parent; } while (all && control !is null); return false; } int traversalCode (short key, NSEvent theEvent) { int code = DWT.TRAVERSE_RETURN | DWT.TRAVERSE_TAB_NEXT | DWT.TRAVERSE_TAB_PREVIOUS | DWT.TRAVERSE_PAGE_NEXT | DWT.TRAVERSE_PAGE_PREVIOUS; Shell shell = getShell (); if (shell.parent !is null) code |= DWT.TRAVERSE_ESCAPE; return code; } bool traverseMnemonic (char key) { return false; } /** * Based on the argument, perform one of the expected platform * traversal action. The argument should be one of the constants: * <code>DWT.TRAVERSE_ESCAPE</code>, <code>DWT.TRAVERSE_RETURN</code>, * <code>DWT.TRAVERSE_TAB_NEXT</code>, <code>DWT.TRAVERSE_TAB_PREVIOUS</code>, * <code>DWT.TRAVERSE_ARROW_NEXT</code> and <code>DWT.TRAVERSE_ARROW_PREVIOUS</code>. * * @param traversal the type of traversal * @return true if the traversal succeeded * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */ public bool traverse (int traversal) { checkWidget(); Event event = new Event (); event.doit = true; event.detail = traversal; return traverse (event); } bool traverse (Event event) { sendEvent (DWT.Traverse, event); if (isDisposed ()) return true; if (!event.doit) return false; switch (event.detail) { case DWT.TRAVERSE_NONE: return true; case DWT.TRAVERSE_ESCAPE: return traverseEscape (); case DWT.TRAVERSE_RETURN: return traverseReturn (); case DWT.TRAVERSE_TAB_NEXT: return traverseGroup (true); case DWT.TRAVERSE_TAB_PREVIOUS: return traverseGroup (false); case DWT.TRAVERSE_ARROW_NEXT: return traverseItem (true); case DWT.TRAVERSE_ARROW_PREVIOUS: return traverseItem (false); case DWT.TRAVERSE_MNEMONIC: return traverseMnemonic (event); case DWT.TRAVERSE_PAGE_NEXT: return traversePage (true); case DWT.TRAVERSE_PAGE_PREVIOUS: return traversePage (false); default: } return false; } bool traverseEscape () { return false; } bool traverseGroup (bool next) { Control root = computeTabRoot (); Control group = computeTabGroup (); Control [] list = root.computeTabList (); int length = list.length; int index = 0; while (index < length) { if (list [index] is group) break; index++; } /* * It is possible (but unlikely), that application * code could have disposed the widget in focus in * or out events. Ensure that a disposed widget is * not accessed. */ if (index is length) return false; int start = index, offset = (next) ? 1 : -1; while ((index = ((index + offset + length) % length)) !is start) { Control control = list [index]; if (!control.isDisposed () && control.setTabGroupFocus ()) { return true; } } if (group.isDisposed ()) return false; return group.setTabGroupFocus (); } bool traverseItem (bool next) { Control [] children = parent._getChildren (); int length = children.length; int index = 0; while (index < length) { if (children [index] is this) break; index++; } /* * It is possible (but unlikely), that application * code could have disposed the widget in focus in * or out events. Ensure that a disposed widget is * not accessed. */ if (index is length) return false; int start = index, offset = (next) ? 1 : -1; while ((index = (index + offset + length) % length) !is start) { Control child = children [index]; if (!child.isDisposed () && child.isTabItem ()) { if (child.setTabItemFocus ()) return true; } } return false; } bool traverseReturn () { return false; } bool traversePage (bool next) { return false; } bool traverseMnemonic (Event event) { return false; } /** * Forces all outstanding paint requests for the widget * to be processed before this method returns. If there * are no outstanding paint request, this method does * nothing. * <p> * Note: This method does not cause a redraw. * </p> * * @exception DWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @see #redraw() * @see #redraw(int, int, int, int, bool) * @see PaintListener * @see DWT#Paint */ public void update () { checkWidget(); update (false); } void update (bool all) { // checkWidget(); //TODO - not all view.displayIfNeeded (); } void updateBackgroundMode () { int oldState = state & PARENT_BACKGROUND; checkBackground (); if (oldState !is (state & PARENT_BACKGROUND)) { setBackground (); } } void updateLayout (bool all) { /* Do nothing */ } }