Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Composite.java')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Composite.java1082
1 files changed, 1082 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Composite.java
new file mode 100644
index 0000000000..18f0e3d27f
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Composite.java
@@ -0,0 +1,1082 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.carbon.OS;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Instances of this class are controls which are capable
+ * of containing other controls.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>NO_BACKGROUND, NO_FOCUS, NO_MERGE_PAINTS, NO_REDRAW_RESIZE, NO_RADIO_GROUP, EMBEDDED, DOUBLE_BUFFERED</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * Note: The <code>NO_BACKGROUND</code>, <code>NO_FOCUS</code>, <code>NO_MERGE_PAINTS</code>,
+ * and <code>NO_REDRAW_RESIZE</code> styles are intended for use with <code>Canvas</code>.
+ * They can be used with <code>Composite</code> if you are drawing your own, but their
+ * behavior is undefined if they are used with subclasses of <code>Composite</code> other
+ * than <code>Canvas</code>.
+ * </p><p>
+ * Note: The <code>CENTER</code> style, although undefined for composites, has the
+ * same value as <code>EMBEDDED</code> which is used to embed widgets from other
+ * widget toolkits into SWT. On some operating systems (GTK, Motif), this may cause
+ * the children of this composite to be obscured.
+ * </p><p>
+ * This class may be subclassed by custom control implementors
+ * who are building controls that are constructed from aggregates
+ * of other controls.
+ * </p>
+ *
+ * @see Canvas
+ * @see <a href="http://www.eclipse.org/swt/snippets/#composite">Composite snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ */
+public class Composite extends Scrollable {
+ Layout layout;
+ Control[] tabList;
+ int scrolledVisibleRgn, siblingsVisibleRgn;
+ int layoutCount, backgroundMode;
+
+Composite () {
+ /* 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
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a widget which will be the parent of the new instance (cannot be null)
+ * @param style the style of widget 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>
+ * </ul>
+ *
+ * @see SWT#NO_BACKGROUND
+ * @see SWT#NO_FOCUS
+ * @see SWT#NO_MERGE_PAINTS
+ * @see SWT#NO_REDRAW_RESIZE
+ * @see SWT#NO_RADIO_GROUP
+ * @see SWT#EMBEDDED
+ * @see SWT#DOUBLE_BUFFERED
+ * @see Widget#getStyle
+ */
+public Composite (Composite parent, int style) {
+ super (parent, style);
+}
+
+Control [] _getChildren () {
+ short [] buffer = new short [1];
+ OS.CountSubControls (handle, buffer);
+ int count = buffer [0];
+ Control [] children = new Control [count];
+ int i = 0, j = 0;
+ int child = OS.HIViewGetFirstSubview (handle);
+ while (i < count) {
+ if (child != 0) {
+ Widget widget = display.getWidget (child);
+ if (widget != null && widget != this) {
+ if (widget instanceof Control) {
+ children [j++] = (Control) widget;
+ }
+ }
+ }
+ child = OS.HIViewGetNextView (child);
+ i++;
+ }
+ if (j == count) return children;
+ Control [] newChildren = new Control [j];
+ System.arraycopy (children, 0, newChildren, 0, j);
+ return newChildren;
+}
+
+Control [] _getTabList () {
+ if (tabList == null) return null;
+ int count = 0;
+ for (int i=0; i<tabList.length; i++) {
+ if (!tabList [i].isDisposed ()) count++;
+ }
+ if (count == tabList.length) return tabList;
+ Control [] newList = new Control [count];
+ int index = 0;
+ for (int i=0; i<tabList.length; i++) {
+ if (!tabList [i].isDisposed ()) {
+ newList [index++] = tabList [i];
+ }
+ }
+ tabList = newList;
+ return tabList;
+}
+
+int callFocusEventHandler (int nextHandler, int theEvent) {
+ if ((state & CANVAS) != 0) return OS.noErr;
+ return super.callFocusEventHandler (nextHandler, theEvent);
+}
+
+/**
+ * Clears any data that has been cached by a Layout for all widgets that
+ * are in the parent hierarchy of the changed control up to and including the
+ * receiver. If an ancestor does not have a layout, it is skipped.
+ *
+ * @param changed an array of controls that changed state and require a recalculation of size
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the changed array is null any of its controls are null or have been disposed</li>
+ * <li>ERROR_INVALID_PARENT - if any control in changed is not in the widget tree of the receiver</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>
+ *
+ * @since 3.1
+ */
+public void changed (Control[] changed) {
+ checkWidget ();
+ if (changed == null) error (SWT.ERROR_INVALID_ARGUMENT);
+ for (int i=0; i<changed.length; i++) {
+ Control control = changed [i];
+ if (control == null) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ boolean ancestor = false;
+ Composite composite = control.parent;
+ while (composite != null) {
+ ancestor = composite == this;
+ if (ancestor) break;
+ composite = composite.parent;
+ }
+ if (!ancestor) error (SWT.ERROR_INVALID_PARENT);
+ }
+ for (int i=0; i<changed.length; i++) {
+ Control child = changed [i];
+ Composite composite = child.parent;
+ while (child != this) {
+ if (composite.layout == null || !composite.layout.flushCache (child)) {
+ composite.state |= LAYOUT_CHANGED;
+ }
+ child = composite;
+ composite = child.parent;
+ }
+ }
+}
+
+public Point computeSize (int wHint, int hHint, boolean changed) {
+ checkWidget();
+ Point size;
+ if (layout != null) {
+ if ((wHint == SWT.DEFAULT) || (hHint == SWT.DEFAULT)) {
+ changed |= (state & LAYOUT_CHANGED) != 0;
+ size = layout.computeSize (this, wHint, hHint, changed);
+ state &= ~LAYOUT_CHANGED;
+ } else {
+ size = new Point (wHint, hHint);
+ }
+ } else {
+ size = minimumSize (wHint, hHint, changed);
+ }
+ if (size.x == 0) size.x = DEFAULT_WIDTH;
+ if (size.y == 0) size.y = DEFAULT_HEIGHT;
+ if (wHint != SWT.DEFAULT) size.x = wHint;
+ if (hHint != SWT.DEFAULT) size.y = hHint;
+ Rectangle trim = computeTrim (0, 0, size.x, size.y);
+ return new Point (trim.width, trim.height);
+}
+
+protected void checkSubclass () {
+ /* Do nothing - Subclassing is allowed */
+}
+
+Control [] computeTabList () {
+ Control result [] = super.computeTabList ();
+ if (result.length == 0) return result;
+ Control [] list = tabList != null ? _getTabList () : _getChildren ();
+ for (int i=0; i<list.length; i++) {
+ Control child = list [i];
+ Control [] childList = child.computeTabList ();
+ if (childList.length != 0) {
+ Control [] newResult = new Control [result.length + childList.length];
+ System.arraycopy (result, 0, newResult, 0, result.length);
+ System.arraycopy (childList, 0, newResult, result.length, childList.length);
+ result = newResult;
+ }
+ }
+ return result;
+}
+
+void createHandle () {
+ state |= CANVAS | GRAB;
+ boolean scrolled = (style & (SWT.H_SCROLL | SWT.V_SCROLL)) != 0;
+ if (!scrolled) state |= THEME_BACKGROUND;
+ if (scrolled || (style & SWT.BORDER) != 0) {
+ createScrolledHandle (parent.handle);
+ } else {
+ createHandle (parent.handle);
+ }
+}
+
+void createHandle (int parentHandle) {
+ int features = OS.kControlSupportsEmbedding | OS.kControlSupportsFocus;
+ int [] outControl = new int [1];
+ int window = OS.GetControlOwner (parentHandle);
+ OS.CreateUserPaneControl (window, null, features, outControl);
+ if (outControl [0] == 0) error (SWT.ERROR_NO_HANDLES);
+ handle = outControl [0];
+ OS.HIObjectSetAccessibilityIgnored (handle, true);
+}
+
+void createScrolledHandle (int parentHandle) {
+ int features = OS.kControlSupportsEmbedding;
+ int [] outControl = new int [1];
+ int window = OS.GetControlOwner (parentHandle);
+ OS.CreateUserPaneControl (window, null, features, outControl);
+ if (outControl [0] == 0) error (SWT.ERROR_NO_HANDLES);
+ scrolledHandle = outControl [0];
+ outControl [0] = 0;
+ features |= OS.kControlSupportsFocus;
+ OS.CreateUserPaneControl (window, null, features, outControl);
+ if (outControl [0] == 0) error (SWT.ERROR_NO_HANDLES);
+ handle = outControl [0];
+ OS.HIObjectSetAccessibilityIgnored (scrolledHandle, true);
+ OS.HIObjectSetAccessibilityIgnored (handle, true);
+}
+
+void drawBackground (int control, int context) {
+ if (control == scrolledHandle) {
+ Composite parent = this;
+ Shell shell = getShell ();
+ if (shell != this) parent = this.parent;
+ boolean drawBackground = (style & SWT.TRANSPARENT) == 0;
+ if ((style & SWT.NO_FOCUS) == 0 && hooksKeys ()) {
+ parent.drawFocus (control, context, hasFocus () && drawFocusRing (), hasBorder (), drawBackground, inset ());
+ } else {
+ if (hasBorder ()) {
+ parent.drawFocus (control, context, false, hasBorder (), drawBackground, inset ());
+ } else {
+ parent.fillBackground (control, context, null);
+ }
+ }
+ } else {
+ if ((state & CANVAS) != 0) {
+ if ((style & (SWT.NO_BACKGROUND | SWT.TRANSPARENT)) == 0) {
+ fillBackground (control, context, null);
+ }
+ }
+ }
+}
+
+void enableWidget (boolean enabled) {
+ //NOT DONE - take into account current scroll bar state
+ if ((state & CANVAS) != 0) {
+ if (horizontalBar != null) horizontalBar.enableWidget (enabled);
+ if (verticalBar != null) verticalBar.enableWidget (enabled);
+ return;
+ }
+ super.enableWidget (enabled);
+}
+
+Composite findDeferredControl () {
+ return layoutCount > 0 ? this : parent.findDeferredControl ();
+}
+
+Menu [] findMenus (Control control) {
+ if (control == this) return new Menu [0];
+ Menu result [] = super.findMenus (control);
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ Control child = children [i];
+ Menu [] menuList = child.findMenus (control);
+ if (menuList.length != 0) {
+ Menu [] newResult = new Menu [result.length + menuList.length];
+ System.arraycopy (result, 0, newResult, 0, result.length);
+ System.arraycopy (menuList, 0, newResult, result.length, menuList.length);
+ result = newResult;
+ }
+ }
+ return result;
+}
+
+void fixChildren (Shell newShell, Shell oldShell, Decorations newDecorations, Decorations oldDecorations, Menu [] menus) {
+ super.fixChildren (newShell, oldShell, newDecorations, oldDecorations, menus);
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ children [i].fixChildren (newShell, oldShell, newDecorations, oldDecorations, menus);
+ }
+}
+
+void fixTabList (Control control) {
+ if (tabList == null) return;
+ int count = 0;
+ for (int i=0; i<tabList.length; i++) {
+ if (tabList [i] == control) count++;
+ }
+ if (count == 0) return;
+ Control [] newList = null;
+ int length = tabList.length - count;
+ if (length != 0) {
+ newList = new Control [length];
+ int index = 0;
+ for (int i=0; i<tabList.length; i++) {
+ if (tabList [i] != control) {
+ newList [index++] = tabList [i];
+ }
+ }
+ }
+ tabList = newList;
+}
+
+/**
+ * Returns the receiver's background drawing mode. This
+ * will be one of the following constants defined in class
+ * <code>SWT</code>:
+ * <code>INHERIT_NONE</code>, <code>INHERIT_DEFAULT</code>,
+ * <code>INHERTIT_FORCE</code>.
+ *
+ * @return the background mode
+ *
+ * @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 SWT
+ *
+ * @since 3.2
+ */
+public int getBackgroundMode () {
+ checkWidget ();
+ return backgroundMode;
+}
+
+/**
+ * Returns a (possibly empty) array containing the receiver's children.
+ * Children are returned in the order that they are drawn. The topmost
+ * control appears at the beginning of the array. Subsequent controls
+ * draw beneath this control and appear later in the array.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of children, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return an array of children
+ *
+ * @see Control#moveAbove
+ * @see Control#moveBelow
+ *
+ * @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 Control [] getChildren () {
+ checkWidget();
+ return _getChildren ();
+}
+
+int getChildrenCount () {
+ /*
+ * NOTE: The current implementation will count
+ * non-registered children.
+ */
+ short [] count = new short [1];
+ OS.CountSubControls (handle, count);
+ return count [0];
+}
+
+/**
+ * Returns layout which is associated with the receiver, or
+ * null if one has not been set.
+ *
+ * @return the receiver's layout 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 Layout getLayout () {
+ checkWidget();
+ return layout;
+}
+
+/**
+ * Returns <code>true</code> if the receiver has deferred
+ * the performing of layout, and <code>false</code> otherwise.
+ *
+ * @return the receiver's deferred layout 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 #setLayoutDeferred(boolean)
+ * @see #isLayoutDeferred()
+ *
+ * @since 3.1
+ */
+public boolean getLayoutDeferred () {
+ checkWidget ();
+ return layoutCount > 0 ;
+}
+
+/**
+ * Gets the (possibly empty) tabbing order for the control.
+ *
+ * @return tabList the ordered list of controls representing the tab order
+ *
+ * @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 #setTabList
+ */
+public Control [] getTabList () {
+ checkWidget ();
+ Control [] tabList = _getTabList ();
+ if (tabList == null) {
+ int count = 0;
+ Control [] list =_getChildren ();
+ for (int i=0; i<list.length; i++) {
+ if (list [i].isTabGroup ()) count++;
+ }
+ tabList = new Control [count];
+ int index = 0;
+ for (int i=0; i<list.length; i++) {
+ if (list [i].isTabGroup ()) {
+ tabList [index++] = list [i];
+ }
+ }
+ }
+ return tabList;
+}
+
+int getVisibleRegion (int control, boolean clipChildren) {
+ if (!clipChildren && control == handle) {
+ if (siblingsVisibleRgn == 0) {
+ siblingsVisibleRgn = OS.NewRgn ();
+ calculateVisibleRegion (control, siblingsVisibleRgn, clipChildren);
+ }
+ int result = OS.NewRgn ();
+ OS.CopyRgn (siblingsVisibleRgn, result);
+ return result;
+ }
+ if (control == scrolledHandle) {
+ if (!clipChildren) return super.getVisibleRegion (control, clipChildren);
+ if (scrolledVisibleRgn == 0) {
+ scrolledVisibleRgn = OS.NewRgn ();
+ calculateVisibleRegion (control, scrolledVisibleRgn, clipChildren);
+ }
+ int result = OS.NewRgn ();
+ OS.CopyRgn (scrolledVisibleRgn, result);
+ return result;
+ }
+ return super.getVisibleRegion (control, clipChildren);
+}
+
+int kEventControlClick (int nextHandler, int theEvent, int userData) {
+ int result = super.kEventControlClick (nextHandler, theEvent, userData);
+ if (result == OS.noErr) return result;
+ if ((state & CANVAS) != 0) {
+ if (!isEnabled ()) return result;
+ if ((style & SWT.NO_FOCUS) == 0 && hooksKeys ()) {
+ int [] theControl = new int [1];
+ int window = OS.GetControlOwner (handle);
+ OS.GetKeyboardFocus (window, theControl);
+ if (handle != theControl [0]) {
+ short [] count = new short [1];
+ OS.CountSubControls (handle, count);
+ if (count [0] == 0) {
+ if (OS.SetKeyboardFocus (window, handle, (short) focusPart ()) == OS.noErr) {
+ return OS.noErr;
+ }
+ }
+ }
+ }
+ }
+ return result;
+}
+
+int kEventControlGetFocusPart (int nextHandler, int theEvent, int userData) {
+ if ((state & CANVAS) != 0) return OS.noErr;
+ return super.kEventControlGetFocusPart (nextHandler, theEvent, userData);
+}
+
+int kEventControlSetFocusPart (int nextHandler, int theEvent, int userData) {
+ int result = super.kEventControlSetFocusPart (nextHandler, theEvent, userData);
+ if (result == OS.noErr) {
+ if ((state & CANVAS) != 0) {
+ if (scrolledHandle != 0) {
+ if ((style & SWT.NO_FOCUS) == 0 && hooksKeys ()) {
+ short [] part = new short [1];
+ OS.GetEventParameter (theEvent, OS.kEventParamControlPart, OS.typeControlPartCode, null, 2, null, part);
+ redrawWidget (scrolledHandle, false);
+ }
+ }
+ }
+ }
+ return result;
+}
+
+int kEventMouseDown (int nextHandler, int theEvent, int userData) {
+ int result = super.kEventMouseDown (nextHandler, theEvent, userData);
+ if (result == OS.noErr) return result;
+ if ((state & CANVAS) != 0) {
+ if ((style & SWT.NO_FOCUS) != 0) {
+ Shell shell = getShell ();
+ int bits = SWT.ON_TOP | SWT.NO_FOCUS;
+ if ((shell.style & bits) == bits) return OS.noErr;
+ }
+ }
+ return result;
+}
+
+int kEventRawKeyPressed (int nextHandler, int theEvent, int userData) {
+ /*
+ * For some reason the next event handler for embedded controls
+ * stops the event chain and does not let the default handler
+ * process the raw key event into unicode. The fix to send
+ * the key from kEventRawKeyDown instead.
+ *
+ * Note: should the embedded control no longer stop the event
+ * chain, there will be two key events issued for one key press.
+ */
+ if ((state & CANVAS) != 0 && (style & SWT.EMBEDDED) != 0) {
+ int [] theControl = new int[1];
+ OS.GetKeyboardFocus (OS.GetControlOwner(handle), theControl);
+ if (theControl[0] != handle) {
+ if (!sendKeyEvent (SWT.KeyDown, theEvent)) return OS.noErr;
+ return OS.eventNotHandledErr;
+ }
+ }
+
+ /*
+ * Feature in the Macintosh. For some reason, the default handler
+ * does not issue kEventTextInputUnicodeForKeyEvent when the user
+ * types Command+Space. The fix is to look for this case and
+ * send the key from kEventRawKeyDown instead.
+ *
+ * NOTE: This code relies on Command+Space being consumed and
+ * will deliver two events if this ever changes.
+ */
+ if ((state & CANVAS) != 0) {
+ int [] keyCode = new int [1];
+ OS.GetEventParameter (theEvent, OS.kEventParamKeyCode, OS.typeUInt32, null, keyCode.length * 4, null, keyCode);
+ if (keyCode [0] == 49 /* Space */) {
+ int [] modifiers = new int [1];
+ OS.GetEventParameter (theEvent, OS.kEventParamKeyModifiers, OS.typeUInt32, null, 4, null, modifiers);
+ if (modifiers [0] == OS.cmdKey) {
+ if (!sendKeyEvent (SWT.KeyDown, theEvent)) return OS.noErr;
+ }
+ }
+ }
+ return OS.eventNotHandledErr;
+}
+
+int kEventUnicodeKeyPressed (int nextHandler, int theEvent, int userData) {
+ int result = super.kEventUnicodeKeyPressed (nextHandler, theEvent, userData);
+ if ((state & CANVAS) != 0) {
+ int [] keyboardEvent = new int [1];
+ OS.GetEventParameter (theEvent, OS.kEventParamTextInputSendKeyboardEvent, OS.typeEventRef, null, keyboardEvent.length * 4, null, keyboardEvent);
+ int [] keyCode = new int [1];
+ OS.GetEventParameter (keyboardEvent [0], OS.kEventParamKeyCode, OS.typeUInt32, null, keyCode.length * 4, null, keyCode);
+ switch (keyCode [0]) {
+ case 76: /* KP Enter */
+ case 36: /* Return */
+ /*
+ * Feature in the Macintosh. The default behaviour when the return key is pressed is
+ * to select the default button. This is not the expected behaviour for Composite and
+ * its subclasses. The fix is to avoid calling the default handler.
+ */
+ return OS.noErr;
+ }
+ }
+ return result;
+}
+
+boolean hooksKeys () {
+ return hooks (SWT.KeyDown) || hooks (SWT.KeyUp);
+}
+
+void invalidateChildrenVisibleRegion (int control) {
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ Control child = children [i];
+ child.resetVisibleRegion (control);
+ child.invalidateChildrenVisibleRegion (control);
+ }
+}
+
+/**
+ * Returns <code>true</code> if the receiver or any ancestor
+ * up to and including the receiver's nearest ancestor shell
+ * has deferred the performing of layouts. Otherwise, <code>false</code>
+ * is returned.
+ *
+ * @return the receiver's deferred layout 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 #setLayoutDeferred(boolean)
+ * @see #getLayoutDeferred()
+ *
+ * @since 3.1
+ */
+public boolean isLayoutDeferred () {
+ checkWidget ();
+ return findDeferredControl () != null;
+}
+
+boolean isTabGroup () {
+ if ((state & CANVAS) != 0) return true;
+ return super.isTabGroup ();
+}
+
+/**
+ * If the receiver has a layout, asks the layout to <em>lay out</em>
+ * (that is, set the size and location of) the receiver's children.
+ * If the receiver does not have a layout, do nothing.
+ * <p>
+ * This is equivalent to calling <code>layout(true)</code>.
+ * </p>
+ * <p>
+ * Note: Layout is different from painting. If a child is
+ * moved or resized such that an area in the parent is
+ * exposed, then the parent will paint. If no child is
+ * affected, the parent will not paint.
+ * </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>
+ */
+public void layout () {
+ checkWidget ();
+ layout (true);
+}
+
+/**
+ * If the receiver has a layout, asks the layout to <em>lay out</em>
+ * (that is, set the size and location of) the receiver's children.
+ * If the argument is <code>true</code> the layout must not rely
+ * on any information it has cached about the immediate children. If it
+ * is <code>false</code> the layout may (potentially) optimize the
+ * work it is doing by assuming that none of the receiver's
+ * children has changed state since the last layout.
+ * If the receiver does not have a layout, do nothing.
+ * <p>
+ * If a child is resized as a result of a call to layout, the
+ * resize event will invoke the layout of the child. The layout
+ * will cascade down through all child widgets in the receiver's widget
+ * tree until a child is encountered that does not resize. Note that
+ * a layout due to a resize will not flush any cached information
+ * (same as <code>layout(false)</code>).
+ * </p>
+ * <p>
+ * Note: Layout is different from painting. If a child is
+ * moved or resized such that an area in the parent is
+ * exposed, then the parent will paint. If no child is
+ * affected, the parent will not paint.
+ * </p>
+ *
+ * @param changed <code>true</code> if the layout must flush its caches, 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>
+ */
+public void layout (boolean changed) {
+ checkWidget ();
+ if (layout == null) return;
+ layout (changed, false);
+}
+
+/**
+ * If the receiver has a layout, asks the layout to <em>lay out</em>
+ * (that is, set the size and location of) the receiver's children.
+ * If the changed argument is <code>true</code> the layout must not rely
+ * on any information it has cached about its children. If it
+ * is <code>false</code> the layout may (potentially) optimize the
+ * work it is doing by assuming that none of the receiver's
+ * children has changed state since the last layout.
+ * If the all argument is <code>true</code> the layout will cascade down
+ * through all child widgets in the receiver's widget tree, regardless of
+ * whether the child has changed size. The changed argument is applied to
+ * all layouts. If the all argument is <code>false</code>, the layout will
+ * <em>not</em> cascade down through all child widgets in the receiver's widget
+ * tree. However, if a child is resized as a result of a call to layout, the
+ * resize event will invoke the layout of the child. Note that
+ * a layout due to a resize will not flush any cached information
+ * (same as <code>layout(false)</code>).
+ * </p>
+ * <p>
+ * Note: Layout is different from painting. If a child is
+ * moved or resized such that an area in the parent is
+ * exposed, then the parent will paint. If no child is
+ * affected, the parent will not paint.
+ * </p>
+ *
+ * @param changed <code>true</code> if the layout must flush its caches, and <code>false</code> otherwise
+ * @param all <code>true</code> if all children in the receiver's widget tree should be laid out, 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>
+ *
+ * @since 3.1
+ */
+public void layout (boolean changed, boolean all) {
+ checkWidget ();
+ if (layout == null && !all) return;
+ markLayout (changed, all);
+ updateLayout (all);
+}
+
+/**
+ * Forces a lay out (that is, sets the size and location) of all widgets that
+ * are in the parent hierarchy of the changed control up to and including the
+ * receiver. The layouts in the hierarchy must not rely on any information
+ * cached about the changed control or any of its ancestors. The layout may
+ * (potentially) optimize the work it is doing by assuming that none of the
+ * peers of the changed control have changed state since the last layout.
+ * If an ancestor does not have a layout, skip it.
+ * <p>
+ * Note: Layout is different from painting. If a child is
+ * moved or resized such that an area in the parent is
+ * exposed, then the parent will paint. If no child is
+ * affected, the parent will not paint.
+ * </p>
+ *
+ * @param changed a control that has had a state change which requires a recalculation of its size
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the changed array is null any of its controls are null or have been disposed</li>
+ * <li>ERROR_INVALID_PARENT - if any control in changed is not in the widget tree of the receiver</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>
+ *
+ * @since 3.1
+ */
+public void layout (Control [] changed) {
+ checkWidget ();
+ if (changed == null) error (SWT.ERROR_INVALID_ARGUMENT);
+ for (int i=0; i<changed.length; i++) {
+ Control control = changed [i];
+ if (control == null) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ boolean ancestor = false;
+ Composite composite = control.parent;
+ while (composite != null) {
+ ancestor = composite == this;
+ if (ancestor) break;
+ composite = composite.parent;
+ }
+ if (!ancestor) error (SWT.ERROR_INVALID_PARENT);
+ }
+ int updateCount = 0;
+ Composite [] update = new Composite [16];
+ for (int i=0; i<changed.length; i++) {
+ Control child = changed [i];
+ Composite composite = child.parent;
+ while (child != this) {
+ if (composite.layout != null) {
+ composite.state |= LAYOUT_NEEDED;
+ if (!composite.layout.flushCache (child)) {
+ composite.state |= LAYOUT_CHANGED;
+ }
+ }
+ if (updateCount == update.length) {
+ Composite [] newUpdate = new Composite [update.length + 16];
+ System.arraycopy (update, 0, newUpdate, 0, update.length);
+ update = newUpdate;
+ }
+ child = update [updateCount++] = composite;
+ composite = child.parent;
+ }
+ }
+ for (int i=updateCount-1; i>=0; i--) {
+ update [i].updateLayout (false);
+ }
+}
+
+void markLayout (boolean changed, boolean all) {
+ if (layout != null) {
+ state |= LAYOUT_NEEDED;
+ if (changed) state |= LAYOUT_CHANGED;
+ }
+ if (all) {
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ children [i].markLayout (changed, all);
+ }
+ }
+}
+
+Point minimumSize (int wHint, int Hint, boolean changed) {
+ Control [] children = _getChildren ();
+ int width = 0, height = 0;
+ for (int i=0; i<children.length; i++) {
+ Rectangle rect = children [i].getBounds ();
+ width = Math.max (width, rect.x + rect.width);
+ height = Math.max (height, rect.y + rect.height);
+ }
+ return new Point (width, height);
+}
+
+void releaseChildren (boolean destroy) {
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ Control child = children [i];
+ if (child != null && !child.isDisposed ()) {
+ child.release (false);
+ }
+ }
+ super.releaseChildren (destroy);
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+ if (scrolledVisibleRgn != 0) OS.DisposeRgn (scrolledVisibleRgn);
+ if (siblingsVisibleRgn != 0) OS.DisposeRgn (siblingsVisibleRgn);
+ siblingsVisibleRgn = scrolledVisibleRgn = 0;
+ layout = null;
+ tabList = null;
+}
+
+void removeControl (Control control) {
+ fixTabList (control);
+}
+
+void resetVisibleRegion (int control) {
+ if (scrolledVisibleRgn != 0) {
+ OS.DisposeRgn (scrolledVisibleRgn);
+ scrolledVisibleRgn = 0;
+ }
+ if (siblingsVisibleRgn != 0) {
+ OS.DisposeRgn (siblingsVisibleRgn);
+ siblingsVisibleRgn = 0;
+ }
+ super.resetVisibleRegion (control);
+}
+
+/**
+ * Sets the background drawing mode to the argument which should
+ * be one of the following constants defined in class <code>SWT</code>:
+ * <code>INHERIT_NONE</code>, <code>INHERIT_DEFAULT</code>,
+ * <code>INHERIT_FORCE</code>.
+ *
+ * @param mode the new background mode
+ *
+ * @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 SWT
+ *
+ * @since 3.2
+ */
+public void setBackgroundMode (int mode) {
+ checkWidget ();
+ backgroundMode = mode;
+ Control [] children = _getChildren ();
+ for (int i = 0; i < children.length; i++) {
+ children [i].updateBackgroundMode ();
+ }
+}
+
+int setBounds (int x, int y, int width, int height, boolean move, boolean resize, boolean events) {
+ int result = super.setBounds (x, y, width, height, move, resize, events);
+ if (layout != null && (result & RESIZED) != 0) {
+ markLayout (false, false);
+ updateLayout (false);
+ }
+ return result;
+}
+
+public boolean setFocus () {
+ checkWidget ();
+ Control [] children = _getChildren ();
+ for (int i= 0; i < children.length; i++) {
+ if (children [i].setFocus ()) return true;
+ }
+ return super.setFocus ();
+}
+
+/**
+ * Sets the layout which is associated with the receiver to be
+ * the argument which may be null.
+ *
+ * @param layout the receiver's new layout 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 setLayout (Layout layout) {
+ checkWidget();
+ this.layout = layout;
+}
+
+/**
+ * If the argument is <code>true</code>, causes subsequent layout
+ * operations in the receiver or any of its children to be ignored.
+ * No layout of any kind can occur in the receiver or any of its
+ * children until the flag is set to false.
+ * Layout operations that occurred while the flag was
+ * <code>true</code> are remembered and when the flag is set to
+ * <code>false</code>, the layout operations are performed in an
+ * optimized manner. Nested calls to this method are stacked.
+ *
+ * @param defer the new defer 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 #layout(boolean)
+ * @see #layout(Control[])
+ *
+ * @since 3.1
+ */
+public void setLayoutDeferred (boolean defer) {
+ if (!defer) {
+ if (--layoutCount == 0) {
+ if ((state & LAYOUT_CHILD) != 0 || (state & LAYOUT_NEEDED) != 0) {
+ updateLayout (true);
+ }
+ }
+ } else {
+ layoutCount++;
+ }
+}
+
+boolean setScrollBarVisible (ScrollBar bar, boolean visible) {
+ boolean changed = super.setScrollBarVisible (bar, visible);
+ if (changed && layout != null) {
+ markLayout (false, false);
+ updateLayout (false);
+ }
+ return changed;
+}
+
+boolean setTabGroupFocus () {
+ if (isTabItem ()) return setTabItemFocus ();
+ boolean takeFocus = (style & SWT.NO_FOCUS) == 0;
+ if ((state & CANVAS) != 0) takeFocus = hooksKeys ();
+ if (takeFocus && setTabItemFocus ()) return true;
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ Control child = children [i];
+ if (child.isTabItem () && child.setTabItemFocus ()) return true;
+ }
+ return false;
+}
+
+/**
+ * Sets the tabbing order for the specified controls to
+ * match the order that they occur in the argument list.
+ *
+ * @param tabList the ordered list of controls representing the tab order or null
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if a widget in the tabList is null or has been disposed</li>
+ * <li>ERROR_INVALID_PARENT - if widget in the tabList 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 setTabList (Control [] tabList) {
+ checkWidget ();
+ if (tabList != null) {
+ for (int i=0; i<tabList.length; i++) {
+ Control control = tabList [i];
+ if (control == null) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (control.parent != this) error (SWT.ERROR_INVALID_PARENT);
+ }
+ Control [] newList = new Control [tabList.length];
+ System.arraycopy (tabList, 0, newList, 0, tabList.length);
+ tabList = newList;
+ }
+ this.tabList = tabList;
+}
+
+int traversalCode (int key, int theEvent) {
+ if ((state & CANVAS) != 0) {
+ if ((style & SWT.NO_FOCUS) != 0) return 0;
+ if (hooksKeys ()) return 0;
+ }
+ return super.traversalCode (key, theEvent);
+}
+
+void updateBackgroundMode () {
+ super.updateBackgroundMode ();
+ Control [] children = _getChildren ();
+ for (int i = 0; i < children.length; i++) {
+ children [i].updateBackgroundMode ();
+ }
+}
+
+void updateLayout (boolean all) {
+ Composite parent = findDeferredControl ();
+ if (parent != null) {
+ parent.state |= LAYOUT_CHILD;
+ return;
+ }
+ if ((state & LAYOUT_NEEDED) != 0) {
+ boolean changed = (state & LAYOUT_CHANGED) != 0;
+ state &= ~(LAYOUT_NEEDED | LAYOUT_CHANGED);
+ layout.layout (this, changed);
+ }
+ if (all) {
+ state &= ~LAYOUT_CHILD;
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ children [i].updateLayout (all);
+ }
+ }
+}
+
+}

Back to the top