/******************************************************************************* * Copyright (c) 2000, 2011 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.*; import org.eclipse.swt.accessibility.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.cocoa.*; /** * Instances of this class are controls which are capable * of containing other controls. *
*
Styles:
*
NO_BACKGROUND, NO_FOCUS, NO_MERGE_PAINTS, NO_REDRAW_RESIZE, NO_RADIO_GROUP, EMBEDDED, DOUBLE_BUFFERED
*
Events:
*
(none)
*
*

* Note: The NO_BACKGROUND, NO_FOCUS, NO_MERGE_PAINTS, * and NO_REDRAW_RESIZE styles are intended for use with Canvas. * They can be used with Composite if you are drawing your own, but their * behavior is undefined if they are used with subclasses of Composite other * than Canvas. *

* Note: The CENTER style, although undefined for composites, has the * same value as EMBEDDED 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. *

* This class may be subclassed by custom control implementors * who are building controls that are constructed from aggregates * of other controls. *

* * @see Canvas * @see Composite snippets * @see Sample code and further information */ public class Composite extends Scrollable { Layout layout; Control[] tabList; 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. *

* The style value is either one of the style constants defined in * class SWT which is applicable to instances of this * class, or must be built by bitwise OR'ing together * (that is, using the int "|" operator) two or more * of those SWT style constants. The class description * lists the style constants that are applicable to the class. * Style bits are also inherited from superclasses. *

* * @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 * @exception SWTException * * @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 () { NSArray views = contentView().subviews(); int count = (int)/*64*/views.count(); Control [] children = new Control [count]; if (count == 0) return children; int j = 0; for (int i=0; i *
  • ERROR_INVALID_ARGUMENT - if the changed array is null any of its controls are null or have been disposed
  • *
  • ERROR_INVALID_PARENT - if any control in changed is not in the widget tree of the receiver
  • * * @exception SWTException * * @since 3.1 */ public void changed (Control[] changed) { checkWidget (); if (changed == null) error (SWT.ERROR_INVALID_ARGUMENT); for (int i=0; iThe offsetX and offsetY are used to map from * the gc origin to the origin of the parent image background. This is useful * to ensure proper alignment of the image background.

    * * @param gc the gc where the rectangle is to be filled * @param x the x coordinate of the rectangle to be filled * @param y the y coordinate of the rectangle to be filled * @param width the width of the rectangle to be filled * @param height the height of the rectangle to be filled * @param offsetX the image background x offset * @param offsetY the image background y offset * * @exception IllegalArgumentException * @exception SWTException * * @since 3.6 */ public void drawBackground(GC gc, int x, int y, int width, int height, int offsetX, int offsetY) { checkWidget (); if (gc == null) error (SWT.ERROR_NULL_ARGUMENT); if (gc.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); Control control = findBackgroundControl (); if (control != null) { NSRect rect = new NSRect(); rect.x = x; rect.y = y; rect.width = width; rect.height = height; int imgHeight = -1; GCData data = gc.getGCData(); if (data.image != null) imgHeight = data.image.getBounds().height; NSGraphicsContext context = gc.handle; if (data.flippedContext != null) { NSGraphicsContext.static_saveGraphicsState(); NSGraphicsContext.setCurrentContext(context); } control.fillBackground (view, context, rect, imgHeight, data.view, offsetX, offsetY); if (data.flippedContext != null) { NSGraphicsContext.static_restoreGraphicsState(); } } else { gc.fillRectangle (x, y, width, height); } } void drawBackground (int /*long*/ id, NSGraphicsContext context, NSRect rect) { if (id != view.id) return; if ((state & CANVAS) != 0) { if ((style & SWT.NO_BACKGROUND) == 0) { fillBackground (view, context, rect, -1); } } } 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; iSWT: * INHERIT_NONE, INHERIT_DEFAULT, * INHERTIT_FORCE. * * @return the background mode * * @exception SWTException
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    * * @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. *

    * 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. *

    * * @return an array of children * * @see Control#moveAbove * @see Control#moveBelow * * @exception SWTException
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    */ public Control [] getChildren () { checkWidget(); return _getChildren (); } /** * 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
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    */ public Layout getLayout () { checkWidget(); return layout; } /** * Returns true if the receiver has deferred * the performing of layout, and false otherwise. * * @return the receiver's deferred layout state * * @exception SWTException
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    * * @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
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    * * @see #setTabList */ public Control [] getTabList () { checkWidget (); Control [] tabList = _getTabList (); if (tabList == null) { int count = 0; Control [] list =_getChildren (); for (int i=0; itrue if the receiver or any ancestor * up to and including the receiver's nearest ancestor shell * has deferred the performing of layouts. Otherwise, false * is returned. * * @return the receiver's deferred layout state * * @exception SWTException
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    * * @see #setLayoutDeferred(boolean) * @see #getLayoutDeferred() * * @since 3.1 */ public boolean isLayoutDeferred () { checkWidget (); return findDeferredControl () != null; } boolean isOpaque (int /*long*/ id, int /*long*/ sel) { if ((state & CANVAS) != 0) { if (id == view.id) { return region == null && background != null && background[3] == 1 && !isObscured (); } } return super.isOpaque (id, sel); } boolean isTabGroup () { if ((state & CANVAS) != 0) return true; return super.isTabGroup (); } void keyDown (int /*long*/ id, int /*long*/ sel, int /*long*/ theEvent) { if (hasFocus()) { if ((state & CANVAS) != 0) { Shell s = this.getShell(); s.deferFlushing(); NSArray array = NSArray.arrayWithObject (new NSEvent (theEvent)); s.keyInputHappened = false; view.interpretKeyEvents (array); if (imeInComposition ()) return; if (!s.keyInputHappened) { NSEvent nsEvent = new NSEvent (theEvent); boolean [] consume = new boolean [1]; if (translateTraversal (nsEvent.keyCode (), nsEvent, consume)) return; if (isDisposed ()) return; if (!sendKeyEvent (nsEvent, SWT.KeyDown)) return; if (consume [0]) return; } return; } } super.keyDown (id, sel, theEvent); } /** * If the receiver has a layout, asks the layout to lay out * (that is, set the size and location of) the receiver's children. * If the receiver does not have a layout, do nothing. *

    * This is equivalent to calling layout(true). *

    *

    * 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. *

    * * @exception SWTException
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    */ public void layout () { checkWidget (); layout (true); } /** * If the receiver has a layout, asks the layout to lay out * (that is, set the size and location of) the receiver's children. * If the argument is true the layout must not rely * on any information it has cached about the immediate children. If it * is false 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. *

    * 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 layout(false)). *

    *

    * 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. *

    * * @param changed true if the layout must flush its caches, and false otherwise * * @exception SWTException
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    */ public void layout (boolean changed) { checkWidget (); if (layout == null) return; layout (changed, false); } /** * If the receiver has a layout, asks the layout to lay out * (that is, set the size and location of) the receiver's children. * If the changed argument is true the layout must not rely * on any information it has cached about its children. If it * is false 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 true 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 false, the layout will * not 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 layout(false)). *

    *

    * 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. *

    * * @param changed true if the layout must flush its caches, and false otherwise * @param all true if all children in the receiver's widget tree should be laid out, and false otherwise * * @exception SWTException
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    * * @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. *

    * 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. *

    * * @param changed a control that has had a state change which requires a recalculation of its size * * @exception IllegalArgumentException
      *
    • ERROR_INVALID_ARGUMENT - if the changed array is null any of its controls are null or have been disposed
    • *
    • ERROR_INVALID_PARENT - if any control in changed is not in the widget tree of the receiver
    • *
    * @exception SWTException
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    * * @since 3.1 */ public void layout (Control [] changed) { checkWidget (); if (changed == null) error (SWT.ERROR_INVALID_ARGUMENT); layout (changed, SWT.NONE); } /** * 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 parameter flags may be a combination of: *

    *
    SWT.ALL
    *
    all children in the receiver's widget tree should be laid out
    *
    SWT.CHANGED
    *
    the layout must flush its caches
    *
    SWT.DEFER
    *
    layout will be deferred
    *
    *

    *

    * When the changed array is specified, the flags SWT.ALL * and SWT.CHANGED have no effect. In this case, 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. *

    *

    * When the changed array is not specified, the flag SWT.ALL * indicates that the whole widget tree should be laid out. And the flag * SWT.CHANGED indicates that the layouts should flush any cached * information for all controls that are laid out. *

    *

    * The SWT.DEFER flag always causes the layout to be deferred by * calling Composite.setLayoutDeferred(true) and scheduling a call * to Composite.setLayoutDeferred(false), which will happen when * appropriate (usually before the next event is handled). When this flag is set, * the application should not call Composite.setLayoutDeferred(boolean). *

    *

    * 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. *

    * * @param changed a control that has had a state change which requires a recalculation of its size * @param flags the flags specifying how the layout should happen * * @exception IllegalArgumentException
      *
    • ERROR_INVALID_ARGUMENT - if any of the controls in changed is null or has been disposed
    • *
    • ERROR_INVALID_PARENT - if any control in changed is not in the widget tree of the receiver
    • *
    * @exception SWTException
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    * * @since 3.6 */ public void layout (Control [] changed, int flags) { checkWidget (); if (changed != null) { for (int i=0; i=0; i--) { update [i].updateLayout (false); } } else { if (layout == null && (flags & SWT.ALL) == 0) return; markLayout ((flags & SWT.CHANGED) != 0, (flags & SWT.ALL) != 0); if ((flags & SWT.DEFER) != 0) { setLayoutDeferred (true); display.addLayoutDeferred (this); } updateLayout ((flags & SWT.ALL) != 0); } } 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 0 ? SWT.PAGE_UP : SWT.PAGE_DOWN; bar.sendSelectionEvent (SWT.Selection, event, true); handled = true; } if (!doit) handled = true; } if (deltaX != 0) { boolean doit = true; if (hooks (SWT.MouseHorizontalWheel) || filters (SWT.MouseHorizontalWheel)) { doit = sendMouseEvent(nsEvent, SWT.MouseHorizontalWheel, true); } ScrollBar bar = horizontalBar; if (doit && bar != null && bar.getEnabled ()) { if (-1 < deltaX && deltaX < 0) deltaX = -1; if (0 < deltaX && deltaX < 1) deltaX = 1; int selection = Math.max (0, (int)(0.5f + bar.getSelection () - bar.getIncrement () * deltaX)); bar.setSelection (selection); Event event = new Event (); event.detail = deltaX > 0 ? SWT.PAGE_UP : SWT.PAGE_DOWN; bar.sendSelectionEvent (SWT.Selection, event, true); handled = true; } if (!doit) handled = true; } if (!handled) view.superview().scrollWheel(nsEvent); } return; } callSuper(id, sel, theEvent); return; } super.scrollWheel (id, sel, theEvent); } /** * Sets the background drawing mode to the argument which should * be one of the following constants defined in class SWT: * INHERIT_NONE, INHERIT_DEFAULT, * INHERIT_FORCE. * * @param mode the new background mode * * @exception SWTException
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    * * @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 (); } } 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
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    */ public void setLayout (Layout layout) { checkWidget(); this.layout = layout; } /** * If the argument is true, 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 * true are remembered and when the flag is set to * false, the layout operations are performed in an * optimized manner. Nested calls to this method are stacked. * * @param defer the new defer state * * @exception SWTException
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    * * @see #layout(boolean) * @see #layout(Control[]) * * @since 3.1 */ public void setLayoutDeferred (boolean defer) { checkWidget(); 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 *
  • ERROR_INVALID_ARGUMENT - if a widget in the tabList is null or has been disposed
  • *
  • ERROR_INVALID_PARENT - if widget in the tabList is not in the same widget tree
  • * * @exception SWTException
      *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • *
    */ public void setTabList (Control [] tabList) { checkWidget (); if (tabList != null) { for (int i=0; i