| package org.eclipse.swt.widgets;
|
|
|
| /* |
| * (c) Copyright IBM Corp. 2000, 2001. |
| * All Rights Reserved |
| */ |
|
|
| import org.eclipse.swt.internal.*;
|
| import org.eclipse.swt.internal.motif.*;
|
| import org.eclipse.swt.graphics.*;
|
| import org.eclipse.swt.*;
|
| import org.eclipse.swt.events.*;
|
|
|
| /** |
| * Control is the abstract superclass of all windowed user interface classes. |
| * <p> |
| * <dl> |
| * <dt><b>Styles:</b> |
| * <dd>BORDER</dd> |
| * <dt><b>Events:</b> |
| * <dd>FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick, MouseDown, MouseEnter, |
| * MouseExit, MouseHover, MouseUp, MouseMove, Move, Paint, Resize</dd> |
| * </dl> |
| * <p> |
| * IMPORTANT: This class is intended to be subclassed <em>only</em> |
| * within the SWT implementation. |
| * </p> |
| */ |
| public abstract class Control extends Widget implements Drawable {
|
| Composite parent;
|
| int fontList;
|
| Menu menu;
|
| String toolTipText;
|
| Object layoutData;
|
| Control () {
|
| /* Do nothing */
|
| }
|
| /** |
| * Constructs a new instance of this class given its parent |
| * and a style value describing its behavior and appearance. |
| * <p> |
| * The style value is either one of the style constants defined in |
| * class <code>SWT</code> which is applicable to instances of this |
| * class, or must be built by <em>bitwise OR</em>'ing together |
| * (that is, using the <code>int</code> "|" operator) two or more |
| * of those <code>SWT</code> style constants. The class description |
| * for all SWT widget classes should include a comment which |
| * describes the style constants which are applicable to the class. |
| * </p> |
| * |
| * @param parent a composite control which will be the parent of the new instance (cannot be null) |
| * @param style the style of control to construct |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> |
| * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> |
| * </ul> |
| * |
| * @see SWT |
| * @see Widget#checkSubclass |
| * @see Widget#getStyle |
| */ |
| public Control (Composite parent, int style) {
|
| super (parent, style);
|
| this.parent = parent;
|
| createWidget (0);
|
| }
|
| /** |
| * Adds the listener to the collection of listeners who will |
| * be notified when the control is moved or resized, by sending |
| * it one of the messages defined in the <code>ControlListener</code> |
| * interface. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see ControlListener |
| * @see #removeControlListener |
| */
|
| public void addControlListener(ControlListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| TypedListener typedListener = new TypedListener (listener);
|
| addListener (SWT.Resize,typedListener);
|
| addListener (SWT.Move,typedListener);
|
| }
|
| /** |
| * Adds the listener to the collection of listeners who will |
| * be notified when the control gains or loses focus, by sending |
| * it one of the messages defined in the <code>FocusListener</code> |
| * interface. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see FocusListener |
| * @see #removeFocusListener |
| */
|
| public void addFocusListener(FocusListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| TypedListener typedListener = new TypedListener (listener);
|
| addListener(SWT.FocusIn,typedListener);
|
| addListener(SWT.FocusOut,typedListener);
|
| }
|
| /** |
| * Adds the listener to the collection of listeners who will |
| * be notified when the help events are generated for the control, by sending |
| * it one of the messages defined in the <code>HelpListener</code> |
| * interface. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see HelpListener |
| * @see #removeHelpListener |
| */
|
| public void addHelpListener (HelpListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| TypedListener typedListener = new TypedListener (listener);
|
| addListener (SWT.Help, typedListener);
|
| }
|
| /** |
| * Adds the listener to the collection of listeners who will |
| * be notified when keys are pressed and released on the system keyboard, by sending |
| * it one of the messages defined in the <code>KeyListener</code> |
| * interface. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see KeyListener |
| * @see #removeKeyListener |
| */
|
| public void addKeyListener(KeyListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| TypedListener typedListener = new TypedListener (listener);
|
| addListener(SWT.KeyUp,typedListener);
|
| addListener(SWT.KeyDown,typedListener);
|
| }
|
| /** |
| * Adds the listener to the collection of listeners who will |
| * be notified when mouse buttons are pressed and released, by sending |
| * it one of the messages defined in the <code>MouseListener</code> |
| * interface. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see MouseListener |
| * @see #removeMouseListener |
| */
|
| public void addMouseListener(MouseListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| TypedListener typedListener = new TypedListener (listener);
|
| addListener(SWT.MouseDown,typedListener);
|
| addListener(SWT.MouseUp,typedListener);
|
| addListener(SWT.MouseDoubleClick,typedListener);
|
| }
|
| /** |
| * Adds the listener to the collection of listeners who will |
| * be notified when the mouse passes or hovers over controls, by sending |
| * it one of the messages defined in the <code>MouseTrackListener</code> |
| * interface. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see MouseTrackListener |
| * @see #removeMouseTrackListener |
| */
|
| public void addMouseTrackListener (MouseTrackListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| TypedListener typedListener = new TypedListener (listener);
|
| addListener (SWT.MouseEnter,typedListener);
|
| addListener (SWT.MouseExit,typedListener);
|
| addListener (SWT.MouseHover,typedListener);
|
| }
|
| /** |
| * Adds the listener to the collection of listeners who will |
| * be notified when the mouse moves, by sending it one of the |
| * messages defined in the <code>MouseMoveListener</code> |
| * interface. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see MouseMoveListener |
| * @see #removeMouseMoveListener |
| */
|
| public void addMouseMoveListener(MouseMoveListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| TypedListener typedListener = new TypedListener (listener);
|
| addListener(SWT.MouseMove,typedListener);
|
| }
|
| /** |
| * Adds the listener to the collection of listeners who will |
| * be notified when the receiver needs to be painted, by sending it |
| * one of the messages defined in the <code>PaintListener</code> |
| * interface. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see PaintListener |
| * @see #removePaintListener |
| */
|
| public void addPaintListener(PaintListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| TypedListener typedListener = new TypedListener (listener);
|
| addListener(SWT.Paint,typedListener);
|
| }
|
| /** |
| * Adds the listener to the collection of listeners who will |
| * be notified when traversal events occur, by sending it |
| * one of the messages defined in the <code>TraverseListener</code> |
| * interface. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see TraverseListener |
| * @see #removeTraverseListener |
| */
|
| public void addTraverseListener (TraverseListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| TypedListener typedListener = new TypedListener (listener);
|
| addListener (SWT.Traverse,typedListener);
|
| }
|
| /** |
| * Returns the preferred size of the receiver. |
| * <p> |
| * The <em>prefered size</em> of a control is the size that it would |
| * best be displayed at. The width hint and height hint arguments |
| * allow the caller to ask a control questions such as "Given a particular |
| * width, how high does the control need to be to show all of the contents?" |
| * To indicate that the caller does not wish to constrain a particular |
| * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint. |
| * </p> |
| * |
| * @param wHint the width hint (can be <code>SWT.DEFAULT</code>) |
| * @param hHint the height hint (can be <code>SWT.DEFAULT</code>) |
| * @return the preferred size of the control |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see Layout |
| */ |
| public Point computeSize (int wHint, int hHint) {
|
| return computeSize (wHint, hHint, true);
|
| }
|
| /** |
| * Returns the preferred size of the receiver. |
| * <p> |
| * The <em>prefered size</em> of a control is the size that it would |
| * best be displayed at. The width hint and height hint arguments |
| * allow the caller to ask a control questions such as "Given a particular |
| * width, how high does the control need to be to show all of the contents?" |
| * To indicate that the caller does not wish to constrain a particular |
| * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint. |
| * </p><p> |
| * If the changed flag is <code>true</code>, it indicates that the receiver's |
| * <em>contents</em> have changed, therefore any caches that a layout manager |
| * containing the control may have been keeping need to be flushed. When the |
| * control is resized, the changed flag will be <code>false</code>, so layout |
| * manager caches can be retained. |
| * </p> |
| * |
| * @param wHint the width hint (can be <code>SWT.DEFAULT</code>) |
| * @param hHint the height hint (can be <code>SWT.DEFAULT</code>) |
| * @param changed <code>true</code> if the control's contents have changed, and <code>false</code> otherwise |
| * @return the preferred size of the control. |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see Layout |
| */
|
| public Point computeSize (int wHint, int hHint, boolean changed) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| int width = DEFAULT_WIDTH;
|
| int height = DEFAULT_HEIGHT;
|
| if (wHint != SWT.DEFAULT) width = wHint;
|
| if (hHint != SWT.DEFAULT) height = hHint;
|
| int border = getBorderWidth ();
|
| width += border * 2;
|
| height += border * 2;
|
| return new Point (width, height);
|
| }
|
|
|
| void createWidget (int index) {
|
| super.createWidget (index);
|
|
|
| /* |
| * Feature in MOTIF. When a widget is created before the |
| * parent has been realized, the widget is created behind |
| * all siblings in the Z-order. When a widget is created |
| * after the parent has been realized, it is created in |
| * front of all siblings. This is not incorrect but is |
| * unexpected. The fix is to force all widgets to always |
| * be created behind their siblings. |
| */ |
| int topHandle = topHandle (); |
| if (OS.XtIsRealized (topHandle)) { |
| int window = OS.XtWindow (topHandle); |
| if (window != 0) { |
| int display = OS.XtDisplay (topHandle); |
| if (display != 0) OS.XLowerWindow (display, window); |
| } |
| /* |
| * Make that the widget has been properly realized |
| * because the widget was created after the parent |
| * has been realized. This is not part of the fix |
| * for Z-order in the code above. |
| */ |
| realizeChildren (); |
| }
|
|
|
| /*
|
| * Bug in Motif. Under certain circumstances, when a
|
| * text widget is created as a child of another control
|
| * that has drag and drop, starting a drag in the text
|
| * widget causes a protection fault. The fix is to
|
| * disable the built in drag and drop for all widgets
|
| * by overriding the drag start traslation.
|
| */
|
| Display display = getDisplay ();
|
| OS.XtOverrideTranslations (handle, display.dragTranslations);
|
| }
|
| int defaultBackground () {
|
| return getDisplay ().defaultBackground;
|
| }
|
| int defaultFont () {
|
| return getDisplay ().defaultFontList;
|
| }
|
| int defaultForeground () {
|
| return getDisplay ().defaultForeground;
|
| }
|
| void enableHandle (boolean enabled, int widgetHandle) {
|
| int [] argList = {OS.XmNsensitive, enabled ? 1 : 0};
|
| OS.XtSetValues (widgetHandle, argList, argList.length / 2);
|
| }
|
| void enableWidget (boolean enabled) {
|
| enableHandle (enabled, handle);
|
| }
|
| char findMnemonic (String string) {
|
| int index = 0;
|
| int length = string.length ();
|
| do {
|
| while ((index < length) && (string.charAt (index) != Mnemonic)) index++;
|
| if (++index >= length) return '\0';
|
| if (string.charAt (index) != Mnemonic) return string.charAt (index);
|
| index++;
|
| } while (index < length);
|
| return '\0';
|
| }
|
| int fontHandle () {
|
| return handle;
|
| }
|
| /** |
| * Forces the receiver to have the <em>keyboard focus</em>, causing |
| * all keyboard events to be delivered to it. |
| * |
| * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to. |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see #setFocus |
| */ |
| public boolean forceFocus () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| Decorations shell = menuShell ();
|
| shell.setSavedFocus (this);
|
| shell.bringToTop ();
|
| return OS.XmProcessTraversal (handle, OS.XmTRAVERSE_CURRENT);
|
| }
|
| /** |
| * Returns the receiver's background color. |
| * |
| * @return the background color |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Color getBackground () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return Color.motif_new (getDisplay (), getXColor (getBackgroundPixel ()));
|
| }
|
| int getBackgroundPixel () {
|
| int [] argList = {OS.XmNbackground, 0};
|
| OS.XtGetValues (handle, argList, argList.length / 2);
|
| return argList [1];
|
| }
|
| /** |
| * Returns the receiver's border width. |
| * |
| * @return the border width |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public int getBorderWidth () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| int topHandle = topHandle ();
|
| int [] argList = {OS.XmNborderWidth, 0};
|
| OS.XtGetValues (topHandle, argList, argList.length / 2);
|
| return argList [1];
|
| }
|
| /** |
| * Returns a rectangle describing the receiver's size and location |
| * relative to its parent (or its display if its parent is null). |
| * |
| * @return the receiver's bounding rectangle |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Rectangle getBounds () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| int topHandle = topHandle ();
|
| int [] argList = {OS.XmNx, 0, OS.XmNy, 0, OS.XmNwidth, 0, OS.XmNheight, 0, OS.XmNborderWidth, 0};
|
| OS.XtGetValues (topHandle, argList, argList.length / 2);
|
| int borders = argList [9] * 2;
|
| return new Rectangle ((short) argList [1], (short) argList [3], argList [5] + borders, argList [7] + borders);
|
| }
|
| Point getClientLocation () {
|
| short [] handle_x = new short [1], handle_y = new short [1];
|
| OS.XtTranslateCoords (handle, (short) 0, (short) 0, handle_x, handle_y);
|
| short [] topHandle_x = new short [1], topHandle_y = new short [1];
|
| OS.XtTranslateCoords (parent.handle, (short) 0, (short) 0, topHandle_x, topHandle_y);
|
| return new Point (handle_x [0] - topHandle_x [0], handle_y [0] - topHandle_y [0]);
|
| }
|
| /** |
| * Returns the display that the receiver was created on. |
| * |
| * @return the receiver's display |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */
|
| public Display getDisplay () {
|
| Composite parent = this.parent;
|
| if (parent == null) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return parent.getDisplay ();
|
| }
|
| /** |
| * Returns <code>true</code> if the receiver is enabled, and |
| * <code>false</code> otherwise. A disabled control is typically |
| * not selectable from the user interface and draws with an |
| * inactive or "grayed" look. |
| * |
| * @return the receiver's enabled state |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public boolean getEnabled () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| int [] argList = {OS.XmNsensitive, 0};
|
| OS.XtGetValues (topHandle (), argList, argList.length / 2);
|
| return argList [1] != 0;
|
| }
|
| /** |
| * Returns the font that the receiver will use to paint textual information. |
| * |
| * @return the receiver's font |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Font getFont () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return Font.motif_new (getDisplay (), getFontList ());
|
| }
|
|
|
| int getFontAscent () {
|
| int fontList = getFontList ();
|
|
|
| /* Create a font context to iterate over each element in the font list */
|
| int [] buffer = new int [1];
|
| if (!OS.XmFontListInitFontContext (buffer, fontList)) {
|
| error (SWT.ERROR_NO_HANDLES);
|
| }
|
| int context = buffer [0];
|
|
|
| /* Values discovering during iteration */
|
| int ascent = 0;
|
| XFontStruct fontStruct = new XFontStruct ();
|
| int fontListEntry;
|
| int [] fontStructPtr = new int [1];
|
| int [] fontNamePtr = new int [1];
|
|
|
| /* Go through each entry in the font list. */
|
| while ((fontListEntry = OS.XmFontListNextEntry (context)) != 0) {
|
| int fontPtr = OS.XmFontListEntryGetFont (fontListEntry, buffer);
|
| if (buffer [0] == 0) {
|
| /* FontList contains a single font */
|
| OS.memmove (fontStruct, fontPtr, XFontStruct.sizeof);
|
| int fontAscent = Math.max (fontStruct.ascent, fontStruct.max_bounds_ascent);
|
| if (fontAscent > ascent) ascent = fontAscent;
|
| } else {
|
| /* FontList contains a fontSet */
|
| int nFonts = OS.XFontsOfFontSet (fontPtr, fontStructPtr, fontNamePtr);
|
| int [] fontStructs = new int [nFonts];
|
| OS.memmove (fontStructs, fontStructPtr [0], nFonts * 4);
|
|
|
| /* Go through each fontStruct in the font set */
|
| for (int i=0; i<nFonts; i++) {
|
| OS.memmove (fontStruct, fontStructs[i], XFontStruct.sizeof);
|
| int fontAscent = Math.max (fontStruct.ascent, fontStruct.max_bounds_ascent);
|
| if (fontAscent > ascent) ascent = fontAscent;
|
| }
|
| }
|
| }
|
|
|
| OS.XmFontListFreeFontContext (context);
|
| return ascent;
|
| }
|
|
|
| int getFontHeight () {
|
| int fontList = getFontList ();
|
|
|
| /* Create a font context to iterate over each element in the font list */
|
| int [] buffer = new int [1];
|
| if (!OS.XmFontListInitFontContext (buffer, fontList)) {
|
| error (SWT.ERROR_NO_HANDLES);
|
| }
|
| int context = buffer [0];
|
|
|
| /* Values discovering during iteration */
|
| int height = 0;
|
| XFontStruct fontStruct = new XFontStruct ();
|
| int fontListEntry;
|
| int [] fontStructPtr = new int [1];
|
| int [] fontNamePtr = new int [1];
|
|
|
| /* Go through each entry in the font list. */
|
| while ((fontListEntry = OS.XmFontListNextEntry (context)) != 0) {
|
| int fontPtr = OS.XmFontListEntryGetFont (fontListEntry, buffer);
|
| if (buffer [0] == 0) {
|
| /* FontList contains a single font */
|
| OS.memmove (fontStruct, fontPtr, XFontStruct.sizeof);
|
| int fontAscent = Math.max (fontStruct.ascent, fontStruct.max_bounds_ascent);
|
| int fontDescent = Math.max (fontStruct.descent, fontStruct.max_bounds_descent);
|
| int fontHeight = fontAscent + fontDescent;
|
| if (fontHeight > height) height = fontHeight;
|
| } else {
|
| /* FontList contains a fontSet */
|
| int nFonts = OS.XFontsOfFontSet (fontPtr, fontStructPtr, fontNamePtr);
|
| int [] fontStructs = new int [nFonts];
|
| OS.memmove (fontStructs, fontStructPtr [0], nFonts * 4);
|
|
|
| /* Go through each fontStruct in the font set */
|
| for (int i=0; i<nFonts; i++) {
|
| OS.memmove (fontStruct, fontStructs[i], XFontStruct.sizeof);
|
| int fontAscent = Math.max (fontStruct.ascent, fontStruct.max_bounds_ascent);
|
| int fontDescent = Math.max (fontStruct.descent, fontStruct.max_bounds_descent);
|
| int fontHeight = fontAscent + fontDescent;
|
| if (fontHeight > height) height = fontHeight;
|
| }
|
| }
|
| }
|
|
|
| OS.XmFontListFreeFontContext (context);
|
| return height;
|
| }
|
| int getFontList () {
|
| int fontHandle = fontHandle ();
|
| int [] argList = {OS.XmNfontList, 0};
|
| OS.XtGetValues (fontHandle, argList, argList.length / 2);
|
| if (argList [1] != 0) return argList [1];
|
| if (fontList == 0) fontList = defaultFont ();
|
| return fontList;
|
| }
|
| /** |
| * Returns the foreground color that the receiver will use to draw. |
| * |
| * @return the receiver's foreground color |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Color getForeground () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return Color.motif_new (getDisplay (), getXColor (getForegroundPixel ()));
|
| }
|
| int getForegroundPixel () {
|
| int [] argList = {OS.XmNforeground, 0};
|
| OS.XtGetValues (handle, argList, argList.length / 2);
|
| return argList [1];
|
| }
|
| /** |
| * Returns layout data which is associated with the receiver. |
| * |
| * @return the receiver's layout data |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Object getLayoutData () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return layoutData;
|
| }
|
| /** |
| * Returns a point describing the receiver's location relative |
| * to its parent (or its display if its parent is null). |
| * |
| * @return the receiver's location |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Point getLocation () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| int topHandle = topHandle ();
|
| int [] argList = {OS.XmNx, 0, OS.XmNy, 0};
|
| OS.XtGetValues (topHandle, argList, argList.length / 2);
|
| return new Point ((short) argList [1], (short) argList [3]);
|
| }
|
| /** |
| * Returns the receiver's pop up menu if it has one, or null |
| * if it does not. All controls may optionally have a pop up |
| * menu that is displayed when the user requests one for |
| * the control. The sequence of key strokes, button presses |
| * and/or button releases that are used to request a pop up |
| * menu is platform specific. |
| * |
| * @return the receiver's menu |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Menu getMenu () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return menu;
|
| }
|
| /** |
| * Returns the receiver's parent, which must be a <code>Composite</code> |
| * or null when the receiver is a shell that was created with null or |
| * a display for a parent. |
| * |
| * @return the receiver's parent |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Composite getParent () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return parent;
|
| }
|
| Control [] getPath () {
|
| int count = 0;
|
| Shell shell = getShell ();
|
| Control control = this;
|
| while (control != shell) {
|
| count++;
|
| control = control.parent;
|
| }
|
| control = this;
|
| Control [] result = new Control [count];
|
| while (control != shell) {
|
| result [--count] = control;
|
| control = control.parent;
|
| }
|
| return result;
|
| }
|
| /** |
| * Returns the receiver's shell. For all controls other than |
| * shells, this simply returns the control's nearest ancestor |
| * shell. Shells return themselves, even if they are children |
| * of other shells. |
| * |
| * @return the receiver's shell |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see #getParent |
| */ |
| public Shell getShell () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return parent.getShell ();
|
| }
|
| /** |
| * Returns a point describing the receiver's size. The |
| * x coordinate of the result is the width of the receiver. |
| * The y coordinate of the result is the height of the |
| * receiver. |
| * |
| * @return the receiver's size |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Point getSize () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| int topHandle = topHandle ();
|
| int [] argList = {OS.XmNwidth, 0, OS.XmNheight, 0, OS.XmNborderWidth, 0};
|
| OS.XtGetValues (topHandle, argList, argList.length / 2);
|
| int borders = argList [5] * 2;
|
| return new Point (argList [1] + borders, argList [3] + borders);
|
| }
|
| /** |
| * Returns the receiver's tool tip text, or null if it has |
| * not been set. |
| * |
| * @return the receiver's tool tip text |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */
|
| public String getToolTipText () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return toolTipText;
|
| }
|
| /** |
| * Returns <code>true</code> if the receiver is visible, and |
| * <code>false</code> otherwise. |
| * <p> |
| * If one of the receiver's ancestors is not visible or some |
| * other condition makes the receiver not visible, this method |
| * may still indicate that it is considered visible even though |
| * it may not actually be showing. |
| * </p> |
| * |
| * @return the receiver's visibility state |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public boolean getVisible () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| int topHandle = topHandle ();
|
| int [] argList = {OS.XmNmappedWhenManaged, 0};
|
| OS.XtGetValues (topHandle, argList, argList.length / 2);
|
| return argList [1] != 0;
|
| }
|
| XColor getXColor (int pixel) {
|
| int display = OS.XtDisplay (handle);
|
| if (display == 0) return null;
|
| int [] argList = {OS.XmNcolormap, 0};
|
| OS.XtGetValues (handle, argList, argList.length / 2);
|
| int colormap = argList [1];
|
| if (colormap == 0) return null;
|
| XColor color = new XColor ();
|
| color.pixel = pixel;
|
| OS.XQueryColor (display, colormap, color);
|
| return color;
|
| }
|
| boolean hasFocus () {
|
| return this == getDisplay ().getFocusControl ();
|
| }
|
| void hookEvents () {
|
| int windowProc = getDisplay ().windowProc;
|
| OS.XtAddEventHandler (handle, OS.KeyPressMask, false, windowProc, SWT.KeyDown);
|
| OS.XtAddEventHandler (handle, OS.KeyReleaseMask, false, windowProc, SWT.KeyUp);
|
| OS.XtAddEventHandler (handle, OS.ButtonPressMask, false, windowProc, SWT.MouseDown);
|
| OS.XtAddEventHandler (handle, OS.ButtonReleaseMask, false, windowProc, SWT.MouseUp);
|
| OS.XtAddEventHandler (handle, OS.PointerMotionMask, false, windowProc, SWT.MouseMove);
|
| OS.XtAddEventHandler (handle, OS.EnterWindowMask, false, windowProc, SWT.MouseEnter);
|
| OS.XtAddEventHandler (handle, OS.LeaveWindowMask, false, windowProc, SWT.MouseExit);
|
| OS.XtAddEventHandler (handle, OS.ExposureMask, false, windowProc, SWT.Paint);
|
| OS.XtAddEventHandler (handle, OS.FocusChangeMask, false, windowProc, SWT.FocusIn);
|
| OS.XtAddCallback (handle, OS.XmNhelpCallback, windowProc, SWT.Help);
|
| }
|
| int inputContext () {
|
| return getShell ().inputContext ();
|
| }
|
| /** |
| * Invokes platform specific functionality to allocate a new GC handle. |
| * <p> |
| * <b>IMPORTANT:</b> This method is <em>not</em> part of the public |
| * API for <code>Control</code>. It is marked public only so that it |
| * can be shared within the packages provided by SWT. It is not |
| * available on all platforms, and should never be called from |
| * application code. |
| * </p> |
| * |
| * @param data the platform specific GC data |
| * @return the platform specific GC handle |
| * |
| * @private |
| */ |
| public int internal_new_GC (GCData data) { |
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS); |
| if (!OS.XtIsRealized (handle)) { |
| Shell shell = getShell (); |
| shell.realizeWidget (); |
| }
|
| int xDisplay = OS.XtDisplay (handle);
|
| if (xDisplay == 0) SWT.error(SWT.ERROR_NO_HANDLES);
|
| int xWindow = OS.XtWindow (handle);
|
| if (xWindow == 0) SWT.error(SWT.ERROR_NO_HANDLES);
|
| int xGC = OS.XCreateGC (xDisplay, xWindow, 0, null);
|
| if (xGC == 0) SWT.error(SWT.ERROR_NO_HANDLES);
|
| OS.XSetGraphicsExposures (xDisplay, xGC, false);
|
| int [] argList = {OS.XmNforeground, 0, OS.XmNbackground, 0, OS.XmNcolormap, 0};
|
| OS.XtGetValues (handle, argList, argList.length / 2);
|
| if (data != null) {
|
| data.device = getDisplay ();
|
| data.display = xDisplay;
|
| data.drawable = xWindow;
|
| data.foreground = argList [1];
|
| data.background = argList [3];
|
| data.fontList = getFontList ();
|
| data.colormap = argList [5];
|
| }
|
| return xGC;
|
| }
|
| /** |
| * Invokes platform specific functionality to dispose a GC handle. |
| * <p> |
| * <b>IMPORTANT:</b> This method is <em>not</em> part of the public |
| * API for <code>Control</code>. It is marked public only so that it |
| * can be shared within the packages provided by SWT. It is not |
| * available on all platforms, and should never be called from |
| * application code. |
| * </p> |
| * |
| * @param handle the platform specific GC handle |
| * @param data the platform specific GC data |
| * |
| * @private |
| */ |
| public void internal_dispose_GC (int xGC, GCData data) { |
| int xDisplay = 0; |
| if (data != null) xDisplay = data.display; |
| if (xDisplay == 0 && handle != 0) xDisplay = OS.XtDisplay (handle);
|
| if (xDisplay == 0) SWT.error(SWT.ERROR_NO_HANDLES);
|
| OS.XFreeGC (xDisplay, xGC);
|
| }
|
| /** |
| * Returns <code>true</code> if the receiver is enabled, and |
| * <code>false</code> otherwise. A disabled control is typically |
| * not selectable from the user interface and draws with an |
| * inactive or "grayed" look. |
| * |
| * @return the receiver's enabled state |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public boolean isEnabled () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return getEnabled () && parent.isEnabled ();
|
| }
|
| /** |
| * Returns <code>true</code> if the receiver has the user-interface |
| * focus, and <code>false</code> otherwise. |
| * |
| * @return the receiver's focus state |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public boolean isFocusControl () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return hasFocus ();
|
| }
|
| /** |
| * Returns <code>true</code> if the underlying operating |
| * system supports this reparenting, otherwise <code>false</code> |
| * |
| * @return <code>true</code> if the widget can be reparented, otherwise <code>false</code> |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public boolean isReparentable () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return false;
|
| }
|
| /** |
| * Returns <code>true</code> if the receiver is visible, and |
| * <code>false</code> otherwise. |
| * <p> |
| * If one of the receiver's ancestors is not visible or some |
| * other condition makes the receiver not visible, this method |
| * may still indicate that it is considered visible even though |
| * it may not actually be showing. |
| * </p> |
| * |
| * @return the receiver's visibility state |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public boolean isVisible () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return getVisible () && parent.isVisible ();
|
| }
|
| void manageChildren () {
|
| OS.XtSetMappedWhenManaged (handle, false);
|
| OS.XtManageChild (handle);
|
| int [] argList = {OS.XmNborderWidth, 0};
|
| OS.XtGetValues (handle, argList, argList.length / 2);
|
| OS.XtResizeWidget (handle, 1, 1, argList [1]);
|
| OS.XtSetMappedWhenManaged (handle, true);
|
| }
|
| Decorations menuShell () {
|
| return parent.menuShell ();
|
| }
|
| boolean mnemonicHit () {
|
| return false;
|
| }
|
| boolean mnemonicMatch (char key) {
|
| return false;
|
| }
|
| /** |
| * Moves the receiver above the specified control in the |
| * drawing order. If the argument is null, then the receiver |
| * is moved to the top of the drawing order. The control at |
| * the top of the drawing order will not be covered by other |
| * controls even if they occupy intersecting areas. |
| * |
| * @param the sibling control (or null) |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void moveAbove (Control control) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| setZOrder (control, true);
|
| }
|
| /** |
| * Moves the receiver below the specified control in the |
| * drawing order. If the argument is null, then the receiver |
| * is moved to the bottom of the drawing order. The control at |
| * the bottom of the drawing order will be covered by all other |
| * controls which occupy intersecting areas. |
| * |
| * @param the sibling control (or null) |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void moveBelow (Control control) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| setZOrder (control, false);
|
| }
|
| /** |
| * Causes the receiver to be resized to its preferred size. |
| * For a composite, this involves computing the preferred size |
| * from its layout, if there is one. |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see #computeSize |
| */
|
| public void pack () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| pack (true);
|
| }
|
| /** |
| * Causes the receiver to be resized to its preferred size. |
| * For a composite, this involves computing the preferred size |
| * from its layout, if there is one. |
| * <p> |
| * If the changed flag is <code>true</code>, it indicates that the receiver's |
| * <em>contents</em> have changed, therefore any caches that a layout manager |
| * containing the control may have been keeping need to be flushed. When the |
| * control is resized, the changed flag will be <code>false</code>, so layout |
| * manager caches can be retained. |
| * </p> |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see #computeSize |
| */
|
| public void pack (boolean changed) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| setSize (computeSize (SWT.DEFAULT, SWT.DEFAULT, changed));
|
| }
|
| int processDefaultSelection (int callData) {
|
| postEvent (SWT.DefaultSelection);
|
| return 0;
|
| }
|
| int processFocusIn () {
|
| sendEvent (SWT.FocusIn);
|
| // IsDBLocale ifTrue: [self killImeFocus].
|
| return 0;
|
| }
|
| int processFocusOut () {
|
| sendEvent (SWT.FocusOut);
|
| // IsDBLocale ifTrue: [self killImeFocus].
|
| return 0;
|
| }
|
| int processHelp (int callData) {
|
| sendHelpEvent (callData);
|
| return 0;
|
| }
|
| int processKeyDown (int callData) {
|
| XKeyEvent xEvent = new XKeyEvent ();
|
| OS.memmove (xEvent, callData, XKeyEvent.sizeof);
|
| sendKeyEvent (SWT.KeyDown, xEvent);
|
| return 0;
|
| }
|
| int processKeyUp (int callData) {
|
| XKeyEvent xEvent = new XKeyEvent ();
|
| OS.memmove (xEvent, callData, XKeyEvent.sizeof);
|
| sendKeyEvent (SWT.KeyUp, xEvent);
|
| return 0;
|
| }
|
| int processModify (int callData) {
|
| sendEvent (SWT.Modify);
|
| return 0;
|
| }
|
| int processMouseDown (int callData) {
|
| Display display = getDisplay ();
|
| display.hideToolTip ();
|
| XButtonEvent xEvent = new XButtonEvent ();
|
| OS.memmove (xEvent, callData, XButtonEvent.sizeof);
|
| sendMouseEvent (SWT.MouseDown, xEvent.button, xEvent.state, xEvent);
|
| if (xEvent.button == 2 && hooks (SWT.DragDetect)) {
|
| sendEvent (SWT.DragDetect);
|
| }
|
| if (xEvent.button == 3 && menu != null) {
|
| OS.XmProcessTraversal (handle, OS.XmTRAVERSE_CURRENT);
|
| menu.setVisible (true);
|
| }
|
| int clickTime = display.getDoubleClickTime ();
|
| int lastTime = display.lastTime, eventTime = xEvent.time;
|
| int lastButton = display.lastButton, eventButton = xEvent.button;
|
| if (lastButton == eventButton && lastTime != 0 && Math.abs (lastTime - eventTime) <= clickTime) {
|
| sendMouseEvent (SWT.MouseDoubleClick, eventButton, xEvent.state, xEvent);
|
| }
|
| if (eventTime == 0) eventTime = 1;
|
| display.lastTime = eventTime;
|
| display.lastButton = eventButton;
|
| return 0;
|
| }
|
| int processMouseEnter (int callData) {
|
| XCrossingEvent xEvent = new XCrossingEvent ();
|
| OS.memmove (xEvent, callData, XCrossingEvent.sizeof);
|
| if (xEvent.mode != OS.NotifyNormal) return 0;
|
| if (xEvent.subwindow != 0) return 0;
|
| Event event = new Event ();
|
| event.x = xEvent.x;
|
| event.y = xEvent.y;
|
| postEvent (SWT.MouseEnter, event);
|
| return 0;
|
| }
|
| int processMouseMove (int callData) {
|
| Display display = getDisplay ();
|
| display.addMouseHoverTimeOut (handle);
|
| XMotionEvent xEvent = new XMotionEvent ();
|
| OS.memmove (xEvent, callData, XMotionEvent.sizeof);
|
| sendMouseEvent (SWT.MouseMove, 0, xEvent.state, xEvent);
|
| return 0;
|
| }
|
| int processMouseExit (int callData) {
|
| Display display = getDisplay ();
|
| display.removeMouseHoverTimeOut ();
|
| display.hideToolTip ();
|
| XCrossingEvent xEvent = new XCrossingEvent ();
|
| OS.memmove (xEvent, callData, XCrossingEvent.sizeof);
|
| if (xEvent.mode != OS.NotifyNormal) return 0;
|
| if (xEvent.subwindow != 0) return 0;
|
| Event event = new Event ();
|
| event.x = xEvent.x;
|
| event.y = xEvent.y;
|
| postEvent (SWT.MouseExit, event);
|
| return 0;
|
| }
|
| int processMouseHover (int id) {
|
| Display display = getDisplay ();
|
| Event event = new Event ();
|
| Point local = toControl (display.getCursorLocation ());
|
| event.x = local.x; event.y = local.y;
|
| postEvent (SWT.MouseHover, event);
|
| display.showToolTip (handle, toolTipText);
|
| return 0;
|
| }
|
| int processMouseUp (int callData) {
|
| Display display = getDisplay ();
|
| display.hideToolTip ();
|
| XButtonEvent xEvent = new XButtonEvent ();
|
| OS.memmove (xEvent, callData, XButtonEvent.sizeof);
|
| sendMouseEvent (SWT.MouseUp, xEvent.button, xEvent.state, xEvent);
|
| return 0;
|
| }
|
| int processPaint (int callData) {
|
| if (!hooks (SWT.Paint)) return 0;
|
| XExposeEvent xEvent = new XExposeEvent ();
|
| OS.memmove (xEvent, callData, XExposeEvent.sizeof);
|
| int xDisplay = OS.XtDisplay (handle);
|
| if (xDisplay == 0) return 0;
|
| Event event = new Event ();
|
| event.count = xEvent.count;
|
| event.time = OS.XtLastTimestampProcessed (xDisplay);
|
| event.x = xEvent.x; event.y = xEvent.y;
|
| event.width = xEvent.width; event.height = xEvent.height;
|
| GC gc = event.gc = new GC (this);
|
| XRectangle rect = new XRectangle ();
|
| rect.x = (short) xEvent.x; rect.y = (short) xEvent.y;
|
| rect.width = (short) xEvent.width; rect.height = (short) xEvent.height;
|
| OS.XSetClipRectangles (xDisplay, gc.handle, 0, 0, rect, 1, OS.Unsorted);
|
| sendEvent (SWT.Paint, event);
|
| if (!gc.isDisposed ()) gc.dispose ();
|
| event.gc = null;
|
| return 0;
|
| }
|
| int processSelection (int callData) {
|
| postEvent (SWT.Selection);
|
| return 0;
|
| }
|
| int processSetFocus (int callData) {
|
|
|
| /* Get the focus change event */
|
| XFocusChangeEvent xEvent = new XFocusChangeEvent ();
|
| OS.memmove (xEvent, callData, XFocusChangeEvent.sizeof);
|
|
|
| /* Ignore focus changes caused by grabbing and ungrabing */
|
| if (xEvent.mode != OS.NotifyNormal) return 0;
|
|
|
| /* Only process focus callbacks between windows */
|
| if (xEvent.detail != OS.NotifyAncestor &&
|
| xEvent.detail != OS.NotifyInferior &&
|
| xEvent.detail != OS.NotifyNonlinear) return 0;
|
|
|
| /*
|
| * Ignore focus change events when the window getting or losing
|
| * focus is a menu. Because XmGetFocusWidget() does not answer
|
| * the menu shell (it answers the menu parent), it is necessary
|
| * to use XGetInputFocus() to get the real X focus window.
|
| */
|
| int xDisplay = xEvent.display;
|
| if (xDisplay == 0) return 0;
|
| int [] unused = new int [1], xWindow = new int [1];
|
| OS.XGetInputFocus (xDisplay, xWindow, unused);
|
| if (xWindow [0] != 0) {
|
| int widget = OS.XtWindowToWidget (xDisplay, xWindow [0]);
|
| if (widget != 0 && OS.XtClass (widget) == OS.XmMenuShellWidgetClass ()) return 0;
|
| }
|
|
|
| /* Process the focus change for the widget */
|
| switch (xEvent.type) {
|
| case OS.FocusIn: {
|
| processFocusIn ();
|
| // widget could be disposed at this point
|
| if (handle == 0) return 0;
|
| int index = 0;
|
| Shell shell = getShell ();
|
| Control [] focusIn = getPath ();
|
| Control lastFocus = shell.lastFocus;
|
| if (lastFocus != null) {
|
| if (!lastFocus.isDisposed ()) {
|
| Control [] focusOut = lastFocus.getPath ();
|
| int length = Math.min (focusIn.length, focusOut.length);
|
| while (index < length) {
|
| if (focusIn [index] != focusOut [index]) break;
|
| index++;
|
| }
|
| for (int i=focusOut.length-1; i>=index; --i) {
|
| focusOut [i].sendEvent (SWT.Deactivate);
|
| }
|
| }
|
| shell.lastFocus = null;
|
| }
|
| for (int i=focusIn.length-1; i>=index; --i) {
|
| focusIn [i].sendEvent (SWT.Activate);
|
| }
|
| break;
|
| }
|
| case OS.FocusOut: {
|
| processFocusOut ();
|
| // widget could be disposed at this point
|
| if (handle == 0) return 0;
|
| Shell shell = getShell ();
|
| shell.lastFocus = this;
|
| Display display = getDisplay ();
|
| Control focusControl = display.getFocusControl ();
|
| if (focusControl == null || shell != focusControl.getShell ()) {
|
| Control [] focusOut = getPath ();
|
| for (int i=focusOut.length-1; i>=0; --i) {
|
| focusOut [i].sendEvent (SWT.Deactivate);
|
| }
|
| shell.lastFocus = null;
|
| }
|
| break;
|
| }
|
| }
|
| return 0;
|
| }
|
| void propagateChildren (boolean enabled) {
|
| propagateWidget (enabled);
|
| }
|
| void propagateHandle (boolean enabled, int widgetHandle) {
|
| int xDisplay = OS.XtDisplay (widgetHandle);
|
| if (xDisplay == 0) return;
|
| int xWindow = OS.XtWindow (widgetHandle);
|
| if (xWindow == 0) return;
|
| int event_mask = OS.XtBuildEventMask (widgetHandle);
|
| int do_not_propagate_mask = OS.KeyPressMask | OS.KeyReleaseMask | OS.ButtonPressMask | OS.ButtonReleaseMask | OS.PointerMotionMask;
|
| if (!enabled) {
|
| event_mask &= ~do_not_propagate_mask;
|
| do_not_propagate_mask = 0;
|
| }
|
| XSetWindowAttributes attributes = new XSetWindowAttributes ();
|
| attributes.event_mask = event_mask;
|
| attributes.do_not_propagate_mask = do_not_propagate_mask;
|
| OS.XChangeWindowAttributes (xDisplay, xWindow, OS.CWDontPropagate | OS.CWEventMask, attributes);
|
| int [] argList = {OS.XmNtraversalOn, enabled ? 1 : 0};
|
| OS.XtSetValues (widgetHandle, argList, argList.length / 2);
|
| }
|
| void propagateWidget (boolean enabled) {
|
| propagateHandle (enabled, handle);
|
| }
|
| void realizeChildren () {
|
| if (!isEnabled ()) propagateWidget (false);
|
| }
|
| /** |
| * Causes the entire bounds of the receiver to be marked |
| * as needing to be redrawn. The next time a paint request |
| * is processed, the control will be completely painted. |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see #update |
| */ |
| public void redraw () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| redrawWidget (0, 0, 0, 0, false);
|
| }
|
| /** |
| * Causes the rectangular area of the receiver specified by |
| * the arguments to be marked as needing to be redrawn. |
| * The next time a paint request is processed, that area of |
| * the receiver will be painted. If the <code>all</code> flag |
| * is <code>true</code>, any children of the receiver which |
| * intersect with the specified area will also paint their |
| * intersecting areas. If the <code>all</code> flag is |
| * <code>false</code>, the children will not be painted. |
| * |
| * @param x the x coordinate of the area to draw |
| * @param y the y coordinate of the area to draw |
| * @param width the width of the area to draw |
| * @param height the height of the area to draw |
| * @param all <code>true</code> if children should redraw, and <code>false</code> otherwise |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see #update |
| */ |
| public void redraw (int x, int y, int width, int height, boolean all) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (x == 0 && y == 0 && width == 0 && height == 0) return;
|
| redrawWidget (x, y, width, height, all);
|
| }
|
| void redrawHandle (int x, int y, int width, int height, int widgetHandle) {
|
| int display = OS.XtDisplay (widgetHandle);
|
| if (display == 0) return;
|
| int window = OS.XtWindow (widgetHandle);
|
| if (window == 0) return;
|
| int [] argList = {OS.XmNborderWidth, 0, OS.XmNborderColor, 0};
|
| OS.XtGetValues (widgetHandle, argList, argList.length / 2);
|
| if (argList [1] != 0) {
|
| /* Force the border to repaint by setting the color */
|
| OS.XtSetValues (widgetHandle, argList, argList.length / 2);
|
| }
|
| OS.XClearArea (display, window, x, y, width, height, true);
|
| }
|
| void redrawWidget (int x, int y, int width, int height, boolean all) {
|
| redrawHandle (x, y, width, height, handle);
|
| }
|
| void releaseWidget () {
|
| super.releaseWidget ();
|
| Display display = getDisplay ();
|
| display.releaseToolTipHandle (handle);
|
| toolTipText = null;
|
| if (menu != null && !menu.isDisposed ()) {
|
| menu.dispose ();
|
| }
|
| menu = null;
|
| /*
|
| "Release the IME."
|
| self isMenu ifFalse: [
|
| handle xtIsWidget ifTrue: [
|
| handle xmImUnregister.
|
|
|
| "Bug in X. On Solaris only, destroying the window that has IME focus causes
|
| a segment fault. The fix is to set focus to the IME client window (typically
|
| the shell) when the receiver is being destroyed. Destroying the shell window
|
| does not have the problem. Note that this fix is not necessary on AIX."
|
| (xIC := self inputContext) == nil ifFalse: [
|
| (window := handle xtWindow) isNull ifFalse: [
|
| xIC xGetICValues: XNFocusWindow with: (buffer := ByteArray new: 4) with: 0.
|
| (buffer uint32At: 0) = window asInteger ifTrue: [
|
| xIC xGetICValues: XNClientWindow with: (buffer := ByteArray new: 4) with: 0.
|
| xIC
|
| xUnsetICFocus;
|
| xSetICValues: XNFocusWindow with: (buffer uint32At: 0) with: 0;
|
| xSetICFocus]]]]].
|
| */
|
| parent = null;
|
| layoutData = null;
|
| }
|
| /** |
| * Removes the listener from the collection of listeners who will |
| * be notified when the control is moved or resized. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see ControlListener |
| * @see #addControlListener |
| */
|
| public void removeControlListener (ControlListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| if (eventTable == null) return;
|
| eventTable.unhook (SWT.Move, listener);
|
| eventTable.unhook (SWT.Resize, listener);
|
| }
|
| /** |
| * Removes the listener from the collection of listeners who will |
| * be notified when the control gains or loses focus. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see FocusListener |
| * @see #addFocusListener |
| */
|
| public void removeFocusListener(FocusListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| if (eventTable == null) return;
|
| eventTable.unhook(SWT.FocusIn, listener);
|
| eventTable.unhook(SWT.FocusOut, listener);
|
| }
|
| /** |
| * Removes the listener from the collection of listeners who will |
| * be notified when the help events are generated for the control. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see HelpListener |
| * @see #addHelpListener |
| */
|
| public void removeHelpListener (HelpListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| if (eventTable == null) return;
|
| eventTable.unhook (SWT.Help, listener);
|
| }
|
| /** |
| * Removes the listener from the collection of listeners who will |
| * be notified when keys are pressed and released on the system keyboard. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see KeyListener |
| * @see #addKeyListener |
| */
|
| public void removeKeyListener(KeyListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| if (eventTable == null) return;
|
| eventTable.unhook(SWT.KeyUp, listener);
|
| eventTable.unhook(SWT.KeyDown, listener);
|
| }
|
| /** |
| * Removes the listener from the collection of listeners who will |
| * be notified when mouse buttons are pressed and released. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see MouseListener |
| * @see #addMouseListener |
| */
|
| public void removeMouseListener(MouseListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| if (eventTable == null) return;
|
| eventTable.unhook(SWT.MouseDown, listener);
|
| eventTable.unhook(SWT.MouseUp, listener);
|
| eventTable.unhook(SWT.MouseDoubleClick, listener);
|
| }
|
| /** |
| * Removes the listener from the collection of listeners who will |
| * be notified when the mouse moves. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see MouseMoveListener |
| * @see #addMouseMoveListener |
| */
|
| public void removeMouseMoveListener(MouseMoveListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| if (eventTable == null) return;
|
| eventTable.unhook(SWT.MouseMove, listener);
|
| }
|
| /** |
| * Removes the listener from the collection of listeners who will |
| * be notified when the mouse passes or hovers over controls. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see MouseTrackListener |
| * @see #addMouseTrackListener |
| */
|
| public void removeMouseTrackListener(MouseTrackListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| if (eventTable == null) return;
|
| eventTable.unhook (SWT.MouseEnter, listener);
|
| eventTable.unhook (SWT.MouseExit, listener);
|
| eventTable.unhook (SWT.MouseHover, listener);
|
| }
|
| /** |
| * Removes the listener from the collection of listeners who will |
| * be notified when the receiver needs to be painted. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see PaintListener |
| * @see #addPaintListener |
| */
|
| public void removePaintListener(PaintListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| if (eventTable == null) return;
|
| eventTable.unhook(SWT.Paint, listener);
|
| }/** |
| * Removes the listener from the collection of listeners who will |
| * be notified when traversal events occur. |
| * |
| * @param listener the listener which should be notified |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see TraverseListener |
| * @see #addTraverseListener |
| */
|
| public void removeTraverseListener(TraverseListener listener) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| if (eventTable == null) return;
|
| eventTable.unhook (SWT.Traverse, listener);
|
| }
|
| void sendHelpEvent (int callData) {
|
| Control control = this;
|
| while (control != null) {
|
| if (control.hooks (SWT.Help)) {
|
| control.postEvent (SWT.Help);
|
| return;
|
| }
|
| control = control.parent;
|
| }
|
| }
|
| void sendKeyEvent (int type, XKeyEvent xEvent) {
|
|
|
| /* Look up the keysym and character(s) */
|
| byte [] buffer;
|
| boolean isVirtual = false;
|
| int [] keysym = new int [1], status = new int [1];
|
| if (xEvent.keycode != 0) {
|
| buffer = new byte [1];
|
| isVirtual = OS.XLookupString (xEvent, buffer, buffer.length, keysym, status) == 0;
|
| } else {
|
| int size = 0;
|
| buffer = new byte [2];
|
| int xIC = inputContext ();
|
| if (xIC == 0) {
|
| size = OS.XmImMbLookupString (handle, xEvent, buffer, buffer.length, keysym, status);
|
| if (status [0] == OS.XBufferOverflow) {
|
| buffer = new byte [size];
|
| size = OS.XmImMbLookupString (handle, xEvent, buffer, size, keysym, status);
|
| }
|
| } else {
|
| size = OS.XmbLookupString (xIC, xEvent, buffer, buffer.length, keysym, status);
|
| if (status [0] == OS.XBufferOverflow) {
|
| buffer = new byte [size];
|
| size = OS.XmbLookupString (xIC, xEvent, buffer, size, keysym, status);
|
| }
|
| }
|
| if (size == 0) return;
|
| }
|
|
|
| /*
|
| * Bug in MOTIF. On Solaris only, XK_F11 and XK_F12 are not
|
| * translated correctly by XLookupString(). They are mapped
|
| * to 0x1005FF10 and 0x1005FF11 respectively. The fix is to
|
| * look for these values explicitly and correct them.
|
| */
|
| if (IsSunOS) {
|
| if ((keysym [0] == 0x1005FF10) || (keysym [0] == 0x1005FF11)) {
|
| if (keysym [0] == 0x1005FF10) keysym [0] = OS.XK_F11;
|
| if (keysym [0] == 0x1005FF11) keysym [0] = OS.XK_F12;
|
| }
|
| }
|
|
|
| /*
|
| * Bug in MOTIF. On Solaris only, their is garbage in the
|
| * high 16-bits for Keysyms such as XK_Down. Since Keysyms
|
| * must be 16-bits to fit into a Character, mask away the
|
| * high 16-bits on all platforms.
|
| */
|
| keysym [0] &= 0xFFFF;
|
|
|
| /* Convert from MBCS to UNICODE and send the event */
|
| char [] result = Converter.mbcsToWcs (null, buffer);
|
| for (int i=0; i<result.length; i++) {
|
| Event event = new Event ();
|
| event.time = xEvent.time;
|
| event.character = result [i];
|
| if (isVirtual) event.keyCode = Display.translateKey (keysym [0]);
|
| if ((xEvent.state & OS.Mod1Mask) != 0) event.stateMask |= SWT.ALT;
|
| if ((xEvent.state & OS.ShiftMask) != 0) event.stateMask |= SWT.SHIFT;
|
| if ((xEvent.state & OS.ControlMask) != 0) event.stateMask |= SWT.CONTROL;
|
| if ((xEvent.state & OS.Button1Mask) != 0) event.stateMask |= SWT.BUTTON1;
|
| if ((xEvent.state & OS.Button2Mask) != 0) event.stateMask |= SWT.BUTTON2;
|
| if ((xEvent.state & OS.Button3Mask) != 0) event.stateMask |= SWT.BUTTON3;
|
| postEvent (type, event);
|
| }
|
| }
|
| void sendMouseEvent (int type, int button, int mask, XWindowEvent xEvent) {
|
| Event event = new Event ();
|
| event.time = xEvent.time;
|
| event.button = button;
|
| event.x = xEvent.x; event.y = xEvent.y;
|
| if ((mask & OS.Mod1Mask) != 0) event.stateMask |= SWT.ALT;
|
| if ((mask & OS.ShiftMask) != 0) event.stateMask |= SWT.SHIFT;
|
| if ((mask & OS.ControlMask) != 0) event.stateMask |= SWT.CONTROL;
|
| if ((mask & OS.Button1Mask) != 0) event.stateMask |= SWT.BUTTON1;
|
| if ((mask & OS.Button2Mask) != 0) event.stateMask |= SWT.BUTTON2;
|
| if ((mask & OS.Button3Mask) != 0) event.stateMask |= SWT.BUTTON3;
|
| postEvent (type, event);
|
| }
|
| /** |
| * Sets the receiver's background color to the color specified |
| * by the argument, or to the default system color for the control |
| * if the argument is null. |
| * |
| * @param color the new color (or null) |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setBackground (Color color) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (color == null) {
|
| setBackgroundPixel (defaultBackground ());
|
| } else {
|
| if (color.isDisposed ()) return;
|
| setBackgroundPixel (color.handle.pixel);
|
| }
|
| }
|
| void setBackgroundPixel (int pixel) {
|
| int [] argList = {OS.XmNforeground, 0, OS.XmNhighlightColor, 0};
|
| OS.XtGetValues (handle, argList, argList.length / 2);
|
| OS.XmChangeColor (handle, pixel);
|
| OS.XtSetValues (handle, argList, argList.length / 2);
|
| }
|
| /** |
| * Sets the receiver's size and location to the rectangular |
| * area specified by the arguments. The <code>x</code> and |
| * <code>y</code> arguments are relative to the receiver's |
| * parent (or its display if its parent is null). |
| * <p> |
| * Note: Attempting to set the width or height of the |
| * receiver to a negative number will cause that |
| * value to be set to zero instead. |
| * </p> |
| * |
| * @param x the new x coordinate for the receiver |
| * @param y the new y coordinate for the receiver |
| * @param width the new width for the receiver |
| * @param height the new height for the receiver |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setBounds (int x, int y, int width, int height) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| /*
|
| * Feature in Motif. Motif will not allow a window
|
| * to have a zero width or zero height. The fix is
|
| * to ensure these values are never zero.
|
| */
|
| int topHandle = topHandle ();
|
| int [] argList = {
|
| OS.XmNx, 0, /* 1 */
|
| OS.XmNy, 0, /* 3 */
|
| OS.XmNwidth, 0, /* 5 */
|
| OS.XmNheight, 0, /* 7 */
|
| OS.XmNborderWidth, 0, /* 9 */
|
| };
|
| OS.XtGetValues (topHandle, argList, argList.length / 2);
|
| int newWidth = Math.max (width - (argList [9] * 2), 1);
|
| int newHeight = Math.max (height - (argList [9] * 2), 1);
|
| boolean sameOrigin = (x == (short) argList [1]) && (y == (short) argList [3]);
|
| boolean sameExtent = (newWidth == argList [5]) && (newHeight == argList [7]);
|
| if (sameOrigin && sameExtent) return;
|
| OS.XtConfigureWidget (topHandle, x, y, newWidth, newHeight, argList [9]);
|
| if (!sameOrigin) sendEvent (SWT.Move);
|
| if (!sameExtent) sendEvent (SWT.Resize);
|
| }
|
| /** |
| * Sets the receiver's size and location to the rectangular |
| * area specified by the argument. The <code>x</code> and |
| * <code>y</code> fields of the rectangle are relative to |
| * the receiver's parent (or its display if its parent is null). |
| * <p> |
| * Note: Attempting to set the width or height of the |
| * receiver to a negative number will cause that |
| * value to be set to zero instead. |
| * </p> |
| * |
| * @param rect the new bounds for the receiver |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setBounds (Rectangle rect) {
|
| if (rect == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| setBounds (rect.x, rect.y, rect.width, rect.height);
|
| }
|
| /** |
| * If the argument is <code>true</code>, causes the receiver to have |
| * all mouse events delivered to it until the method is called with |
| * <code>false</code> as the argument. |
| * |
| * @param capture <code>true</code> to capture the mouse, and <code>false</code> to release it |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setCapture (boolean capture) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| int display = OS.XtDisplay (handle);
|
| if (display == 0) return;
|
| if (capture) {
|
| int window = OS.XtWindow (handle);
|
| if (window == 0) return;
|
| OS.XGrabPointer (
|
| display,
|
| window,
|
| 0,
|
| OS.ButtonPressMask | OS.ButtonReleaseMask | OS.PointerMotionMask,
|
| OS.GrabModeAsync,
|
| OS.GrabModeAsync,
|
| OS.None,
|
| OS.None,
|
| OS.CurrentTime);
|
| } else {
|
| OS.XUngrabPointer (display, OS.CurrentTime);
|
| }
|
| }
|
| /** |
| * Sets the receiver's cursor to the cursor specified by the |
| * argument, or to the default cursor for that kind of control |
| * if the argument is null. |
| * <p> |
| * When the mouse pointer passes over a control its appearance |
| * is changed to match the control's cursor. |
| * </p> |
| * |
| * @param cursor the new cursor (or null) |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setCursor (Cursor cursor) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| int display = OS.XtDisplay (handle);
|
| if (display == 0) return;
|
| int window = OS.XtWindow (handle);
|
| if (window == 0) {
|
| if (!OS.XtIsRealized (handle)) getShell ().realizeWidget ();
|
| window = OS.XtWindow (handle);
|
| if (window == 0) return;
|
| }
|
| if (cursor == null) {
|
| OS.XUndefineCursor (display, window);
|
| } else {
|
| int xCursor = cursor.handle;
|
| OS.XDefineCursor (display, window, xCursor);
|
| OS.XFlush (display);
|
| }
|
| }
|
| /** |
| * Enables the receiver if the argument is <code>true</code>, |
| * and disables it otherwise. A disabled control is typically |
| * not selectable from the user interface and draws with an |
| * inactive or "grayed" look. |
| * |
| * @param enabled the new enabled state |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setEnabled (boolean enabled) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| enableWidget (enabled);
|
| if (!enabled || (isEnabled () && enabled)) {
|
| propagateChildren (enabled);
|
| }
|
| }
|
| /** |
| * Causes the receiver to have the <em>keyboard focus</em>, |
| * such that all keyboard events will be delivered to it. |
| * |
| * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to. |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see #forceFocus |
| */ |
| public boolean setFocus () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| Decorations shell = menuShell ();
|
| shell.setSavedFocus (this);
|
| shell.bringToTop ();
|
| return OS.XmProcessTraversal (handle, OS.XmTRAVERSE_CURRENT);
|
| }
|
| /** |
| * Sets the font that the receiver will use to paint textual information |
| * to the font specified by the argument, or to the default font for that |
| * kind of control if the argument is null. |
| * |
| * @param font the new font (or null) |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setFont (Font font) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| int fontList = 0;
|
| if (font != null) fontList = font.handle;
|
| if (fontList == 0) fontList = defaultFont ();
|
| setFontList (fontList);
|
| }
|
| void setFontList (int fontList) {
|
| this.fontList = fontList;
|
|
|
| /*
|
| * Feature in Motif. Setting the font in a widget
|
| * can cause the widget to automatically resize in
|
| * the OS. This behavior is unwanted. The fix is
|
| * to force the widget to resize to original size
|
| * after every font change.
|
| */
|
| int [] argList1 = {OS.XmNwidth, 0, OS.XmNheight, 0, OS.XmNborderWidth, 0};
|
| OS.XtGetValues (handle, argList1, argList1.length / 2);
|
|
|
| /* Set the font list */
|
| int fontHandle = fontHandle ();
|
| int [] argList2 = {OS.XmNfontList, fontList};
|
| OS.XtSetValues (fontHandle, argList2, argList2.length / 2);
|
|
|
| /* Restore the widget size */
|
| OS.XtSetValues (handle, argList1, argList1.length / 2);
|
| }
|
| /** |
| * Sets the receiver's foreground color to the color specified |
| * by the argument, or to the default system color for the control |
| * if the argument is null. |
| * |
| * @param color the new color (or null) |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setForeground (Color color) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (color == null) {
|
| setForegroundPixel (defaultForeground ());
|
| } else {
|
| if (color.isDisposed ()) return;
|
| setForegroundPixel (color.handle.pixel);
|
| }
|
| }
|
| void setForegroundPixel (int pixel) {
|
| int [] argList = {OS.XmNforeground, pixel};
|
| OS.XtSetValues (handle, argList, argList.length / 2);
|
| int xDisplay = OS.XtDisplay (handle);
|
| if (xDisplay == 0) return;
|
| int xWindow = OS.XtWindow (handle);
|
| if (xWindow == 0) return;
|
| OS.XClearArea (xDisplay, xWindow, 0, 0, 0, 0, true);
|
| }
|
| void setGrabCursor (int cursor) {
|
| /* | window attributes eventMask grabMask |
|
| handle xtIsWidget ifFalse: [^self].
|
| (window := handle xtWindow) isNull ifTrue: [^self].
|
| attributes := OSXWindowAttributesPtr new.
|
| XDisplay
|
| xGetWindowAttributes: window
|
| windowAttributesReturn: attributes.
|
| grabMask := ((((((((((ButtonPressMask bitOr: ButtonReleaseMask) bitOr:
|
| EnterWindowMask) bitOr: LeaveWindowMask) bitOr: PointerMotionMask) bitOr:
|
| PointerMotionHintMask) bitOr: Button1MotionMask) bitOr: Button2MotionMask) bitOr:
|
| Button3MotionMask) bitOr: Button4MotionMask) bitOr: Button5MotionMask) bitOr: ButtonMotionMask.
|
| eventMask := attributes yourEventMask bitAnd: grabMask.
|
| XDisplay xChangeActivePointerGrab: eventMask cursor: aCursor time: CurrentTime.
|
| */
|
| }
|
| void setKeyState (Event event, XKeyEvent xEvent) {
|
| if (xEvent.keycode != 0) {
|
| event.time = xEvent.time;
|
| byte [] buffer1 = new byte [1];
|
| int [] keysym = new int [1], status = new int [1];
|
| if (OS.XLookupString (xEvent, buffer1, buffer1.length, keysym, status) == 0) {
|
| event.keyCode = Display.translateKey (keysym [0] & 0xFFFF);
|
| } else {
|
| event.character = (char) buffer1 [0];
|
| }
|
| if ((xEvent.state & OS.Mod1Mask) != 0) event.stateMask |= SWT.ALT;
|
| if ((xEvent.state & OS.ShiftMask) != 0) event.stateMask |= SWT.SHIFT;
|
| if ((xEvent.state & OS.ControlMask) != 0) event.stateMask |= SWT.CONTROL;
|
| if ((xEvent.state & OS.Button1Mask) != 0) event.stateMask |= SWT.BUTTON1;
|
| if ((xEvent.state & OS.Button2Mask) != 0) event.stateMask |= SWT.BUTTON2;
|
| if ((xEvent.state & OS.Button3Mask) != 0) event.stateMask |= SWT.BUTTON3;
|
| }
|
| }
|
| /** |
| * Sets the layout data associated with the receiver to the argument. |
| * |
| * @param layoutData the new layout data for the receiver. |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setLayoutData (Object layoutData) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| this.layoutData = layoutData;
|
| }
|
| /** |
| * Sets the receiver's location to the point specified by |
| * the arguments which are relative to the receiver's |
| * parent (or its display if its parent is null). |
| * |
| * @param x the new x coordinate for the receiver |
| * @param y the new y coordinate for the receiver |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setLocation (int x, int y) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| int topHandle = topHandle ();
|
| int [] argList = {OS.XmNx, 0, OS.XmNy, 0};
|
| OS.XtGetValues (topHandle, argList, argList.length / 2);
|
| boolean sameOrigin = (x == (short) argList [1]) && (y == (short) argList [3]);
|
| if (sameOrigin) return;
|
| OS.XtMoveWidget (topHandle, x, y);
|
| if (!sameOrigin) sendEvent (SWT.Move);
|
| }
|
| /** |
| * Sets the receiver's location to the point specified by |
| * the argument which is relative to the receiver's |
| * parent (or its display if its parent is null). |
| * |
| * @param location the new location for the receiver |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setLocation (Point location) {
|
| if (location == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| setLocation (location.x, location.y);
|
| }
|
| /** |
| * Sets the receiver's pop up menu to the argument. |
| * All controls may optionally have a pop up |
| * menu that is displayed when the user requests one for |
| * the control. The sequence of key strokes, button presses |
| * and/or button releases that are used to request a pop up |
| * menu is platform specific. |
| * |
| * @param menu the new pop up menu |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu</li> |
| * <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */
|
| public void setMenu (Menu menu) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (menu != null) {
|
| if ((menu.style & SWT.POP_UP) == 0) {
|
| error (SWT.ERROR_MENU_NOT_POP_UP);
|
| }
|
| if (menu.parent != menuShell ()) {
|
| error (SWT.ERROR_INVALID_PARENT);
|
| }
|
| }
|
| this.menu = menu;
|
| }
|
|
|
| /** |
| * Changes the parent of the widget to be the one provided if |
| * the underlying operating system supports this feature. |
| * Answers <code>true</code> if the parent is successfully changed. |
| * |
| * @param parent the new parent for the control. |
| * @return <code>true</code> if the parent is changed and <code>false</code> otherwise. |
| * |
| * @exception SWTError <ul> |
| * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li> |
| * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li> |
| * </ul> |
| */
|
| public boolean setParent (Composite parent) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| return false;
|
| }
|
|
|
| /** |
| * If the argument is <code>false</code>, causes subsequent drawing |
| * operations in the receiver to be ignored. No drawing of any kind |
| * can occur in the receiver until the flag is set to true. |
| * Graphics operations that occurred while the flag was |
| * <code>false</code> are lost. When the flag is set to <code>true</code>, |
| * the entire widget is marked as needing to be redrawn. |
| * <p> |
| * Note: This operation is a hint and may not be supported on some |
| * platforms or for some widgets. |
| * </p> |
| * |
| * @param redraw the new redraw state |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see #redraw |
| * @see #update |
| */ |
| public void setRedraw (boolean redraw) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| }
|
| /** |
| * Sets the receiver's size to the point specified by the arguments. |
| * <p> |
| * Note: Attempting to set the width or height of the |
| * receiver to a negative number will cause that |
| * value to be set to zero instead. |
| * </p> |
| * |
| * @param width the new width for the receiver |
| * @param height the new height for the receiver |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setSize (int width, int height) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| /*
|
| * Feature in Motif. Motif will not allow a window
|
| * to have a zero width or zero height. The fix is
|
| * to ensure these values are never zero.
|
| */
|
| int topHandle = topHandle ();
|
| int [] argList = {OS.XmNwidth, 0, OS.XmNheight, 0, OS.XmNborderWidth, 0};
|
| OS.XtGetValues (topHandle, argList, argList.length / 2);
|
| int newWidth = Math.max (width - (argList [5] * 2), 1);
|
| int newHeight = Math.max (height - (argList [5] * 2), 1);
|
| boolean sameExtent = (newWidth == argList [1]) && (newHeight == argList [3]);
|
| if (sameExtent) return;
|
| OS.XtResizeWidget (topHandle, newWidth, newHeight, argList [5]);
|
| if (!sameExtent) sendEvent (SWT.Resize);
|
| }
|
| /** |
| * Sets the receiver's size to the point specified by the argument. |
| * <p> |
| * Note: Attempting to set the width or height of the |
| * receiver to a negative number will cause them to be |
| * set to zero instead. |
| * </p> |
| * |
| * @param size the new size for the receiver |
| * @param height the new height for the receiver |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the point is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setSize (Point size) {
|
| if (size == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| setSize (size.x, size.y);
|
| }
|
| /** |
| * Sets the receiver's tool tip text to the argument, which |
| * may be null indicating that no tool tip text should be shown. |
| * |
| * @param string the new tool tip text (or null) |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */
|
| public void setToolTipText (String string) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| toolTipText = string;
|
| }
|
| /** |
| * Marks the receiver as visible if the argument is <code>true</code>, |
| * and marks it invisible otherwise. |
| * <p> |
| * If one of the receiver's ancestors is not visible or some |
| * other condition makes the receiver not visible, marking |
| * it visible may not actually cause it to be displayed. |
| * </p> |
| * |
| * @param visible the new visibility state |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setVisible (boolean visible) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| int topHandle = topHandle ();
|
| int [] argList = {OS.XmNmappedWhenManaged, 0};
|
| OS.XtGetValues (topHandle, argList, argList.length / 2);
|
| if ((argList [1] != 0) == visible) return;
|
| OS.XtSetMappedWhenManaged (topHandle, visible);
|
| sendEvent (visible ? SWT.Show : SWT.Hide);
|
| }
|
| void setZOrder (Control control, boolean above) {
|
| /*
|
| * Feature in Xt. We cannot use XtMakeGeometryRequest() to
|
| * restack widgets because this call can fail under certain
|
| * conditions. For example, XtMakeGeometryRequest() answers
|
| * XtGeometryNo when attempting to bring a child widget that
|
| * is larger than the parent widget to the front. The fix
|
| * is to use X calls instead.
|
| */
|
| int topHandle1 = topHandle ();
|
| int display = OS.XtDisplay (topHandle1);
|
| if (display == 0) return;
|
| if (!OS.XtIsRealized (topHandle1)) {
|
| Shell shell = this.getShell ();
|
| shell.realizeWidget ();
|
| }
|
| int window1 = OS.XtWindow (topHandle1);
|
| if (window1 == 0) return;
|
| if (control == null) {
|
| if (above) {
|
| OS.XRaiseWindow (display, window1);
|
| if (parent != null) parent.moveAbove (topHandle1, 0);
|
| } else {
|
| OS.XLowerWindow (display, window1);
|
| if (parent != null) parent.moveBelow (topHandle1, 0);
|
| }
|
| return;
|
| }
|
| int topHandle2 = control.topHandle ();
|
| if (display != OS.XtDisplay (topHandle2)) return;
|
| if (!OS.XtIsRealized (topHandle2)) {
|
| Shell shell = control.getShell ();
|
| shell.realizeWidget ();
|
| }
|
| int window2 = OS.XtWindow (topHandle2);
|
| if (window2 == 0) return;
|
| XWindowChanges struct = new XWindowChanges ();
|
| struct.sibling = window2;
|
| struct.stack_mode = above ? OS.Above : OS.Below;
|
| /*
|
| * Feature in X. If the receiver is a top level, XConfigureWindow ()
|
| * will fail (with a BadMatch error) for top level shells because top
|
| * level shells are reparented by the window manager and do not share
|
| * the same X window parent. This is the correct behavior but it is
|
| * unexpected. The fix is to use XReconfigureWMWindow () instead.
|
| * When the receiver is not a top level shell, XReconfigureWMWindow ()
|
| * behaves the same as XConfigureWindow ().
|
| */
|
| int screen = OS.XDefaultScreen (display);
|
| int flags = OS.CWStackMode | OS.CWSibling;
|
| OS.XReconfigureWMWindow (display, window1, screen, flags, struct);
|
| if (above) {
|
| if (parent != null) parent.moveAbove (topHandle1, topHandle2);
|
| } else {
|
| if (parent != null) parent.moveBelow (topHandle1, topHandle2);
|
| }
|
| }
|
| /** |
| * Returns a point which is the result of converting the |
| * argument, which is specified in display relative coordinates, |
| * to coordinates relative to the receiver. |
| * <p> |
| * @param point the point to be translated (must not be null) |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the point is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Point toControl (Point point) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| short [] root_x = new short [1], root_y = new short [1];
|
| OS.XtTranslateCoords (handle, (short) 0, (short) 0, root_x, root_y);
|
| return new Point (point.x - root_x [0], point.y - root_y [0]);
|
| }
|
| /** |
| * Returns a point which is the result of converting the |
| * argument, which is specified in coordinates relative to |
| * the receiver, to display relative coordinates. |
| * <p> |
| * @param point the point to be translated (must not be null) |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the point is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public Point toDisplay (Point point) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| short [] root_x = new short [1], root_y = new short [1];
|
| OS.XtTranslateCoords (handle, (short) point.x, (short) point.y, root_x, root_y);
|
| return new Point (root_x [0], root_y [0]);
|
| }
|
| boolean translateMnemonic (int aKey, XKeyEvent xEvent) {
|
| if (xEvent.state != OS.Mod1Mask) {
|
| if (xEvent.state != 0 || !(this instanceof Button)) {
|
| return false;
|
| }
|
| }
|
| Decorations shell = menuShell ();
|
| if (!shell.isVisible () || !shell.isEnabled ()) return false;
|
| char ch = mbcsToWcs ((char) aKey);
|
| return ch != 0 && shell.traverseMnemonic (ch);
|
| }
|
| boolean translateTraversal (int key, XKeyEvent xEvent) {
|
| int detail = 0;
|
| switch (key) {
|
| case OS.XK_Escape:
|
| case OS.XK_Cancel:
|
| Shell shell = getShell ();
|
| if (shell.parent == null) return false;
|
| if (!shell.isVisible () || !shell.isEnabled ()) return false;
|
| detail = SWT.TRAVERSE_ESCAPE;
|
| break;
|
| case OS.XK_Return:
|
| Button button = menuShell ().getDefaultButton ();
|
| if (button == null || button.isDisposed ()) return false;
|
| if (!button.isVisible () || !button.isEnabled ()) return false;
|
| detail = SWT.TRAVERSE_RETURN;
|
| break;
|
| case OS.XK_Tab:
|
| detail = SWT.TRAVERSE_TAB_PREVIOUS;
|
| boolean next = (xEvent.state & OS.ShiftMask) == 0;
|
| if (next && ((xEvent.state & OS.ControlMask) != 0)) return false;
|
| if (next) detail = SWT.TRAVERSE_TAB_NEXT;
|
| break;
|
| case OS.XK_Up:
|
| case OS.XK_Left:
|
| detail = SWT.TRAVERSE_ARROW_PREVIOUS;
|
| break;
|
| case OS.XK_Down:
|
| case OS.XK_Right:
|
| detail = SWT.TRAVERSE_ARROW_NEXT;
|
| break;
|
| default:
|
| return false;
|
| }
|
| boolean doit = (detail & traversalCode ()) != 0;
|
| if (hooks (SWT.Traverse)) {
|
| Event event = new Event();
|
| event.doit = doit;
|
| event.detail = detail;
|
| setKeyState (event, xEvent);
|
| sendEvent (SWT.Traverse, event);
|
| doit = event.doit;
|
| detail = event.detail;
|
| }
|
| /*
|
| * NOTE: The native widgets handle tab and arrow key traversal
|
| * so it is not necessary to traverse these keys. A canvas widget
|
| * has no native traversal by definition so it is necessary to
|
| * traverse all keys.
|
| */
|
| if (doit) {
|
| int flags = SWT.TRAVERSE_RETURN | SWT.TRAVERSE_ESCAPE;
|
| if ((detail & flags) != 0 || (state & CANVAS) != 0) {
|
| return traverse (detail);
|
| }
|
| }
|
| return false;
|
| }
|
| int traversalCode () {
|
| int code = SWT.TRAVERSE_ESCAPE | SWT.TRAVERSE_RETURN;
|
| int [] argList = {OS.XmNnavigationType, 0};
|
| OS.XtGetValues (handle, argList, argList.length / 2);
|
| if (argList [1] == OS.XmNONE) {
|
| code |= SWT.TRAVERSE_ARROW_NEXT | SWT.TRAVERSE_ARROW_PREVIOUS;
|
| } else {
|
| code |= SWT.TRAVERSE_TAB_NEXT | SWT.TRAVERSE_TAB_PREVIOUS;
|
| }
|
| return code;
|
| }
|
| boolean traverseMnemonic (char key) {
|
| if (!isVisible () || !isEnabled ()) return false;
|
| return mnemonicMatch (key) && mnemonicHit ();
|
| }
|
| /** |
| * Based on the argument, perform one of the expected platform |
| * traversal action. The argument should be one of the constants: |
| * <code>SWT.TRAVERSE_ESCAPE</code>, <code>SWT.TRAVERSE_RETURN</code>, |
| * <code>SWT.TRAVERSE_TAB_NEXT</code>, <code>SWT.TRAVERSE_TAB_PREVIOUS</code>, |
| * <code>SWT.TRAVERSE_ARROW_NEXT</code> and <code>SWT.TRAVERSE_ARROW_PREVIOUS</code>. |
| * |
| * @param traversal the type of traversal |
| * @return true if the traversal succeeded |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| */
|
| public boolean traverse (int traversal) {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| if (!isFocusControl () && !setFocus ()) return false;
|
| switch (traversal) {
|
| case SWT.TRAVERSE_ESCAPE: return traverseEscape ();
|
| case SWT.TRAVERSE_RETURN: return traverseReturn ();
|
| case SWT.TRAVERSE_TAB_NEXT: return traverseGroup (true);
|
| case SWT.TRAVERSE_TAB_PREVIOUS: return traverseGroup (false);
|
| case SWT.TRAVERSE_ARROW_NEXT: return traverseItem (true);
|
| case SWT.TRAVERSE_ARROW_PREVIOUS: return traverseItem (false);
|
| }
|
| return false;
|
| }
|
| boolean traverseEscape () {
|
| Shell shell = getShell ();
|
| if (shell.parent == null) return false;
|
| if (!shell.isVisible () || !shell.isEnabled ()) return false;
|
| shell.close ();
|
| return true;
|
| }
|
| boolean traverseGroup (boolean next) {
|
| return OS.XmProcessTraversal (handle, next ? OS.XmTRAVERSE_NEXT_TAB_GROUP : OS.XmTRAVERSE_PREV_TAB_GROUP);
|
| }
|
| boolean traverseItem (boolean next) {
|
| return OS.XmProcessTraversal (handle, next ? OS.XmTRAVERSE_NEXT : OS.XmTRAVERSE_PREV);
|
| }
|
| boolean traverseReturn () {
|
| Button button = menuShell ().getDefaultButton ();
|
| if (button == null || button.isDisposed ()) return false;
|
| if (!button.isVisible () || !button.isEnabled ()) return false;
|
| button.click ();
|
| return true;
|
| }
|
| /** |
| * Forces all outstanding paint requests for the widget tree |
| * to be processed before this method returns. |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
| * </ul> |
| * |
| * @see #redraw |
| */ |
| public void update () {
|
| if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
|
| if (!isValidWidget ()) error (SWT.ERROR_WIDGET_DISPOSED);
|
| int display = OS.XtDisplay (handle);
|
| if (display == 0) return;
|
| int window = OS.XtWindow (handle);
|
| if (window == 0) return;
|
| XAnyEvent event = new XAnyEvent ();
|
| OS.XSync (display, false); OS.XSync (display, false);
|
| while (OS.XCheckWindowEvent (display, window, OS.ExposureMask, event)) {
|
| OS.XtDispatchEvent (event);
|
| }
|
| }
|
| } |