diff options
author | Veronika Irvine | 2004-11-09 20:34:53 +0000 |
---|---|---|
committer | Veronika Irvine | 2004-11-09 20:34:53 +0000 |
commit | 5031e89b84cea3a085afa6d4253219a01dbda95b (patch) | |
tree | e47159c35f4a0719381fa3e7d2905ade9c215f3f | |
parent | 2715ac63c760dcb467c70ace9439516fc8bcdea3 (diff) | |
download | eclipse.platform.swt-5031e89b84cea3a085afa6d4253219a01dbda95b.tar.gz eclipse.platform.swt-5031e89b84cea3a085afa6d4253219a01dbda95b.tar.xz eclipse.platform.swt-5031e89b84cea3a085afa6d4253219a01dbda95b.zip |
fix changed
10 files changed, 310 insertions, 33 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 index 88fbdcf9c7..d2e61f1bbf 100644 --- 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 @@ -164,8 +164,8 @@ public void changed (Control[] changed) { Control child = changed [i]; Composite composite = child.parent; while (child != this) { - if (layout == null || !layout.flushCache (child)) { - state |= LAYOUT_CHANGED; + if (composite.layout == null || !composite.layout.flushCache (child)) { + composite.state |= LAYOUT_CHANGED; } child = composite; composite = child.parent; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java index 79b4ab2e23..71af180d5e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java @@ -166,8 +166,8 @@ public void changed (Control[] changed) { Control child = changed [i]; Composite composite = child.parent; while (child != this) { - if (layout == null || !layout.flushCache (child)) { - state |= LAYOUT_CHANGED; + if (composite.layout == null || !composite.layout.flushCache (child)) { + composite.state |= LAYOUT_CHANGED; } child = composite; composite = child.parent; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Composite.java index 49210ee621..a11802da55 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Composite.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Composite.java @@ -204,8 +204,8 @@ public void changed (Control[] changed) { Control child = changed [i]; Composite composite = child.parent; while (child != this) { - if (layout == null || !layout.flushCache (child)) { - state |= LAYOUT_CHANGED; + if (composite.layout == null || !composite.layout.flushCache (child)) { + composite.state |= LAYOUT_CHANGED; } child = composite; composite = child.parent; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Composite.java index 97087d6651..048a77552b 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Composite.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Composite.java @@ -42,6 +42,7 @@ public class Composite extends Scrollable { Layout layout; Control [] tabList; int cornerHandle; + int layoutCount = 0; Composite () { /* Do nothing */ @@ -126,6 +127,53 @@ Control [] _getTabList () { return tabList; } +/** + * 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; + } + } +} + protected void checkSubclass () { /* Do nothing - Subclassing is allowed */ } @@ -152,7 +200,9 @@ public Point computeSize (int wHint, int hHint, boolean changed) { 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); } @@ -433,6 +483,27 @@ public Layout getLayout () { 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 ; +} + boolean hasBorder () { return (style & SWT.BORDER) != 0; } @@ -446,6 +517,29 @@ boolean hooksKeys () { } /** + * 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 layoutCount > 0 || parent.isLayoutDeferred (); +} + +/** * Gets the last specified tabbing order for the control. * * @return tabList the ordered list of controls representing the tab order @@ -491,34 +585,26 @@ public Control [] getTabList () { * </ul> */ public void layout () { - checkWidget(); + checkWidget (); layout (true); } -Point minimumSize () { - 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 moveToBack (int child) { - OS.PtWidgetToBack (child); -} - /** * 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 the argument is <code>true</code> the layout must not rely - * on any cached information it is keeping about the children. If it - * is <code>false</code> the layout may (potentially) simplify the - * work it is doing by assuming that the state of the none of the - * receiver's children has changed since the last layout. + * 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> * * @param changed <code>true</code> if the layout must flush its caches, and <code>false</code> otherwise * @@ -528,11 +614,136 @@ void moveToBack (int child) { * </ul> */ public void layout (boolean changed) { - checkWidget(); + checkWidget (); if (layout == null) return; - int count = getChildrenCount (); - if (count == 0) return; - layout.layout (this, changed); + 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> + * + * @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. + * + * @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 () { + 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 moveToBack (int child) { + OS.PtWidgetToBack (child); } int parentingHandle () { @@ -737,6 +948,38 @@ public void setLayout (Layout layout) { 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 (!isLayoutDeferred ()) updateLayout (true); + } + } else { + layoutCount++; + } +} + boolean setTabGroupFocus () { if (isTabItem ()) return setTabItemFocus (); boolean takeFocus = (style & SWT.NO_FOCUS) == 0; @@ -785,6 +1028,21 @@ int traversalCode (int key_sym, PhKeyEvent_t ke) { return super.traversalCode (key_sym, ke); } +void updateLayout (boolean all) { + if (isLayoutDeferred ()) return; + if ((state & LAYOUT_NEEDED) != 0) { + boolean changed = (state & LAYOUT_CHANGED) != 0; + state &= ~(LAYOUT_NEEDED | LAYOUT_CHANGED); + layout.layout (this, changed); + } + if (all) { + Control [] children = _getChildren (); + for (int i=0; i<children.length; i++) { + children [i].updateLayout (all); + } + } +} + int widgetClass () { if ((state & CANVAS) != 0) return OS.PtContainer (); return super.widgetClass (); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Control.java index b6a5140952..8682dde590 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Control.java @@ -1134,6 +1134,10 @@ public boolean isVisible () { return OS.PtWidgetIsRealized (handle); } +void markLayout (boolean changed, boolean all) { + /* Do nothing */ +} + Decorations menuShell () { return parent.menuShell (); } @@ -2771,6 +2775,10 @@ public void update () { OS.PtFlush (); } +void updateLayout (boolean all) { + /* Do nothing */ +} + int widgetClass () { return 0; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Group.java b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Group.java index 83c1b9e683..66d4767fb8 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Group.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Group.java @@ -92,7 +92,9 @@ public Point computeSize (int wHint, int hHint, boolean changed) { Point titleSize = getTitleSize(); Point size; if (layout != null) { + changed |= (state & LAYOUT_CHANGED) != 0; size = layout.computeSize (this, wHint, hHint, changed); + state &= ~LAYOUT_CHANGED; } else { size = minimumSize (); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Shell.java index afc043331c..e1613abc80 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Shell.java @@ -702,6 +702,11 @@ int hotkeyProc (int w, int data, int info) { return OS.Pt_CONTINUE; } +public boolean isLayoutDeferred () { + checkWidget (); + return layoutCount > 0; +} + /** * Moves the receiver to the top of the drawing order for * the display on which it was created (so that all other diff --git a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/TabFolder.java b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/TabFolder.java index 518d5acd1f..741c63550e 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/TabFolder.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/TabFolder.java @@ -134,7 +134,9 @@ public Point computeSize (int wHint, int hHint, boolean changed) { int width = dim.w, height = dim.h; Point size; if (layout != null) { + changed |= (state & LAYOUT_CHANGED) != 0; size = layout.computeSize (this, wHint, hHint, changed); + state &= ~LAYOUT_CHANGED; } else { size = minimumSize (wHint, hHint, changed); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Widget.java index 290b900ba7..d594392a7d 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Widget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/Widget.java @@ -62,6 +62,8 @@ public abstract class Widget { static final int MOVED = 1 << 5; static final int RESIZED = 1 << 6; static final int GRAB = 1 << 7; + static final int LAYOUT_CHANGED = 1 << 8; + static final int LAYOUT_NEEDED = 1 << 9; static final int DEFAULT_WIDTH = 64; static final int DEFAULT_HEIGHT = 64; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java index 2a651ecca1..50cf6fc8f7 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java @@ -167,8 +167,8 @@ public void changed (Control[] changed) { Control child = changed [i]; Composite composite = child.parent; while (child != this) { - if (layout == null || !layout.flushCache (child)) { - state |= LAYOUT_CHANGED; + if (composite.layout == null || !composite.layout.flushCache (child)) { + composite.state |= LAYOUT_CHANGED; } child = composite; composite = child.parent; |