0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.swt.widgets;
0011:
0012: import org.eclipse.swt.internal.carbon.ATSFontMetrics;
0013: import org.eclipse.swt.internal.carbon.HIThemeTextInfo;
0014: import org.eclipse.swt.internal.carbon.OS;
0015: import org.eclipse.swt.internal.carbon.CGRect;
0016: import org.eclipse.swt.internal.carbon.CGPoint;
0017: import org.eclipse.swt.internal.carbon.ControlFontStyleRec;
0018: import org.eclipse.swt.internal.carbon.HMHelpContentRec;
0019: import org.eclipse.swt.internal.carbon.HIThemeFrameDrawInfo;
0020: import org.eclipse.swt.internal.carbon.Rect;
0021:
0022: import org.eclipse.swt.*;
0023: import org.eclipse.swt.events.*;
0024: import org.eclipse.swt.graphics.*;
0025: import org.eclipse.swt.accessibility.Accessible;
0026:
0027: /**
0028: * Control is the abstract superclass of all windowed user interface classes.
0029: * <p>
0030: * <dl>
0031: * <dt><b>Styles:</b>
0032: * <dd>BORDER</dd>
0033: * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd>
0034: * <dt><b>Events:</b>
0035: * <dd>DragDetect, FocusIn, FocusOut, Help, KeyDown, KeyUp, MenuDetect, MouseDoubleClick, MouseDown, MouseEnter,
0036: * MouseExit, MouseHover, MouseUp, MouseMove, Move, Paint, Resize, Traverse</dd>
0037: * </dl>
0038: * </p><p>
0039: * Only one of LEFT_TO_RIGHT or RIGHT_TO_LEFT may be specified.
0040: * </p><p>
0041: * IMPORTANT: This class is intended to be subclassed <em>only</em>
0042: * within the SWT implementation.
0043: * </p>
0044: */
0045: public abstract class Control extends Widget implements Drawable {
0046: /**
0047: * the handle to the OS resource
0048: * (Warning: This field is platform dependent)
0049: * <p>
0050: * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
0051: * public API. It is marked public only so that it can be shared
0052: * within the packages provided by SWT. It is not available on all
0053: * platforms and should never be accessed from application code.
0054: * </p>
0055: */
0056: public int handle;
0057: Composite parent;
0058: String toolTipText;
0059: Object layoutData;
0060: int drawCount, visibleRgn;
0061: Menu menu;
0062: float[] foreground, background;
0063: Image backgroundImage;
0064: Font font;
0065: Cursor cursor;
0066: GCData gcs[];
0067: Accessible accessible;
0068:
0069: static final String RESET_VISIBLE_REGION = "org.eclipse.swt.internal.resetVisibleRegion";
0070:
0071: Control() {
0072: /* Do nothing */
0073: }
0074:
0075: /**
0076: * Constructs a new instance of this class given its parent
0077: * and a style value describing its behavior and appearance.
0078: * <p>
0079: * The style value is either one of the style constants defined in
0080: * class <code>SWT</code> which is applicable to instances of this
0081: * class, or must be built by <em>bitwise OR</em>'ing together
0082: * (that is, using the <code>int</code> "|" operator) two or more
0083: * of those <code>SWT</code> style constants. The class description
0084: * lists the style constants that are applicable to the class.
0085: * Style bits are also inherited from superclasses.
0086: * </p>
0087: *
0088: * @param parent a composite control which will be the parent of the new instance (cannot be null)
0089: * @param style the style of control to construct
0090: *
0091: * @exception IllegalArgumentException <ul>
0092: * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
0093: * </ul>
0094: * @exception SWTException <ul>
0095: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
0096: * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
0097: * </ul>
0098: *
0099: * @see SWT#BORDER
0100: * @see Widget#checkSubclass
0101: * @see Widget#getStyle
0102: */
0103: public Control(Composite parent, int style) {
0104: super (parent, style);
0105: this .parent = parent;
0106: createWidget();
0107: }
0108:
0109: int actionProc(int theControl, int partCode) {
0110: int result = super .actionProc(theControl, partCode);
0111: if (result == OS.noErr)
0112: return result;
0113: if (isDisposed())
0114: return OS.noErr;
0115: sendTrackEvents();
0116: return result;
0117: }
0118:
0119: /**
0120: * Adds the listener to the collection of listeners who will
0121: * be notified when the control is moved or resized, by sending
0122: * it one of the messages defined in the <code>ControlListener</code>
0123: * interface.
0124: *
0125: * @param listener the listener which should be notified
0126: *
0127: * @exception IllegalArgumentException <ul>
0128: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0129: * </ul>
0130: * @exception SWTException <ul>
0131: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0132: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0133: * </ul>
0134: *
0135: * @see ControlListener
0136: * @see #removeControlListener
0137: */
0138: public void addControlListener(ControlListener listener) {
0139: checkWidget();
0140: if (listener == null)
0141: error(SWT.ERROR_NULL_ARGUMENT);
0142: TypedListener typedListener = new TypedListener(listener);
0143: addListener(SWT.Resize, typedListener);
0144: addListener(SWT.Move, typedListener);
0145: }
0146:
0147: /**
0148: * Adds the listener to the collection of listeners who will
0149: * be notified when a drag gesture occurs, by sending it
0150: * one of the messages defined in the <code>DragDetectListener</code>
0151: * interface.
0152: *
0153: * @param listener the listener which should be notified
0154: *
0155: * @exception IllegalArgumentException <ul>
0156: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0157: * </ul>
0158: * @exception SWTException <ul>
0159: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0160: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0161: * </ul>
0162: *
0163: * @see DragDetectListener
0164: * @see #removeDragDetectListener
0165: *
0166: * @since 3.3
0167: */
0168: public void addDragDetectListener(DragDetectListener listener) {
0169: checkWidget();
0170: if (listener == null)
0171: error(SWT.ERROR_NULL_ARGUMENT);
0172: TypedListener typedListener = new TypedListener(listener);
0173: addListener(SWT.DragDetect, typedListener);
0174: }
0175:
0176: /**
0177: * Adds the listener to the collection of listeners who will
0178: * be notified when the control gains or loses focus, by sending
0179: * it one of the messages defined in the <code>FocusListener</code>
0180: * interface.
0181: *
0182: * @param listener the listener which should be notified
0183: *
0184: * @exception IllegalArgumentException <ul>
0185: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0186: * </ul>
0187: * @exception SWTException <ul>
0188: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0189: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0190: * </ul>
0191: *
0192: * @see FocusListener
0193: * @see #removeFocusListener
0194: */
0195: public void addFocusListener(FocusListener listener) {
0196: checkWidget();
0197: if (listener == null)
0198: error(SWT.ERROR_NULL_ARGUMENT);
0199: TypedListener typedListener = new TypedListener(listener);
0200: addListener(SWT.FocusIn, typedListener);
0201: addListener(SWT.FocusOut, typedListener);
0202: }
0203:
0204: /**
0205: * Adds the listener to the collection of listeners who will
0206: * be notified when help events are generated for the control,
0207: * by sending it one of the messages defined in the
0208: * <code>HelpListener</code> interface.
0209: *
0210: * @param listener the listener which should be notified
0211: *
0212: * @exception IllegalArgumentException <ul>
0213: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0214: * </ul>
0215: * @exception SWTException <ul>
0216: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0217: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0218: * </ul>
0219: *
0220: * @see HelpListener
0221: * @see #removeHelpListener
0222: */
0223: public void addHelpListener(HelpListener listener) {
0224: checkWidget();
0225: if (listener == null)
0226: error(SWT.ERROR_NULL_ARGUMENT);
0227: TypedListener typedListener = new TypedListener(listener);
0228: addListener(SWT.Help, typedListener);
0229: }
0230:
0231: /**
0232: * Adds the listener to the collection of listeners who will
0233: * be notified when keys are pressed and released on the system keyboard, by sending
0234: * it one of the messages defined in the <code>KeyListener</code>
0235: * interface.
0236: * <p>
0237: * When a key listener is added to a control, the control
0238: * will take part in widget traversal. By default, all
0239: * traversal keys (such as the tab key and so on) are
0240: * delivered to the control. In order for a control to take
0241: * part in traversal, it should listen for traversal events.
0242: * Otherwise, the user can traverse into a control but not
0243: * out. Note that native controls such as table and tree
0244: * implement key traversal in the operating system. It is
0245: * not necessary to add traversal listeners for these controls,
0246: * unless you want to override the default traversal.
0247: * </p>
0248: * @param listener the listener which should be notified
0249: *
0250: * @exception IllegalArgumentException <ul>
0251: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0252: * </ul>
0253: * @exception SWTException <ul>
0254: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0255: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0256: * </ul>
0257: *
0258: * @see KeyListener
0259: * @see #removeKeyListener
0260: */
0261: public void addKeyListener(KeyListener listener) {
0262: checkWidget();
0263: if (listener == null)
0264: error(SWT.ERROR_NULL_ARGUMENT);
0265: TypedListener typedListener = new TypedListener(listener);
0266: addListener(SWT.KeyUp, typedListener);
0267: addListener(SWT.KeyDown, typedListener);
0268: }
0269:
0270: /**
0271: * Adds the listener to the collection of listeners who will
0272: * be notified when the platform-specific context menu trigger
0273: * has occurred, by sending it one of the messages defined in
0274: * the <code>MenuDetectListener</code> interface.
0275: *
0276: * @param listener the listener which should be notified
0277: *
0278: * @exception IllegalArgumentException <ul>
0279: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0280: * </ul>
0281: * @exception SWTException <ul>
0282: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0283: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0284: * </ul>
0285: *
0286: * @see MenuDetectListener
0287: * @see #removeMenuDetectListener
0288: *
0289: * @since 3.3
0290: */
0291: public void addMenuDetectListener(MenuDetectListener listener) {
0292: checkWidget();
0293: if (listener == null)
0294: error(SWT.ERROR_NULL_ARGUMENT);
0295: TypedListener typedListener = new TypedListener(listener);
0296: addListener(SWT.MenuDetect, typedListener);
0297: }
0298:
0299: /**
0300: * Adds the listener to the collection of listeners who will
0301: * be notified when mouse buttons are pressed and released, by sending
0302: * it one of the messages defined in the <code>MouseListener</code>
0303: * interface.
0304: *
0305: * @param listener the listener which should be notified
0306: *
0307: * @exception IllegalArgumentException <ul>
0308: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0309: * </ul>
0310: * @exception SWTException <ul>
0311: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0312: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0313: * </ul>
0314: *
0315: * @see MouseListener
0316: * @see #removeMouseListener
0317: */
0318: public void addMouseListener(MouseListener listener) {
0319: checkWidget();
0320: if (listener == null)
0321: error(SWT.ERROR_NULL_ARGUMENT);
0322: TypedListener typedListener = new TypedListener(listener);
0323: addListener(SWT.MouseDown, typedListener);
0324: addListener(SWT.MouseUp, typedListener);
0325: addListener(SWT.MouseDoubleClick, typedListener);
0326: }
0327:
0328: /**
0329: * Adds the listener to the collection of listeners who will
0330: * be notified when the mouse passes or hovers over controls, by sending
0331: * it one of the messages defined in the <code>MouseTrackListener</code>
0332: * interface.
0333: *
0334: * @param listener the listener which should be notified
0335: *
0336: * @exception IllegalArgumentException <ul>
0337: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0338: * </ul>
0339: * @exception SWTException <ul>
0340: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0341: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0342: * </ul>
0343: *
0344: * @see MouseTrackListener
0345: * @see #removeMouseTrackListener
0346: */
0347: public void addMouseTrackListener(MouseTrackListener listener) {
0348: checkWidget();
0349: if (listener == null)
0350: error(SWT.ERROR_NULL_ARGUMENT);
0351: TypedListener typedListener = new TypedListener(listener);
0352: addListener(SWT.MouseEnter, typedListener);
0353: addListener(SWT.MouseExit, typedListener);
0354: addListener(SWT.MouseHover, typedListener);
0355: }
0356:
0357: /**
0358: * Adds the listener to the collection of listeners who will
0359: * be notified when the mouse moves, by sending it one of the
0360: * messages defined in the <code>MouseMoveListener</code>
0361: * interface.
0362: *
0363: * @param listener the listener which should be notified
0364: *
0365: * @exception IllegalArgumentException <ul>
0366: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0367: * </ul>
0368: * @exception SWTException <ul>
0369: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0370: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0371: * </ul>
0372: *
0373: * @see MouseMoveListener
0374: * @see #removeMouseMoveListener
0375: */
0376: public void addMouseMoveListener(MouseMoveListener listener) {
0377: checkWidget();
0378: if (listener == null)
0379: error(SWT.ERROR_NULL_ARGUMENT);
0380: TypedListener typedListener = new TypedListener(listener);
0381: addListener(SWT.MouseMove, typedListener);
0382: }
0383:
0384: /**
0385: * Adds the listener to the collection of listeners who will
0386: * be notified when the mouse wheel is scrolled, by sending
0387: * it one of the messages defined in the
0388: * <code>MouseWheelListener</code> interface.
0389: *
0390: * @param listener the listener which should be notified
0391: *
0392: * @exception IllegalArgumentException <ul>
0393: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0394: * </ul>
0395: * @exception SWTException <ul>
0396: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0397: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0398: * </ul>
0399: *
0400: * @see MouseWheelListener
0401: * @see #removeMouseWheelListener
0402: *
0403: * @since 3.3
0404: */
0405: public void addMouseWheelListener(MouseWheelListener listener) {
0406: checkWidget();
0407: if (listener == null)
0408: error(SWT.ERROR_NULL_ARGUMENT);
0409: TypedListener typedListener = new TypedListener(listener);
0410: addListener(SWT.MouseWheel, typedListener);
0411: }
0412:
0413: /**
0414: * Adds the listener to the collection of listeners who will
0415: * be notified when the receiver needs to be painted, by sending it
0416: * one of the messages defined in the <code>PaintListener</code>
0417: * interface.
0418: *
0419: * @param listener the listener which should be notified
0420: *
0421: * @exception IllegalArgumentException <ul>
0422: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0423: * </ul>
0424: * @exception SWTException <ul>
0425: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0426: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0427: * </ul>
0428: *
0429: * @see PaintListener
0430: * @see #removePaintListener
0431: */
0432: public void addPaintListener(PaintListener listener) {
0433: checkWidget();
0434: if (listener == null)
0435: error(SWT.ERROR_NULL_ARGUMENT);
0436: TypedListener typedListener = new TypedListener(listener);
0437: addListener(SWT.Paint, typedListener);
0438: }
0439:
0440: /**
0441: * Adds the listener to the collection of listeners who will
0442: * be notified when traversal events occur, by sending it
0443: * one of the messages defined in the <code>TraverseListener</code>
0444: * interface.
0445: *
0446: * @param listener the listener which should be notified
0447: *
0448: * @exception IllegalArgumentException <ul>
0449: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0450: * </ul>
0451: * @exception SWTException <ul>
0452: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0453: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0454: * </ul>
0455: *
0456: * @see TraverseListener
0457: * @see #removeTraverseListener
0458: */
0459: public void addTraverseListener(TraverseListener listener) {
0460: checkWidget();
0461: if (listener == null)
0462: error(SWT.ERROR_NULL_ARGUMENT);
0463: TypedListener typedListener = new TypedListener(listener);
0464: addListener(SWT.Traverse, typedListener);
0465: }
0466:
0467: int colorProc(int inControl, int inMessage, int inDrawDepth,
0468: int inDrawInColor) {
0469: switch (inMessage) {
0470: case OS.kControlMsgApplyTextColor: {
0471: if (foreground != null) {
0472: OS.RGBForeColor(toRGBColor(foreground));
0473: } else {
0474: OS.SetThemeTextColor(
0475: (short) OS.kThemeTextColorDialogActive,
0476: (short) inDrawDepth, inDrawInColor != 0);
0477: }
0478: return OS.noErr;
0479: }
0480: case OS.kControlMsgSetUpBackground: {
0481: float[] background = this .background != null ? this .background
0482: : getParentBackground();
0483: if (background != null) {
0484: OS.RGBBackColor(toRGBColor(background));
0485: } else {
0486: OS.SetThemeBackground(
0487: (short) OS.kThemeBrushDialogBackgroundActive,
0488: (short) inDrawDepth, inDrawInColor != 0);
0489: }
0490: return OS.noErr;
0491: }
0492: }
0493: return OS.eventNotHandledErr;
0494: }
0495:
0496: int callFocusEventHandler(int nextHandler, int theEvent) {
0497: return OS.CallNextEventHandler(nextHandler, theEvent);
0498: }
0499:
0500: void checkBackground() {
0501: Shell shell = getShell();
0502: if (this == shell)
0503: return;
0504: state &= ~PARENT_BACKGROUND;
0505: Composite composite = parent;
0506: do {
0507: int mode = composite.backgroundMode;
0508: if (mode != 0) {
0509: if (mode == SWT.INHERIT_DEFAULT) {
0510: Control control = this ;
0511: do {
0512: if ((control.state & THEME_BACKGROUND) == 0) {
0513: return;
0514: }
0515: control = control.parent;
0516: } while (control != composite);
0517: }
0518: state |= PARENT_BACKGROUND;
0519: return;
0520: }
0521: if (composite == shell)
0522: break;
0523: composite = composite.parent;
0524: } while (true);
0525: }
0526:
0527: void checkBuffered() {
0528: style |= SWT.DOUBLE_BUFFERED;
0529: }
0530:
0531: /**
0532: * Returns the preferred size of the receiver.
0533: * <p>
0534: * The <em>preferred size</em> of a control is the size that it would
0535: * best be displayed at. The width hint and height hint arguments
0536: * allow the caller to ask a control questions such as "Given a particular
0537: * width, how high does the control need to be to show all of the contents?"
0538: * To indicate that the caller does not wish to constrain a particular
0539: * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint.
0540: * </p>
0541: *
0542: * @param wHint the width hint (can be <code>SWT.DEFAULT</code>)
0543: * @param hHint the height hint (can be <code>SWT.DEFAULT</code>)
0544: * @return the preferred size of the control
0545: *
0546: * @exception SWTException <ul>
0547: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0548: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0549: * </ul>
0550: *
0551: * @see Layout
0552: * @see #getBorderWidth
0553: * @see #getBounds
0554: * @see #getSize
0555: * @see #pack(boolean)
0556: * @see "computeTrim, getClientArea for controls that implement them"
0557: */
0558: public Point computeSize(int wHint, int hHint) {
0559: return computeSize(wHint, hHint, true);
0560: }
0561:
0562: /**
0563: * Returns the preferred size of the receiver.
0564: * <p>
0565: * The <em>preferred size</em> of a control is the size that it would
0566: * best be displayed at. The width hint and height hint arguments
0567: * allow the caller to ask a control questions such as "Given a particular
0568: * width, how high does the control need to be to show all of the contents?"
0569: * To indicate that the caller does not wish to constrain a particular
0570: * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint.
0571: * </p><p>
0572: * If the changed flag is <code>true</code>, it indicates that the receiver's
0573: * <em>contents</em> have changed, therefore any caches that a layout manager
0574: * containing the control may have been keeping need to be flushed. When the
0575: * control is resized, the changed flag will be <code>false</code>, so layout
0576: * manager caches can be retained.
0577: * </p>
0578: *
0579: * @param wHint the width hint (can be <code>SWT.DEFAULT</code>)
0580: * @param hHint the height hint (can be <code>SWT.DEFAULT</code>)
0581: * @param changed <code>true</code> if the control's contents have changed, and <code>false</code> otherwise
0582: * @return the preferred size of the control.
0583: *
0584: * @exception SWTException <ul>
0585: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0586: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0587: * </ul>
0588: *
0589: * @see Layout
0590: * @see #getBorderWidth
0591: * @see #getBounds
0592: * @see #getSize
0593: * @see #pack(boolean)
0594: * @see "computeTrim, getClientArea for controls that implement them"
0595: */
0596: public Point computeSize(int wHint, int hHint, boolean changed) {
0597: checkWidget();
0598: int width = DEFAULT_WIDTH;
0599: int height = DEFAULT_HEIGHT;
0600: if (wHint != SWT.DEFAULT)
0601: width = wHint;
0602: if (hHint != SWT.DEFAULT)
0603: height = hHint;
0604: int border = getBorderWidth();
0605: width += border * 2;
0606: height += border * 2;
0607: return new Point(width, height);
0608: }
0609:
0610: Control computeTabGroup() {
0611: if (isTabGroup())
0612: return this ;
0613: return parent.computeTabGroup();
0614: }
0615:
0616: Control[] computeTabList() {
0617: if (isTabGroup()) {
0618: if (getVisible() && getEnabled()) {
0619: return new Control[] { this };
0620: }
0621: }
0622: return new Control[0];
0623: }
0624:
0625: Control computeTabRoot() {
0626: Control[] tabList = parent._getTabList();
0627: if (tabList != null) {
0628: int index = 0;
0629: while (index < tabList.length) {
0630: if (tabList[index] == this )
0631: break;
0632: index++;
0633: }
0634: if (index == tabList.length) {
0635: if (isTabGroup())
0636: return this ;
0637: }
0638: }
0639: return parent.computeTabRoot();
0640: }
0641:
0642: void createWidget() {
0643: state |= DRAG_DETECT;
0644: checkOrientation(parent);
0645: super .createWidget();
0646: checkBackground();
0647: checkBuffered();
0648: setDefaultFont();
0649: setZOrder();
0650: }
0651:
0652: Color defaultBackground() {
0653: return display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
0654: }
0655:
0656: Font defaultFont() {
0657: byte[] family = new byte[256];
0658: short[] size = new short[1];
0659: byte[] style = new byte[1];
0660: OS.GetThemeFont((short) defaultThemeFont(),
0661: (short) OS.smSystemScript, family, size, style);
0662: short id = OS.FMGetFontFamilyFromName(family);
0663: int[] font = new int[1];
0664: OS.FMGetFontFromFontFamilyInstance(id, style[0], font, null);
0665: return Font.carbon_new(display, OS
0666: .FMGetATSFontRefFromFont(font[0]), style[0], size[0]);
0667: }
0668:
0669: Color defaultForeground() {
0670: return display.getSystemColor(SWT.COLOR_WIDGET_FOREGROUND);
0671: }
0672:
0673: int defaultThemeFont() {
0674: if (display.smallFonts)
0675: return OS.kThemeSmallSystemFont;
0676: return OS.kThemeSystemFont;
0677: }
0678:
0679: void deregister() {
0680: super .deregister();
0681: display.removeWidget(handle);
0682: }
0683:
0684: void destroyWidget() {
0685: int theControl = topHandle();
0686: releaseHandle();
0687: if (theControl != 0) {
0688: OS.DisposeControl(theControl);
0689: }
0690: }
0691:
0692: /**
0693: * Detects a drag and drop gesture. This method is used
0694: * to detect a drag gesture when called from within a mouse
0695: * down listener.
0696: *
0697: * <p>By default, a drag is detected when the gesture
0698: * occurs anywhere within the client area of a control.
0699: * Some controls, such as tables and trees, override this
0700: * behavior. In addition to the operating system specific
0701: * drag gesture, they require the mouse to be inside an
0702: * item. Custom widget writers can use <code>setDragDetect</code>
0703: * to disable the default detection, listen for mouse down,
0704: * and then call <code>dragDetect()</code> from within the
0705: * listener to conditionally detect a drag.
0706: * </p>
0707: *
0708: * @param event the mouse down event
0709: *
0710: * @return <code>true</code> if the gesture occurred, and <code>false</code> otherwise.
0711: *
0712: * @exception IllegalArgumentException <ul>
0713: * <li>ERROR_NULL_ARGUMENT when the event is null</li>
0714: * </ul>
0715: * @exception SWTException <ul>
0716: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0717: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0718: * </ul>
0719: *
0720: * @see DragDetectListener
0721: * @see #addDragDetectListener
0722: *
0723: * @see #getDragDetect
0724: * @see #setDragDetect
0725: *
0726: * @since 3.3
0727: */
0728: public boolean dragDetect(Event event) {
0729: checkWidget();
0730: if (event == null)
0731: error(SWT.ERROR_NULL_ARGUMENT);
0732: return dragDetect(event.button, event.count, event.stateMask,
0733: event.x, event.y);
0734: }
0735:
0736: /**
0737: * Detects a drag and drop gesture. This method is used
0738: * to detect a drag gesture when called from within a mouse
0739: * down listener.
0740: *
0741: * <p>By default, a drag is detected when the gesture
0742: * occurs anywhere within the client area of a control.
0743: * Some controls, such as tables and trees, override this
0744: * behavior. In addition to the operating system specific
0745: * drag gesture, they require the mouse to be inside an
0746: * item. Custom widget writers can use <code>setDragDetect</code>
0747: * to disable the default detection, listen for mouse down,
0748: * and then call <code>dragDetect()</code> from within the
0749: * listener to conditionally detect a drag.
0750: * </p>
0751: *
0752: * @param event the mouse down event
0753: *
0754: * @return <code>true</code> if the gesture occurred, and <code>false</code> otherwise.
0755: *
0756: * @exception IllegalArgumentException <ul>
0757: * <li>ERROR_NULL_ARGUMENT when the event is null</li>
0758: * </ul>
0759: * @exception SWTException <ul>
0760: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0761: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0762: * </ul>
0763: *
0764: * @see DragDetectListener
0765: * @see #addDragDetectListener
0766: *
0767: * @see #getDragDetect
0768: * @see #setDragDetect
0769: *
0770: * @since 3.3
0771: */
0772: public boolean dragDetect(MouseEvent event) {
0773: checkWidget();
0774: if (event == null)
0775: error(SWT.ERROR_NULL_ARGUMENT);
0776: return dragDetect(event.button, event.count, event.stateMask,
0777: event.x, event.y);
0778: }
0779:
0780: boolean dragDetect(int button, int count, int stateMask, int x,
0781: int y) {
0782: if (button != 1 || count != 1)
0783: return false;
0784: if (!dragDetect(x, y, false, null))
0785: return false;
0786: return sendDragEvent(button, stateMask, x, y);
0787: }
0788:
0789: boolean dragDetect(int x, int y, boolean filter, boolean[] consume) {
0790: Rect rect = new Rect();
0791: int window = OS.GetControlOwner(handle);
0792: CGPoint pt = new CGPoint();
0793: OS.HIViewConvertPoint(pt, handle, 0);
0794: x += (int) pt.x;
0795: y += (int) pt.y;
0796: OS
0797: .GetWindowBounds(window,
0798: (short) OS.kWindowStructureRgn, rect);
0799: x += rect.left;
0800: y += rect.top;
0801: org.eclipse.swt.internal.carbon.Point pt1 = new org.eclipse.swt.internal.carbon.Point();
0802: pt1.h = (short) x;
0803: pt1.v = (short) y;
0804: return OS.WaitMouseMoved(pt1);
0805: }
0806:
0807: void drawFocus(int control, int context, boolean hasFocus,
0808: boolean hasBorder, Rect inset) {
0809: fillBackground(control, context, null);
0810: CGRect rect = new CGRect();
0811: OS.HIViewGetBounds(control, rect);
0812: rect.x += inset.left;
0813: rect.y += inset.top;
0814: rect.width -= inset.right + inset.left;
0815: rect.height -= inset.bottom + inset.top;
0816: int state;
0817: if (OS.IsControlEnabled(control)) {
0818: state = OS.IsControlActive(control) ? OS.kThemeStateActive
0819: : OS.kThemeStateInactive;
0820: } else {
0821: state = OS.IsControlActive(control) ? OS.kThemeStateUnavailable
0822: : OS.kThemeStateUnavailableInactive;
0823: }
0824: if (hasBorder) {
0825: HIThemeFrameDrawInfo info = new HIThemeFrameDrawInfo();
0826: info.state = state;
0827: info.kind = OS.kHIThemeFrameTextFieldSquare;
0828: info.isFocused = hasFocus;
0829: OS.HIThemeDrawFrame(rect, info, context,
0830: OS.kHIThemeOrientationNormal);
0831: } else {
0832: OS.HIThemeDrawFocusRect(rect, hasFocus, context,
0833: OS.kHIThemeOrientationNormal);
0834: }
0835: }
0836:
0837: boolean drawFocusRing() {
0838: return hasBorder();
0839: }
0840:
0841: boolean drawGripper(int x, int y, int width, int height,
0842: boolean vertical) {
0843: return false;
0844: }
0845:
0846: void drawWidget(int control, int context, int damageRgn,
0847: int visibleRgn, int theEvent) {
0848: if (control != handle)
0849: return;
0850: if (!hooks(SWT.Paint) && !filters(SWT.Paint))
0851: return;
0852:
0853: /* Retrieve the damage rect */
0854: Rect rect = new Rect();
0855: OS.GetRegionBounds(visibleRgn, rect);
0856:
0857: /* Send paint event */
0858: int[] port = new int[1];
0859: OS.GetPort(port);
0860: GCData data = new GCData();
0861: data.port = port[0];
0862: data.paintEvent = theEvent;
0863: data.visibleRgn = visibleRgn;
0864: GC gc = GC.carbon_new(this , data);
0865: Event event = new Event();
0866: event.gc = gc;
0867: event.x = rect.left;
0868: event.y = rect.top;
0869: event.width = rect.right - rect.left;
0870: event.height = rect.bottom - rect.top;
0871: sendEvent(SWT.Paint, event);
0872: event.gc = null;
0873: gc.dispose();
0874: }
0875:
0876: void enableWidget(boolean enabled) {
0877: int topHandle = topHandle();
0878: if (enabled) {
0879: OS.EnableControl(topHandle);
0880: } else {
0881: OS.DisableControl(topHandle);
0882: }
0883: }
0884:
0885: boolean equals(float[] color1, float[] color2) {
0886: if (color1 == color2)
0887: return true;
0888: if (color1 == null)
0889: return color2 == null;
0890: if (color2 == null)
0891: return color1 == null;
0892: for (int i = 0; i < color1.length; i++) {
0893: if (color1[i] != color2[i])
0894: return false;
0895: }
0896: return true;
0897: }
0898:
0899: void fillBackground(int control, int context, Rectangle bounds) {
0900: OS.CGContextSaveGState(context);
0901: CGRect rect = new CGRect();
0902: if (bounds != null) {
0903: rect.x = bounds.x;
0904: rect.y = bounds.y;
0905: rect.width = bounds.width;
0906: rect.height = bounds.height;
0907: } else {
0908: OS.HIViewGetBounds(control, rect);
0909: }
0910: Control widget = findBackgroundControl();
0911: if (widget != null && widget.backgroundImage != null) {
0912: CGPoint pt = new CGPoint();
0913: OS.HIViewConvertPoint(pt, control, widget.handle);
0914: OS.CGContextTranslateCTM(context, -pt.x, -pt.y);
0915: Pattern pattern = new Pattern(display,
0916: widget.backgroundImage);
0917: GCData data = new GCData();
0918: data.device = display;
0919: data.background = widget.getBackgroundColor().handle;
0920: GC gc = GC.carbon_new(context, data);
0921: gc.setBackgroundPattern(pattern);
0922: gc.fillRectangle((int) (rect.x + pt.x),
0923: (int) (rect.y + pt.y), (int) rect.width,
0924: (int) rect.height);
0925: gc.dispose();
0926: pattern.dispose();
0927: } else if (widget != null && widget.background != null) {
0928: int colorspace = OS.CGColorSpaceCreateDeviceRGB();
0929: OS.CGContextSetFillColorSpace(context, colorspace);
0930: OS.CGContextSetFillColor(context, widget.background);
0931: OS.CGColorSpaceRelease(colorspace);
0932: OS.CGContextSetAlpha(context, getThemeAlpha());
0933: OS.CGContextFillRect(context, rect);
0934: } else {
0935: if (OS.VERSION >= 0x1040) {
0936: OS.HIThemeSetFill(OS.kThemeBrushDialogBackgroundActive,
0937: 0, context, OS.kHIThemeOrientationNormal);
0938: OS.CGContextSetAlpha(context, getThemeAlpha());
0939: OS.CGContextFillRect(context, rect);
0940: } else {
0941: Rect rect1 = new Rect();
0942: rect1.left = (short) rect.x;
0943: rect1.top = (short) rect.y;
0944: rect1.right = (short) (rect.x + rect.width);
0945: rect1.bottom = (short) (rect.y + rect.height);
0946: OS.SetThemeBackground(
0947: (short) OS.kThemeBrushDialogBackgroundActive,
0948: (short) 0, true);
0949: OS.EraseRect(rect1);
0950: }
0951: }
0952: OS.CGContextRestoreGState(context);
0953: }
0954:
0955: Cursor findCursor() {
0956: if (cursor != null)
0957: return cursor;
0958: return parent.findCursor();
0959: }
0960:
0961: Control findBackgroundControl() {
0962: if (backgroundImage != null || background != null)
0963: return this ;
0964: return (state & PARENT_BACKGROUND) != 0 ? parent
0965: .findBackgroundControl() : null;
0966: }
0967:
0968: Menu[] findMenus(Control control) {
0969: if (menu != null && this != control)
0970: return new Menu[] { menu };
0971: return new Menu[0];
0972: }
0973:
0974: void fixChildren(Shell newShell, Shell oldShell,
0975: Decorations newDecorations, Decorations oldDecorations,
0976: Menu[] menus) {
0977: oldShell.fixShell(newShell, this );
0978: oldDecorations.fixDecorations(newDecorations, this , menus);
0979: }
0980:
0981: void fixFocus(Control focusControl) {
0982: Shell shell = getShell();
0983: Control control = this ;
0984: while (control != shell && (control = control.parent) != null) {
0985: if (control.setFocus())
0986: return;
0987: }
0988: shell.setSavedFocus(focusControl);
0989: int window = OS.GetControlOwner(handle);
0990: OS.ClearKeyboardFocus(window);
0991: }
0992:
0993: int focusHandle() {
0994: return handle;
0995: }
0996:
0997: int focusPart() {
0998: return OS.kControlFocusNextPart;
0999: }
1000:
1001: /**
1002: * Forces the receiver to have the <em>keyboard focus</em>, causing
1003: * all keyboard events to be delivered to it.
1004: *
1005: * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to.
1006: *
1007: * @exception SWTException <ul>
1008: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1009: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1010: * </ul>
1011: *
1012: * @see #setFocus
1013: */
1014: public boolean forceFocus() {
1015: checkWidget();
1016: if (display.focusEvent == SWT.FocusOut)
1017: return false;
1018: Decorations shell = menuShell();
1019: shell.setSavedFocus(this );
1020: if (!isEnabled() || !isVisible()/* || !isActive ()*/)
1021: return false;
1022: if (isFocusControl())
1023: return true;
1024: shell.setSavedFocus(null);
1025: shell.bringToTop(false);
1026: if (isDisposed())
1027: return false;
1028: /*
1029: * Feature in the Macintosh. SetKeyboardFocus() sends kEventControlSetFocusPart
1030: * with the part code equal to kControlFocusNoPart to the control that is about
1031: * to lose focus and then sends kEventControlSetFocusPart with part code equal
1032: * to kControlFocusNextPart to this control (the one that is about to get focus).
1033: * If the control does not accept focus because of the full keyboard access mode,
1034: * kEventControlSetFocusPart is sent again to the control in focus causing multiple
1035: * focus events to happen. The fix is to ignore focus events and issue them only
1036: * if the focus control changed.
1037: */
1038: int focusHandle = focusHandle();
1039: int window = OS.GetControlOwner(focusHandle);
1040: Control oldFocus = display.getFocusControl(window, true);
1041: if (oldFocus == this )
1042: return true;
1043: display.ignoreFocus = true;
1044: OS.SetKeyboardFocus(window, focusHandle, (short) focusPart());
1045: display.ignoreFocus = false;
1046: Control newFocus = display.getFocusControl();
1047: if (oldFocus != newFocus) {
1048: if (oldFocus != null && !oldFocus.isDisposed())
1049: oldFocus.sendFocusEvent(SWT.FocusOut, false);
1050: if (newFocus != null && !newFocus.isDisposed()
1051: && newFocus.isEnabled())
1052: newFocus.sendFocusEvent(SWT.FocusIn, false);
1053: }
1054: if (isDisposed())
1055: return false;
1056: shell.setSavedFocus(this );
1057: return hasFocus();
1058: }
1059:
1060: /**
1061: * Returns the accessible object for the receiver.
1062: * If this is the first time this object is requested,
1063: * then the object is created and returned.
1064: *
1065: * @return the accessible object
1066: *
1067: * @exception SWTException <ul>
1068: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1069: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1070: * </ul>
1071: *
1072: * @see Accessible#addAccessibleListener
1073: * @see Accessible#addAccessibleControlListener
1074: *
1075: * @since 2.0
1076: */
1077: public Accessible getAccessible() {
1078: checkWidget();
1079: if (accessible == null)
1080: accessible = new_Accessible(this );
1081: return accessible;
1082: }
1083:
1084: /**
1085: * Returns the receiver's background color.
1086: *
1087: * @return the background color
1088: *
1089: * @exception SWTException <ul>
1090: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1091: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1092: * </ul>
1093: */
1094: public Color getBackground() {
1095: checkWidget();
1096: Control control = findBackgroundControl();
1097: if (control == null)
1098: control = this ;
1099: return control.getBackgroundColor();
1100: }
1101:
1102: Color getBackgroundColor() {
1103: return background != null ? Color.carbon_new(display,
1104: background) : defaultBackground();
1105: }
1106:
1107: /**
1108: * Returns the receiver's background image.
1109: *
1110: * @return the background image
1111: *
1112: * @exception SWTException <ul>
1113: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1114: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1115: * </ul>
1116: *
1117: * @since 3.2
1118: */
1119: public Image getBackgroundImage() {
1120: checkWidget();
1121: Control control = findBackgroundControl();
1122: if (control == null)
1123: control = this ;
1124: return control.backgroundImage;
1125: }
1126:
1127: /**
1128: * Returns the receiver's border width.
1129: *
1130: * @return the border width
1131: *
1132: * @exception SWTException <ul>
1133: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1134: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1135: * </ul>
1136: */
1137: public int getBorderWidth() {
1138: checkWidget();
1139: return 0;
1140: }
1141:
1142: /**
1143: * Returns a rectangle describing the receiver's size and location
1144: * relative to its parent (or its display if its parent is null),
1145: * unless the receiver is a shell. In this case, the location is
1146: * relative to the display.
1147: *
1148: * @return the receiver's bounding rectangle
1149: *
1150: * @exception SWTException <ul>
1151: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1152: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1153: * </ul>
1154: */
1155: public Rectangle getBounds() {
1156: checkWidget();
1157: return getControlBounds(topHandle());
1158: }
1159:
1160: /**
1161: * Returns <code>true</code> if the receiver is detecting
1162: * drag gestures, and <code>false</code> otherwise.
1163: *
1164: * @return the receiver's drag detect state
1165: *
1166: * @exception SWTException <ul>
1167: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1168: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1169: * </ul>
1170: *
1171: * @since 3.3
1172: */
1173: public boolean getDragDetect() {
1174: checkWidget();
1175: return (state & DRAG_DETECT) != 0;
1176: }
1177:
1178: int getDrawCount(int control) {
1179: if (!isTrimHandle(control) && drawCount > 0)
1180: return drawCount;
1181: return parent.getDrawCount(control);
1182: }
1183:
1184: /**
1185: * Returns the receiver's cursor, or null if it has not been set.
1186: * <p>
1187: * When the mouse pointer passes over a control its appearance
1188: * is changed to match the control's cursor.
1189: * </p>
1190: * </ul>
1191: * @exception SWTException <ul>
1192: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1193: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1194: * </ul>
1195: *
1196: * @since 3.3
1197: */
1198: public Cursor getCursor() {
1199: checkWidget();
1200: return cursor;
1201: }
1202:
1203: /**
1204: * Returns <code>true</code> if the receiver is enabled, and
1205: * <code>false</code> otherwise. A disabled control is typically
1206: * not selectable from the user interface and draws with an
1207: * inactive or "grayed" look.
1208: *
1209: * @return the receiver's enabled state
1210: *
1211: * @exception SWTException <ul>
1212: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1213: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1214: * </ul>
1215: *
1216: * @see #isEnabled
1217: */
1218: public boolean getEnabled() {
1219: checkWidget();
1220: return (state & DISABLED) == 0;
1221: }
1222:
1223: /**
1224: * Returns the font that the receiver will use to paint textual information.
1225: *
1226: * @return the receiver's font
1227: *
1228: * @exception SWTException <ul>
1229: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1230: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1231: * </ul>
1232: */
1233: public Font getFont() {
1234: checkWidget();
1235: return font != null ? font : defaultFont();
1236: }
1237:
1238: /**
1239: * Returns the foreground color that the receiver will use to draw.
1240: *
1241: * @return the receiver's foreground color
1242: *
1243: * @exception SWTException <ul>
1244: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1245: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1246: * </ul>
1247: */
1248: public Color getForeground() {
1249: checkWidget();
1250: return getForegroundColor();
1251: }
1252:
1253: Color getForegroundColor() {
1254: return foreground != null ? Color.carbon_new(display,
1255: foreground) : defaultForeground();
1256: }
1257:
1258: /**
1259: * Returns layout data which is associated with the receiver.
1260: *
1261: * @return the receiver's layout data
1262: *
1263: * @exception SWTException <ul>
1264: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1265: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1266: * </ul>
1267: */
1268: public Object getLayoutData() {
1269: checkWidget();
1270: return layoutData;
1271: }
1272:
1273: /**
1274: * Returns a point describing the receiver's location relative
1275: * to its parent (or its display if its parent is null), unless
1276: * the receiver is a shell. In this case, the point is
1277: * relative to the display.
1278: *
1279: * @return the receiver's location
1280: *
1281: * @exception SWTException <ul>
1282: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1283: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1284: * </ul>
1285: */
1286: public Point getLocation() {
1287: checkWidget();
1288: Rectangle rect = getControlBounds(topHandle());
1289: return new Point(rect.x, rect.y);
1290: }
1291:
1292: /**
1293: * Returns the receiver's pop up menu if it has one, or null
1294: * if it does not. All controls may optionally have a pop up
1295: * menu that is displayed when the user requests one for
1296: * the control. The sequence of key strokes, button presses
1297: * and/or button releases that are used to request a pop up
1298: * menu is platform specific.
1299: *
1300: * @return the receiver's menu
1301: *
1302: * @exception SWTException <ul>
1303: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1304: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1305: * </ul>
1306: */
1307: public Menu getMenu() {
1308: checkWidget();
1309: return menu;
1310: }
1311:
1312: int getMininumHeight() {
1313: return 0;
1314: }
1315:
1316: /**
1317: * Returns the receiver's monitor.
1318: *
1319: * @return the receiver's monitor
1320: *
1321: * @since 3.0
1322: */
1323: public Monitor getMonitor() {
1324: checkWidget();
1325: Monitor[] monitors = display.getMonitors();
1326: if (monitors.length == 1)
1327: return monitors[0];
1328: int index = -1, value = -1;
1329: Rectangle bounds = getBounds();
1330: if (this != getShell()) {
1331: bounds = display.map(this .parent, null, bounds);
1332: }
1333: for (int i = 0; i < monitors.length; i++) {
1334: Rectangle rect = bounds.intersection(monitors[i]
1335: .getBounds());
1336: int area = rect.width * rect.height;
1337: if (area > 0 && area > value) {
1338: index = i;
1339: value = area;
1340: }
1341: }
1342: if (index >= 0)
1343: return monitors[index];
1344: int centerX = bounds.x + bounds.width / 2, centerY = bounds.y
1345: + bounds.height / 2;
1346: for (int i = 0; i < monitors.length; i++) {
1347: Rectangle rect = monitors[i].getBounds();
1348: int x = centerX < rect.x ? rect.x - centerX
1349: : centerX > rect.x + rect.width ? centerX - rect.x
1350: - rect.width : 0;
1351: int y = centerY < rect.y ? rect.y - centerY
1352: : centerY > rect.y + rect.height ? centerY - rect.y
1353: - rect.height : 0;
1354: int distance = x * x + y * y;
1355: if (index == -1 || distance < value) {
1356: index = i;
1357: value = distance;
1358: }
1359: }
1360: return monitors[index];
1361: }
1362:
1363: /**
1364: * Returns the receiver's parent, which must be a <code>Composite</code>
1365: * or null when the receiver is a shell that was created with null or
1366: * a display for a parent.
1367: *
1368: * @return the receiver's parent
1369: *
1370: * @exception SWTException <ul>
1371: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1372: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1373: * </ul>
1374: */
1375: public Composite getParent() {
1376: checkWidget();
1377: return parent;
1378: }
1379:
1380: float[] getParentBackground() {
1381: return parent.background;
1382: }
1383:
1384: Control[] getPath() {
1385: int count = 0;
1386: Shell shell = getShell();
1387: Control control = this ;
1388: while (control != shell) {
1389: count++;
1390: control = control.parent;
1391: }
1392: control = this ;
1393: Control[] result = new Control[count];
1394: while (control != shell) {
1395: result[--count] = control;
1396: control = control.parent;
1397: }
1398: return result;
1399: }
1400:
1401: /**
1402: * Returns the receiver's shell. For all controls other than
1403: * shells, this simply returns the control's nearest ancestor
1404: * shell. Shells return themselves, even if they are children
1405: * of other shells.
1406: *
1407: * @return the receiver's shell
1408: *
1409: * @exception SWTException <ul>
1410: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1411: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1412: * </ul>
1413: *
1414: * @see #getParent
1415: */
1416: public Shell getShell() {
1417: checkWidget();
1418: return parent.getShell();
1419: }
1420:
1421: /**
1422: * Returns a point describing the receiver's size. The
1423: * x coordinate of the result is the width of the receiver.
1424: * The y coordinate of the result is the height of the
1425: * receiver.
1426: *
1427: * @return the receiver's size
1428: *
1429: * @exception SWTException <ul>
1430: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1431: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1432: * </ul>
1433: */
1434: public Point getSize() {
1435: checkWidget();
1436: return getControlSize(topHandle());
1437: }
1438:
1439: /**
1440: * Returns the receiver's tool tip text, or null if it has
1441: * not been set.
1442: *
1443: * @return the receiver's tool tip text
1444: *
1445: * @exception SWTException <ul>
1446: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1447: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1448: * </ul>
1449: */
1450: public String getToolTipText() {
1451: checkWidget();
1452: return toolTipText;
1453: }
1454:
1455: float getThemeAlpha() {
1456: return 1 * parent.getThemeAlpha();
1457: }
1458:
1459: /**
1460: * Returns <code>true</code> if the receiver is visible, and
1461: * <code>false</code> otherwise.
1462: * <p>
1463: * If one of the receiver's ancestors is not visible or some
1464: * other condition makes the receiver not visible, this method
1465: * may still indicate that it is considered visible even though
1466: * it may not actually be showing.
1467: * </p>
1468: *
1469: * @return the receiver's visibility state
1470: *
1471: * @exception SWTException <ul>
1472: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1473: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1474: * </ul>
1475: */
1476: public boolean getVisible() {
1477: checkWidget();
1478: return (state & HIDDEN) == 0;
1479: }
1480:
1481: int getVisibleRegion(int control, boolean clipChildren) {
1482: if (!clipChildren)
1483: return super .getVisibleRegion(control, clipChildren);
1484: if (visibleRgn == 0) {
1485: visibleRgn = OS.NewRgn();
1486: calculateVisibleRegion(control, visibleRgn, clipChildren);
1487: }
1488: int result = OS.NewRgn();
1489: OS.CopyRgn(visibleRgn, result);
1490: return result;
1491: }
1492:
1493: boolean hasBorder() {
1494: return (style & SWT.BORDER) != 0;
1495: }
1496:
1497: boolean hasFocus() {
1498: return this == display.getFocusControl();
1499: }
1500:
1501: int helpProc(int inControl, int inGlobalMouse, int inRequest,
1502: int outContentProvided, int ioHelpContent) {
1503: switch (inRequest) {
1504: case OS.kHMSupplyContent: {
1505: short[] contentProvided = { OS.kHMContentNotProvidedDontPropagate };
1506: if (toolTipText != null && toolTipText.length() != 0) {
1507: char[] buffer = new char[toolTipText.length()];
1508: toolTipText.getChars(0, buffer.length, buffer, 0);
1509: int length = fixMnemonic(buffer);
1510: if (display.helpString != 0)
1511: OS.CFRelease(display.helpString);
1512: display.helpString = OS.CFStringCreateWithCharacters(
1513: OS.kCFAllocatorDefault, buffer, length);
1514: HMHelpContentRec helpContent = new HMHelpContentRec();
1515: OS.memmove(helpContent, ioHelpContent,
1516: HMHelpContentRec.sizeof);
1517: helpContent.version = OS.kMacHelpVersion;
1518:
1519: /*
1520: * Feature in the Macintosh. Despite the fact that the Mac
1521: * provides 23 different types of alignment for the help text,
1522: * it does not allow the text to be positioned at the current
1523: * mouse position. The fix is to center the text in a rectangle
1524: * that surrounds the original position of the mouse. As the
1525: * mouse is moved, this rectangle is grown to include the new
1526: * location of the mouse. The help text is then centered by
1527: * the Mac in the new rectangle that was carefully constructed
1528: * such that the help text will stay in the same position.
1529: */
1530: int cursorHeight = 16;
1531: helpContent.tagSide = (short) OS.kHMAbsoluteCenterAligned;
1532: org.eclipse.swt.internal.carbon.Point pt = new org.eclipse.swt.internal.carbon.Point();
1533: OS.memmove(pt, new int[] { inGlobalMouse }, 4);
1534: int x = pt.h;
1535: int y = pt.v;
1536: if (display.helpWidget != this ) {
1537: display.lastHelpX = x + cursorHeight / 2;
1538: display.lastHelpY = y + cursorHeight + cursorHeight
1539: / 2;
1540: }
1541: int jitter = 4;
1542: int deltaX = Math.abs(display.lastHelpX - x) + jitter;
1543: int deltaY = Math.abs(display.lastHelpY - y) + jitter;
1544: x = display.lastHelpX - deltaX;
1545: y = display.lastHelpY - deltaY;
1546: int width = deltaX * 2;
1547: int height = deltaY * 2;
1548: display.helpWidget = this ;
1549: helpContent.absHotRect_left = (short) x;
1550: helpContent.absHotRect_top = (short) y;
1551: helpContent.absHotRect_right = (short) (x + width);
1552: helpContent.absHotRect_bottom = (short) (y + height);
1553:
1554: helpContent.content0_contentType = OS.kHMCFStringContent;
1555: helpContent.content0_tagCFString = display.helpString;
1556: helpContent.content1_contentType = OS.kHMCFStringContent;
1557: helpContent.content1_tagCFString = display.helpString;
1558: OS.memmove(ioHelpContent, helpContent,
1559: HMHelpContentRec.sizeof);
1560: contentProvided[0] = OS.kHMContentProvided;
1561: }
1562: OS.memmove(outContentProvided, contentProvided, 2);
1563: break;
1564: }
1565: case OS.kHMDisposeContent: {
1566: if (display.helpString != 0)
1567: OS.CFRelease(display.helpString);
1568: display.helpWidget = null;
1569: display.helpString = 0;
1570: break;
1571: }
1572: }
1573: return OS.noErr;
1574: }
1575:
1576: void hookEvents() {
1577: super .hookEvents();
1578: int controlProc = display.controlProc;
1579: int[] mask = new int[] { OS.kEventClassControl,
1580: OS.kEventControlActivate, OS.kEventClassControl,
1581: OS.kEventControlApplyBackground, OS.kEventClassControl,
1582: OS.kEventControlBoundsChanged, OS.kEventClassControl,
1583: OS.kEventControlClick, OS.kEventClassControl,
1584: OS.kEventControlContextualMenuClick,
1585: OS.kEventClassControl, OS.kEventControlDeactivate,
1586: OS.kEventClassControl, OS.kEventControlDraw,
1587: OS.kEventClassControl, OS.kEventControlHit,
1588: OS.kEventClassControl, OS.kEventControlSetCursor,
1589: OS.kEventClassControl, OS.kEventControlSetFocusPart,
1590: OS.kEventClassControl, OS.kEventControlGetFocusPart,
1591: OS.kEventClassControl, OS.kEventControlTrack,
1592: OS.kEventClassControl, OS.kEventControlHitTest,
1593: OS.kEventClassControl,
1594: OS.kEventControlGetClickActivation, };
1595: int controlTarget = OS.GetControlEventTarget(handle);
1596: OS.InstallEventHandler(controlTarget, controlProc,
1597: mask.length / 2, mask, handle, null);
1598: int accessibilityProc = display.accessibilityProc;
1599: mask = new int[] { OS.kEventClassAccessibility,
1600: OS.kEventAccessibleGetChildAtPoint,
1601: OS.kEventClassAccessibility,
1602: OS.kEventAccessibleGetFocusedChild,
1603: OS.kEventClassAccessibility,
1604: OS.kEventAccessibleGetAllAttributeNames,
1605: OS.kEventClassAccessibility,
1606: OS.kEventAccessibleGetNamedAttribute, };
1607: OS.InstallEventHandler(controlTarget, accessibilityProc,
1608: mask.length / 2, mask, handle, null);
1609: int helpProc = display.helpProc;
1610: OS.HMInstallControlContentCallback(handle, helpProc);
1611: int colorProc = display.colorProc;
1612: OS.SetControlColorProc(handle, colorProc);
1613: if (OS.GetControlAction(handle) == 0) {
1614: OS.SetControlAction(handle, display.actionProc);
1615: }
1616: }
1617:
1618: /**
1619: * Invokes platform specific functionality to allocate a new GC handle.
1620: * <p>
1621: * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
1622: * API for <code>Control</code>. It is marked public only so that it
1623: * can be shared within the packages provided by SWT. It is not
1624: * available on all platforms, and should never be called from
1625: * application code.
1626: * </p>
1627: *
1628: * @param data the platform specific GC data
1629: * @return the platform specific GC handle
1630: */
1631: public int internal_new_GC(GCData data) {
1632: checkWidget();
1633: int window = OS.GetControlOwner(handle);
1634: int port = data != null ? data.port : 0;
1635: if (port == 0)
1636: port = OS.GetWindowPort(window);
1637: int context;
1638: int[] buffer = new int[1];
1639: boolean isPaint = data != null && data.paintEvent != 0;
1640: if (isPaint) {
1641: OS.GetEventParameter(data.paintEvent,
1642: OS.kEventParamCGContextRef, OS.typeCGContextRef,
1643: null, 4, null, buffer);
1644: } else {
1645: OS.CreateCGContextForPort(port, buffer);
1646: }
1647: context = buffer[0];
1648: if (context == 0)
1649: SWT.error(SWT.ERROR_NO_HANDLES);
1650: int visibleRgn = 0;
1651: if (data != null && data.paintEvent != 0) {
1652: visibleRgn = data.visibleRgn;
1653: } else {
1654: if (getDrawCount(handle) > 0) {
1655: visibleRgn = OS.NewRgn();
1656: } else {
1657: visibleRgn = getVisibleRegion(handle, true);
1658: }
1659: }
1660: Rect rect = new Rect();
1661: Rect portRect = new Rect();
1662: OS.GetControlBounds(handle, rect);
1663: OS.GetPortBounds(port, portRect);
1664: if (isPaint) {
1665: rect.right += rect.left;
1666: rect.bottom += rect.top;
1667: rect.left = rect.top = 0;
1668: } else {
1669: int[] contentView = new int[1];
1670: OS.HIViewFindByID(OS.HIViewGetRoot(window), OS
1671: .kHIViewWindowContentID(), contentView);
1672: CGPoint pt = new CGPoint();
1673: OS.HIViewConvertPoint(pt, OS.HIViewGetSuperview(handle),
1674: contentView[0]);
1675: rect.left += (int) pt.x;
1676: rect.top += (int) pt.y;
1677: rect.right += (int) pt.x;
1678: rect.bottom += (int) pt.y;
1679: OS.ClipCGContextToRegion(context, portRect, visibleRgn);
1680: int portHeight = portRect.bottom - portRect.top;
1681: OS.CGContextScaleCTM(context, 1, -1);
1682: OS.CGContextTranslateCTM(context, rect.left, -portHeight
1683: + rect.top);
1684: }
1685: if (data != null) {
1686: int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
1687: if ((data.style & mask) == 0) {
1688: data.style |= style & (mask | SWT.MIRRORED);
1689: }
1690: data.device = display;
1691: data.thread = display.thread;
1692: data.foreground = getForegroundColor().handle;
1693: Control control = findBackgroundControl();
1694: if (control == null)
1695: control = this ;
1696: data.background = control.getBackgroundColor().handle;
1697: data.font = font != null ? font : defaultFont();
1698: data.visibleRgn = visibleRgn;
1699: data.control = handle;
1700: data.portRect = portRect;
1701: data.controlRect = rect;
1702: data.insetRect = getInset();
1703:
1704: if (data.paintEvent == 0) {
1705: if (gcs == null)
1706: gcs = new GCData[4];
1707: int index = 0;
1708: while (index < gcs.length && gcs[index] != null)
1709: index++;
1710: if (index == gcs.length) {
1711: GCData[] newGCs = new GCData[gcs.length + 4];
1712: System.arraycopy(gcs, 0, newGCs, 0, gcs.length);
1713: gcs = newGCs;
1714: }
1715: gcs[index] = data;
1716: }
1717: }
1718: return context;
1719: }
1720:
1721: /**
1722: * Invokes platform specific functionality to dispose a GC handle.
1723: * <p>
1724: * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
1725: * API for <code>Control</code>. It is marked public only so that it
1726: * can be shared within the packages provided by SWT. It is not
1727: * available on all platforms, and should never be called from
1728: * application code.
1729: * </p>
1730: *
1731: * @param hDC the platform specific GC handle
1732: * @param data the platform specific GC data
1733: */
1734: public void internal_dispose_GC(int context, GCData data) {
1735: checkWidget();
1736: if (data != null) {
1737: if (data.paintEvent == 0) {
1738: if (data.visibleRgn != 0) {
1739: OS.DisposeRgn(data.visibleRgn);
1740: data.visibleRgn = 0;
1741: }
1742:
1743: int index = 0;
1744: while (index < gcs.length && gcs[index] != data)
1745: index++;
1746: if (index < gcs.length) {
1747: gcs[index] = null;
1748: index = 0;
1749: while (index < gcs.length && gcs[index] == null)
1750: index++;
1751: if (index == gcs.length)
1752: gcs = null;
1753: }
1754: } else {
1755: return;
1756: }
1757: }
1758:
1759: /*
1760: * This code is intentionally commented. Use CGContextSynchronize
1761: * instead of CGContextFlush to improve performance.
1762: */
1763: // OS.CGContextFlush (context);
1764: OS.CGContextSynchronize(context);
1765: OS.CGContextRelease(context);
1766: }
1767:
1768: void invalidateChildrenVisibleRegion(int control) {
1769: }
1770:
1771: void invalidateVisibleRegion(int control) {
1772: int index = 0;
1773: Control[] siblings = parent._getChildren();
1774: while (index < siblings.length && siblings[index] != this )
1775: index++;
1776: for (int i = index; i < siblings.length; i++) {
1777: Control sibling = siblings[i];
1778: sibling.resetVisibleRegion(control);
1779: sibling.invalidateChildrenVisibleRegion(control);
1780: }
1781: parent.resetVisibleRegion(control);
1782: }
1783:
1784: void invalWindowRgn(int window, int rgn) {
1785: parent.invalWindowRgn(window, rgn);
1786: }
1787:
1788: /**
1789: * Returns <code>true</code> if the receiver is enabled and all
1790: * ancestors up to and including the receiver's nearest ancestor
1791: * shell are enabled. Otherwise, <code>false</code> is returned.
1792: * A disabled control is typically not selectable from the user
1793: * interface and draws with an inactive or "grayed" look.
1794: *
1795: * @return the receiver's enabled state
1796: *
1797: * @exception SWTException <ul>
1798: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1799: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1800: * </ul>
1801: *
1802: * @see #getEnabled
1803: */
1804: public boolean isEnabled() {
1805: checkWidget();
1806: return getEnabled() && parent.isEnabled();
1807: }
1808:
1809: boolean isEnabledCursor() {
1810: return isEnabled();
1811: }
1812:
1813: boolean isEnabledModal() {
1814: //NOT DONE - fails for multiple APP MODAL shells
1815: Shell[] shells = display.getShells();
1816: for (int i = 0; i < shells.length; i++) {
1817: Shell modal = shells[i];
1818: if (modal != this && modal.isVisible()) {
1819: if ((modal.style & SWT.PRIMARY_MODAL) != 0) {
1820: Shell shell = getShell();
1821: if (modal.parent == shell) {
1822: return false;
1823: }
1824: }
1825: int bits = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL;
1826: if ((modal.style & bits) != 0) {
1827: Control control = this ;
1828: while (control != null) {
1829: if (control == modal)
1830: break;
1831: control = control.parent;
1832: }
1833: if (control != modal)
1834: return false;
1835: }
1836: }
1837: }
1838: return true;
1839: }
1840:
1841: boolean isFocusAncestor(Control control) {
1842: while (control != null && control != this
1843: && !(control instanceof Shell)) {
1844: control = control.parent;
1845: }
1846: return control == this ;
1847: }
1848:
1849: /**
1850: * Returns <code>true</code> if the receiver has the user-interface
1851: * focus, and <code>false</code> otherwise.
1852: *
1853: * @return the receiver's focus state
1854: *
1855: * @exception SWTException <ul>
1856: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1857: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1858: * </ul>
1859: */
1860: public boolean isFocusControl() {
1861: checkWidget();
1862: Control focusControl = display.focusControl;
1863: if (focusControl != null && !focusControl.isDisposed()) {
1864: return this == focusControl;
1865: }
1866: return hasFocus();
1867: }
1868:
1869: /**
1870: * Returns <code>true</code> if the underlying operating
1871: * system supports this reparenting, otherwise <code>false</code>
1872: *
1873: * @return <code>true</code> if the widget can be reparented, otherwise <code>false</code>
1874: *
1875: * @exception SWTException <ul>
1876: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1877: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1878: * </ul>
1879: */
1880: public boolean isReparentable() {
1881: checkWidget();
1882: return true;
1883: }
1884:
1885: boolean isShowing() {
1886: /*
1887: * This is not complete. Need to check if the
1888: * widget is obscurred by a parent or sibling.
1889: */
1890: if (!isVisible())
1891: return false;
1892: Control control = this ;
1893: while (control != null) {
1894: Point size = control.getSize();
1895: if (size.x == 0 || size.y == 0) {
1896: return false;
1897: }
1898: control = control.parent;
1899: }
1900: return true;
1901: }
1902:
1903: boolean isTabGroup() {
1904: Control[] tabList = parent._getTabList();
1905: if (tabList != null) {
1906: for (int i = 0; i < tabList.length; i++) {
1907: if (tabList[i] == this )
1908: return true;
1909: }
1910: }
1911: int code = traversalCode(0, 0);
1912: if ((code & (SWT.TRAVERSE_ARROW_PREVIOUS | SWT.TRAVERSE_ARROW_NEXT)) != 0)
1913: return false;
1914: return (code & (SWT.TRAVERSE_TAB_PREVIOUS | SWT.TRAVERSE_TAB_NEXT)) != 0;
1915: }
1916:
1917: boolean isTabItem() {
1918: Control[] tabList = parent._getTabList();
1919: if (tabList != null) {
1920: for (int i = 0; i < tabList.length; i++) {
1921: if (tabList[i] == this )
1922: return false;
1923: }
1924: }
1925: int code = traversalCode(0, 0);
1926: return (code & (SWT.TRAVERSE_ARROW_PREVIOUS | SWT.TRAVERSE_ARROW_NEXT)) != 0;
1927: }
1928:
1929: /**
1930: * Returns <code>true</code> if the receiver is visible and all
1931: * ancestors up to and including the receiver's nearest ancestor
1932: * shell are visible. Otherwise, <code>false</code> is returned.
1933: *
1934: * @return the receiver's visibility state
1935: *
1936: * @exception SWTException <ul>
1937: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1938: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1939: * </ul>
1940: *
1941: * @see #getVisible
1942: */
1943: public boolean isVisible() {
1944: checkWidget();
1945: return getVisible() && parent.isVisible();
1946: }
1947:
1948: Decorations menuShell() {
1949: return parent.menuShell();
1950: }
1951:
1952: int kEventAccessibleGetChildAtPoint(int nextHandler, int theEvent,
1953: int userData) {
1954: if (accessible != null) {
1955: return accessible.internal_kEventAccessibleGetChildAtPoint(
1956: nextHandler, theEvent, userData);
1957: }
1958: return OS.eventNotHandledErr;
1959: }
1960:
1961: int kEventAccessibleGetFocusedChild(int nextHandler, int theEvent,
1962: int userData) {
1963: if (accessible != null) {
1964: return accessible.internal_kEventAccessibleGetFocusedChild(
1965: nextHandler, theEvent, userData);
1966: }
1967: return OS.eventNotHandledErr;
1968: }
1969:
1970: int kEventAccessibleGetAllAttributeNames(int nextHandler,
1971: int theEvent, int userData) {
1972: if (accessible != null) {
1973: return accessible
1974: .internal_kEventAccessibleGetAllAttributeNames(
1975: nextHandler, theEvent, userData);
1976: }
1977: return OS.eventNotHandledErr;
1978: }
1979:
1980: int kEventAccessibleGetNamedAttribute(int nextHandler,
1981: int theEvent, int userData) {
1982: if (accessible != null) {
1983: return accessible
1984: .internal_kEventAccessibleGetNamedAttribute(
1985: nextHandler, theEvent, userData);
1986: }
1987: return OS.eventNotHandledErr;
1988: }
1989:
1990: int kEventControlContextualMenuClick(int nextHandler, int theEvent,
1991: int userData) {
1992: int[] theControl = new int[1];
1993: OS.GetEventParameter(theEvent, OS.kEventParamDirectObject,
1994: OS.typeControlRef, null, 4, null, theControl);
1995: Widget widget = display.getWidget(theControl[0]);
1996: while (widget != null && !(widget instanceof Control)) {
1997: OS.GetSuperControl(theControl[0], theControl);
1998: widget = display.getWidget(theControl[0]);
1999: }
2000: if (widget == this && isEnabled()) {
2001: int x, y;
2002: Rect rect = new Rect();
2003: int window = OS.GetControlOwner(handle);
2004: CGPoint pt = new CGPoint();
2005: OS.GetEventParameter(theEvent,
2006: OS.kEventParamWindowMouseLocation, OS.typeHIPoint,
2007: null, CGPoint.sizeof, null, pt);
2008: x = (int) pt.x;
2009: y = (int) pt.y;
2010: OS.GetWindowBounds(window, (short) OS.kWindowStructureRgn,
2011: rect);
2012: x += rect.left;
2013: y += rect.top;
2014: Event event = new Event();
2015: event.x = x;
2016: event.y = y;
2017: sendEvent(SWT.MenuDetect, event);
2018: if (event.doit) {
2019: if (menu != null && !menu.isDisposed()) {
2020: if (event.x != x || event.y != y) {
2021: menu.setLocation(event.x, event.y);
2022: }
2023: menu.setVisible(true);
2024: }
2025: }
2026: }
2027: return OS.eventNotHandledErr;
2028: }
2029:
2030: int kEventControlHitTest(int nextHandler, int theEvent, int userData) {
2031: int result = super .kEventControlHitTest(nextHandler, theEvent,
2032: userData);
2033: if (result == OS.noErr)
2034: return result;
2035: if ((state & GRAB) != 0) {
2036: CGRect rect = new CGRect();
2037: OS.HIViewGetBounds(handle, rect);
2038: CGPoint pt = new CGPoint();
2039: OS.GetEventParameter(theEvent, OS.kEventParamMouseLocation,
2040: OS.typeHIPoint, null, CGPoint.sizeof, null, pt);
2041: if (OS.CGRectContainsPoint(rect, pt) != 0) {
2042: OS.SetEventParameter(theEvent,
2043: OS.kEventParamControlPart,
2044: OS.typeControlPartCode, 2, new short[] { 1 });
2045: }
2046: return OS.noErr;
2047: }
2048: return result;
2049: }
2050:
2051: int kEventControlSetCursor(int nextHandler, int theEvent,
2052: int userData) {
2053: if (!isEnabledCursor())
2054: return OS.noErr;
2055: Cursor cursor = null;
2056: if (isEnabledModal()) {
2057: if ((cursor = findCursor()) != null)
2058: display.setCursor(cursor.handle);
2059: }
2060: return cursor != null ? OS.noErr : OS.eventNotHandledErr;
2061: }
2062:
2063: int kEventControlSetFocusPart(int nextHandler, int theEvent,
2064: int userData) {
2065: display.focusCombo = null;
2066: int result = callFocusEventHandler(nextHandler, theEvent);
2067: if (!display.ignoreFocus) {
2068: if (result == OS.noErr) {
2069: int window = OS.GetControlOwner(handle);
2070: if (window == OS.GetUserFocusWindow()) {
2071: int focusHandle = focusHandle();
2072: int[] focusControl = new int[1];
2073: OS.GetKeyboardFocus(window, focusControl);
2074: short[] part = new short[1];
2075: OS
2076: .GetEventParameter(theEvent,
2077: OS.kEventParamControlPart,
2078: OS.typeControlPartCode, null, 2,
2079: null, part);
2080: if (part[0] == OS.kControlFocusNoPart) {
2081: if (focusControl[0] == focusHandle)
2082: sendFocusEvent(SWT.FocusOut, false);
2083: } else {
2084: if (focusControl[0] != focusHandle)
2085: sendFocusEvent(SWT.FocusIn, false);
2086: }
2087: }
2088: // widget could be disposed at this point
2089: if (isDisposed())
2090: return OS.noErr;
2091: }
2092: }
2093: return result;
2094: }
2095:
2096: int kEventControlTrack(int nextHandler, int theEvent, int userData) {
2097: /*
2098: * Feature in the Macintosh. The default handler of kEventControlTrack
2099: * calls TrackControl() which consumes key and mouse events until the
2100: * tracking is canceled. The fix is to send those events from the
2101: * action proc of the widget by diffing the mouse and modifier keys
2102: * state.
2103: */
2104: Display display = this .display;
2105: display.lastState = OS.GetCurrentEventButtonState();
2106: display.lastModifiers = OS.GetCurrentEventKeyModifiers();
2107: display.grabControl = this ;
2108: int result = super .kEventControlTrack(nextHandler, theEvent,
2109: userData);
2110: display.grabControl = null;
2111: if (isDisposed())
2112: return OS.noErr;
2113: sendTrackEvents();
2114: return result;
2115: }
2116:
2117: int kEventMouseDown(int nextHandler, int theEvent, int userData) {
2118: Shell shell = getShell();
2119: display.dragging = false;
2120: boolean[] consume = new boolean[1];
2121: short[] button = new short[1];
2122: OS.GetEventParameter(theEvent, OS.kEventParamMouseButton,
2123: OS.typeMouseButton, null, 2, null, button);
2124: int[] clickCount = new int[1];
2125: OS.GetEventParameter(theEvent, OS.kEventParamClickCount,
2126: OS.typeUInt32, null, 4, null, clickCount);
2127: if (button[0] == 1 && clickCount[0] == 1
2128: && (state & DRAG_DETECT) != 0 && hooks(SWT.DragDetect)) {
2129: CGPoint pt = new CGPoint();
2130: OS.GetEventParameter(theEvent,
2131: OS.kEventParamWindowMouseLocation, OS.typeHIPoint,
2132: null, CGPoint.sizeof, null, pt);
2133: OS.HIViewConvertPoint(pt, 0, handle);
2134: int x = (int) pt.x;
2135: int y = (int) pt.y;
2136: if (dragDetect(x, y, true, consume)) {
2137: display.dragging = true;
2138: display.dragButton = button[0];
2139: display.dragX = x;
2140: display.dragY = y;
2141: int[] chord = new int[1];
2142: OS.GetEventParameter(theEvent,
2143: OS.kEventParamMouseChord, OS.typeUInt32, null,
2144: 4, null, chord);
2145: display.dragState = chord[0];
2146: int[] modifiers = new int[1];
2147: OS.GetEventParameter(theEvent,
2148: OS.kEventParamKeyModifiers, OS.typeUInt32,
2149: null, 4, null, modifiers);
2150: display.dragModifiers = modifiers[0];
2151: }
2152: if (isDisposed())
2153: return OS.noErr;
2154: }
2155: if (!sendMouseEvent(SWT.MouseDown, button[0],
2156: display.clickCount, 0, false, theEvent))
2157: consume[0] = true;
2158: if (isDisposed())
2159: return OS.noErr;
2160: if (display.clickCount == 2) {
2161: if (!sendMouseEvent(SWT.MouseDoubleClick, button[0],
2162: display.clickCount, 0, false, theEvent))
2163: consume[0] = true;
2164: if (isDisposed())
2165: return OS.noErr;
2166: }
2167: if (!shell.isDisposed())
2168: shell.setActiveControl(this );
2169: return consume[0] ? OS.noErr : OS.eventNotHandledErr;
2170: }
2171:
2172: int kEventMouseDragged(int nextHandler, int theEvent, int userData) {
2173: if (isEnabledModal()) {
2174: if (display.dragging) {
2175: display.dragging = false;
2176: sendDragEvent(display.dragButton, display.dragState,
2177: display.dragModifiers, display.dragX,
2178: display.dragY);
2179: if (isDisposed())
2180: return OS.noErr;
2181: }
2182: int result = sendMouseEvent(SWT.MouseMove, (short) 0, 0, 0,
2183: false, theEvent) ? OS.eventNotHandledErr : OS.noErr;
2184: if (isDisposed())
2185: return OS.noErr;
2186: return result;
2187: }
2188: return OS.eventNotHandledErr;
2189: }
2190:
2191: int kEventMouseMoved(int nextHandler, int theEvent, int userData) {
2192: if (isEnabledModal()) {
2193: return sendMouseEvent(SWT.MouseMove, (short) 0, 0, 0,
2194: false, theEvent) ? OS.eventNotHandledErr : OS.noErr;
2195: }
2196: return OS.eventNotHandledErr;
2197: }
2198:
2199: int kEventMouseUp(int nextHandler, int theEvent, int userData) {
2200: short[] button = new short[1];
2201: OS.GetEventParameter(theEvent, OS.kEventParamMouseButton,
2202: OS.typeMouseButton, null, 2, null, button);
2203: return sendMouseEvent(SWT.MouseUp, button[0],
2204: display.clickCount, 0, false, theEvent) ? OS.eventNotHandledErr
2205: : OS.noErr;
2206: }
2207:
2208: int kEventMouseWheelMoved(int nextHandler, int theEvent,
2209: int userData) {
2210: if ((state & IGNORE_WHEEL) != 0)
2211: return OS.eventNotHandledErr;
2212: short[] wheelAxis = new short[1];
2213: OS.GetEventParameter(theEvent, OS.kEventParamMouseWheelAxis,
2214: OS.typeMouseWheelAxis, null, 2, null, wheelAxis);
2215: int[] wheelDelta = new int[1];
2216: OS.GetEventParameter(theEvent, OS.kEventParamMouseWheelDelta,
2217: OS.typeSInt32, null, 4, null, wheelDelta);
2218: Shell shell = getShell();
2219: Control control = this ;
2220: while (control != null) {
2221: if (!control.sendMouseEvent(SWT.MouseWheel, (short) 0,
2222: wheelDelta[0], SWT.SCROLL_LINE, true, theEvent)) {
2223: break;
2224: }
2225: if (control.sendMouseWheel(wheelAxis[0], wheelDelta[0]))
2226: break;
2227: if (control == this ) {
2228: /*
2229: * Feature in the Macintosh. For some reason, the kEventMouseWheelMoved
2230: * event is sent twice to each application handler with the same mouse wheel
2231: * data. The fix is to set an ignore flag before calling the next handler
2232: * in the handler chain.
2233: */
2234: state |= IGNORE_WHEEL;
2235: int result = OS.CallNextEventHandler(nextHandler,
2236: theEvent);
2237: state &= ~IGNORE_WHEEL;
2238: if (result == OS.noErr)
2239: break;
2240: }
2241: if (control == shell)
2242: break;
2243: control = control.parent;
2244: }
2245: return OS.noErr;
2246: }
2247:
2248: int kEventTextInputUnicodeForKeyEvent(int nextHandler,
2249: int theEvent, int userData) {
2250: int[] keyboardEvent = new int[1];
2251: OS.GetEventParameter(theEvent,
2252: OS.kEventParamTextInputSendKeyboardEvent,
2253: OS.typeEventRef, null, keyboardEvent.length * 4, null,
2254: keyboardEvent);
2255: int[] keyCode = new int[1];
2256: OS.GetEventParameter(keyboardEvent[0], OS.kEventParamKeyCode,
2257: OS.typeUInt32, null, keyCode.length * 4, null, keyCode);
2258: boolean[] consume = new boolean[1];
2259: if (translateTraversal(keyCode[0], keyboardEvent[0], consume))
2260: return OS.noErr;
2261: if (isDisposed())
2262: return OS.noErr;
2263: if (keyCode[0] == 114) { /* Help */
2264: Control control = this ;
2265: while (control != null) {
2266: if (control.hooks(SWT.Help)) {
2267: control.postEvent(SWT.Help);
2268: break;
2269: }
2270: control = control.parent;
2271: }
2272: }
2273: int result = kEventUnicodeKeyPressed(nextHandler, theEvent,
2274: userData);
2275: if (result == OS.noErr || consume[0])
2276: return OS.noErr;
2277: /*
2278: * Feature in the Macintosh. If the focus target is changed
2279: * before the default handler for the widget has run, the key
2280: * goes to the new focus widget. The fix is to explicitly
2281: * send the event to the original focus widget and stop
2282: * the chain of handlers.
2283: */
2284: if (!isDisposed() && !hasFocus()) {
2285: OS.SendEventToEventTarget(theEvent, OS
2286: .GetControlEventTarget(handle));
2287: return OS.noErr;
2288: }
2289: return result;
2290: }
2291:
2292: int kEventUnicodeKeyPressed(int nextHandler, int theEvent,
2293: int userData) {
2294: int[] keyboardEvent = new int[1];
2295: OS.GetEventParameter(theEvent,
2296: OS.kEventParamTextInputSendKeyboardEvent,
2297: OS.typeEventRef, null, keyboardEvent.length * 4, null,
2298: keyboardEvent);
2299: if (!sendKeyEvent(SWT.KeyDown, keyboardEvent[0]))
2300: return OS.noErr;
2301: return OS.eventNotHandledErr;
2302: }
2303:
2304: void markLayout(boolean changed, boolean all) {
2305: /* Do nothing */
2306: }
2307:
2308: /**
2309: * Moves the receiver above the specified control in the
2310: * drawing order. If the argument is null, then the receiver
2311: * is moved to the top of the drawing order. The control at
2312: * the top of the drawing order will not be covered by other
2313: * controls even if they occupy intersecting areas.
2314: *
2315: * @param control the sibling control (or null)
2316: *
2317: * @exception IllegalArgumentException <ul>
2318: * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
2319: * </ul>
2320: * @exception SWTException <ul>
2321: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2322: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2323: * </ul>
2324: *
2325: * @see Control#moveBelow
2326: * @see Composite#getChildren
2327: */
2328: public void moveAbove(Control control) {
2329: checkWidget();
2330: if (control != null) {
2331: if (control.isDisposed())
2332: error(SWT.ERROR_INVALID_ARGUMENT);
2333: if (parent != control.parent)
2334: return;
2335: }
2336: setZOrder(control, true);
2337: }
2338:
2339: /**
2340: * Moves the receiver below the specified control in the
2341: * drawing order. If the argument is null, then the receiver
2342: * is moved to the bottom of the drawing order. The control at
2343: * the bottom of the drawing order will be covered by all other
2344: * controls which occupy intersecting areas.
2345: *
2346: * @param control the sibling control (or null)
2347: *
2348: * @exception IllegalArgumentException <ul>
2349: * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
2350: * </ul>
2351: * @exception SWTException <ul>
2352: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2353: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2354: * </ul>
2355: *
2356: * @see Control#moveAbove
2357: * @see Composite#getChildren
2358: */
2359: public void moveBelow(Control control) {
2360: checkWidget();
2361: if (control != null) {
2362: if (control.isDisposed())
2363: error(SWT.ERROR_INVALID_ARGUMENT);
2364: if (parent != control.parent)
2365: return;
2366: }
2367: setZOrder(control, false);
2368: }
2369:
2370: Accessible new_Accessible(Control control) {
2371: return Accessible.internal_new_Accessible(this );
2372: }
2373:
2374: /**
2375: * Causes the receiver to be resized to its preferred size.
2376: * For a composite, this involves computing the preferred size
2377: * from its layout, if there is one.
2378: *
2379: * @exception SWTException <ul>
2380: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2381: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2382: * </ul>
2383: *
2384: * @see #computeSize(int, int, boolean)
2385: */
2386: public void pack() {
2387: checkWidget();
2388: pack(true);
2389: }
2390:
2391: /**
2392: * Causes the receiver to be resized to its preferred size.
2393: * For a composite, this involves computing the preferred size
2394: * from its layout, if there is one.
2395: * <p>
2396: * If the changed flag is <code>true</code>, it indicates that the receiver's
2397: * <em>contents</em> have changed, therefore any caches that a layout manager
2398: * containing the control may have been keeping need to be flushed. When the
2399: * control is resized, the changed flag will be <code>false</code>, so layout
2400: * manager caches can be retained.
2401: * </p>
2402: *
2403: * @param changed whether or not the receiver's contents have changed
2404: *
2405: * @exception SWTException <ul>
2406: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2407: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2408: * </ul>
2409: *
2410: * @see #computeSize(int, int, boolean)
2411: */
2412: public void pack(boolean changed) {
2413: checkWidget();
2414: setSize(computeSize(SWT.DEFAULT, SWT.DEFAULT, changed));
2415: }
2416:
2417: /**
2418: * Causes the entire bounds of the receiver to be marked
2419: * as needing to be redrawn. The next time a paint request
2420: * is processed, the control will be completely painted,
2421: * including the background.
2422: *
2423: * @exception SWTException <ul>
2424: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2425: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2426: * </ul>
2427: *
2428: * @see #update()
2429: * @see PaintListener
2430: * @see SWT#Paint
2431: * @see SWT#NO_BACKGROUND
2432: * @see SWT#NO_REDRAW_RESIZE
2433: * @see SWT#NO_MERGE_PAINTS
2434: * @see SWT#DOUBLE_BUFFERED
2435: */
2436: public void redraw() {
2437: checkWidget();
2438: redrawWidget(handle, false);
2439: }
2440:
2441: void redraw(boolean children) {
2442: // checkWidget();
2443: redrawWidget(handle, true);
2444: }
2445:
2446: /**
2447: * Causes the rectangular area of the receiver specified by
2448: * the arguments to be marked as needing to be redrawn.
2449: * The next time a paint request is processed, that area of
2450: * the receiver will be painted, including the background.
2451: * If the <code>all</code> flag is <code>true</code>, any
2452: * children of the receiver which intersect with the specified
2453: * area will also paint their intersecting areas. If the
2454: * <code>all</code> flag is <code>false</code>, the children
2455: * will not be painted.
2456: *
2457: * @param x the x coordinate of the area to draw
2458: * @param y the y coordinate of the area to draw
2459: * @param width the width of the area to draw
2460: * @param height the height of the area to draw
2461: * @param all <code>true</code> if children should redraw, and <code>false</code> otherwise
2462: *
2463: * @exception SWTException <ul>
2464: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2465: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2466: * </ul>
2467: *
2468: * @see #update()
2469: * @see PaintListener
2470: * @see SWT#Paint
2471: * @see SWT#NO_BACKGROUND
2472: * @see SWT#NO_REDRAW_RESIZE
2473: * @see SWT#NO_MERGE_PAINTS
2474: * @see SWT#DOUBLE_BUFFERED
2475: */
2476: public void redraw(int x, int y, int width, int height, boolean all) {
2477: checkWidget();
2478: redrawWidget(handle, x, y, width, height, all);
2479: }
2480:
2481: void register() {
2482: super .register();
2483: display.addWidget(handle, this );
2484: }
2485:
2486: void releaseHandle() {
2487: super .releaseHandle();
2488: handle = 0;
2489: parent = null;
2490: }
2491:
2492: void releaseParent() {
2493: setVisible(topHandle(), false);
2494: parent.removeControl(this );
2495: }
2496:
2497: void releaseWidget() {
2498: super .releaseWidget();
2499: if (menu != null && !menu.isDisposed()) {
2500: menu.dispose();
2501: }
2502: if (visibleRgn != 0)
2503: OS.DisposeRgn(visibleRgn);
2504: visibleRgn = 0;
2505: menu = null;
2506: layoutData = null;
2507: if (accessible != null) {
2508: accessible.internal_dispose_Accessible();
2509: }
2510: accessible = null;
2511: }
2512:
2513: /**
2514: * Removes the listener from the collection of listeners who will
2515: * be notified when the control is moved or resized.
2516: *
2517: * @param listener the listener which should no longer be notified
2518: *
2519: * @exception IllegalArgumentException <ul>
2520: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2521: * </ul>
2522: * @exception SWTException <ul>
2523: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2524: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2525: * </ul>
2526: *
2527: * @see ControlListener
2528: * @see #addControlListener
2529: */
2530: public void removeControlListener(ControlListener listener) {
2531: checkWidget();
2532: if (listener == null)
2533: error(SWT.ERROR_NULL_ARGUMENT);
2534: if (eventTable == null)
2535: return;
2536: eventTable.unhook(SWT.Move, listener);
2537: eventTable.unhook(SWT.Resize, listener);
2538: }
2539:
2540: /**
2541: * Removes the listener from the collection of listeners who will
2542: * be notified when a drag gesture occurs.
2543: *
2544: * @param listener the listener which should no longer be notified
2545: *
2546: * @exception IllegalArgumentException <ul>
2547: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2548: * </ul>
2549: * @exception SWTException <ul>
2550: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2551: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2552: * </ul>
2553: *
2554: * @see DragDetectListener
2555: * @see #addDragDetectListener
2556: *
2557: * @since 3.3
2558: */
2559: public void removeDragDetectListener(DragDetectListener listener) {
2560: checkWidget();
2561: if (listener == null)
2562: error(SWT.ERROR_NULL_ARGUMENT);
2563: if (eventTable == null)
2564: return;
2565: eventTable.unhook(SWT.DragDetect, listener);
2566: }
2567:
2568: /**
2569: * Removes the listener from the collection of listeners who will
2570: * be notified when the control gains or loses focus.
2571: *
2572: * @param listener the listener which should no longer be notified
2573: *
2574: * @exception IllegalArgumentException <ul>
2575: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2576: * </ul>
2577: * @exception SWTException <ul>
2578: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2579: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2580: * </ul>
2581: *
2582: * @see FocusListener
2583: * @see #addFocusListener
2584: */
2585: public void removeFocusListener(FocusListener listener) {
2586: checkWidget();
2587: if (listener == null)
2588: error(SWT.ERROR_NULL_ARGUMENT);
2589: if (eventTable == null)
2590: return;
2591: eventTable.unhook(SWT.FocusIn, listener);
2592: eventTable.unhook(SWT.FocusOut, listener);
2593: }
2594:
2595: /**
2596: * Removes the listener from the collection of listeners who will
2597: * be notified when the help events are generated for the control.
2598: *
2599: * @param listener the listener which should no longer be notified
2600: *
2601: * @exception IllegalArgumentException <ul>
2602: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2603: * </ul>
2604: * @exception SWTException <ul>
2605: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2606: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2607: * </ul>
2608: *
2609: * @see HelpListener
2610: * @see #addHelpListener
2611: */
2612: public void removeHelpListener(HelpListener listener) {
2613: checkWidget();
2614: if (listener == null)
2615: error(SWT.ERROR_NULL_ARGUMENT);
2616: if (eventTable == null)
2617: return;
2618: eventTable.unhook(SWT.Help, listener);
2619: }
2620:
2621: /**
2622: * Removes the listener from the collection of listeners who will
2623: * be notified when keys are pressed and released on the system keyboard.
2624: *
2625: * @param listener the listener which should no longer be notified
2626: *
2627: * @exception IllegalArgumentException <ul>
2628: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2629: * </ul>
2630: * @exception SWTException <ul>
2631: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2632: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2633: * </ul>
2634: *
2635: * @see KeyListener
2636: * @see #addKeyListener
2637: */
2638: public void removeKeyListener(KeyListener listener) {
2639: checkWidget();
2640: if (listener == null)
2641: error(SWT.ERROR_NULL_ARGUMENT);
2642: if (eventTable == null)
2643: return;
2644: eventTable.unhook(SWT.KeyUp, listener);
2645: eventTable.unhook(SWT.KeyDown, listener);
2646: }
2647:
2648: /**
2649: * Removes the listener from the collection of listeners who will
2650: * be notified when the platform-specific context menu trigger has
2651: * occurred.
2652: *
2653: * @param listener the listener which should no longer be notified
2654: *
2655: * @exception IllegalArgumentException <ul>
2656: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2657: * </ul>
2658: * @exception SWTException <ul>
2659: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2660: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2661: * </ul>
2662: *
2663: * @see MenuDetectListener
2664: * @see #addMenuDetectListener
2665: *
2666: * @since 3.3
2667: */
2668: public void removeMenuDetectListener(MenuDetectListener listener) {
2669: checkWidget();
2670: if (listener == null)
2671: error(SWT.ERROR_NULL_ARGUMENT);
2672: if (eventTable == null)
2673: return;
2674: eventTable.unhook(SWT.MenuDetect, listener);
2675: }
2676:
2677: /**
2678: * Removes the listener from the collection of listeners who will
2679: * be notified when mouse buttons are pressed and released.
2680: *
2681: * @param listener the listener which should no longer be notified
2682: *
2683: * @exception IllegalArgumentException <ul>
2684: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2685: * </ul>
2686: * @exception SWTException <ul>
2687: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2688: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2689: * </ul>
2690: *
2691: * @see MouseListener
2692: * @see #addMouseListener
2693: */
2694: public void removeMouseListener(MouseListener listener) {
2695: checkWidget();
2696: if (listener == null)
2697: error(SWT.ERROR_NULL_ARGUMENT);
2698: if (eventTable == null)
2699: return;
2700: eventTable.unhook(SWT.MouseDown, listener);
2701: eventTable.unhook(SWT.MouseUp, listener);
2702: eventTable.unhook(SWT.MouseDoubleClick, listener);
2703: }
2704:
2705: /**
2706: * Removes the listener from the collection of listeners who will
2707: * be notified when the mouse moves.
2708: *
2709: * @param listener the listener which should no longer be notified
2710: *
2711: * @exception IllegalArgumentException <ul>
2712: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2713: * </ul>
2714: * @exception SWTException <ul>
2715: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2716: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2717: * </ul>
2718: *
2719: * @see MouseMoveListener
2720: * @see #addMouseMoveListener
2721: */
2722: public void removeMouseMoveListener(MouseMoveListener listener) {
2723: checkWidget();
2724: if (listener == null)
2725: error(SWT.ERROR_NULL_ARGUMENT);
2726: if (eventTable == null)
2727: return;
2728: eventTable.unhook(SWT.MouseMove, listener);
2729: }
2730:
2731: /**
2732: * Removes the listener from the collection of listeners who will
2733: * be notified when the mouse passes or hovers over controls.
2734: *
2735: * @param listener the listener which should no longer be notified
2736: *
2737: * @exception IllegalArgumentException <ul>
2738: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2739: * </ul>
2740: * @exception SWTException <ul>
2741: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2742: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2743: * </ul>
2744: *
2745: * @see MouseTrackListener
2746: * @see #addMouseTrackListener
2747: */
2748: public void removeMouseTrackListener(MouseTrackListener listener) {
2749: checkWidget();
2750: if (listener == null)
2751: error(SWT.ERROR_NULL_ARGUMENT);
2752: if (eventTable == null)
2753: return;
2754: eventTable.unhook(SWT.MouseEnter, listener);
2755: eventTable.unhook(SWT.MouseExit, listener);
2756: eventTable.unhook(SWT.MouseHover, listener);
2757: }
2758:
2759: /**
2760: * Removes the listener from the collection of listeners who will
2761: * be notified when the mouse wheel is scrolled.
2762: *
2763: * @param listener the listener which should no longer be notified
2764: *
2765: * @exception IllegalArgumentException <ul>
2766: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2767: * </ul>
2768: * @exception SWTException <ul>
2769: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2770: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2771: * </ul>
2772: *
2773: * @see MouseWheelListener
2774: * @see #addMouseWheelListener
2775: *
2776: * @since 3.3
2777: */
2778: public void removeMouseWheelListener(MouseWheelListener listener) {
2779: checkWidget();
2780: if (listener == null)
2781: error(SWT.ERROR_NULL_ARGUMENT);
2782: if (eventTable == null)
2783: return;
2784: eventTable.unhook(SWT.MouseWheel, listener);
2785: }
2786:
2787: /**
2788: * Removes the listener from the collection of listeners who will
2789: * be notified when the receiver needs to be painted.
2790: *
2791: * @param listener the listener which should no longer be notified
2792: *
2793: * @exception IllegalArgumentException <ul>
2794: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2795: * </ul>
2796: * @exception SWTException <ul>
2797: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2798: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2799: * </ul>
2800: *
2801: * @see PaintListener
2802: * @see #addPaintListener
2803: */
2804: public void removePaintListener(PaintListener listener) {
2805: checkWidget();
2806: if (listener == null)
2807: error(SWT.ERROR_NULL_ARGUMENT);
2808: if (eventTable == null)
2809: return;
2810: eventTable.unhook(SWT.Paint, listener);
2811: }
2812:
2813: /**
2814: * Removes the listener from the collection of listeners who will
2815: * be notified when traversal events occur.
2816: *
2817: * @param listener the listener which should no longer be notified
2818: *
2819: * @exception IllegalArgumentException <ul>
2820: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2821: * </ul>
2822: * @exception SWTException <ul>
2823: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2824: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2825: * </ul>
2826: *
2827: * @see TraverseListener
2828: * @see #addTraverseListener
2829: */
2830: public void removeTraverseListener(TraverseListener listener) {
2831: checkWidget();
2832: if (listener == null)
2833: error(SWT.ERROR_NULL_ARGUMENT);
2834: if (eventTable == null)
2835: return;
2836: eventTable.unhook(SWT.Traverse, listener);
2837: }
2838:
2839: void resetVisibleRegion(int control) {
2840: if (visibleRgn != 0) {
2841: OS.DisposeRgn(visibleRgn);
2842: visibleRgn = 0;
2843: }
2844: if (gcs != null) {
2845: int visibleRgn = getVisibleRegion(handle, true);
2846: for (int i = 0; i < gcs.length; i++) {
2847: GCData data = gcs[i];
2848: if (data != null) {
2849: data.updateClip = true;
2850: OS.CopyRgn(visibleRgn, data.visibleRgn);
2851: }
2852: }
2853: OS.DisposeRgn(visibleRgn);
2854: }
2855: Object runnable = getData(RESET_VISIBLE_REGION);
2856: if (runnable != null && runnable instanceof Runnable) {
2857: ((Runnable) runnable).run();
2858: }
2859: }
2860:
2861: boolean sendDragEvent(int button, int stateMask, int x, int y) {
2862: Event event = new Event();
2863: event.button = button;
2864: event.x = x;
2865: event.y = y;
2866: event.stateMask = stateMask;
2867: postEvent(SWT.DragDetect, event);
2868: return event.doit;
2869: }
2870:
2871: boolean sendDragEvent(int button, int chord, int modifiers, int x,
2872: int y) {
2873: Event event = new Event();
2874: switch (button) {
2875: case 1:
2876: event.button = 1;
2877: break;
2878: case 2:
2879: event.button = 3;
2880: break;
2881: case 3:
2882: event.button = 2;
2883: break;
2884: case 4:
2885: event.button = 4;
2886: break;
2887: case 5:
2888: event.button = 5;
2889: break;
2890: }
2891: event.x = x;
2892: event.y = y;
2893: setInputState(event, SWT.DragDetect, chord, modifiers);
2894: postEvent(SWT.DragDetect, event);
2895: return event.doit;
2896: }
2897:
2898: void sendFocusEvent(int type, boolean post) {
2899: Display display = this .display;
2900: Shell shell = getShell();
2901: /*
2902: * Feature in the Macintosh. GetKeyboardFocus() returns NULL during
2903: * kEventControlSetFocusPart if the focus part is not kControlFocusNoPart.
2904: * The fix is to remember the focus control and return it during
2905: * kEventControlSetFocusPart.
2906: */
2907: display.focusControl = this ;
2908: display.focusEvent = type;
2909: if (post) {
2910: postEvent(type);
2911: } else {
2912: sendEvent(type);
2913: }
2914: /*
2915: * It is possible that the shell may be
2916: * disposed at this point. If this happens
2917: * don't send the activate and deactivate
2918: * events.
2919: */
2920: if (!shell.isDisposed()) {
2921: switch (type) {
2922: case SWT.FocusIn:
2923: shell.setActiveControl(this );
2924: break;
2925: case SWT.FocusOut:
2926: if (shell != display.getActiveShell()) {
2927: shell.setActiveControl(null);
2928: }
2929: break;
2930: }
2931: }
2932: display.focusEvent = SWT.None;
2933: display.focusControl = null;
2934: }
2935:
2936: boolean sendMouseEvent(int type, short button, int count,
2937: int detail, boolean send, int theEvent) {
2938: CGPoint pt = new CGPoint();
2939: OS.GetEventParameter(theEvent,
2940: OS.kEventParamWindowMouseLocation, OS.typeHIPoint,
2941: null, CGPoint.sizeof, null, pt);
2942: OS.HIViewConvertPoint(pt, 0, handle);
2943: int x = (int) pt.x;
2944: int y = (int) pt.y;
2945: display.lastX = x;
2946: display.lastY = y;
2947: int[] chord = new int[1];
2948: OS.GetEventParameter(theEvent, OS.kEventParamMouseChord,
2949: OS.typeUInt32, null, 4, null, chord);
2950: int[] modifiers = new int[1];
2951: OS.GetEventParameter(theEvent, OS.kEventParamKeyModifiers,
2952: OS.typeUInt32, null, 4, null, modifiers);
2953: return sendMouseEvent(type, button, count, detail, send,
2954: chord[0], (short) x, (short) y, modifiers[0]);
2955: }
2956:
2957: boolean sendMouseEvent(int type, short button, int count,
2958: boolean send, int chord, short x, short y, int modifiers) {
2959: return sendMouseEvent(type, button, count, 0, send, chord, x,
2960: y, modifiers);
2961: }
2962:
2963: boolean sendMouseEvent(int type, short button, int count,
2964: int detail, boolean send, int chord, short x, short y,
2965: int modifiers) {
2966: if (!hooks(type) && !filters(type))
2967: return true;
2968: Event event = new Event();
2969: switch (button) {
2970: case 1:
2971: event.button = 1;
2972: break;
2973: case 2:
2974: event.button = 3;
2975: break;
2976: case 3:
2977: event.button = 2;
2978: break;
2979: case 4:
2980: event.button = 4;
2981: break;
2982: case 5:
2983: event.button = 5;
2984: break;
2985: }
2986: event.x = x;
2987: event.y = y;
2988: event.count = count;
2989: event.detail = detail;
2990: setInputState(event, type, chord, modifiers);
2991: if (send) {
2992: sendEvent(type, event);
2993: if (isDisposed())
2994: return false;
2995: } else {
2996: postEvent(type, event);
2997: }
2998: return event.doit;
2999: }
3000:
3001: boolean sendMouseWheel(short wheelAxis, int wheelDelta) {
3002: return false;
3003: }
3004:
3005: void sendTrackEvents() {
3006: Display display = this .display;
3007: display.runDeferredEvents();
3008: if (isDisposed())
3009: return;
3010: boolean events = false;
3011: if (display.dragging) {
3012: display.dragging = false;
3013: sendDragEvent(display.dragButton, display.dragState,
3014: display.dragModifiers, display.dragX, display.dragY);
3015: if (isDisposed())
3016: return;
3017: events = true;
3018: }
3019: org.eclipse.swt.internal.carbon.Point outPt = new org.eclipse.swt.internal.carbon.Point();
3020: OS.GetGlobalMouse(outPt);
3021: Rect rect = new Rect();
3022: int window = OS.GetControlOwner(handle);
3023: int newX, newY;
3024: CGPoint pt = new CGPoint();
3025: pt.x = outPt.h;
3026: pt.y = outPt.v;
3027: OS.HIViewConvertPoint(pt, 0, handle);
3028: newX = (int) pt.x;
3029: newY = (int) pt.y;
3030: OS
3031: .GetWindowBounds(window,
3032: (short) OS.kWindowStructureRgn, rect);
3033: newX -= rect.left;
3034: newY -= rect.top;
3035: int newModifiers = OS.GetCurrentEventKeyModifiers();
3036: int newState = OS.GetCurrentEventButtonState();
3037: int oldX = display.lastX;
3038: int oldY = display.lastY;
3039: int oldState = display.lastState;
3040: int oldModifiers = display.lastModifiers;
3041: display.lastX = newX;
3042: display.lastY = newY;
3043: display.lastModifiers = newModifiers;
3044: display.lastState = newState;
3045: if (newState != oldState) {
3046: int button = 0, type = SWT.MouseDown;
3047: if ((oldState & 0x1) == 0 && (newState & 0x1) != 0)
3048: button = 1;
3049: if ((oldState & 0x2) == 0 && (newState & 0x2) != 0)
3050: button = 2;
3051: if ((oldState & 0x4) == 0 && (newState & 0x4) != 0)
3052: button = 3;
3053: if ((oldState & 0x8) == 0 && (newState & 0x8) != 0)
3054: button = 4;
3055: if ((oldState & 0x10) == 0 && (newState & 0x10) != 0)
3056: button = 5;
3057: if (button == 0) {
3058: type = SWT.MouseUp;
3059: if ((oldState & 0x1) != 0 && (newState & 0x1) == 0)
3060: button = 1;
3061: if ((oldState & 0x2) != 0 && (newState & 0x2) == 0)
3062: button = 2;
3063: if ((oldState & 0x4) != 0 && (newState & 0x4) == 0)
3064: button = 3;
3065: if ((oldState & 0x8) != 0 && (newState & 0x8) == 0)
3066: button = 4;
3067: if ((oldState & 0x10) != 0 && (newState & 0x10) == 0)
3068: button = 5;
3069: }
3070: if (button != 0) {
3071: sendMouseEvent(type, (short) button, 1, false,
3072: newState, (short) newX, (short) newY,
3073: newModifiers);
3074: events = true;
3075: }
3076: }
3077: if (newModifiers != oldModifiers && !isDisposed()) {
3078: int key = 0, type = SWT.KeyDown;
3079: if ((newModifiers & OS.alphaLock) != 0
3080: && (oldModifiers & OS.alphaLock) == 0)
3081: key = SWT.CAPS_LOCK;
3082: if ((newModifiers & OS.shiftKey) != 0
3083: && (oldModifiers & OS.shiftKey) == 0)
3084: key = SWT.SHIFT;
3085: if ((newModifiers & OS.controlKey) != 0
3086: && (oldModifiers & OS.controlKey) == 0)
3087: key = SWT.CONTROL;
3088: if ((newModifiers & OS.cmdKey) != 0
3089: && (oldModifiers & OS.cmdKey) == 0)
3090: key = SWT.COMMAND;
3091: if ((newModifiers & OS.optionKey) != 0
3092: && (oldModifiers & OS.optionKey) == 0)
3093: key = SWT.ALT;
3094: if (key == 0) {
3095: type = SWT.KeyUp;
3096: if ((newModifiers & OS.alphaLock) == 0
3097: && (oldModifiers & OS.alphaLock) != 0)
3098: key = SWT.CAPS_LOCK;
3099: if ((newModifiers & OS.shiftKey) == 0
3100: && (oldModifiers & OS.shiftKey) != 0)
3101: key = SWT.SHIFT;
3102: if ((newModifiers & OS.controlKey) == 0
3103: && (oldModifiers & OS.controlKey) != 0)
3104: key = SWT.CONTROL;
3105: if ((newModifiers & OS.cmdKey) == 0
3106: && (oldModifiers & OS.cmdKey) != 0)
3107: key = SWT.COMMAND;
3108: if ((newModifiers & OS.optionKey) == 0
3109: && (oldModifiers & OS.optionKey) != 0)
3110: key = SWT.ALT;
3111: }
3112: if (key != 0) {
3113: Event event = new Event();
3114: event.keyCode = key;
3115: setInputState(event, type, newState, newModifiers);
3116: sendKeyEvent(type, event);
3117: events = true;
3118: }
3119: }
3120: if (newX != oldX || newY != oldY && !isDisposed()) {
3121: display.mouseMoved = true;
3122: sendMouseEvent(SWT.MouseMove, (short) 0, 0, false,
3123: newState, (short) newX, (short) newY, newModifiers);
3124: events = true;
3125: }
3126: if (events)
3127: display.runDeferredEvents();
3128: }
3129:
3130: void setBackground() {
3131: redrawWidget(handle, false);
3132: }
3133:
3134: /**
3135: * Sets the receiver's background color to the color specified
3136: * by the argument, or to the default system color for the control
3137: * if the argument is null.
3138: * <p>
3139: * Note: This operation is a hint and may be overridden by the platform.
3140: * For example, on Windows the background of a Button cannot be changed.
3141: * </p>
3142: * @param color the new color (or null)
3143: *
3144: * @exception IllegalArgumentException <ul>
3145: * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
3146: * </ul>
3147: * @exception SWTException <ul>
3148: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3149: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3150: * </ul>
3151: */
3152: public void setBackground(Color color) {
3153: checkWidget();
3154: if (color != null) {
3155: if (color.isDisposed())
3156: SWT.error(SWT.ERROR_INVALID_ARGUMENT);
3157: }
3158: float[] background = color != null ? color.handle : null;
3159: if (equals(background, this .background))
3160: return;
3161: this .background = background;
3162: setBackground(background);
3163: redrawWidget(handle, false);
3164: }
3165:
3166: /**
3167: * Sets the receiver's background image to the image specified
3168: * by the argument, or to the default system color for the control
3169: * if the argument is null. The background image is tiled to fill
3170: * the available space.
3171: * <p>
3172: * Note: This operation is a hint and may be overridden by the platform.
3173: * For example, on Windows the background of a Button cannot be changed.
3174: * </p>
3175: * @param image the new image (or null)
3176: *
3177: * @exception IllegalArgumentException <ul>
3178: * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
3179: * <li>ERROR_INVALID_ARGUMENT - if the argument is not a bitmap</li>
3180: * </ul>
3181: * @exception SWTException <ul>
3182: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3183: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3184: * </ul>
3185: *
3186: * @since 3.2
3187: */
3188: public void setBackgroundImage(Image image) {
3189: checkWidget();
3190: if (image != null && image.isDisposed())
3191: SWT.error(SWT.ERROR_INVALID_ARGUMENT);
3192: if (image == backgroundImage)
3193: return;
3194: backgroundImage = image;
3195: redrawWidget(handle, false);
3196: }
3197:
3198: void setBackground(float[] color) {
3199: setBackground(handle, color);
3200: }
3201:
3202: void setBackground(int control, float[] color) {
3203: ControlFontStyleRec fontStyle = new ControlFontStyleRec();
3204: OS.GetControlData(control, (short) OS.kControlEntireControl,
3205: OS.kControlFontStyleTag, ControlFontStyleRec.sizeof,
3206: fontStyle, null);
3207: if (color != null) {
3208: fontStyle.backColor_red = (short) (color[0] * 0xffff);
3209: fontStyle.backColor_green = (short) (color[1] * 0xffff);
3210: fontStyle.backColor_blue = (short) (color[2] * 0xffff);
3211: fontStyle.flags |= OS.kControlUseBackColorMask;
3212: } else {
3213: fontStyle.flags &= ~OS.kControlUseBackColorMask;
3214: }
3215: OS.SetControlFontStyle(control, fontStyle);
3216: }
3217:
3218: /**
3219: * Sets the receiver's size and location to the rectangular
3220: * area specified by the arguments. The <code>x</code> and
3221: * <code>y</code> arguments are relative to the receiver's
3222: * parent (or its display if its parent is null), unless
3223: * the receiver is a shell. In this case, the <code>x</code>
3224: * and <code>y</code> arguments are relative to the display.
3225: * <p>
3226: * Note: Attempting to set the width or height of the
3227: * receiver to a negative number will cause that
3228: * value to be set to zero instead.
3229: * </p>
3230: *
3231: * @param x the new x coordinate for the receiver
3232: * @param y the new y coordinate for the receiver
3233: * @param width the new width for the receiver
3234: * @param height the new height for the receiver
3235: *
3236: * @exception SWTException <ul>
3237: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3238: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3239: * </ul>
3240: */
3241: public void setBounds(int x, int y, int width, int height) {
3242: checkWidget();
3243: setBounds(x, y, Math.max(0, width), Math.max(0, height), true,
3244: true, true);
3245: }
3246:
3247: int setBounds(int x, int y, int width, int height, boolean move,
3248: boolean resize, boolean events) {
3249: return setBounds(topHandle(), x, y, width, height, move,
3250: resize, events);
3251: }
3252:
3253: /**
3254: * Sets the receiver's size and location to the rectangular
3255: * area specified by the argument. The <code>x</code> and
3256: * <code>y</code> fields of the rectangle are relative to
3257: * the receiver's parent (or its display if its parent is null).
3258: * <p>
3259: * Note: Attempting to set the width or height of the
3260: * receiver to a negative number will cause that
3261: * value to be set to zero instead.
3262: * </p>
3263: *
3264: * @param rect the new bounds for the receiver
3265: *
3266: * @exception SWTException <ul>
3267: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3268: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3269: * </ul>
3270: */
3271: public void setBounds(Rectangle rect) {
3272: checkWidget();
3273: if (rect == null)
3274: error(SWT.ERROR_NULL_ARGUMENT);
3275: setBounds(rect.x, rect.y, Math.max(0, rect.width), Math.max(0,
3276: rect.height), true, true, true);
3277: }
3278:
3279: /**
3280: * If the argument is <code>true</code>, causes the receiver to have
3281: * all mouse events delivered to it until the method is called with
3282: * <code>false</code> as the argument.
3283: *
3284: * @param capture <code>true</code> to capture the mouse, and <code>false</code> to release it
3285: *
3286: * @exception SWTException <ul>
3287: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3288: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3289: * </ul>
3290: */
3291: public void setCapture(boolean capture) {
3292: checkWidget();
3293: }
3294:
3295: /**
3296: * Sets the receiver's cursor to the cursor specified by the
3297: * argument, or to the default cursor for that kind of control
3298: * if the argument is null.
3299: * <p>
3300: * When the mouse pointer passes over a control its appearance
3301: * is changed to match the control's cursor.
3302: * </p>
3303: *
3304: * @param cursor the new cursor (or null)
3305: *
3306: * @exception IllegalArgumentException <ul>
3307: * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
3308: * </ul>
3309: * @exception SWTException <ul>
3310: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3311: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3312: * </ul>
3313: */
3314: public void setCursor(Cursor cursor) {
3315: checkWidget();
3316: if (cursor != null && cursor.isDisposed())
3317: error(SWT.ERROR_INVALID_ARGUMENT);
3318: this .cursor = cursor;
3319: if (!isEnabled())
3320: return;
3321: org.eclipse.swt.internal.carbon.Point where = new org.eclipse.swt.internal.carbon.Point();
3322: OS.GetGlobalMouse(where);
3323: int[] theWindow = new int[1];
3324: if (display.grabControl == this ) {
3325: theWindow[0] = OS.GetControlOwner(handle);
3326: } else {
3327: if (OS.FindWindow(where, theWindow) != OS.inContent)
3328: return;
3329: if (theWindow[0] == 0)
3330: return;
3331: }
3332: Rect rect = new Rect();
3333: OS.GetWindowBounds(theWindow[0], (short) OS.kWindowContentRgn,
3334: rect);
3335: int[] theControl = new int[1];
3336: if (display.grabControl == this ) {
3337: theControl[0] = handle;
3338: } else {
3339: CGPoint inPoint = new CGPoint();
3340: inPoint.x = where.h - rect.left;
3341: inPoint.y = where.v - rect.top;
3342: int[] theRoot = new int[1];
3343: OS.GetRootControl(theWindow[0], theRoot);
3344: OS.HIViewGetSubviewHit(theRoot[0], inPoint, true,
3345: theControl);
3346: int cursorControl = theControl[0];
3347: while (theControl[0] != 0 && theControl[0] != handle) {
3348: OS.GetSuperControl(theControl[0], theControl);
3349: }
3350: if (theControl[0] == 0)
3351: return;
3352: theControl[0] = cursorControl;
3353: do {
3354: Widget widget = display.getWidget(theControl[0]);
3355: if (widget != null) {
3356: if (widget instanceof Control) {
3357: Control control = (Control) widget;
3358: if (control.isEnabled())
3359: break;
3360: }
3361: }
3362: OS.GetSuperControl(theControl[0], theControl);
3363: } while (theControl[0] != 0);
3364: if (theControl[0] == 0) {
3365: theControl[0] = theRoot[0];
3366: Widget widget = display.getWidget(theControl[0]);
3367: if (widget != null && widget instanceof Control) {
3368: Control control = (Control) widget;
3369: theControl[0] = control.handle;
3370: }
3371: }
3372: }
3373: CGPoint pt = new CGPoint();
3374: OS.HIViewConvertPoint(pt, theControl[0], 0);
3375: where.h -= (int) pt.x;
3376: where.v -= (int) pt.y;
3377: OS.GetWindowBounds(theWindow[0],
3378: (short) OS.kWindowStructureRgn, rect);
3379: where.h -= rect.left;
3380: where.v -= rect.top;
3381: int modifiers = OS.GetCurrentEventKeyModifiers();
3382: boolean[] cursorWasSet = new boolean[1];
3383: OS.HandleControlSetCursor(theControl[0], where,
3384: (short) modifiers, cursorWasSet);
3385: if (!cursorWasSet[0])
3386: OS.SetThemeCursor(OS.kThemeArrowCursor);
3387: }
3388:
3389: void setDefaultFont() {
3390: if (display.smallFonts)
3391: setFontStyle(defaultFont());
3392: }
3393:
3394: /**
3395: * Sets the receiver's drag detect state. If the argument is
3396: * <code>true</code>, the receiver will detect drag gestures,
3397: * otherwise these gestures will be ignored.
3398: *
3399: * @param dragDetect the new drag detect state
3400: *
3401: * @exception SWTException <ul>
3402: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3403: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3404: * </ul>
3405: *
3406: * @since 3.3
3407: */
3408: public void setDragDetect(boolean dragDetect) {
3409: checkWidget();
3410: if (dragDetect) {
3411: state |= DRAG_DETECT;
3412: } else {
3413: state &= ~DRAG_DETECT;
3414: }
3415: }
3416:
3417: /**
3418: * Enables the receiver if the argument is <code>true</code>,
3419: * and disables it otherwise. A disabled control is typically
3420: * not selectable from the user interface and draws with an
3421: * inactive or "grayed" look.
3422: *
3423: * @param enabled the new enabled state
3424: *
3425: * @exception SWTException <ul>
3426: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3427: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3428: * </ul>
3429: */
3430: public void setEnabled(boolean enabled) {
3431: checkWidget();
3432: if (((state & DISABLED) == 0) == enabled)
3433: return;
3434: Control control = null;
3435: boolean fixFocus = false;
3436: if (!enabled) {
3437: if (display.focusEvent != SWT.FocusOut) {
3438: control = display.getFocusControl();
3439: fixFocus = isFocusAncestor(control);
3440: }
3441: }
3442: if (enabled) {
3443: state &= ~DISABLED;
3444: } else {
3445: state |= DISABLED;
3446: }
3447: enableWidget(enabled);
3448: if (fixFocus)
3449: fixFocus(control);
3450: }
3451:
3452: /**
3453: * Causes the receiver to have the <em>keyboard focus</em>,
3454: * such that all keyboard events will be delivered to it. Focus
3455: * reassignment will respect applicable platform constraints.
3456: *
3457: * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to.
3458: *
3459: * @exception SWTException <ul>
3460: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3461: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3462: * </ul>
3463: *
3464: * @see #forceFocus
3465: */
3466: public boolean setFocus() {
3467: checkWidget();
3468: if ((style & SWT.NO_FOCUS) != 0)
3469: return false;
3470: return forceFocus();
3471: }
3472:
3473: /**
3474: * Sets the font that the receiver will use to paint textual information
3475: * to the font specified by the argument, or to the default font for that
3476: * kind of control if the argument is null.
3477: *
3478: * @param font the new font (or null)
3479: *
3480: * @exception IllegalArgumentException <ul>
3481: * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
3482: * </ul>
3483: * @exception SWTException <ul>
3484: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3485: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3486: * </ul>
3487: */
3488: public void setFont(Font font) {
3489: checkWidget();
3490: if (font != null) {
3491: if (font.isDisposed())
3492: SWT.error(SWT.ERROR_INVALID_ARGUMENT);
3493: }
3494: this .font = font;
3495: setFontStyle(display.smallFonts ? (font != null ? font
3496: : defaultFont()) : font);
3497: redrawWidget(handle, false);
3498: }
3499:
3500: void setFontStyle(Font font) {
3501: setFontStyle(handle, font);
3502: }
3503:
3504: void setFontStyle(int control, Font font) {
3505: ControlFontStyleRec fontStyle = new ControlFontStyleRec();
3506: OS.GetControlData(control, (short) OS.kControlEntireControl,
3507: OS.kControlFontStyleTag, ControlFontStyleRec.sizeof,
3508: fontStyle, null);
3509: fontStyle.flags &= ~(OS.kControlUseFontMask
3510: | OS.kControlUseSizeMask | OS.kControlUseFaceMask | OS.kControlUseThemeFontIDMask);
3511: if (font != null) {
3512: short[] family = new short[1], style = new short[1];
3513: OS.FMGetFontFamilyInstanceFromFont(font.handle, family,
3514: style);
3515: fontStyle.flags |= OS.kControlUseFontMask
3516: | OS.kControlUseSizeMask | OS.kControlUseFaceMask;
3517: fontStyle.font = family[0];
3518: fontStyle.style = (short) (style[0] | font.style);
3519: fontStyle.size = (short) font.size;
3520: }
3521: OS.SetControlFontStyle(control, fontStyle);
3522: }
3523:
3524: /**
3525: * Sets the receiver's foreground color to the color specified
3526: * by the argument, or to the default system color for the control
3527: * if the argument is null.
3528: * <p>
3529: * Note: This operation is a hint and may be overridden by the platform.
3530: * </p>
3531: * @param color the new color (or null)
3532: *
3533: * @exception IllegalArgumentException <ul>
3534: * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
3535: * </ul>
3536: * @exception SWTException <ul>
3537: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3538: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3539: * </ul>
3540: */
3541: public void setForeground(Color color) {
3542: checkWidget();
3543: if (color != null) {
3544: if (color.isDisposed())
3545: SWT.error(SWT.ERROR_INVALID_ARGUMENT);
3546: }
3547: float[] foreground = color != null ? color.handle : null;
3548: if (equals(foreground, this .foreground))
3549: return;
3550: this .foreground = foreground;
3551: setForeground(foreground);
3552: redrawWidget(handle, false);
3553: }
3554:
3555: void setForeground(float[] color) {
3556: setForeground(handle, color);
3557: }
3558:
3559: void setForeground(int control, float[] color) {
3560: ControlFontStyleRec fontStyle = new ControlFontStyleRec();
3561: OS.GetControlData(control, (short) OS.kControlEntireControl,
3562: OS.kControlFontStyleTag, ControlFontStyleRec.sizeof,
3563: fontStyle, null);
3564: if (color != null) {
3565: fontStyle.foreColor_red = (short) (color[0] * 0xffff);
3566: fontStyle.foreColor_green = (short) (color[1] * 0xffff);
3567: fontStyle.foreColor_blue = (short) (color[2] * 0xffff);
3568: fontStyle.flags |= OS.kControlUseForeColorMask;
3569: } else {
3570: fontStyle.flags &= ~OS.kControlUseForeColorMask;
3571: }
3572: OS.SetControlFontStyle(control, fontStyle);
3573: }
3574:
3575: /**
3576: * Sets the layout data associated with the receiver to the argument.
3577: *
3578: * @param layoutData the new layout data for the receiver.
3579: *
3580: * @exception SWTException <ul>
3581: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3582: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3583: * </ul>
3584: */
3585: public void setLayoutData(Object layoutData) {
3586: checkWidget();
3587: this .layoutData = layoutData;
3588: }
3589:
3590: /**
3591: * Sets the receiver's location to the point specified by
3592: * the arguments which are relative to the receiver's
3593: * parent (or its display if its parent is null), unless
3594: * the receiver is a shell. In this case, the point is
3595: * relative to the display.
3596: *
3597: * @param x the new x coordinate for the receiver
3598: * @param y the new y coordinate for the receiver
3599: *
3600: * @exception SWTException <ul>
3601: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3602: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3603: * </ul>
3604: */
3605: public void setLocation(int x, int y) {
3606: checkWidget();
3607: setBounds(x, y, 0, 0, true, false, true);
3608: }
3609:
3610: /**
3611: * Sets the receiver's location to the point specified by
3612: * the arguments which are relative to the receiver's
3613: * parent (or its display if its parent is null), unless
3614: * the receiver is a shell. In this case, the point is
3615: * relative to the display.
3616: *
3617: * @param location the new location for the receiver
3618: *
3619: * @exception SWTException <ul>
3620: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3621: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3622: * </ul>
3623: */
3624: public void setLocation(Point location) {
3625: checkWidget();
3626: if (location == null)
3627: error(SWT.ERROR_NULL_ARGUMENT);
3628: setBounds(location.x, location.y, 0, 0, true, false, true);
3629: }
3630:
3631: /**
3632: * Sets the receiver's pop up menu to the argument.
3633: * All controls may optionally have a pop up
3634: * menu that is displayed when the user requests one for
3635: * the control. The sequence of key strokes, button presses
3636: * and/or button releases that are used to request a pop up
3637: * menu is platform specific.
3638: * <p>
3639: * Note: Disposing of a control that has a pop up menu will
3640: * dispose of the menu. To avoid this behavior, set the
3641: * menu to null before the control is disposed.
3642: * </p>
3643: *
3644: * @param menu the new pop up menu
3645: *
3646: * @exception IllegalArgumentException <ul>
3647: * <li>ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu</li>
3648: * <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li>
3649: * <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li>
3650: * </ul>
3651: * @exception SWTException <ul>
3652: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3653: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3654: * </ul>
3655: */
3656: public void setMenu(Menu menu) {
3657: checkWidget();
3658: if (menu != null) {
3659: if (menu.isDisposed())
3660: SWT.error(SWT.ERROR_INVALID_ARGUMENT);
3661: if ((menu.style & SWT.POP_UP) == 0) {
3662: error(SWT.ERROR_MENU_NOT_POP_UP);
3663: }
3664: if (menu.parent != menuShell()) {
3665: error(SWT.ERROR_INVALID_PARENT);
3666: }
3667: }
3668: this .menu = menu;
3669: }
3670:
3671: /**
3672: * Changes the parent of the widget to be the one provided if
3673: * the underlying operating system supports this feature.
3674: * Returns <code>true</code> if the parent is successfully changed.
3675: *
3676: * @param parent the new parent for the control.
3677: * @return <code>true</code> if the parent is changed and <code>false</code> otherwise.
3678: *
3679: * @exception IllegalArgumentException <ul>
3680: * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
3681: * <li>ERROR_NULL_ARGUMENT - if the parent is <code>null</code></li>
3682: * </ul>
3683: * @exception SWTException <ul>
3684: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3685: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3686: * </ul>
3687: */
3688: public boolean setParent(Composite parent) {
3689: checkWidget();
3690: if (parent == null)
3691: error(SWT.ERROR_NULL_ARGUMENT);
3692: if (parent.isDisposed())
3693: SWT.error(SWT.ERROR_INVALID_ARGUMENT);
3694: if (this .parent == parent)
3695: return true;
3696: if (!isReparentable())
3697: return false;
3698: releaseParent();
3699: Shell newShell = parent.getShell(), oldShell = getShell();
3700: Decorations newDecorations = parent.menuShell(), oldDecorations = menuShell();
3701: if (oldShell != newShell || oldDecorations != newDecorations) {
3702: Menu[] menus = oldShell.findMenus(this );
3703: fixChildren(newShell, oldShell, newDecorations,
3704: oldDecorations, menus);
3705: }
3706: int topHandle = topHandle();
3707: OS.HIViewAddSubview(parent.handle, topHandle);
3708: OS.HIViewSetVisible(topHandle, (state & HIDDEN) == 0);
3709: OS.HIViewSetZOrder(topHandle, OS.kHIViewZOrderBelow, 0);
3710: this .parent = parent;
3711: return true;
3712: }
3713:
3714: /**
3715: * If the argument is <code>false</code>, causes subsequent drawing
3716: * operations in the receiver to be ignored. No drawing of any kind
3717: * can occur in the receiver until the flag is set to true.
3718: * Graphics operations that occurred while the flag was
3719: * <code>false</code> are lost. When the flag is set to <code>true</code>,
3720: * the entire widget is marked as needing to be redrawn. Nested calls
3721: * to this method are stacked.
3722: * <p>
3723: * Note: This operation is a hint and may not be supported on some
3724: * platforms or for some widgets.
3725: * </p>
3726: *
3727: * @param redraw the new redraw state
3728: *
3729: * @exception SWTException <ul>
3730: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3731: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3732: * </ul>
3733: *
3734: * @see #redraw(int, int, int, int, boolean)
3735: * @see #update()
3736: */
3737: public void setRedraw(boolean redraw) {
3738: checkWidget();
3739: if (redraw) {
3740: if (--drawCount == 0) {
3741: OS.HIViewSetDrawingEnabled(handle, true);
3742: invalidateVisibleRegion(handle);
3743: redrawWidget(handle, true);
3744: }
3745: } else {
3746: if (drawCount == 0) {
3747: OS.HIViewSetDrawingEnabled(handle, false);
3748: invalidateVisibleRegion(handle);
3749: }
3750: drawCount++;
3751: }
3752: }
3753:
3754: boolean setRadioSelection(boolean value) {
3755: return false;
3756: }
3757:
3758: /**
3759: * Sets the receiver's size to the point specified by the arguments.
3760: * <p>
3761: * Note: Attempting to set the width or height of the
3762: * receiver to a negative number will cause that
3763: * value to be set to zero instead.
3764: * </p>
3765: *
3766: * @param width the new width for the receiver
3767: * @param height the new height for the receiver
3768: *
3769: * @exception SWTException <ul>
3770: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3771: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3772: * </ul>
3773: */
3774: public void setSize(int width, int height) {
3775: checkWidget();
3776: setBounds(0, 0, Math.max(0, width), Math.max(0, height), false,
3777: true, true);
3778: }
3779:
3780: /**
3781: * Sets the receiver's size to the point specified by the argument.
3782: * <p>
3783: * Note: Attempting to set the width or height of the
3784: * receiver to a negative number will cause them to be
3785: * set to zero instead.
3786: * </p>
3787: *
3788: * @param size the new size for the receiver
3789: *
3790: * @exception IllegalArgumentException <ul>
3791: * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
3792: * </ul>
3793: * @exception SWTException <ul>
3794: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3795: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3796: * </ul>
3797: */
3798: public void setSize(Point size) {
3799: checkWidget();
3800: if (size == null)
3801: error(SWT.ERROR_NULL_ARGUMENT);
3802: setBounds(0, 0, Math.max(0, size.x), Math.max(0, size.y),
3803: false, true, true);
3804: }
3805:
3806: boolean setTabGroupFocus() {
3807: return setTabItemFocus();
3808: }
3809:
3810: boolean setTabItemFocus() {
3811: if (!isShowing())
3812: return false;
3813: return forceFocus();
3814: }
3815:
3816: /**
3817: * Sets the receiver's tool tip text to the argument, which
3818: * may be null indicating that no tool tip text should be shown.
3819: *
3820: * @param string the new tool tip text (or null)
3821: *
3822: * @exception SWTException <ul>
3823: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3824: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3825: * </ul>
3826: */
3827: public void setToolTipText(String string) {
3828: checkWidget();
3829: toolTipText = string;
3830: if (display.helpWidget == this ) {
3831: display.helpWidget = null;
3832: OS.HMInstallControlContentCallback(handle, 0);
3833: OS
3834: .HMInstallControlContentCallback(handle,
3835: display.helpProc);
3836: }
3837: }
3838:
3839: /**
3840: * Marks the receiver as visible if the argument is <code>true</code>,
3841: * and marks it invisible otherwise.
3842: * <p>
3843: * If one of the receiver's ancestors is not visible or some
3844: * other condition makes the receiver not visible, marking
3845: * it visible may not actually cause it to be displayed.
3846: * </p>
3847: *
3848: * @param visible the new visibility state
3849: *
3850: * @exception SWTException <ul>
3851: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3852: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3853: * </ul>
3854: */
3855: public void setVisible(boolean visible) {
3856: checkWidget();
3857: if (visible) {
3858: if ((state & HIDDEN) == 0)
3859: return;
3860: state &= ~HIDDEN;
3861: } else {
3862: if ((state & HIDDEN) != 0)
3863: return;
3864: state |= HIDDEN;
3865: }
3866: if (visible) {
3867: /*
3868: * It is possible (but unlikely), that application
3869: * code could have disposed the widget in the show
3870: * event. If this happens, just return.
3871: */
3872: sendEvent(SWT.Show);
3873: if (isDisposed())
3874: return;
3875: }
3876:
3877: /*
3878: * Feature in the Macintosh. If the receiver has focus, hiding
3879: * the receiver causes no control to have focus. Also, the focus
3880: * needs to be cleared from any TXNObject so that it stops blinking
3881: * the caret. The fix is to assign focus to the first ancestor
3882: * control that takes focus. If no control will take focus, clear
3883: * the focus control.
3884: */
3885: Control control = null;
3886: boolean fixFocus = false;
3887: if (!visible) {
3888: if (display.focusEvent != SWT.FocusOut) {
3889: control = display.getFocusControl();
3890: fixFocus = isFocusAncestor(control);
3891: }
3892: }
3893: setVisible(topHandle(), visible);
3894: if (!visible) {
3895: /*
3896: * It is possible (but unlikely), that application
3897: * code could have disposed the widget in the show
3898: * event. If this happens, just return.
3899: */
3900: sendEvent(SWT.Hide);
3901: if (isDisposed())
3902: return;
3903: }
3904: if (fixFocus)
3905: fixFocus(control);
3906: }
3907:
3908: void setZOrder() {
3909: int topHandle = topHandle();
3910: int parentHandle = parent.handle;
3911: OS.HIViewAddSubview(parentHandle, topHandle);
3912: OS.HIViewSetZOrder(topHandle, OS.kHIViewZOrderBelow, 0);
3913: Rect rect = getInset();
3914: rect.right = rect.left;
3915: rect.bottom = rect.top;
3916: OS.SetControlBounds(topHandle, rect);
3917: }
3918:
3919: void setZOrder(Control control, boolean above) {
3920: int otherControl = control == null ? 0 : control.topHandle();
3921: setZOrder(topHandle(), otherControl, above);
3922: }
3923:
3924: void sort(int[] items) {
3925: /* Shell Sort from K&R, pg 108 */
3926: int length = items.length;
3927: for (int gap = length / 2; gap > 0; gap /= 2) {
3928: for (int i = gap; i < length; i++) {
3929: for (int j = i - gap; j >= 0; j -= gap) {
3930: if (items[j] <= items[j + gap]) {
3931: int swap = items[j];
3932: items[j] = items[j + gap];
3933: items[j + gap] = swap;
3934: }
3935: }
3936: }
3937: }
3938: }
3939:
3940: Point textExtent(int ptr, int wHint) {
3941: if (ptr != 0 && OS.CFStringGetLength(ptr) > 0) {
3942: float[] w = new float[1], h = new float[1];
3943: HIThemeTextInfo info = new HIThemeTextInfo();
3944: info.state = OS.kThemeStateActive;
3945: if (font != null) {
3946: short[] family = new short[1], style = new short[1];
3947: OS.FMGetFontFamilyInstanceFromFont(font.handle, family,
3948: style);
3949: OS.TextFont(family[0]);
3950: OS.TextFace((short) (style[0] | font.style));
3951: OS.TextSize((short) font.size);
3952: info.fontID = (short) OS.kThemeCurrentPortFont;
3953: } else {
3954: info.fontID = (short) defaultThemeFont();
3955: }
3956: OS.HIThemeGetTextDimensions(ptr, wHint == SWT.DEFAULT ? 0
3957: : wHint, info, w, h, null);
3958: return new Point((int) w[0], (int) h[0]);
3959: } else {
3960: Font font = getFont();
3961: ATSFontMetrics metrics = new ATSFontMetrics();
3962: OS.ATSFontGetVerticalMetrics(font.handle,
3963: OS.kATSOptionFlagsDefault, metrics);
3964: OS.ATSFontGetHorizontalMetrics(font.handle,
3965: OS.kATSOptionFlagsDefault, metrics);
3966: return new Point(0, (int) (0.5f + (metrics.ascent
3967: - metrics.descent + metrics.leading)
3968: * font.size));
3969: }
3970: }
3971:
3972: Point textExtent(char[] chars, int wHint) {
3973: int ptr = OS.CFStringCreateWithCharacters(
3974: OS.kCFAllocatorDefault, chars, chars.length);
3975: Point result = textExtent(ptr, wHint);
3976: if (ptr != 0)
3977: OS.CFRelease(ptr);
3978: return result;
3979: }
3980:
3981: /**
3982: * Returns a point which is the result of converting the
3983: * argument, which is specified in display relative coordinates,
3984: * to coordinates relative to the receiver.
3985: * <p>
3986: * @param x the x coordinate to be translated
3987: * @param y the y coordinate to be translated
3988: * @return the translated coordinates
3989: *
3990: * @exception SWTException <ul>
3991: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3992: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3993: * </ul>
3994: *
3995: * @since 2.1
3996: */
3997: public Point toControl(int x, int y) {
3998: checkWidget();
3999: Rect rect = new Rect();
4000: int window = OS.GetControlOwner(handle);
4001: CGPoint pt = new CGPoint();
4002: OS.HIViewConvertPoint(pt, handle, 0);
4003: x -= (int) pt.x;
4004: y -= (int) pt.y;
4005: OS
4006: .GetWindowBounds(window,
4007: (short) OS.kWindowStructureRgn, rect);
4008: x -= rect.left;
4009: y -= rect.top;
4010: Rect inset = getInset();
4011: x += inset.left;
4012: y += inset.top;
4013: return new Point(x, y);
4014: }
4015:
4016: /**
4017: * Returns a point which is the result of converting the
4018: * argument, which is specified in display relative coordinates,
4019: * to coordinates relative to the receiver.
4020: * <p>
4021: * @param point the point to be translated (must not be null)
4022: * @return the translated coordinates
4023: *
4024: * @exception IllegalArgumentException <ul>
4025: * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
4026: * </ul>
4027: * @exception SWTException <ul>
4028: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4029: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4030: * </ul>
4031: */
4032: public Point toControl(Point point) {
4033: checkWidget();
4034: if (point == null)
4035: error(SWT.ERROR_NULL_ARGUMENT);
4036: return toControl(point.x, point.y);
4037: }
4038:
4039: /**
4040: * Returns a point which is the result of converting the
4041: * argument, which is specified in coordinates relative to
4042: * the receiver, to display relative coordinates.
4043: * <p>
4044: * @param x the x coordinate to be translated
4045: * @param y the y coordinate to be translated
4046: * @return the translated coordinates
4047: *
4048: * @exception SWTException <ul>
4049: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4050: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4051: * </ul>
4052: *
4053: * @since 2.1
4054: */
4055: public Point toDisplay(int x, int y) {
4056: checkWidget();
4057: Rect rect = new Rect();
4058: int window = OS.GetControlOwner(handle);
4059: CGPoint pt = new CGPoint();
4060: OS.HIViewConvertPoint(pt, handle, 0);
4061: x += (int) pt.x;
4062: y += (int) pt.y;
4063: OS
4064: .GetWindowBounds(window,
4065: (short) OS.kWindowStructureRgn, rect);
4066: x += rect.left;
4067: y += rect.top;
4068: Rect inset = getInset();
4069: x -= inset.left;
4070: y -= inset.top;
4071: return new Point(x, y);
4072: }
4073:
4074: /**
4075: * Returns a point which is the result of converting the
4076: * argument, which is specified in coordinates relative to
4077: * the receiver, to display relative coordinates.
4078: * <p>
4079: * @param point the point to be translated (must not be null)
4080: * @return the translated coordinates
4081: *
4082: * @exception IllegalArgumentException <ul>
4083: * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
4084: * </ul>
4085: * @exception SWTException <ul>
4086: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4087: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4088: * </ul>
4089: */
4090: public Point toDisplay(Point point) {
4091: checkWidget();
4092: if (point == null)
4093: error(SWT.ERROR_NULL_ARGUMENT);
4094: return toDisplay(point.x, point.y);
4095: }
4096:
4097: int topHandle() {
4098: return handle;
4099: }
4100:
4101: boolean translateTraversal(int key, int theEvent, boolean[] consume) {
4102: int detail = SWT.TRAVERSE_NONE;
4103: int code = traversalCode(key, theEvent);
4104: boolean all = false;
4105: switch (key) {
4106: case 53: /* Esc */{
4107: all = true;
4108: detail = SWT.TRAVERSE_ESCAPE;
4109: break;
4110: }
4111: case 76: /* KP Enter */
4112: case 36: /* Return */{
4113: all = true;
4114: detail = SWT.TRAVERSE_RETURN;
4115: break;
4116: }
4117: case 48: /* Tab */{
4118: int[] modifiers = new int[1];
4119: OS.GetEventParameter(theEvent, OS.kEventParamKeyModifiers,
4120: OS.typeUInt32, null, 4, null, modifiers);
4121: boolean next = (modifiers[0] & OS.shiftKey) == 0;
4122: detail = next ? SWT.TRAVERSE_TAB_NEXT
4123: : SWT.TRAVERSE_TAB_PREVIOUS;
4124: break;
4125: }
4126: case 126: /* Up arrow */
4127: case 123: /* Left arrow */
4128: case 125: /* Down arrow */
4129: case 124: /* Right arrow */{
4130: boolean next = key == 125 /* Down arrow */|| key == 124 /* Right arrow */;
4131: detail = next ? SWT.TRAVERSE_ARROW_NEXT
4132: : SWT.TRAVERSE_ARROW_PREVIOUS;
4133: break;
4134: }
4135: case 116: /* Page up */
4136: case 121: /* Page down */{
4137: all = true;
4138: int[] modifiers = new int[1];
4139: OS.GetEventParameter(theEvent, OS.kEventParamKeyModifiers,
4140: OS.typeUInt32, null, 4, null, modifiers);
4141: if ((modifiers[0] & OS.controlKey) == 0)
4142: return false;
4143: detail = key == 121 /* Page down */? SWT.TRAVERSE_PAGE_NEXT
4144: : SWT.TRAVERSE_PAGE_PREVIOUS;
4145: break;
4146: }
4147: default:
4148: return false;
4149: }
4150: Event event = new Event();
4151: event.doit = consume[0] = (code & detail) != 0;
4152: event.detail = detail;
4153: if (!setKeyState(event, SWT.Traverse, theEvent))
4154: return false;
4155: Shell shell = getShell();
4156: Control control = this ;
4157: do {
4158: if (control.traverse(event))
4159: return true;
4160: if (!event.doit && control.hooks(SWT.Traverse)) {
4161: return false;
4162: }
4163: if (control == shell)
4164: return false;
4165: control = control.parent;
4166: } while (all && control != null);
4167: return false;
4168: }
4169:
4170: int traversalCode(int key, int theEvent) {
4171: int code = SWT.TRAVERSE_RETURN | SWT.TRAVERSE_TAB_NEXT
4172: | SWT.TRAVERSE_TAB_PREVIOUS;
4173: Shell shell = getShell();
4174: if (shell.parent != null)
4175: code |= SWT.TRAVERSE_ESCAPE;
4176: return code;
4177: }
4178:
4179: boolean traverseMnemonic(char key) {
4180: return false;
4181: }
4182:
4183: /**
4184: * Based on the argument, perform one of the expected platform
4185: * traversal action. The argument should be one of the constants:
4186: * <code>SWT.TRAVERSE_ESCAPE</code>, <code>SWT.TRAVERSE_RETURN</code>,
4187: * <code>SWT.TRAVERSE_TAB_NEXT</code>, <code>SWT.TRAVERSE_TAB_PREVIOUS</code>,
4188: * <code>SWT.TRAVERSE_ARROW_NEXT</code> and <code>SWT.TRAVERSE_ARROW_PREVIOUS</code>.
4189: *
4190: * @param traversal the type of traversal
4191: * @return true if the traversal succeeded
4192: *
4193: * @exception SWTException <ul>
4194: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4195: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4196: * </ul>
4197: */
4198: public boolean traverse(int traversal) {
4199: checkWidget();
4200: Event event = new Event();
4201: event.doit = true;
4202: event.detail = traversal;
4203: return traverse(event);
4204: }
4205:
4206: boolean traverse(Event event) {
4207: sendEvent(SWT.Traverse, event);
4208: if (isDisposed())
4209: return true;
4210: if (!event.doit)
4211: return false;
4212: switch (event.detail) {
4213: case SWT.TRAVERSE_NONE:
4214: return true;
4215: case SWT.TRAVERSE_ESCAPE:
4216: return traverseEscape();
4217: case SWT.TRAVERSE_RETURN:
4218: return traverseReturn();
4219: case SWT.TRAVERSE_TAB_NEXT:
4220: return traverseGroup(true);
4221: case SWT.TRAVERSE_TAB_PREVIOUS:
4222: return traverseGroup(false);
4223: case SWT.TRAVERSE_ARROW_NEXT:
4224: return traverseItem(true);
4225: case SWT.TRAVERSE_ARROW_PREVIOUS:
4226: return traverseItem(false);
4227: case SWT.TRAVERSE_MNEMONIC:
4228: return traverseMnemonic(event);
4229: case SWT.TRAVERSE_PAGE_NEXT:
4230: return traversePage(true);
4231: case SWT.TRAVERSE_PAGE_PREVIOUS:
4232: return traversePage(false);
4233: }
4234: return false;
4235: }
4236:
4237: boolean traverseEscape() {
4238: return false;
4239: }
4240:
4241: boolean traverseGroup(boolean next) {
4242: Control root = computeTabRoot();
4243: Control group = computeTabGroup();
4244: Control[] list = root.computeTabList();
4245: int length = list.length;
4246: int index = 0;
4247: while (index < length) {
4248: if (list[index] == group)
4249: break;
4250: index++;
4251: }
4252: /*
4253: * It is possible (but unlikely), that application
4254: * code could have disposed the widget in focus in
4255: * or out events. Ensure that a disposed widget is
4256: * not accessed.
4257: */
4258: if (index == length)
4259: return false;
4260: int start = index, offset = (next) ? 1 : -1;
4261: while ((index = ((index + offset + length) % length)) != start) {
4262: Control control = list[index];
4263: if (!control.isDisposed() && control.setTabGroupFocus()) {
4264: return true;
4265: }
4266: }
4267: if (group.isDisposed())
4268: return false;
4269: return group.setTabGroupFocus();
4270: }
4271:
4272: boolean traverseItem(boolean next) {
4273: Control[] children = parent._getChildren();
4274: int length = children.length;
4275: int index = 0;
4276: while (index < length) {
4277: if (children[index] == this )
4278: break;
4279: index++;
4280: }
4281: /*
4282: * It is possible (but unlikely), that application
4283: * code could have disposed the widget in focus in
4284: * or out events. Ensure that a disposed widget is
4285: * not accessed.
4286: */
4287: if (index == length)
4288: return false;
4289: int start = index, offset = (next) ? 1 : -1;
4290: while ((index = (index + offset + length) % length) != start) {
4291: Control child = children[index];
4292: if (!child.isDisposed() && child.isTabItem()) {
4293: if (child.setTabItemFocus())
4294: return true;
4295: }
4296: }
4297: return false;
4298: }
4299:
4300: boolean traverseReturn() {
4301: return false;
4302: }
4303:
4304: boolean traversePage(boolean next) {
4305: return false;
4306: }
4307:
4308: boolean traverseMnemonic(Event event) {
4309: return false;
4310: }
4311:
4312: /**
4313: * Forces all outstanding paint requests for the widget
4314: * to be processed before this method returns. If there
4315: * are no outstanding paint request, this method does
4316: * nothing.
4317: * <p>
4318: * Note: This method does not cause a redraw.
4319: * </p>
4320: *
4321: * @exception SWTException <ul>
4322: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4323: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4324: * </ul>
4325: *
4326: * @see #redraw()
4327: * @see #redraw(int, int, int, int, boolean)
4328: * @see PaintListener
4329: * @see SWT#Paint
4330: */
4331: public void update() {
4332: checkWidget();
4333: update(false);
4334: }
4335:
4336: void update(boolean all) {
4337: // checkWidget();
4338: //TODO - not all
4339: OS.HIViewRender(handle);
4340: }
4341:
4342: void updateBackgroundMode() {
4343: int oldState = state & PARENT_BACKGROUND;
4344: checkBackground();
4345: if (oldState != (state & PARENT_BACKGROUND)) {
4346: setBackground();
4347: }
4348: }
4349:
4350: void updateLayout(boolean all) {
4351: /* Do nothing */
4352: }
4353:
4354: }
|