diff options
Diffstat (limited to 'src')
60 files changed, 1835 insertions, 3763 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 201c3a1cd6..4fbb4b26b9 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -12,11 +12,13 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; +import com.google.gwt.core.client.Duration; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.JsArrayString; import com.google.gwt.core.client.Scheduler; +import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.http.client.Request; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.RequestCallback; @@ -29,12 +31,9 @@ import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Timer; -import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConfiguration.ErrorMessage; -import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize; -import com.vaadin.terminal.gwt.client.RenderInformation.Size; import com.vaadin.terminal.gwt.client.ui.VContextMenu; import com.vaadin.terminal.gwt.client.ui.VNotification; import com.vaadin.terminal.gwt.client.ui.VNotification.HideEvent; @@ -153,7 +152,6 @@ public class ApplicationConnection { /** redirectTimer scheduling interval in seconds */ private int sessionExpirationInterval; - private ArrayList<VPaintableWidget> relativeSizeChanges = new ArrayList<VPaintableWidget>(); private ArrayList<Widget> componentCaptionSizeChanges = new ArrayList<Widget>(); private Date requestStartTime; @@ -164,6 +162,8 @@ public class ApplicationConnection { private Set<VPaintableWidget> zeroHeightComponents = null; + private final MeasureManager measureManager = new MeasureManager(); + public ApplicationConnection() { view = GWT.create(VViewPaintable.class); view.setConnection(this); @@ -996,9 +996,10 @@ public class ApplicationConnection { JsArray<ValueMap> changes = json.getJSValueMapArray("changes"); ArrayList<VPaintableWidget> updatedVPaintableWidgets = new ArrayList<VPaintableWidget>(); - relativeSizeChanges.clear(); componentCaptionSizeChanges.clear(); + Duration updateDuration = new Duration(); + int length = changes.length(); for (int i = 0; i < length; i++) { try { @@ -1044,26 +1045,10 @@ public class ApplicationConnection { json.getValueMap("dd")); } - // Check which widgets' size has been updated - Set<Widget> sizeUpdatedWidgets = new HashSet<Widget>(); - - updatedVPaintableWidgets.addAll(relativeSizeChanges); - sizeUpdatedWidgets.addAll(componentCaptionSizeChanges); + VConsole.log("updateFromUidl: " + + updateDuration.elapsedMillis() + " ms"); - for (VPaintableWidget paintable : updatedVPaintableWidgets) { - Widget widget = paintable.getWidgetForPaintable(); - Size oldSize = paintableMap.getOffsetSize(paintable); - Size newSize = new Size(widget.getOffsetWidth(), - widget.getOffsetHeight()); - - if (oldSize == null || !oldSize.equals(newSize)) { - sizeUpdatedWidgets.add(widget); - paintableMap.setOffsetSize(paintable, newSize); - } - - } - - Util.componentSizeUpdated(sizeUpdatedWidgets); + doLayout(false); if (meta != null) { if (meta.containsKey("appError")) { @@ -1586,59 +1571,6 @@ public class ApplicationConnection { return result.toString(); } - public void updateComponentSize(VPaintableWidget paintable, UIDL uidl) { - String w = uidl.hasAttribute("width") ? uidl - .getStringAttribute("width") : ""; - - String h = uidl.hasAttribute("height") ? uidl - .getStringAttribute("height") : ""; - - float relativeWidth = Util.parseRelativeSize(w); - float relativeHeight = Util.parseRelativeSize(h); - - // First update maps so they are correct in the setHeight/setWidth calls - if (relativeHeight >= 0.0 || relativeWidth >= 0.0) { - // One or both is relative - FloatSize relativeSize = new FloatSize(relativeWidth, - relativeHeight); - - if (paintableMap.getRelativeSize(paintable) == null - && paintableMap.getOffsetSize(paintable) != null) { - // The component has changed from absolute size to relative size - relativeSizeChanges.add(paintable); - } - paintableMap.setRelativeSize(paintable, relativeSize); - } else if (relativeHeight < 0.0 && relativeWidth < 0.0) { - if (paintableMap.getRelativeSize(paintable) != null) { - // The component has changed from relative size to absolute size - relativeSizeChanges.add(paintable); - } - paintableMap.setRelativeSize(paintable, null); - } - - Widget component = paintableMap.getWidget(paintable); - // Set absolute sizes - if (relativeHeight < 0.0) { - component.setHeight(h); - } - if (relativeWidth < 0.0) { - component.setWidth(w); - } - - // Set relative sizes - if (relativeHeight >= 0.0 || relativeWidth >= 0.0) { - // One or both is relative - handleComponentRelativeSize(paintable); - } - - } - - /** - * Traverses recursively child widgets until ContainerResizedListener child - * widget is found. They will delegate it further if needed. - * - * @param container - */ private boolean runningLayout = false; /** @@ -1660,13 +1592,11 @@ public class ApplicationConnection { * development. Published to JavaScript. */ public void forceLayout() { - Set<Widget> set = new HashSet<Widget>(); - for (VPaintable paintable : paintableMap.getPaintables()) { - if (paintable instanceof VPaintableWidget) { - set.add(((VPaintableWidget) paintable).getWidgetForPaintable()); - } - } - Util.componentSizeUpdated(set); + Duration duration = new Duration(); + + doLayout(false); + + VConsole.log("forceLayout in " + duration.elapsedMillis() + " ms"); } private void internalRunDescendentsLayout(HasWidgets container) { @@ -1708,144 +1638,7 @@ public class ApplicationConnection { * @return true if the child has a relative size */ private boolean handleComponentRelativeSize(VPaintableWidget paintable) { - if (paintable == null) { - return false; - } - boolean debugSizes = true; - - FloatSize relativeSize = paintableMap.getRelativeSize(paintable); - if (relativeSize == null) { - return false; - } - Widget widget = paintableMap.getWidget(paintable); - - boolean horizontalScrollBar = false; - boolean verticalScrollBar = false; - - VPaintableWidgetContainer parentPaintable = paintable.getParent(); - RenderSpace renderSpace; - - // Parent-less components (like sub-windows) are relative to browser - // window. - if (parentPaintable == null) { - renderSpace = new RenderSpace(Window.getClientWidth(), - Window.getClientHeight()); - } else { - renderSpace = ((Container) parentPaintable.getWidgetForPaintable()) - .getAllocatedSpace(widget); - } - - if (relativeSize.getHeight() >= 0) { - if (renderSpace != null) { - - if (renderSpace.getScrollbarSize() > 0) { - if (relativeSize.getWidth() > 100) { - horizontalScrollBar = true; - } else if (relativeSize.getWidth() < 0 - && renderSpace.getWidth() > 0) { - int offsetWidth = widget.getOffsetWidth(); - int width = renderSpace.getWidth(); - if (offsetWidth > width) { - horizontalScrollBar = true; - } - } - } - - int height = renderSpace.getHeight(); - if (horizontalScrollBar) { - height -= renderSpace.getScrollbarSize(); - } - if (validatingLayouts && height <= 0) { - zeroHeightComponents.add(paintable); - } - - height = (int) (height * relativeSize.getHeight() / 100.0); - - if (height < 0) { - height = 0; - } - - if (debugSizes) { - VConsole.log("Widget " - + Util.getSimpleName(widget) - + "/" - + paintableMap.getPid(paintable) - + " relative height " - + relativeSize.getHeight() - + "% of " - + renderSpace.getHeight() - + "px (reported by " - - + Util.getSimpleName(parentPaintable) - + "/" - + (parentPaintable == null ? "?" : parentPaintable - .hashCode()) + ") : " + height + "px"); - } - widget.setHeight(height + "px"); - } else { - widget.setHeight(relativeSize.getHeight() + "%"); - VConsole.error(Util.getLayout(widget).getClass().getName() - + " did not produce allocatedSpace for " - + widget.getClass().getName()); - } - } - - if (relativeSize.getWidth() >= 0) { - - if (renderSpace != null) { - - int width = renderSpace.getWidth(); - - if (renderSpace.getScrollbarSize() > 0) { - if (relativeSize.getHeight() > 100) { - verticalScrollBar = true; - } else if (relativeSize.getHeight() < 0 - && renderSpace.getHeight() > 0 - && widget.getOffsetHeight() > renderSpace - .getHeight()) { - verticalScrollBar = true; - } - } - - if (verticalScrollBar) { - width -= renderSpace.getScrollbarSize(); - } - if (validatingLayouts && width <= 0) { - zeroWidthComponents.add(paintable); - } - - width = (int) (width * relativeSize.getWidth() / 100.0); - - if (width < 0) { - width = 0; - } - - if (debugSizes) { - VConsole.log("Widget " - + Util.getSimpleName(widget) - + "/" - + paintableMap.getPid(paintable) - + " relative width " - + relativeSize.getWidth() - + "% of " - + renderSpace.getWidth() - + "px (reported by " - + Util.getSimpleName(parentPaintable) - + "/" - + (parentPaintable == null ? "?" : paintableMap - .getPid(parentPaintable)) + ") : " + width - + "px"); - } - widget.setWidth(width + "px"); - } else { - widget.setWidth(relativeSize.getWidth() + "%"); - VConsole.error(Util.getLayout(widget).getClass().getName() - + " did not produce allocatedSpace for " - + widget.getClass().getName()); - } - } - - return true; + return false; } /** @@ -1860,17 +1653,6 @@ public class ApplicationConnection { } /** - * Gets the specified Paintables relative size (percent). - * - * @param widget - * the paintable whose size is needed - * @return the the size if the paintable is relatively sized, -1 otherwise - */ - public FloatSize getRelativeSize(Widget widget) { - return paintableMap.getRelativeSize(paintableMap.getPaintable(widget)); - } - - /** * Get either existing or new Paintable for given UIDL. * * If corresponding Paintable has been previously painted, return it. @@ -2219,4 +2001,21 @@ public class ApplicationConnection { eventIdentifier); } + private boolean layoutScheduled = false; + private ScheduledCommand layoutCommand = new ScheduledCommand() { + public void execute() { + layoutScheduled = false; + + measureManager.doLayout(ApplicationConnection.this); + } + }; + + public void doLayout(boolean lazy) { + if (!lazy) { + layoutCommand.execute(); + } else if (!layoutScheduled) { + layoutScheduled = true; + Scheduler.get().scheduleDeferred(layoutCommand); + } + } } diff --git a/src/com/vaadin/terminal/gwt/client/CalculatingLayout.java b/src/com/vaadin/terminal/gwt/client/CalculatingLayout.java new file mode 100644 index 0000000000..ada9ab140e --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/CalculatingLayout.java @@ -0,0 +1,7 @@ +package com.vaadin.terminal.gwt.client; + +public interface CalculatingLayout extends VPaintableWidgetContainer { + public void updateVerticalSizes(); + + public void updateHorizontalSizes(); +}
\ No newline at end of file diff --git a/src/com/vaadin/terminal/gwt/client/ComponentDetail.java b/src/com/vaadin/terminal/gwt/client/ComponentDetail.java index 8e4e13aa1c..eff5a76583 100644 --- a/src/com/vaadin/terminal/gwt/client/ComponentDetail.java +++ b/src/com/vaadin/terminal/gwt/client/ComponentDetail.java @@ -6,7 +6,6 @@ package com.vaadin.terminal.gwt.client; import java.util.HashMap; import com.google.gwt.core.client.JsArrayString; -import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize; import com.vaadin.terminal.gwt.client.RenderInformation.Size; class ComponentDetail { @@ -44,26 +43,11 @@ class ComponentDetail { this.tooltipInfo = tooltipInfo; } - private FloatSize relativeSize; private Size offsetSize; private HashMap<Object, TooltipInfo> additionalTooltips; /** - * @return the relativeSize - */ - FloatSize getRelativeSize() { - return relativeSize; - } - - /** - * @param relativeSize - * the relativeSize to set - */ - void setRelativeSize(FloatSize relativeSize) { - this.relativeSize = relativeSize; - } - - /** + * * @return the offsetSize */ Size getOffsetSize() { diff --git a/src/com/vaadin/terminal/gwt/client/ComputedStyle.java b/src/com/vaadin/terminal/gwt/client/ComputedStyle.java index 662cb5fc34..ff976468e7 100644 --- a/src/com/vaadin/terminal/gwt/client/ComputedStyle.java +++ b/src/com/vaadin/terminal/gwt/client/ComputedStyle.java @@ -4,7 +4,7 @@ package com.vaadin.terminal.gwt.client; import com.google.gwt.core.client.JavaScriptObject; -import com.google.gwt.user.client.Element; +import com.google.gwt.dom.client.Element; public class ComputedStyle { diff --git a/src/com/vaadin/terminal/gwt/client/FastStringSet.java b/src/com/vaadin/terminal/gwt/client/FastStringSet.java new file mode 100644 index 0000000000..918c44d38a --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/FastStringSet.java @@ -0,0 +1,45 @@ +package com.vaadin.terminal.gwt.client; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArrayString; + +public final class FastStringSet extends JavaScriptObject { + protected FastStringSet() { + // JSO constructor + } + + public native boolean contains(String string) + /*-{ + return this.hasOwnProperty(string); + }-*/; + + public native void add(String string) + /*-{ + this[string] = true; + }-*/; + + public native void addAll(JsArrayString array) + /*-{ + for(var i = 0; i < array.length; i++) { + this[array[i]] = true; + } + }-*/; + + public native JsArrayString dump() + /*-{ + var array = []; + for(var string in this) { + array.push(string); + } + return array; + }-*/; + + public native void remove(String string) + /*-{ + delete this[string]; + }-*/; + + public static FastStringSet create() { + return JavaScriptObject.createObject().cast(); + } +}
\ No newline at end of file diff --git a/src/com/vaadin/terminal/gwt/client/MeasureManager.java b/src/com/vaadin/terminal/gwt/client/MeasureManager.java new file mode 100644 index 0000000000..ffb9628641 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/MeasureManager.java @@ -0,0 +1,151 @@ +package com.vaadin.terminal.gwt.client; + +import com.google.gwt.core.client.Duration; +import com.google.gwt.core.client.JsArrayString; +import com.vaadin.terminal.gwt.client.ui.LayoutPhaseListener; +import com.vaadin.terminal.gwt.client.ui.ResizeRequired; + +public class MeasureManager { + + public void doLayout(ApplicationConnection client) { + VPaintableMap paintableMap = client.getPaintableMap(); + VPaintableWidget[] paintableWidgets = paintableMap + .getRegisteredPaintableWidgets(); + + for (VPaintableWidget vPaintableWidget : paintableWidgets) { + if (vPaintableWidget instanceof LayoutPhaseListener) { + ((LayoutPhaseListener) vPaintableWidget).beforeLayout(); + } + } + + int passes = 0; + Duration totalDuration = new Duration(); + + while (true) { + Duration passDuration = new Duration(); + passes++; + measureWidgets(paintableWidgets); + + FastStringSet needsHeightUpdate = FastStringSet.create(); + FastStringSet needsWidthUpdate = FastStringSet.create(); + + for (VPaintableWidget paintable : paintableWidgets) { + MeasuredSize measuredSize = paintable.getMeasuredSize(); + boolean notifiableType = isNotifiableType(paintable); + + VPaintableWidgetContainer parent = paintable.getParent(); + boolean parentNotifiable = parent != null + && isNotifiableType(parent); + + if (measuredSize.isHeightNeedsUpdate()) { + if (notifiableType) { + needsHeightUpdate.add(paintable.getId()); + } + if (!paintable.isRelativeHeight() && parentNotifiable) { + needsHeightUpdate.add(parent.getId()); + } + } + if (measuredSize.isWidthNeedsUpdate()) { + if (notifiableType) { + needsWidthUpdate.add(paintable.getId()); + } + if (!paintable.isRelativeWidth() && parentNotifiable) { + needsWidthUpdate.add(parent.getId()); + } + } + measuredSize.clearDirtyState(); + } + + int measureTime = passDuration.elapsedMillis(); + VConsole.log("Measure in " + measureTime + " ms"); + + FastStringSet updatedSet = FastStringSet.create(); + + JsArrayString needsWidthUpdateArray = needsWidthUpdate.dump(); + + for (int i = 0; i < needsWidthUpdateArray.length(); i++) { + String pid = needsWidthUpdateArray.get(i); + + VPaintable paintable = paintableMap.getPaintable(pid); + if (paintable instanceof CalculatingLayout) { + CalculatingLayout cl = (CalculatingLayout) paintable; + cl.updateHorizontalSizes(); + } else if (paintable instanceof ResizeRequired) { + ResizeRequired rr = (ResizeRequired) paintable; + rr.onResize(); + needsHeightUpdate.remove(pid); + } + updatedSet.add(pid); + } + + JsArrayString needsHeightUpdateArray = needsHeightUpdate.dump(); + for (int i = 0; i < needsHeightUpdateArray.length(); i++) { + String pid = needsHeightUpdateArray.get(i); + + VPaintableWidget paintable = (VPaintableWidget) paintableMap + .getPaintable(pid); + if (paintable instanceof CalculatingLayout) { + CalculatingLayout cl = (CalculatingLayout) paintable; + cl.updateVerticalSizes(); + } else if (paintable instanceof ResizeRequired) { + ResizeRequired rr = (ResizeRequired) paintable; + rr.onResize(); + } + updatedSet.add(pid); + } + + JsArrayString changed = updatedSet.dump(); + VConsole.log(changed.length() + " requestLayout invocations in " + + (passDuration.elapsedMillis() - measureTime) + "ms"); + + StringBuilder b = new StringBuilder(); + b.append(changed.length()); + b.append(" changed widgets in pass "); + b.append(passes); + b.append(" in "); + b.append(passDuration.elapsedMillis()); + b.append(" ms: "); + if (changed.length() < 10) { + for (int i = 0; i < changed.length(); i++) { + if (i != 0) { + b.append(", "); + } + b.append(changed.get(i)); + } + } + VConsole.log(b.toString()); + + if (changed.length() == 0) { + VConsole.log("No more changes in pass " + passes); + break; + } + + if (passes > 100) { + VConsole.log("Aborting layout"); + break; + } + } + + for (VPaintableWidget vPaintableWidget : paintableWidgets) { + if (vPaintableWidget instanceof LayoutPhaseListener) { + ((LayoutPhaseListener) vPaintableWidget).afterLayout(); + } + } + + VConsole.log("Total layout time: " + totalDuration.elapsedMillis() + + "ms"); + } + + private void measureWidgets(VPaintableWidget[] paintableWidgets) { + + for (VPaintableWidget paintableWidget : paintableWidgets) { + MeasuredSize measuredSize = paintableWidget.getMeasuredSize(); + measuredSize.measure(); + } + } + + private static boolean isNotifiableType(VPaintableWidget paintable) { + return paintable instanceof ResizeRequired + || paintable instanceof CalculatingLayout; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/MeasuredSize.java b/src/com/vaadin/terminal/gwt/client/MeasuredSize.java new file mode 100644 index 0000000000..93642df7ec --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/MeasuredSize.java @@ -0,0 +1,265 @@ +package com.vaadin.terminal.gwt.client; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import com.google.gwt.dom.client.Element; +import com.google.gwt.user.client.ui.Widget; + +public final class MeasuredSize { + private int width = -1; + private int height = -1; + + private int[] paddings = new int[4]; + private int[] borders = new int[4]; + private int[] margins = new int[4]; + + private final VPaintableWidget paintable; + + private boolean heightChanged = true; + private boolean widthChanged = true; + + private final Map<Element, int[]> dependencySizes = new HashMap<Element, int[]>(); + + public MeasuredSize(VPaintableWidget paintable) { + this.paintable = paintable; + } + + public int getOuterHeight() { + return height; + } + + public int getOuterWidth() { + return width; + } + + private static int sumWidths(int[] sizes) { + return sizes[1] + sizes[3]; + } + + private static int sumHeights(int[] sizes) { + return sizes[0] + sizes[2]; + } + + public int getInnerHeight() { + return height - sumHeights(margins) - sumHeights(borders) + - sumHeights(paddings); + } + + public int getInnerWidth() { + return width - sumWidths(margins) - sumWidths(borders) + - sumWidths(paddings); + } + + public void setOuterHeight(int height) { + if (this.height != height) { + heightChanged = true; + this.height = height; + } + } + + public void setOuterWidth(int width) { + if (this.width != width) { + widthChanged = true; + this.width = width; + } + } + + public void registerDependency(Element element) { + if (!dependencySizes.containsKey(element)) { + dependencySizes.put(element, new int[] { -1, -1 }); + } + } + + public void deRegisterDependency(Element element) { + dependencySizes.remove(element); + } + + public int getDependencyOuterWidth(Element e) { + return getDependencySize(e, 0); + } + + public int getDependencyOuterHeight(Element e) { + return getDependencySize(e, 1); + } + + private int getDependencySize(Element e, int index) { + int[] sizes = dependencySizes.get(e); + if (sizes == null) { + return -1; + } else { + return sizes[index]; + } + } + + public int getBorderHeight() { + return sumHeights(borders); + } + + public int getBorderWidth() { + return sumWidths(borders); + } + + public int getPaddingHeight() { + return sumHeights(paddings); + } + + public int getPaddingWidth() { + return sumWidths(paddings); + } + + public int getMarginHeight() { + return sumHeights(margins); + } + + public int getMarginWidth() { + return sumWidths(margins); + } + + public int getMarginTop() { + return margins[0]; + } + + public int getMarginRight() { + return margins[1]; + } + + public int getMarginBottom() { + return margins[2]; + } + + public int getMarginLeft() { + return margins[3]; + } + + public int getBorderTop() { + return margins[0]; + } + + public int getBorderRight() { + return margins[1]; + } + + public int getBorderBottom() { + return margins[2]; + } + + public int getBorderLeft() { + return margins[3]; + } + + public int getPaddingTop() { + return paddings[0]; + } + + public int getPaddingRight() { + return paddings[1]; + } + + public int getPaddingBottom() { + return paddings[2]; + } + + public int getPaddingLeft() { + return paddings[3]; + } + + void measure() { + Widget widget = paintable.getWidgetForPaintable(); + ComputedStyle computedStyle = new ComputedStyle(widget.getElement()); + + int[] paddings = computedStyle.getPadding(); + if (!heightChanged && hasHeightChanged(this.paddings, paddings)) { + heightChanged = true; + } + if (!widthChanged && hasWidthChanged(this.paddings, paddings)) { + widthChanged = true; + } + this.paddings = paddings; + + int[] margins = computedStyle.getMargin(); + if (!heightChanged && hasHeightChanged(this.margins, margins)) { + heightChanged = true; + } + if (!widthChanged && hasWidthChanged(this.margins, margins)) { + widthChanged = true; + } + this.margins = margins; + + int[] borders = computedStyle.getBorder(); + if (!heightChanged && hasHeightChanged(this.borders, borders)) { + heightChanged = true; + } + if (!widthChanged && hasWidthChanged(this.borders, borders)) { + widthChanged = true; + } + this.borders = borders; + + int offsetHeight = widget.getOffsetHeight(); + int marginHeight = sumHeights(margins); + setOuterHeight(offsetHeight + marginHeight); + + int offsetWidth = widget.getOffsetWidth(); + int marginWidth = sumWidths(margins); + setOuterWidth(offsetWidth + marginWidth); + + // int i = 0; + for (Entry<Element, int[]> entry : dependencySizes.entrySet()) { + Element element = entry.getKey(); + // int[] elementMargin = new ComputedStyle(element).getMargin(); + int[] sizes = entry.getValue(); + + int elementWidth = element.getOffsetWidth(); + // elementWidth += elementMargin[1] + elementMargin[3]; + if (elementWidth != sizes[0]) { + // System.out.println(paintable.getId() + " dependency " + i + // + " width changed from " + sizes[0] + " to " + // + elementWidth); + sizes[0] = elementWidth; + widthChanged = true; + } + + int elementHeight = element.getOffsetHeight(); + // Causes infinite loops as a negative margin based on the + // measured height is currently used for captions + // elementHeight += elementMargin[0] + elementMargin[1]; + if (elementHeight != sizes[1]) { + // System.out.println(paintable.getId() + " dependency " + i + // + " height changed from " + sizes[1] + " to " + // + elementHeight); + sizes[1] = elementHeight; + heightChanged = true; + } + // i++; + } + } + + void clearDirtyState() { + heightChanged = widthChanged = false; + } + + public boolean isHeightNeedsUpdate() { + return heightChanged; + } + + public boolean isWidthNeedsUpdate() { + return widthChanged; + } + + private static boolean hasWidthChanged(int[] sizes1, int[] sizes2) { + return sizes1[1] != sizes2[1] || sizes1[3] != sizes2[3]; + } + + private static boolean hasHeightChanged(int[] sizes1, int[] sizes2) { + return sizes1[0] != sizes2[0] || sizes1[2] != sizes2[2]; + } + + public void setWidthNeedsUpdate() { + widthChanged = true; + } + + public void setHeightNeedsUpdate() { + heightChanged = true; + } +}
\ No newline at end of file diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java index 11122b1b0b..a3604b6b63 100644 --- a/src/com/vaadin/terminal/gwt/client/Util.java +++ b/src/com/vaadin/terminal/gwt/client/Util.java @@ -5,11 +5,7 @@ package com.vaadin.terminal.gwt.client; import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; +import java.util.List; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; @@ -24,7 +20,6 @@ import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.EventListener; -import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.RootPanel; @@ -65,30 +60,6 @@ public class Util { return el; }-*/; - private static final int LAZY_SIZE_CHANGE_TIMEOUT = 400; - private static Set<Widget> latelyChangedWidgets = new HashSet<Widget>(); - - private static Timer lazySizeChangeTimer = new Timer() { - private boolean lazySizeChangeTimerScheduled = false; - - @Override - public void run() { - componentSizeUpdated(latelyChangedWidgets); - latelyChangedWidgets.clear(); - lazySizeChangeTimerScheduled = false; - } - - @Override - public void schedule(int delayMillis) { - if (lazySizeChangeTimerScheduled) { - cancel(); - } else { - lazySizeChangeTimerScheduled = true; - } - super.schedule(delayMillis); - } - }; - /** * This helper method can be called if components size have been changed * outside rendering phase. It notifies components parent about the size @@ -106,58 +77,40 @@ public class Util { * run componentSizeUpdated lazyly */ public static void notifyParentOfSizeChange(Widget widget, boolean lazy) { - if (lazy) { - latelyChangedWidgets.add(widget); - lazySizeChangeTimer.schedule(LAZY_SIZE_CHANGE_TIMEOUT); - } else { - Set<Widget> widgets = new HashSet<Widget>(); - widgets.add(widget); - Util.componentSizeUpdated(widgets); + ApplicationConnection applicationConnection = findApplicationConnectionFor(widget); + if (applicationConnection != null) { + applicationConnection.doLayout(lazy); } } - /** - * Called when the size of one or more widgets have changed during - * rendering. Finds parent container and notifies them of the size change. - * - * @param paintables - */ - public static void componentSizeUpdated(Set<Widget> widgets) { - if (widgets.isEmpty()) { - return; - } + private static boolean findAppConnectionWarningDisplayed = false; - Map<Container, Set<Widget>> childWidgets = new HashMap<Container, Set<Widget>>(); + private static ApplicationConnection findApplicationConnectionFor( + Widget widget) { + if (!findAppConnectionWarningDisplayed) { + findAppConnectionWarningDisplayed = true; + VConsole.log("Warning: Using Util.findApplicationConnectionFor which should be eliminated once there is a better way to find the ApplicationConnection for a Paintable"); + } - for (Widget widget : widgets) { - if (!widget.isAttached()) { + List<ApplicationConnection> runningApplications = ApplicationConfiguration + .getRunningApplications(); + for (ApplicationConnection applicationConnection : runningApplications) { + VPaintableMap paintableMap = applicationConnection + .getPaintableMap(); + VPaintableWidget paintable = paintableMap.getPaintable(widget); + if (paintable == null) { continue; } - - // ApplicationConnection.getConsole().log( - // "Widget " + Util.getSimpleName(widget) + " size updated"); - Widget parent = widget.getParent(); - while (parent != null && !(parent instanceof Container)) { - parent = parent.getParent(); - } - if (parent != null) { - Set<Widget> set = childWidgets.get(parent); - if (set == null) { - set = new HashSet<Widget>(); - childWidgets.put((Container) parent, set); + String pid = paintableMap.getPid(paintable); + if (pid != null) { + VPaintable otherPaintable = paintableMap.getPaintable(pid); + if (otherPaintable == paintable) { + return applicationConnection; } - set.add(widget); - } - } - - Set<Widget> parentChanges = new HashSet<Widget>(); - for (Container parent : childWidgets.keySet()) { - if (!parent.requestLayout(childWidgets.get(parent))) { - parentChanges.add((Widget) parent); } } - componentSizeUpdated(parentChanges); + return null; } public static float parseRelativeSize(String size) { @@ -173,26 +126,6 @@ public class Util { } } - /** - * Returns closest parent Widget in hierarchy that implements Container - * interface - * - * @param component - * @return closest parent Container - */ - public static Container getLayout(Widget component) { - Widget parent = component.getParent(); - while (parent != null && !(parent instanceof Container)) { - parent = parent.getParent(); - } - if (parent != null) { - assert ((Container) parent).hasChildComponent(component); - - return (Container) parent; - } - return null; - } - private static final Element escapeHtmlHelper = DOM.createDiv(); /** @@ -615,20 +548,7 @@ public class Util { public static void updateRelativeChildrenAndSendSizeUpdateEvent( ApplicationConnection client, HasWidgets container, Widget widget) { - /* - * Relative sized children must be updated first so the component has - * the correct outer dimensions when signaling a size change to the - * parent. - */ - Iterator<Widget> childIterator = container.iterator(); - while (childIterator.hasNext()) { - Widget w = childIterator.next(); - client.handleComponentRelativeSize(w); - } - - HashSet<Widget> widgets = new HashSet<Widget>(); - widgets.add(widget); - Util.componentSizeUpdated(widgets); + notifyParentOfSizeChange(widget, false); } public static native int getRequiredWidth( @@ -717,62 +637,13 @@ public class Util { }-*/; /** - * Locates the child component of <literal>parent</literal> which contains - * the element <literal>element</literal>. The child component is also - * returned if "element" is part of its caption. If - * <literal>element</literal> is not part of any child component, null is - * returned. - * - * This method returns the immediate child of the parent that contains the - * element. See - * {@link #getPaintableForElement(ApplicationConnection, Container, Element)} - * for the deepest nested paintable of parent that contains the element. - * - * @param client - * A reference to ApplicationConnection - * @param parent - * The widget that contains <literal>element</literal>. - * @param element - * An element that is a sub element of the parent - * @return The VPaintableWidget which the element is a part of. Null if the - * element does not belong to a child. - */ - public static VPaintableWidget getChildPaintableForElement( - ApplicationConnection client, Container parent, Element element) { - Element rootElement = ((Widget) parent).getElement(); - while (element != null && element != rootElement) { - VPaintableWidget paintable = VPaintableMap.get(client) - .getPaintable(element); - if (paintable == null) { - String ownerPid = VCaption.getCaptionOwnerPid(element); - if (ownerPid != null) { - paintable = (VPaintableWidget) VPaintableMap.get(client) - .getPaintable(ownerPid); - } - } - - if (paintable != null - && parent.hasChildComponent(paintable - .getWidgetForPaintable())) { - return paintable; - } - - element = (Element) element.getParentElement(); - } - - return null; - } - - /** * Locates the nested child component of <literal>parent</literal> which * contains the element <literal>element</literal>. The child component is * also returned if "element" is part of its caption. If * <literal>element</literal> is not part of any child component, null is * returned. * - * This method returns the deepest nested VPaintableWidget. See - * {@link #getChildPaintableForElement(ApplicationConnection, Container, Element)} - * for the immediate child component of parent that contains the element. + * This method returns the deepest nested VPaintableWidget. * * @param client * A reference to ApplicationConnection diff --git a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java index 76c312676a..d3a963a7e1 100644 --- a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java +++ b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java @@ -523,8 +523,7 @@ public class VDebugConsole extends VOverlay implements Console { private void printClientSideDetectedIssues( Set<VPaintableWidget> zeroHeightComponents, ApplicationConnection ac) { for (final VPaintableWidget paintable : zeroHeightComponents) { - final Container layout = Util.getLayout(paintable - .getWidgetForPaintable()); + final Widget layout = paintable.getParent().getWidgetForPaintable(); VerticalPanel errorDetails = new VerticalPanel(); errorDetails.add(new Label("" + Util.getSimpleName(paintable) @@ -534,7 +533,7 @@ public class VDebugConsole extends VOverlay implements Console { emphasisInUi.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { if (paintable != null) { - Element element2 = ((Widget) layout).getElement(); + Element element2 = layout.getElement(); Widget.setStyleName(element2, "invalidlayout", emphasisInUi.getValue()); } diff --git a/src/com/vaadin/terminal/gwt/client/VPaintableMap.java b/src/com/vaadin/terminal/gwt/client/VPaintableMap.java index a3b6f62174..03fb599fe9 100644 --- a/src/com/vaadin/terminal/gwt/client/VPaintableMap.java +++ b/src/com/vaadin/terminal/gwt/client/VPaintableMap.java @@ -3,6 +3,7 @@ */ package com.vaadin.terminal.gwt.client; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -16,7 +17,6 @@ import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.Paintable; -import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize; import com.vaadin.terminal.gwt.client.RenderInformation.Size; public class VPaintableMap { @@ -208,6 +208,21 @@ public class VPaintableMap { } + public VPaintableWidget[] getRegisteredPaintableWidgets() { + ArrayList<VPaintableWidget> result = new ArrayList<VPaintableWidget>(); + + for (VPaintable paintable : getPaintables()) { + if (paintable instanceof VPaintableWidget) { + VPaintableWidget paintableWidget = (VPaintableWidget) paintable; + if (!unregistryBag.contains(getPid(paintable))) { + result.add(paintableWidget); + } + } + } + + return result.toArray(new VPaintableWidget[result.size()]); + } + void purgeUnregistryBag(boolean unregisterPaintables) { if (unregisterPaintables) { for (String pid : unregistryBag) { @@ -305,34 +320,10 @@ public class VPaintableMap { * @return */ @Deprecated - public FloatSize getRelativeSize(VPaintableWidget paintable) { - return getComponentDetail(paintable).getRelativeSize(); - } - - /** - * FIXME: Should not be here - * - * @param paintable - * @return - */ - @Deprecated public void setOffsetSize(VPaintableWidget paintable, Size newSize) { getComponentDetail(paintable).setOffsetSize(newSize); } - /** - * FIXME: Should not be here - * - * @param paintable - * @return - */ - @Deprecated - public void setRelativeSize(VPaintableWidget paintable, - FloatSize relativeSize) { - getComponentDetail(paintable).setRelativeSize(relativeSize); - - } - private ComponentDetail getComponentDetail(VPaintableWidget paintable) { return idToComponentDetail.get(getPid(paintable)); } diff --git a/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java b/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java index 4b8720b132..52740e59a1 100644 --- a/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java +++ b/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java @@ -28,4 +28,60 @@ public interface VPaintableWidget extends VPaintable { */ // FIXME: Rename to getParent() public VPaintableWidgetContainer getParent(); + + public MeasuredSize getMeasuredSize(); + + /** + * Returns <code>true</code> if the width of this paintable is currently + * undefined. If the width is undefined, the actual width of the paintable + * is defined by its contents. + * + * @return <code>true</code> if the width is undefined, else + * <code>false</code> + */ + public boolean isUndefinedWidth(); + + /** + * Returns <code>true</code> if the height of this paintable is currently + * undefined. If the height is undefined, the actual height of the paintable + * is defined by its contents. + * + * @return <code>true</code> if the height is undefined, else + * <code>false</code> + */ + public boolean isUndefinedHeight(); + + /** + * Returns <code>true</code> if the width of this paintable is currently + * relative. If the width is relative, the actual width of the paintable is + * a percentage of the size allocated to it by its parent. + * + * @return <code>true</code> if the width is undefined, else + * <code>false</code> + */ + public boolean isRelativeWidth(); + + /** + * Returns <code>true</code> if the height of this paintable is currently + * relative. If the height is relative, the actual height of the paintable + * is a percentage of the size allocated to it by its parent. + * + * @return <code>true</code> if the width is undefined, else + * <code>false</code> + */ + public boolean isRelativeHeight(); + + /** + * Gets the width of this paintable as defined on the server. + * + * @return the server side width definition + */ + public String getDefinedWidth(); + + /** + * Gets the height of this paintable as defined on the server. + * + * @return the server side height definition + */ + public String getDefinedHeight(); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/LayoutPhaseListener.java b/src/com/vaadin/terminal/gwt/client/ui/LayoutPhaseListener.java new file mode 100644 index 0000000000..3ab7b8a9ea --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/LayoutPhaseListener.java @@ -0,0 +1,7 @@ +package com.vaadin.terminal.gwt.client.ui; + +public interface LayoutPhaseListener { + public void beforeLayout(); + + public void afterLayout(); +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/ResizeRequired.java b/src/com/vaadin/terminal/gwt/client/ui/ResizeRequired.java new file mode 100644 index 0000000000..a03fff0210 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/ResizeRequired.java @@ -0,0 +1,7 @@ +package com.vaadin.terminal.gwt.client.ui; + +import com.vaadin.terminal.gwt.client.VPaintableWidget; + +public interface ResizeRequired extends VPaintableWidget { + public void onResize(); +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java b/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java index 2bd578a45d..a90c0c33ff 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java +++ b/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java @@ -17,7 +17,6 @@ import com.google.gwt.user.client.ui.KeyboardListener; import com.google.gwt.user.client.ui.KeyboardListenerCollection; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; -import com.vaadin.terminal.gwt.client.Container; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VPaintableWidget; @@ -33,9 +32,8 @@ import com.vaadin.terminal.gwt.client.ui.richtextarea.VRichTextArea; public class ShortcutActionHandler { /** - * An interface implemented by those users (most often {@link Container}s, - * but HasWidgets at least) of this helper class that want to support - * special components like {@link VRichTextArea} that don't properly + * An interface implemented by those users of this helper class that want to + * support special components like {@link VRichTextArea} that don't properly * propagate key down events. Those components can build support for * shortcut actions by traversing the closest * {@link ShortcutActionHandlerOwner} from the component hierarchy an diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java index 7ac44bc4b7..fb28f452d8 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java @@ -4,10 +4,7 @@ package com.vaadin.terminal.gwt.client.ui; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Document; @@ -18,15 +15,13 @@ import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.client.Container; -import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VCaption; import com.vaadin.terminal.gwt.client.VPaintableMap; import com.vaadin.terminal.gwt.client.VPaintableWidget; -public class VAbsoluteLayout extends ComplexPanel implements Container { +public class VAbsoluteLayout extends ComplexPanel { /** Tag name for widget creation */ public static final String TAGNAME = "absolutelayout"; @@ -38,18 +33,12 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { protected final Element canvas = DOM.createDiv(); - // private int excessPixelsHorizontal; - // - // private int excessPixelsVertical; - private Object previousStyleName; Map<String, AbsoluteWrapper> pidToComponentWrappper = new HashMap<String, AbsoluteWrapper>(); protected ApplicationConnection client; - boolean rendering; - public VAbsoluteLayout() { setElement(Document.get().createDivElement()); setStyleName(CLASSNAME); @@ -60,63 +49,6 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { getElement().appendChild(marginElement); } - public RenderSpace getAllocatedSpace(Widget child) { - // TODO needs some special handling for components with only on edge - // horizontally or vertically defined - AbsoluteWrapper wrapper = (AbsoluteWrapper) child.getParent(); - int w; - if (wrapper.left != null && wrapper.right != null) { - w = wrapper.getOffsetWidth(); - } else if (wrapper.right != null) { - // left == null - // available width == right edge == offsetleft + width - w = wrapper.getOffsetWidth() + wrapper.getElement().getOffsetLeft(); - } else { - // left != null && right == null || left == null && - // right == null - // available width == canvas width - offset left - w = canvas.getOffsetWidth() - wrapper.getElement().getOffsetLeft(); - } - int h; - if (wrapper.top != null && wrapper.bottom != null) { - h = wrapper.getOffsetHeight(); - } else if (wrapper.bottom != null) { - // top not defined, available space 0... bottom of wrapper - h = wrapper.getElement().getOffsetTop() + wrapper.getOffsetHeight(); - } else { - // top defined or both undefined, available space == canvas - top - h = canvas.getOffsetHeight() - wrapper.getElement().getOffsetTop(); - } - - return new RenderSpace(w, h); - } - - public boolean hasChildComponent(Widget component) { - for (Iterator<Entry<String, AbsoluteWrapper>> iterator = pidToComponentWrappper - .entrySet().iterator(); iterator.hasNext();) { - if (iterator.next().getValue().paintable == component) { - return true; - } - } - return false; - } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - for (Widget wrapper : getChildren()) { - AbsoluteWrapper w = (AbsoluteWrapper) wrapper; - if (w.getWidget() == oldComponent) { - w.setWidget(newComponent); - return; - } - } - } - - public boolean requestLayout(Set<Widget> children) { - // component inside an absolute panel never affects parent nor the - // layout - return true; - } - AbsoluteWrapper getWrapper(ApplicationConnection client, UIDL componentUIDL) { AbsoluteWrapper wrapper = pidToComponentWrappper.get(componentUIDL .getId()); @@ -135,34 +67,11 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { } @Override - public void setStyleName(String style) { - super.setStyleName(style); - if (previousStyleName == null || !previousStyleName.equals(style)) { - // excessPixelsHorizontal = -1; - // excessPixelsVertical = -1; - } - } - - @Override public void setWidth(String width) { super.setWidth(width); // TODO do this so that canvas gets the sized properly (the area // inside marginals) canvas.getStyle().setProperty("width", width); - - if (!rendering) { - relayoutRelativeChildren(); - } - } - - private void relayoutRelativeChildren() { - for (Widget widget : getChildren()) { - if (widget instanceof AbsoluteWrapper) { - AbsoluteWrapper w = (AbsoluteWrapper) widget; - client.handleComponentRelativeSize(w.getWidget()); - w.updateCaptionPosition(); - } - } } @Override @@ -171,18 +80,14 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { // TODO do this so that canvas gets the sized properly (the area // inside marginals) canvas.getStyle().setProperty("height", height); - - if (!rendering) { - relayoutRelativeChildren(); - } } public class AbsoluteWrapper extends SimplePanel { private String css; - private String left; - private String top; - private String right; - private String bottom; + String left; + String top; + String right; + String bottom; private String zIndex; private VPaintableWidget paintable; @@ -284,7 +189,7 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { updateCaptionPosition(); } - private void updateCaptionPosition() { + void updateCaptionPosition() { if (caption != null) { Style style = caption.getElement().getStyle(); style.setProperty("position", "absolute"); diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java index 75597e27e0..6ae01c5c23 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java @@ -7,18 +7,22 @@ import java.util.HashSet; import java.util.Iterator; import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style; +import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.DomEvent.Type; import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.CalculatingLayout; import com.vaadin.terminal.gwt.client.EventId; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.VPaintableWidget; import com.vaadin.terminal.gwt.client.ui.VAbsoluteLayout.AbsoluteWrapper; -public class VAbsoluteLayoutPaintable extends VAbstractPaintableWidgetContainer { +public class VAbsoluteLayoutPaintable extends VAbstractPaintableWidgetContainer + implements CalculatingLayout { private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler( this, EventId.LAYOUT_CLICK) { @@ -37,12 +41,10 @@ public class VAbsoluteLayoutPaintable extends VAbstractPaintableWidgetContainer @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - getWidgetForPaintable().rendering = true; getWidgetForPaintable().client = client; // TODO margin handling super.updateFromUIDL(uidl, client); if (!isRealUpdate(uidl)) { - getWidgetForPaintable().rendering = false; return; } @@ -68,7 +70,6 @@ public class VAbsoluteLayoutPaintable extends VAbstractPaintableWidgetContainer getWidgetForPaintable().pidToComponentWrappper.remove(pid); absoluteWrapper.destroy(); } - getWidgetForPaintable().rendering = false; } public void updateCaption(VPaintableWidget component, UIDL uidl) { @@ -86,4 +87,67 @@ public class VAbsoluteLayoutPaintable extends VAbstractPaintableWidgetContainer public VAbsoluteLayout getWidgetForPaintable() { return (VAbsoluteLayout) super.getWidgetForPaintable(); } + + public void updateVerticalSizes() { + VAbsoluteLayout layout = getWidgetForPaintable(); + for (VPaintableWidget paintable : getChildren()) { + Widget widget = paintable.getWidgetForPaintable(); + AbsoluteWrapper wrapper = (AbsoluteWrapper) widget.getParent(); + Style wrapperStyle = wrapper.getElement().getStyle(); + + if (paintable.isRelativeHeight()) { + int h; + if (wrapper.top != null && wrapper.bottom != null) { + h = wrapper.getOffsetHeight(); + } else if (wrapper.bottom != null) { + // top not defined, available space 0... bottom of + // wrapper + h = wrapper.getElement().getOffsetTop() + + wrapper.getOffsetHeight(); + } else { + // top defined or both undefined, available space == + // canvas - top + h = layout.canvas.getOffsetHeight() + - wrapper.getElement().getOffsetTop(); + } + wrapperStyle.setHeight(h, Unit.PX); + } else { + wrapperStyle.clearHeight(); + } + + wrapper.updateCaptionPosition(); + } + } + + public void updateHorizontalSizes() { + VAbsoluteLayout layout = getWidgetForPaintable(); + for (VPaintableWidget paintable : getChildren()) { + Widget widget = paintable.getWidgetForPaintable(); + AbsoluteWrapper wrapper = (AbsoluteWrapper) widget.getParent(); + Style wrapperStyle = wrapper.getElement().getStyle(); + + if (paintable.isRelativeWidth()) { + int w; + if (wrapper.left != null && wrapper.right != null) { + w = wrapper.getOffsetWidth(); + } else if (wrapper.right != null) { + // left == null + // available width == right edge == offsetleft + width + w = wrapper.getOffsetWidth() + + wrapper.getElement().getOffsetLeft(); + } else { + // left != null && right == null || left == null && + // right == null + // available width == canvas width - offset left + w = layout.canvas.getOffsetWidth() + - wrapper.getElement().getOffsetLeft(); + } + wrapperStyle.setWidth(w, Unit.PX); + } else { + wrapperStyle.clearWidth(); + } + + wrapper.updateCaptionPosition(); + } + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java index 355516ccd1..9c8853bd88 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java @@ -8,6 +8,7 @@ import com.google.gwt.user.client.ui.FocusWidget; import com.google.gwt.user.client.ui.Focusable; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.MeasuredSize; import com.vaadin.terminal.gwt.client.TooltipInfo; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.VPaintableMap; @@ -23,10 +24,15 @@ public abstract class VAbstractPaintableWidget implements VPaintableWidget { private ApplicationConnection connection; private String id; + private final MeasuredSize measuredSize = new MeasuredSize(this); + /* State variables */ private boolean enabled = true; private boolean visible = true; + private String definedWidth = ""; + private String definedHeight = ""; + /** * Default constructor */ @@ -180,7 +186,64 @@ public abstract class VAbstractPaintableWidget implements VPaintableWidget { * taken into account */ - getConnection().updateComponentSize(this, uidl); + updateComponentSize(uidl); + } + + private void updateComponentSize(UIDL uidl) { + String w = uidl.hasAttribute("width") ? uidl + .getStringAttribute("width") : ""; + + String h = uidl.hasAttribute("height") ? uidl + .getStringAttribute("height") : ""; + + // Parent should be updated if either dimension changed between relative + // and non-relative + if (w.endsWith("%") != definedWidth.endsWith("%")) { + VPaintableWidgetContainer parent = getParent(); + if (parent != null) { + parent.getMeasuredSize().setWidthNeedsUpdate(); + } + } + + if (h.endsWith("%") != definedHeight.endsWith("%")) { + VPaintableWidgetContainer parent = getParent(); + if (parent != null) { + parent.getMeasuredSize().setHeightNeedsUpdate(); + } + } + + definedWidth = w; + definedHeight = h; + + // Set defined sizes + Widget component = getWidgetForPaintable(); + + component.setHeight(h); + component.setWidth(w); + } + + public boolean isRelativeHeight() { + return definedHeight.endsWith("%"); + } + + public boolean isRelativeWidth() { + return definedWidth.endsWith("%"); + } + + public boolean isUndefinedHeight() { + return definedHeight.length() == 0; + } + + public boolean isUndefinedWidth() { + return definedWidth.length() == 0; + } + + public String getDefinedHeight() { + return definedHeight; + } + + public String getDefinedWidth() { + return definedWidth; } /** @@ -263,6 +326,7 @@ public abstract class VAbstractPaintableWidget implements VPaintableWidget { StringBuffer styleBuf = new StringBuffer(); styleBuf.append(primaryStyleName); + styleBuf.append(" v-paintable"); // first disabling and read-only status if (!enabled) { @@ -310,4 +374,7 @@ public abstract class VAbstractPaintableWidget implements VPaintableWidget { return styleBuf.toString(); } + public MeasuredSize getMeasuredSize() { + return measuredSize; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java index f1a932b3a3..d3ac9b2def 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java @@ -4,9 +4,8 @@ package com.vaadin.terminal.gwt.client.ui; -import java.util.Set; - import com.google.gwt.dom.client.Node; +import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.TouchCancelEvent; import com.google.gwt.event.dom.client.TouchCancelHandler; import com.google.gwt.event.dom.client.TouchEndEvent; @@ -22,15 +21,10 @@ import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; -import com.vaadin.terminal.gwt.client.Container; -import com.vaadin.terminal.gwt.client.ContainerResizedListener; -import com.vaadin.terminal.gwt.client.RenderInformation; -import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VConsole; -public class VAbstractSplitPanel extends ComplexPanel implements Container, - ContainerResizedListener { +public class VAbstractSplitPanel extends ComplexPanel { private boolean enabled = false; @@ -78,21 +72,10 @@ public class VAbstractSplitPanel extends ComplexPanel implements Container, ApplicationConnection client; - private String width = ""; - - private String height = ""; - - private RenderSpace firstRenderSpace = new RenderSpace(0, 0, true); - private RenderSpace secondRenderSpace = new RenderSpace(0, 0, true); - - RenderInformation renderInformation = new RenderInformation(); - String id; boolean immediate; - boolean rendering = false; - /* The current position of the split handle in either percentages or pixels */ String position; @@ -248,42 +231,40 @@ public class VAbstractSplitPanel extends ComplexPanel implements Container, // Convert percentage values to pixels if (pos.indexOf("%") > 0) { - pos = Float.parseFloat(pos.substring(0, pos.length() - 1)) - / 100 - * (orientation == ORIENTATION_HORIZONTAL ? getOffsetWidth() - : getOffsetHeight()) + "px"; + int size = orientation == ORIENTATION_HORIZONTAL ? getOffsetWidth() + : getOffsetHeight(); + float percentage = Float.parseFloat(pos.substring(0, + pos.length() - 1)); + pos = percentage / 100 * size + "px"; } + String attributeName; if (orientation == ORIENTATION_HORIZONTAL) { if (positionReversed) { - DOM.setStyleAttribute(splitter, "right", pos); + attributeName = "right"; } else { - DOM.setStyleAttribute(splitter, "left", pos); + attributeName = "left"; } } else { if (positionReversed) { - DOM.setStyleAttribute(splitter, "bottom", pos); + attributeName = "bottom"; } else { - DOM.setStyleAttribute(splitter, "top", pos); + attributeName = "top"; } } - iLayout(); - client.runDescendentsLayout(this); + Style style = splitter.getStyle(); + if (!pos.equals(style.getProperty(attributeName))) { + style.setProperty(attributeName, pos); + updateSizes(); + } } - /* - * Calculates absolutely positioned container places/sizes (non-Javadoc) - * - * @see com.vaadin.terminal.gwt.client.NeedsLayout#layout() - */ - public void iLayout() { + void updateSizes() { if (!isAttached()) { return; } - renderInformation.updateSize(getElement()); - int wholeSize; int pixelPosition; @@ -313,12 +294,6 @@ public class VAbstractSplitPanel extends ComplexPanel implements Container, DOM.setStyleAttribute(secondContainer, "left", (pixelPosition + getSplitterSize()) + "px"); - int contentHeight = renderInformation.getRenderedSize().getHeight(); - firstRenderSpace.setHeight(contentHeight); - firstRenderSpace.setWidth(pixelPosition); - secondRenderSpace.setHeight(contentHeight); - secondRenderSpace.setWidth(secondContainerWidth); - break; case ORIENTATION_VERTICAL: wholeSize = DOM.getElementPropertyInt(wrapper, "clientHeight"); @@ -346,12 +321,6 @@ public class VAbstractSplitPanel extends ComplexPanel implements Container, DOM.setStyleAttribute(secondContainer, "top", (pixelPosition + getSplitterSize()) + "px"); - int contentWidth = renderInformation.getRenderedSize().getWidth(); - firstRenderSpace.setHeight(pixelPosition); - firstRenderSpace.setWidth(contentWidth); - secondRenderSpace.setHeight(secondContainerHeight); - secondRenderSpace.setWidth(contentWidth); - break; } @@ -489,6 +458,7 @@ public class VAbstractSplitPanel extends ComplexPanel implements Container, } setSplitPosition(newX + "px"); + client.doLayout(false); } private void onVerticalMouseMove(int y) { @@ -532,6 +502,7 @@ public class VAbstractSplitPanel extends ComplexPanel implements Container, } setSplitPosition(newY + "px"); + client.doLayout(false); } public void onMouseUp(Event event) { @@ -606,79 +577,6 @@ public class VAbstractSplitPanel extends ComplexPanel implements Container, return splitterSize; } - @Override - public void setHeight(String height) { - if (this.height.equals(height)) { - return; - } - - this.height = height; - super.setHeight(height); - - if (!rendering && client != null) { - setSplitPosition(position); - } - } - - @Override - public void setWidth(String width) { - if (this.width.equals(width)) { - return; - } - - this.width = width; - super.setWidth(width); - - if (!rendering && client != null) { - setSplitPosition(position); - } - } - - public RenderSpace getAllocatedSpace(Widget child) { - if (child == firstChild) { - return firstRenderSpace; - } else if (child == secondChild) { - return secondRenderSpace; - } - - return null; - } - - public boolean hasChildComponent(Widget component) { - return (component != null && (component == firstChild || component == secondChild)); - } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - if (oldComponent == firstChild) { - setFirstWidget(newComponent); - } else if (oldComponent == secondChild) { - setSecondWidget(newComponent); - } - } - - public boolean requestLayout(Set<Widget> children) { - // content size change might cause change to its available space - // (scrollbars) - for (Widget widget : children) { - client.handleComponentRelativeSize(widget); - } - if (height != null && width != null) { - /* - * If the height and width has been specified the child components - * cannot make the size of the layout change - */ - - return true; - } - - if (renderInformation.updateSize(getElement())) { - return false; - } else { - return true; - } - - } - /** * Updates the new split position back to server. */ diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java index ccf3119d13..7f33c0fa28 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java @@ -16,7 +16,7 @@ import com.vaadin.terminal.gwt.client.VPaintableMap; import com.vaadin.terminal.gwt.client.VPaintableWidget; public abstract class VAbstractSplitPanelPaintable extends - VAbstractPaintableWidgetContainer { + VAbstractPaintableWidgetContainer implements ResizeRequired { public static final String SPLITTER_CLICK_EVENT_IDENTIFIER = "sp_click"; @@ -68,13 +68,11 @@ public abstract class VAbstractSplitPanelPaintable extends public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { getWidgetForPaintable().client = client; getWidgetForPaintable().id = uidl.getId(); - getWidgetForPaintable().rendering = true; getWidgetForPaintable().immediate = uidl.hasAttribute("immediate"); super.updateFromUIDL(uidl, client); if (!isRealUpdate(uidl)) { - getWidgetForPaintable().rendering = false; return; } getWidgetForPaintable().setEnabled( @@ -96,8 +94,6 @@ public abstract class VAbstractSplitPanelPaintable extends getWidgetForPaintable().setStylenames(); getWidgetForPaintable().position = uidl.getStringAttribute("position"); - getWidgetForPaintable().setSplitPosition( - getWidgetForPaintable().position); final VPaintableWidget newFirstChildPaintable = client .getPaintable(uidl.getChildUIDL(0)); @@ -123,15 +119,15 @@ public abstract class VAbstractSplitPanelPaintable extends newFirstChildPaintable.updateFromUIDL(uidl.getChildUIDL(0), client); newSecondChildPaintable.updateFromUIDL(uidl.getChildUIDL(1), client); - getWidgetForPaintable().renderInformation - .updateSize(getWidgetForPaintable().getElement()); - // This is needed at least for cases like #3458 to take // appearing/disappearing scrollbars into account. client.runDescendentsLayout(getWidgetForPaintable()); + } - getWidgetForPaintable().rendering = false; - + public void onResize() { + VAbstractSplitPanel splitPanel = getWidgetForPaintable(); + splitPanel.setSplitPosition(splitPanel.position); + splitPanel.updateSizes(); } @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAccordion.java b/src/com/vaadin/terminal/gwt/client/ui/VAccordion.java index 3e4f21477b..ed1acc3849 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAccordion.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAccordion.java @@ -15,34 +15,23 @@ import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.Widget; -import com.vaadin.terminal.gwt.client.ContainerResizedListener; import com.vaadin.terminal.gwt.client.RenderInformation; -import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VCaption; import com.vaadin.terminal.gwt.client.VPaintableMap; import com.vaadin.terminal.gwt.client.VPaintableWidget; -public class VAccordion extends VTabsheetBase implements - ContainerResizedListener { +public class VAccordion extends VTabsheetBase { public static final String CLASSNAME = "v-accordion"; private Set<Widget> widgets = new HashSet<Widget>(); - private String height; - - private String width = ""; - HashMap<StackItem, UIDL> lazyUpdateMap = new HashMap<StackItem, UIDL>(); - private RenderSpace renderSpace = new RenderSpace(0, 0, true); - StackItem openTab = null; - boolean rendering = false; - int selectedUIDLItemIndex = -1; RenderInformation renderInformation = new RenderInformation(); @@ -202,58 +191,19 @@ public class VAccordion extends VTabsheetBase implements } } - @Override - public void setWidth(String width) { - if (this.width.equals(width)) { - return; - } - - Util.setWidthExcludingPaddingAndBorder(this, width, 2); - this.width = width; - if (!rendering) { - updateOpenTabSize(); - - if (isDynamicHeight()) { - Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, - openTab, this); - updateOpenTabSize(); - } - - if (isDynamicHeight()) { - openTab.setHeightFromWidget(); - } - iLayout(); - } - } - - @Override - public void setHeight(String height) { - Util.setHeightExcludingPaddingAndBorder(this, height, 2); - this.height = height; - - if (!rendering) { - updateOpenTabSize(); - } - - } - /** * Sets the size of the open tab */ - private void updateOpenTabSize() { + void updateOpenTabSize() { if (openTab == null) { - renderSpace.setHeight(0); - renderSpace.setWidth(0); return; } // WIDTH if (!isDynamicWidth()) { - int w = getOffsetWidth(); - openTab.setWidth(w); - renderSpace.setWidth(w); + openTab.setWidth("100%"); } else { - renderSpace.setWidth(0); + openTab.setWidth(null); } // HEIGHT @@ -277,10 +227,8 @@ public class VAccordion extends VTabsheetBase implements spaceForOpenItem = 0; } - renderSpace.setHeight(spaceForOpenItem); openTab.setHeight(spaceForOpenItem); } else { - renderSpace.setHeight(0); openTab.setHeightFromWidget(); } @@ -512,12 +460,16 @@ public class VAccordion extends VTabsheetBase implements clear(); } - public boolean isDynamicHeight() { - return height == null || height.equals(""); + boolean isDynamicWidth() { + VPaintableWidget paintable = VPaintableMap.get(client).getPaintable( + this); + return paintable.isUndefinedWidth(); } - public boolean isDynamicWidth() { - return width == null || width.equals(""); + boolean isDynamicHeight() { + VPaintableWidget paintable = VPaintableMap.get(client).getPaintable( + this); + return paintable.isUndefinedHeight(); } @Override @@ -526,65 +478,6 @@ public class VAccordion extends VTabsheetBase implements return widgets.iterator(); } - public boolean hasChildComponent(Widget component) { - for (Widget w : widgets) { - if (w == component) { - return true; - } - } - return false; - } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - for (Widget w : getChildren()) { - StackItem item = (StackItem) w; - if (item.getChildWidget() == oldComponent) { - item.replaceWidget(newComponent); - return; - } - } - } - - public boolean requestLayout(Set<Widget> children) { - if (!isDynamicHeight() && !isDynamicWidth()) { - /* - * If the height and width has been specified for this container the - * child components cannot make the size of the layout change - */ - // layout size change may affect its available space (scrollbars) - for (Widget widget : children) { - client.handleComponentRelativeSize(widget); - } - - return true; - } - - updateOpenTabSize(); - - if (renderInformation.updateSize(getElement())) { - /* - * Size has changed so we let the child components know about the - * new size. - */ - iLayout(); - // TODO Check if this is needed - client.runDescendentsLayout(this); - - return false; - } else { - /* - * Size has not changed so we do not need to propagate the event - * further - */ - return true; - } - - } - - public RenderSpace getAllocatedSpace(Widget child) { - return renderSpace; - } - @Override protected int getTabCount() { return getWidgetCount(); diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java index 2ed356127c..86ef5d1c96 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java @@ -12,11 +12,11 @@ import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.VPaintableWidget; import com.vaadin.terminal.gwt.client.ui.VAccordion.StackItem; -public class VAccordionPaintable extends VTabsheetBasePaintable { +public class VAccordionPaintable extends VTabsheetBasePaintable implements + ResizeRequired { @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - getWidgetForPaintable().rendering = true; getWidgetForPaintable().selectedUIDLItemIndex = -1; super.updateFromUIDL(uidl, client); /* @@ -50,8 +50,6 @@ public class VAccordionPaintable extends VTabsheetBasePaintable { getWidgetForPaintable().renderInformation .updateSize(getWidgetForPaintable().getElement()); - - getWidgetForPaintable().rendering = false; } @Override @@ -68,4 +66,16 @@ public class VAccordionPaintable extends VTabsheetBasePaintable { /* Accordion does not render its children's captions */ } + public void onResize() { + VAccordion accordion = getWidgetForPaintable(); + + accordion.updateOpenTabSize(); + + if (isUndefinedHeight()) { + accordion.openTab.setHeightFromWidget(); + } + accordion.iLayout(); + + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java index 839b84061c..bdf9718573 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java @@ -8,7 +8,6 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.Set; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.DOM; @@ -18,8 +17,6 @@ import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; -import com.vaadin.terminal.gwt.client.Container; -import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.StyleConstants; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; @@ -29,7 +26,7 @@ import com.vaadin.terminal.gwt.client.VPaintableMap; import com.vaadin.terminal.gwt.client.VPaintableWidget; import com.vaadin.terminal.gwt.client.ValueMap; -public class VCssLayout extends SimplePanel implements Container { +public class VCssLayout extends SimplePanel { public static final String TAGNAME = "csslayout"; public static final String CLASSNAME = "v-" + TAGNAME; @@ -37,10 +34,6 @@ public class VCssLayout extends SimplePanel implements Container { Element margin = DOM.createDiv(); - private boolean hasHeight; - private boolean hasWidth; - boolean rendering; - public VCssLayout() { super(); getElement().appendChild(margin); @@ -54,34 +47,6 @@ public class VCssLayout extends SimplePanel implements Container { return margin; } - @Override - public void setWidth(String width) { - super.setWidth(width); - // panel.setWidth(width); - hasWidth = width != null && !width.equals(""); - if (!rendering) { - panel.updateRelativeSizes(); - } - } - - @Override - public void setHeight(String height) { - super.setHeight(height); - // panel.setHeight(height); - hasHeight = height != null && !height.equals(""); - if (!rendering) { - panel.updateRelativeSizes(); - } - } - - public boolean hasChildComponent(Widget component) { - return panel.hasChildComponent(component); - } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - panel.replaceChildComponent(oldComponent, newComponent); - } - public class FlowPane extends FlowPanel { private final HashMap<Widget, VCaption> widgetToCaption = new HashMap<Widget, VCaption>(); @@ -93,14 +58,6 @@ public class VCssLayout extends SimplePanel implements Container { setStyleName(CLASSNAME + "-container"); } - public void updateRelativeSizes() { - for (Widget w : getChildren()) { - if (w instanceof VPaintableWidget) { - client.handleComponentRelativeSize(w); - } - } - } - public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { // for later requests @@ -187,24 +144,6 @@ public class VCssLayout extends SimplePanel implements Container { insert(child, index); } - public boolean hasChildComponent(Widget component) { - return component.getParent() == this; - } - - public void replaceChildComponent(Widget oldComponent, - Widget newComponent) { - VCaption caption = widgetToCaption.get(oldComponent); - if (caption != null) { - remove(caption); - widgetToCaption.remove(oldComponent); - } - int index = getWidgetIndex(oldComponent); - if (index >= 0) { - remove(oldComponent); - insert(newComponent, index); - } - } - public void updateCaption(VPaintableWidget paintable, UIDL uidl) { Widget widget = paintable.getWidgetForPaintable(); VCaption caption = widgetToCaption.get(widget); @@ -232,50 +171,6 @@ public class VCssLayout extends SimplePanel implements Container { } - private RenderSpace space; - - public RenderSpace getAllocatedSpace(Widget child) { - if (space == null) { - space = new RenderSpace(-1, -1) { - @Override - public int getWidth() { - if (BrowserInfo.get().isIE()) { - int width = getOffsetWidth(); - int margins = margin.getOffsetWidth() - - panel.getOffsetWidth(); - return width - margins; - } else { - return panel.getOffsetWidth(); - } - } - - @Override - public int getHeight() { - int height = getOffsetHeight(); - int margins = margin.getOffsetHeight() - - panel.getOffsetHeight(); - return height - margins; - } - }; - } - return space; - } - - public boolean requestLayout(Set<Widget> children) { - if (hasSize()) { - return true; - } else { - // Size may have changed - // TODO optimize this: cache size if not fixed, handle both width - // and height separately - return false; - } - } - - private boolean hasSize() { - return hasWidth && hasHeight; - } - private static final String makeCamelCase(String cssProperty) { // TODO this might be cleaner to implement with regexp while (cssProperty.contains("-")) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java index 016474973f..a3795600bc 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java @@ -33,11 +33,9 @@ public class VCssLayoutPaintable extends VAbstractPaintableWidgetContainer { @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - getWidgetForPaintable().rendering = true; super.updateFromUIDL(uidl, client); if (!isRealUpdate(uidl)) { - getWidgetForPaintable().rendering = false; return; } clickEventHandler.handleEventHandlerRegistration(client); @@ -46,7 +44,6 @@ public class VCssLayoutPaintable extends VAbstractPaintableWidgetContainer { new VMarginInfo(uidl.getIntAttribute("margins")), uidl.hasAttribute("spacing")); getWidgetForPaintable().panel.updateFromUIDL(uidl, client); - getWidgetForPaintable().rendering = false; } @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java index d8181cf00c..f552870a53 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java @@ -4,111 +4,15 @@ package com.vaadin.terminal.gwt.client.ui; -import java.util.Set; - import com.google.gwt.user.client.ui.SimplePanel; -import com.google.gwt.user.client.ui.Widget; -import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.client.Container; -import com.vaadin.terminal.gwt.client.RenderSpace; -import com.vaadin.terminal.gwt.client.Util; -public class VCustomComponent extends SimplePanel implements Container { +public class VCustomComponent extends SimplePanel { private static final String CLASSNAME = "v-customcomponent"; - private String height; - ApplicationConnection client; - boolean rendering; - private String width; - RenderSpace renderSpace = new RenderSpace(); public VCustomComponent() { super(); setStyleName(CLASSNAME); } - boolean updateDynamicSize() { - boolean updated = false; - if (isDynamicWidth()) { - int childWidth = Util.getRequiredWidth(getWidget()); - getElement().getStyle().setPropertyPx("width", childWidth); - updated = true; - } - if (isDynamicHeight()) { - int childHeight = Util.getRequiredHeight(getWidget()); - getElement().getStyle().setPropertyPx("height", childHeight); - updated = true; - } - - return updated; - } - - protected boolean isDynamicWidth() { - return width == null || width.equals(""); - } - - protected boolean isDynamicHeight() { - return height == null || height.equals(""); - } - - public boolean hasChildComponent(Widget component) { - if (getWidget() == component) { - return true; - } else { - return false; - } - } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - if (hasChildComponent(oldComponent)) { - clear(); - setWidget(newComponent); - } else { - throw new IllegalStateException(); - } - } - - public boolean requestLayout(Set<Widget> children) { - // If a child grows in size, it will not necessarily be calculated - // correctly unless we remove previous size definitions - if (isDynamicWidth()) { - getElement().getStyle().setProperty("width", ""); - } - if (isDynamicHeight()) { - getElement().getStyle().setProperty("height", ""); - } - - return !updateDynamicSize(); - } - - public RenderSpace getAllocatedSpace(Widget child) { - return renderSpace; - } - - @Override - public void setHeight(String height) { - super.setHeight(height); - renderSpace.setHeight(getElement().getOffsetHeight()); - - if (!height.equals(this.height)) { - this.height = height; - if (!rendering) { - client.handleComponentRelativeSize(getWidget()); - } - } - } - - @Override - public void setWidth(String width) { - super.setWidth(width); - renderSpace.setWidth(getElement().getOffsetWidth()); - - if (!width.equals(this.width)) { - this.width = width; - if (!rendering) { - client.handleComponentRelativeSize(getWidget()); - } - } - } - } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java index 25289c6adb..78a68609ea 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java @@ -4,8 +4,6 @@ package com.vaadin.terminal.gwt.client.ui; import com.google.gwt.core.client.GWT; -import com.google.gwt.core.client.Scheduler; -import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.UIDL; @@ -17,14 +15,10 @@ public class VCustomComponentPaintable extends @Override public void updateFromUIDL(UIDL uidl, final ApplicationConnection client) { - getWidgetForPaintable().rendering = true; super.updateFromUIDL(uidl, client); if (!isRealUpdate(uidl)) { - getWidgetForPaintable().rendering = false; return; } - getWidgetForPaintable().client = client; - final UIDL child = uidl.getChildUIDL(0); if (child != null) { final VPaintableWidget paintable = client.getPaintable(child); @@ -39,32 +33,6 @@ public class VCustomComponentPaintable extends } paintable.updateFromUIDL(child, client); } - - boolean updateDynamicSize = getWidgetForPaintable().updateDynamicSize(); - if (updateDynamicSize) { - Scheduler.get().scheduleDeferred(new Command() { - public void execute() { - // FIXME deferred relative size update needed to fix some - // scrollbar issues in sampler. This must be the wrong way - // to do it. Might be that some other component is broken. - client.handleComponentRelativeSize(getWidgetForPaintable()); - - } - }); - } - - getWidgetForPaintable().renderSpace.setWidth(getWidgetForPaintable() - .getElement().getOffsetWidth()); - getWidgetForPaintable().renderSpace.setHeight(getWidgetForPaintable() - .getElement().getOffsetHeight()); - - /* - * Needed to update client size if the size of this component has - * changed and the child uses relative size(s). - */ - client.runDescendentsLayout(getWidgetForPaintable()); - - getWidgetForPaintable().rendering = false; } @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java index 4aa838b660..6b1802e027 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java @@ -5,9 +5,7 @@ package com.vaadin.terminal.gwt.client.ui; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; -import java.util.Set; import com.google.gwt.dom.client.ImageElement; import com.google.gwt.dom.client.NodeList; @@ -18,10 +16,6 @@ import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; -import com.vaadin.terminal.gwt.client.Container; -import com.vaadin.terminal.gwt.client.ContainerResizedListener; -import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize; -import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VCaption; @@ -35,8 +29,7 @@ import com.vaadin.terminal.gwt.client.VPaintableWidget; * @author Vaadin Ltd * */ -public class VCustomLayout extends ComplexPanel implements Container, - ContainerResizedListener { +public class VCustomLayout extends ComplexPanel { public static final String CLASSNAME = "v-customlayout"; @@ -69,8 +62,6 @@ public class VCustomLayout extends ComplexPanel implements Container, private String width = ""; - private HashMap<String, FloatSize> locationToExtraSize = new HashMap<String, FloatSize>(); - public VCustomLayout() { setElement(DOM.createDiv()); // Clear any unwanted styling @@ -221,12 +212,6 @@ public class VCustomLayout extends ComplexPanel implements Container, if (!"".equals(location)) { locationToElement.put(location, elem); elem.setInnerHTML(""); - int x = Util.measureHorizontalPaddingAndBorder(elem, 0); - int y = Util.measureVerticalPaddingAndBorder(elem, 0); - - FloatSize fs = new FloatSize(x, y); - - locationToExtraSize.put(location, fs); } else { final int len = DOM.getChildCount(elem); @@ -314,20 +299,6 @@ public class VCustomLayout extends ComplexPanel implements Container, return res; } - /** Replace child components */ - public void replaceChildComponent(Widget from, Widget to) { - final String location = getLocation(from); - if (location == null) { - throw new IllegalArgumentException(); - } - setWidget(to, location); - } - - /** Does this layout contain given child */ - public boolean hasChildComponent(Widget component) { - return locationToWidget.containsValue(component); - } - /** Update caption for given widget */ public void updateCaption(VPaintableWidget paintable, UIDL uidl) { VCaptionWrapper wrapper = paintableToCaptionWrapper.get(paintable); @@ -398,10 +369,6 @@ public class VCustomLayout extends ComplexPanel implements Container, paintableToCaptionWrapper.clear(); } - public void iLayout() { - iLayoutJS(DOM.getFirstChild(getElement())); - } - /** * This method is published to JS side with the same name into first DOM * node of custom layout. This way if one implements some resizeable @@ -447,7 +414,7 @@ public class VCustomLayout extends ComplexPanel implements Container, * @return true if layout function exists and was run successfully, else * false. */ - private native boolean iLayoutJS(Element el) + native boolean iLayoutJS(Element el) /*-{ if(el && el.iLayoutJS) { try { @@ -461,27 +428,6 @@ public class VCustomLayout extends ComplexPanel implements Container, } }-*/; - public boolean requestLayout(Set<Widget> children) { - updateRelativeSizedComponents(true, true); - - if (width.equals("") || height.equals("")) { - /* Automatically propagated upwards if the size can change */ - return false; - } - - return true; - } - - public RenderSpace getAllocatedSpace(Widget child) { - com.google.gwt.dom.client.Element pe = child.getElement() - .getParentElement(); - - FloatSize extra = locationToExtraSize.get(getLocation(child)); - return new RenderSpace(pe.getOffsetWidth() - (int) extra.getWidth(), - pe.getOffsetHeight() - (int) extra.getHeight(), - Util.mayHaveScrollBars(pe)); - } - @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); @@ -491,103 +437,4 @@ public class VCustomLayout extends ComplexPanel implements Container, } } - @Override - public void setHeight(String height) { - if (this.height.equals(height)) { - return; - } - - boolean shrinking = true; - if (isLarger(height, this.height)) { - shrinking = false; - } - - this.height = height; - super.setHeight(height); - - /* - * If the height shrinks we must remove all components with relative - * height from the DOM, update their height when they do not affect the - * available space and finally restore them to the original state - */ - if (shrinking) { - updateRelativeSizedComponents(false, true); - } - } - - @Override - public void setWidth(String width) { - if (this.width.equals(width)) { - return; - } - - boolean shrinking = true; - if (isLarger(width, this.width)) { - shrinking = false; - } - - super.setWidth(width); - this.width = width; - - /* - * If the width shrinks we must remove all components with relative - * width from the DOM, update their width when they do not affect the - * available space and finally restore them to the original state - */ - if (shrinking) { - updateRelativeSizedComponents(true, false); - } - } - - private void updateRelativeSizedComponents(boolean relativeWidth, - boolean relativeHeight) { - - Set<Widget> relativeSizeWidgets = new HashSet<Widget>(); - - for (Widget widget : locationToWidget.values()) { - FloatSize relativeSize = client.getRelativeSize(widget); - if (relativeSize != null) { - if ((relativeWidth && (relativeSize.getWidth() >= 0.0f)) - || (relativeHeight && (relativeSize.getHeight() >= 0.0f))) { - - relativeSizeWidgets.add(widget); - widget.getElement().getStyle() - .setProperty("position", "absolute"); - } - } - } - - for (Widget widget : relativeSizeWidgets) { - client.handleComponentRelativeSize(widget); - widget.getElement().getStyle().setProperty("position", ""); - } - } - - /** - * Compares newSize with currentSize and returns true if it is clear that - * newSize is larger than currentSize. Returns false if newSize is smaller - * or if it is unclear which one is smaller. - * - * @param newSize - * @param currentSize - * @return - */ - private boolean isLarger(String newSize, String currentSize) { - if (newSize.equals("") || currentSize.equals("")) { - return false; - } - - if (!newSize.endsWith("px") || !currentSize.endsWith("px")) { - return false; - } - - int newSizePx = Integer.parseInt(newSize.substring(0, - newSize.length() - 2)); - int currentSizePx = Integer.parseInt(currentSize.substring(0, - currentSize.length() - 2)); - - boolean larger = newSizePx > currentSizePx; - return larger; - } - } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java index ea3f3c0bc0..f914d157d3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java @@ -8,12 +8,14 @@ import java.util.Iterator; import java.util.Set; import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.VPaintableWidget; -public class VCustomLayoutPaintable extends VAbstractPaintableWidgetContainer { +public class VCustomLayoutPaintable extends VAbstractPaintableWidgetContainer + implements ResizeRequired { /** Update the layout from UIDL */ @Override @@ -35,7 +37,6 @@ public class VCustomLayoutPaintable extends VAbstractPaintableWidgetContainer { VCustomLayout.eval(getWidgetForPaintable().scripts); getWidgetForPaintable().scripts = null; - getWidgetForPaintable().iLayout(); // TODO Check if this is needed client.runDescendentsLayout(getWidgetForPaintable()); @@ -69,7 +70,6 @@ public class VCustomLayoutPaintable extends VAbstractPaintableWidgetContainer { } } - getWidgetForPaintable().iLayout(); // TODO Check if this is needed client.runDescendentsLayout(getWidgetForPaintable()); @@ -89,4 +89,9 @@ public class VCustomLayoutPaintable extends VAbstractPaintableWidgetContainer { getWidgetForPaintable().updateCaption(paintable, uidl); } + + public void onResize() { + getWidgetForPaintable().iLayoutJS( + DOM.getFirstChild(getWidgetForPaintable().getElement())); + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java index 0297e8df3f..1b4dab5a33 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java @@ -563,11 +563,6 @@ public class VDragAndDropWrapper extends VCustomComponent implements } protected void deEmphasis(boolean doLayout) { - Size size = null; - if (doLayout) { - size = new RenderInformation.Size(getOffsetWidth(), - getOffsetHeight()); - } if (emphasizedVDrop != null) { VDragAndDropWrapper.setStyleName(getElement(), OVER_STYLE, false); VDragAndDropWrapper.setStyleName(getElement(), OVER_STYLE + "-" @@ -576,7 +571,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements + emphasizedHDrop.toString().toLowerCase(), false); } if (doLayout) { - handleVaadinRelatedSizeChange(size); + client.doLayout(false); } } @@ -594,20 +589,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements // TODO build (to be an example) an emphasis mode where drag image // is fitted before or after the content - handleVaadinRelatedSizeChange(size); - - } - - protected void handleVaadinRelatedSizeChange(Size originalSize) { - if (isDynamicHeight() || isDynamicWidth()) { - if (!originalSize.equals(new RenderInformation.Size( - getOffsetWidth(), getOffsetHeight()))) { - Util.notifyParentOfSizeChange(VDragAndDropWrapper.this, false); - } - } - client.handleComponentRelativeSize(VDragAndDropWrapper.this); - Util.notifyParentOfSizeChange(this, false); - + client.doLayout(false); } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VForm.java b/src/com/vaadin/terminal/gwt/client/ui/VForm.java index f3276db008..be205d2a88 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VForm.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VForm.java @@ -4,8 +4,6 @@ package com.vaadin.terminal.gwt.client.ui; -import java.util.Set; - import com.google.gwt.dom.client.Style.Display; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; @@ -16,21 +14,12 @@ import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.client.Container; -import com.vaadin.terminal.gwt.client.RenderInformation; -import com.vaadin.terminal.gwt.client.RenderSpace; -import com.vaadin.terminal.gwt.client.Util; -import com.vaadin.terminal.gwt.client.VConsole; import com.vaadin.terminal.gwt.client.VErrorMessage; -public class VForm extends ComplexPanel implements Container, KeyDownHandler { +public class VForm extends ComplexPanel implements KeyDownHandler { protected String id; - private String height = ""; - - private String width = ""; - public static final String CLASSNAME = "v-form"; Widget lo; @@ -51,12 +40,6 @@ public class VForm extends ComplexPanel implements Container, KeyDownHandler { ApplicationConnection client; - private RenderInformation renderInformation = new RenderInformation(); - - private int borderPaddingHorizontal = -1; - - boolean rendering = false; - ShortcutActionHandler shortcutHandler; HandlerRegistration keyDownRegistration; @@ -74,6 +57,7 @@ public class VForm extends ComplexPanel implements Container, KeyDownHandler { fieldSet.appendChild(desc); // Adding description for initial padding // measurements, removed later if no // description is set + fieldContainer.setClassName(CLASSNAME + "-content"); fieldSet.appendChild(fieldContainer); errorMessage.setVisible(false); errorMessage.setStyleName(CLASSNAME + "-errormessage"); @@ -81,116 +65,6 @@ public class VForm extends ComplexPanel implements Container, KeyDownHandler { fieldSet.appendChild(footerContainer); } - public void updateSize() { - - renderInformation.updateSize(getElement()); - - renderInformation.setContentAreaHeight(renderInformation - .getRenderedSize().getHeight() - getSpaceConsumedVertically()); - renderInformation.setContentAreaWidth(renderInformation - .getRenderedSize().getWidth() - borderPaddingHorizontal); - } - - public RenderSpace getAllocatedSpace(Widget child) { - if (child == lo) { - return renderInformation.getContentAreaSize(); - } else if (child == footer) { - return new RenderSpace(renderInformation.getContentAreaSize() - .getWidth(), 0); - } else { - VConsole.error("Invalid child requested RenderSpace information"); - return null; - } - } - - public boolean hasChildComponent(Widget component) { - return component != null && (component == lo || component == footer); - } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - if (!hasChildComponent(oldComponent)) { - throw new IllegalArgumentException( - "Old component is not inside this Container"); - } - remove(oldComponent); - if (oldComponent == lo) { - lo = newComponent; - add(newComponent, fieldContainer); - } else { - footer = newComponent; - add(newComponent, footerContainer); - } - - } - - public boolean requestLayout(Set<Widget> child) { - - if (height != null && !"".equals(height) && width != null - && !"".equals(width)) { - /* - * If the height and width has been specified the child components - * cannot make the size of the layout change - */ - - return true; - } - - if (renderInformation.updateSize(getElement())) { - return false; - } else { - return true; - } - - } - - @Override - public void setHeight(String height) { - if (this.height.equals(height)) { - return; - } - - this.height = height; - super.setHeight(height); - - updateSize(); - } - - /** - * @return pixels consumed by decoration, captions, descrioptiosn etc.. In - * other words space, not used by the actual layout in form. - */ - private int getSpaceConsumedVertically() { - int offsetHeight2 = fieldSet.getOffsetHeight(); - int offsetHeight3 = fieldContainer.getOffsetHeight(); - int borderPadding = offsetHeight2 - offsetHeight3; - return borderPadding; - } - - @Override - public void setWidth(String width) { - if (borderPaddingHorizontal < 0) { - // measure excess size lazily after stylename setting, but before - // setting width - int ow = getOffsetWidth(); - int dow = desc.getOffsetWidth(); - borderPaddingHorizontal = ow - dow; - } - if (Util.equals(this.width, width)) { - return; - } - - this.width = width; - super.setWidth(width); - - updateSize(); - - if (!rendering && height.equals("")) { - // Width might affect height - Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this, - this); - } - } - public void onKeyDown(KeyDownEvent event) { shortcutHandler.handleKeyboardEvent(Event.as(event.getNativeEvent())); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java index 6d3072f407..be8f5736af 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java @@ -8,7 +8,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Set; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; @@ -21,12 +20,9 @@ import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; -import com.vaadin.terminal.gwt.client.Container; import com.vaadin.terminal.gwt.client.Focusable; -import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.StyleConstants; import com.vaadin.terminal.gwt.client.UIDL; -import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VPaintableMap; import com.vaadin.terminal.gwt.client.VPaintableWidget; import com.vaadin.terminal.gwt.client.VTooltip; @@ -34,18 +30,13 @@ import com.vaadin.terminal.gwt.client.VTooltip; /** * Two col Layout that places caption on left col and field on right col */ -public class VFormLayout extends SimplePanel implements Container { +public class VFormLayout extends SimplePanel { private final static String CLASSNAME = "v-formlayout"; ApplicationConnection client; VFormLayoutTable table; - private String width = ""; - private String height = ""; - - boolean rendering = false; - public VFormLayout() { super(); setStyleName(CLASSNAME); @@ -143,14 +134,19 @@ public class VFormLayout extends SimplePanel implements Container { CLASSNAME + "-captioncell"); setWidget(i, COLUMN_CAPTION, caption); - setContentWidth(i); - getCellFormatter().setStyleName(i, COLUMN_ERRORFLAG, CLASSNAME + "-errorcell"); setWidget(i, COLUMN_ERRORFLAG, error); childPaintable.updateFromUIDL(childUidl, client); + // Update cell width when isRelativeWidth has been udpated + if (childPaintable.isRelativeWidth()) { + getCellFormatter().setWidth(i, COLUMN_WIDGET, "100%"); + } else { + getCellFormatter().setWidth(i, COLUMN_WIDGET, null); + } + String rowstyles = CLASSNAME + "-row"; if (i == 0) { rowstyles += " " + CLASSNAME + "-firstrow"; @@ -181,55 +177,6 @@ public class VFormLayout extends SimplePanel implements Container { } } - public void setContentWidths() { - for (int row = 0; row < getRowCount(); row++) { - setContentWidth(row); - } - } - - private void setContentWidth(int row) { - String width = ""; - if (!isDynamicWidth()) { - width = "100%"; - } - getCellFormatter().setWidth(row, COLUMN_WIDGET, width); - } - - public void replaceChildComponent(Widget oldComponent, - Widget newComponent) { - int i; - for (i = 0; i < getRowCount(); i++) { - Widget candidate = getWidget(i, COLUMN_WIDGET); - if (oldComponent == candidate) { - VPaintableMap paintableMap = VPaintableMap.get(client); - VPaintableWidget oldPaintable = paintableMap - .getPaintable(oldComponent); - VPaintableWidget newPaintable = paintableMap - .getPaintable(newComponent); - Caption oldCap = widgetToCaption.get(oldComponent); - final Caption newCap = new Caption(newPaintable, client); - newCap.addClickHandler(this); - newCap.setStyleName(oldCap.getStyleName()); - widgetToCaption.put(newComponent, newCap); - ErrorFlag error = widgetToError.get(newComponent); - if (error == null) { - error = new ErrorFlag(); - widgetToError.put(newComponent, error); - } - - setWidget(i, COLUMN_CAPTION, newCap); - setWidget(i, COLUMN_ERRORFLAG, error); - setWidget(i, COLUMN_WIDGET, newComponent); - break; - } - } - - } - - public boolean hasChildComponent(Widget component) { - return widgetToCaption.containsKey(component); - } - public void updateCaption(VPaintableWidget paintable, UIDL uidl) { final Caption c = widgetToCaption.get(paintable .getWidgetForPaintable()); @@ -244,21 +191,6 @@ public class VFormLayout extends SimplePanel implements Container { } - public int getAllocatedWidth(Widget child, int availableWidth) { - Caption caption = widgetToCaption.get(child); - ErrorFlag error = widgetToError.get(child); - int width = availableWidth; - - if (caption != null) { - width -= DOM.getParent(caption.getElement()).getOffsetWidth(); - } - if (error != null) { - width -= DOM.getParent(error.getElement()).getOffsetWidth(); - } - - return width; - } - /* * (non-Javadoc) * @@ -279,18 +211,6 @@ public class VFormLayout extends SimplePanel implements Container { } } - public boolean isDynamicWidth() { - return width.equals(""); - } - - public boolean hasChildComponent(Widget component) { - return table.hasChildComponent(component); - } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - table.replaceChildComponent(oldComponent, newComponent); - } - public class Caption extends HTML { public static final String CLASSNAME = "v-caption"; @@ -475,55 +395,4 @@ public class VFormLayout extends SimplePanel implements Container { } } - - public boolean requestLayout(Set<Widget> children) { - if (height.equals("") || width.equals("")) { - // A dynamic size might change due to children changes - return false; - } - - return true; - } - - public RenderSpace getAllocatedSpace(Widget child) { - int width = 0; - int height = 0; - - if (!this.width.equals("")) { - int availableWidth = getOffsetWidth(); - width = table.getAllocatedWidth(child, availableWidth); - } - - return new RenderSpace(width, height, false); - } - - @Override - public void setHeight(String height) { - if (this.height.equals(height)) { - return; - } - - this.height = height; - super.setHeight(height); - } - - @Override - public void setWidth(String width) { - if (this.width.equals(width)) { - return; - } - - this.width = width; - super.setWidth(width); - - if (!rendering) { - table.setContentWidths(); - if (height.equals("")) { - // Width might affect height - Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this, - this); - } - } - } - } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java index 8769466ce4..8e30bdb997 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java @@ -12,19 +12,14 @@ import com.vaadin.terminal.gwt.client.VPaintableWidget; public class VFormLayoutPaintable extends VAbstractPaintableWidgetContainer { @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - getWidgetForPaintable().rendering = true; - getWidgetForPaintable().client = client; super.updateFromUIDL(uidl, client); if (!isRealUpdate(uidl)) { - getWidgetForPaintable().rendering = false; return; } getWidgetForPaintable().table.updateFromUIDL(uidl, client); - - getWidgetForPaintable().rendering = false; } public void updateCaption(VPaintableWidget component, UIDL uidl) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java index a15a5b7837..a350983e6c 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java @@ -4,14 +4,23 @@ package com.vaadin.terminal.gwt.client.ui; import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.MeasuredSize; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.VPaintableMap; import com.vaadin.terminal.gwt.client.VPaintableWidget; -public class VFormPaintable extends VAbstractPaintableWidgetContainer { +public class VFormPaintable extends VAbstractPaintableWidgetContainer implements + ResizeRequired { + + public VFormPaintable() { + VForm form = getWidgetForPaintable(); + MeasuredSize measuredSize = getMeasuredSize(); + measuredSize.registerDependency(form.footerContainer); + } @Override protected boolean delegateCaptionHandling() { @@ -20,13 +29,11 @@ public class VFormPaintable extends VAbstractPaintableWidgetContainer { @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - getWidgetForPaintable().rendering = true; getWidgetForPaintable().client = client; getWidgetForPaintable().id = uidl.getId(); super.updateFromUIDL(uidl, client); if (!isRealUpdate(uidl)) { - getWidgetForPaintable().rendering = false; return; } @@ -83,8 +90,6 @@ public class VFormPaintable extends VAbstractPaintableWidgetContainer { } } - getWidgetForPaintable().updateSize(); - // first render footer so it will be easier to handle relative height of // main layout if (uidl.getChildCount() > 1 @@ -106,15 +111,11 @@ public class VFormPaintable extends VAbstractPaintableWidgetContainer { } getWidgetForPaintable().footer = newFooterWidget; newFooter.updateFromUIDL(uidl.getChildUIDL(1), client); - // needed for the main layout to know the space it has available - getWidgetForPaintable().updateSize(); } else { if (getWidgetForPaintable().footer != null) { getWidgetForPaintable().remove(getWidgetForPaintable().footer); client.unregisterPaintable(VPaintableMap.get(getConnection()) .getPaintable(getWidgetForPaintable().footer)); - // needed for the main layout to know the space it has available - getWidgetForPaintable().updateSize(); } } @@ -139,7 +140,6 @@ public class VFormPaintable extends VAbstractPaintableWidgetContainer { // also recalculates size of the footer if undefined size form - see // #3710 - getWidgetForPaintable().updateSize(); client.runDescendentsLayout(getWidgetForPaintable()); // We may have actions attached @@ -161,8 +161,6 @@ public class VFormPaintable extends VAbstractPaintableWidgetContainer { getWidgetForPaintable().shortcutHandler = null; getWidgetForPaintable().keyDownRegistration = null; } - - getWidgetForPaintable().rendering = false; } public void updateCaption(VPaintableWidget component, UIDL uidl) { @@ -180,4 +178,14 @@ public class VFormPaintable extends VAbstractPaintableWidgetContainer { return GWT.create(VForm.class); } + public void onResize() { + MeasuredSize measuredSize = getMeasuredSize(); + VForm form = getWidgetForPaintable(); + + int footerHeight = measuredSize + .getDependencyOuterHeight(form.footerContainer); + form.fieldContainer.getStyle().setPaddingBottom(footerHeight, Unit.PX); + form.footerContainer.getStyle().setMarginTop(-footerHeight, Unit.PX); + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java index 5302fa6f67..6285121901 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java @@ -19,17 +19,14 @@ import com.google.gwt.user.client.ui.AbsolutePanel; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.client.Container; import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.StyleConstants; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; -import com.vaadin.terminal.gwt.client.VPaintableMap; import com.vaadin.terminal.gwt.client.VPaintableWidget; -import com.vaadin.terminal.gwt.client.ui.layout.CellBasedLayout; import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer; -public class VGridLayout extends SimplePanel implements Container { +public class VGridLayout extends SimplePanel { public static final String CLASSNAME = "v-gridlayout"; @@ -49,9 +46,13 @@ public class VGridLayout extends SimplePanel implements Container { int[] columnWidths; int[] rowHeights; - private String height; + private int height; - private String width; + private int width; + + private boolean undefinedWidth; + + private boolean undefinedHeight; int[] colExpandRatioArray; @@ -124,7 +125,7 @@ public class VGridLayout extends SimplePanel implements Container { } void expandRows() { - if (!"".equals(height)) { + if (!isUndefinedHeight()) { int usedSpace = minRowHeights[0]; for (int i = 1; i < minRowHeights.length; i++) { usedSpace += spacingPixelsVertical + minRowHeights[i]; @@ -149,10 +150,9 @@ public class VGridLayout extends SimplePanel implements Container { } } - @Override - public void setHeight(String height) { - super.setHeight(height); - if (!height.equals(this.height)) { + void updateHeight(int height, boolean undefinedHeight) { + if (height != this.height || this.undefinedHeight != undefinedHeight) { + this.undefinedHeight = undefinedHeight; this.height = height; if (rendering) { sizeChangedDuringRendering = true; @@ -166,10 +166,9 @@ public class VGridLayout extends SimplePanel implements Container { } } - @Override - public void setWidth(String width) { - super.setWidth(width); - if (!width.equals(this.width)) { + void updateWidth(int width, boolean undefinedWidth) { + if (width != this.width || undefinedWidth != this.undefinedWidth) { + this.undefinedWidth = undefinedWidth; this.width = width; if (rendering) { sizeChangedDuringRendering = true; @@ -255,7 +254,7 @@ public class VGridLayout extends SimplePanel implements Container { for (Widget w : widgetToCell.keySet()) { client.handleComponentRelativeSize(w); } - if (heightChanged && "".equals(height)) { + if (heightChanged && isUndefinedHeight()) { Util.notifyParentOfSizeChange(this, false); } } @@ -263,7 +262,7 @@ public class VGridLayout extends SimplePanel implements Container { } void expandColumns() { - if (!"".equals(width)) { + if (!isUndefinedWidth()) { int usedSpace = minColumnWidths[0]; for (int i = 1; i < minColumnWidths.length; i++) { usedSpace += spacingPixelsHorizontal + minColumnWidths[i]; @@ -324,11 +323,11 @@ public class VGridLayout extends SimplePanel implements Container { } private boolean isUndefinedHeight() { - return "".equals(height); + return undefinedHeight; } private boolean isUndefinedWidth() { - return "".equals(width); + return undefinedWidth; } void renderRemainingComponents(LinkedList<Cell> pendingCells) { @@ -562,31 +561,13 @@ public class VGridLayout extends SimplePanel implements Container { - canvas.getOffsetHeight(); } - public boolean hasChildComponent(Widget component) { - return widgetToCell.containsKey(component); - } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - ChildComponentContainer componentContainer = widgetToComponentContainer - .remove(oldComponent); - if (componentContainer == null) { - return; - } - - componentContainer.setPaintable(VPaintableMap.get(client).getPaintable( - newComponent)); - widgetToComponentContainer.put(newComponent, componentContainer); - - widgetToCell.put(newComponent, widgetToCell.get(oldComponent)); - } - public boolean requestLayout(final Set<Widget> changedChildren) { boolean needsLayout = false; boolean reDistributeColSpanWidths = false; boolean reDistributeRowSpanHeights = false; int offsetHeight = canvas.getOffsetHeight(); int offsetWidth = canvas.getOffsetWidth(); - if ("".equals(width) || "".equals(height)) { + if (isUndefinedWidth() || isUndefinedHeight()) { needsLayout = true; } ArrayList<Integer> dirtyColumns = new ArrayList<Integer>(); @@ -733,12 +714,6 @@ public class VGridLayout extends SimplePanel implements Container { } } - public RenderSpace getAllocatedSpace(Widget child) { - Cell cell = widgetToCell.get(child); - assert cell != null; - return cell.getAllocatedSpace(); - } - Cell[][] cells; /** @@ -860,7 +835,7 @@ public class VGridLayout extends SimplePanel implements Container { } else { // A new component cc = new ChildComponentContainer(paintable, - CellBasedLayout.ORIENTATION_VERTICAL); + ChildComponentContainer.ORIENTATION_VERTICAL); widgetToComponentContainer.put(w, cc); cc.setWidth(""); canvas.add(cc, 0, 0); diff --git a/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java index c7e9f79d9a..a753a40377 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java @@ -3,7 +3,9 @@ */ package com.vaadin.terminal.gwt.client.ui; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; @@ -14,6 +16,7 @@ import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.CalculatingLayout; import com.vaadin.terminal.gwt.client.EventId; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.VPaintableMap; @@ -21,7 +24,8 @@ import com.vaadin.terminal.gwt.client.VPaintableWidget; import com.vaadin.terminal.gwt.client.ui.VGridLayout.Cell; import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer; -public class VGridLayoutPaintable extends VAbstractPaintableWidgetContainer { +public class VGridLayoutPaintable extends VAbstractPaintableWidgetContainer + implements CalculatingLayout { private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler( this, EventId.LAYOUT_CLICK) { @@ -38,7 +42,6 @@ public class VGridLayoutPaintable extends VAbstractPaintableWidgetContainer { }; @Override - @SuppressWarnings("unchecked") public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { getWidgetForPaintable().rendering = true; getWidgetForPaintable().client = client; @@ -195,4 +198,25 @@ public class VGridLayoutPaintable extends VAbstractPaintableWidgetContainer { return GWT.create(VGridLayout.class); } + public void updateVerticalSizes() { + int innerHeight = getMeasuredSize().getInnerHeight(); + getWidgetForPaintable().updateHeight(innerHeight, isUndefinedHeight()); + layoutAllChildren(); + } + + private void layoutAllChildren() { + HashSet<Widget> childWidgets = new HashSet<Widget>(); + Collection<VPaintableWidget> children = getChildren(); + for (VPaintableWidget vPaintableWidget : children) { + childWidgets.add(vPaintableWidget.getWidgetForPaintable()); + } + getWidgetForPaintable().requestLayout(childWidgets); + } + + public void updateHorizontalSizes() { + int innerWidth = getMeasuredSize().getInnerWidth(); + getWidgetForPaintable().updateWidth(innerWidth, isUndefinedWidth()); + + layoutAllChildren(); + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayout.java index b3a036f748..30796b1660 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayout.java @@ -3,12 +3,12 @@ */ package com.vaadin.terminal.gwt.client.ui; -public class VHorizontalLayout extends VOrderedLayout { +public class VHorizontalLayout extends VMeasuringOrderedLayout { public static final String CLASSNAME = "v-horizontallayout"; public VHorizontalLayout() { - super(CLASSNAME, ORIENTATION_HORIZONTAL); + super(CLASSNAME, false); } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java index acc49ece18..2fee82e974 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java @@ -5,7 +5,8 @@ package com.vaadin.terminal.gwt.client.ui; import com.google.gwt.core.client.GWT; -public class VHorizontalLayoutPaintable extends VOrderedLayoutPaintable { +public class VHorizontalLayoutPaintable extends + VMeasuringOrderedLayoutPaintable { @Override public VHorizontalLayout getWidgetForPaintable() { diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayout.java new file mode 100644 index 0000000000..dd3cb41a13 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayout.java @@ -0,0 +1,190 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui; + +import com.google.gwt.dom.client.DivElement; +import com.google.gwt.dom.client.Document; +import com.google.gwt.dom.client.Style; +import com.google.gwt.dom.client.Style.Position; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.ComplexPanel; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.terminal.gwt.client.VCaption; +import com.vaadin.terminal.gwt.client.ui.layout.VLayoutSlot; + +public class VMeasuringOrderedLayout extends ComplexPanel { + + final boolean isVertical; + + final DivElement spacingMeasureElement; + + protected VMeasuringOrderedLayout(String className, boolean isVertical) { + DivElement element = Document.get().createDivElement(); + setElement(element); + + spacingMeasureElement = Document.get().createDivElement(); + Style spacingStyle = spacingMeasureElement.getStyle(); + spacingStyle.setPosition(Position.ABSOLUTE); + getElement().appendChild(spacingMeasureElement); + + setStyleName(className); + this.isVertical = isVertical; + } + + public void addSlot(VLayoutSlot layoutSlot) { + Widget widget = layoutSlot.getWidget(); + Element wrapperElement = layoutSlot.getWrapperElement(); + + getElement().appendChild(wrapperElement); + add(widget, wrapperElement); + + widget.setLayoutData(layoutSlot); + } + + private void togglePrefixedStyleName(String name, boolean enabled) { + if (enabled) { + addStyleDependentName(name); + } else { + removeStyleDependentName(name); + } + } + + void updateMarginStyleNames(VMarginInfo marginInfo) { + togglePrefixedStyleName("margin-top", marginInfo.hasTop()); + togglePrefixedStyleName("margin-right", marginInfo.hasRight()); + togglePrefixedStyleName("margin-bottom", marginInfo.hasBottom()); + togglePrefixedStyleName("margin-left", marginInfo.hasLeft()); + } + + void updateSpacingStyleName(boolean spacingEnabled) { + String styleName = getStylePrimaryName(); + if (spacingEnabled) { + spacingMeasureElement.addClassName(styleName + "-spacing-on"); + spacingMeasureElement.removeClassName(styleName + "-spacing-off"); + } else { + spacingMeasureElement.removeClassName(styleName + "-spacing-on"); + spacingMeasureElement.addClassName(styleName + "-spacing-off"); + } + } + + public void removeSlot(VLayoutSlot slot) { + VCaption caption = slot.getCaption(); + if (caption != null) { + remove(caption); + } + + remove(slot.getWidget()); + getElement().removeChild(slot.getWrapperElement()); + } + + public VLayoutSlot getSlotForChild(Widget widget) { + return (VLayoutSlot) widget.getLayoutData(); + } + + public void setCaption(Widget child, VCaption caption) { + VLayoutSlot slot = getSlotForChild(child); + + if (caption != null) { + // Logical attach. + getChildren().add(caption); + } + + // Physical attach if not null, also removes old caption + slot.setCaption(caption); + + if (caption != null) { + // Adopt. + adopt(caption); + } + } + + public int layoutPrimaryDirection(int spacingSize, int allocatedSize, + int startPadding) { + int actuallyAllocated = 0; + double totalExpand = 0; + + int childCount = 0; + for (Widget child : this) { + if (child instanceof VCaption) { + continue; + } + childCount++; + + VLayoutSlot slot = getSlotForChild(child); + totalExpand += slot.getExpandRatio(); + + if (!slot.isRelativeInDirection(isVertical)) { + actuallyAllocated += slot.getUsedSizeInDirection(isVertical); + } + } + + actuallyAllocated += spacingSize * (childCount - 1); + + if (allocatedSize == -1) { + allocatedSize = actuallyAllocated; + } + + double unallocatedSpace = Math + .max(0, allocatedSize - actuallyAllocated); + + double currentLocation = startPadding; + + for (Widget child : this) { + if (child instanceof VCaption) { + continue; + } + + VLayoutSlot slot = getSlotForChild(child); + + double childExpandRatio; + if (totalExpand == 0) { + childExpandRatio = 1d / childCount; + } else { + childExpandRatio = slot.getExpandRatio() / totalExpand; + } + + double extraPixels = unallocatedSpace * childExpandRatio; + double allocatedSpace = extraPixels; + if (!slot.isRelativeInDirection(isVertical)) { + allocatedSpace += slot.getUsedSizeInDirection(isVertical); + } + + slot.positionInDirection(currentLocation, allocatedSpace, + isVertical); + currentLocation += allocatedSpace + spacingSize; + } + + return allocatedSize; + } + + public int layoutSecondaryDirection(int allocatedSize, int startPadding) { + int maxSize = 0; + for (Widget child : this) { + if (child instanceof VCaption) { + continue; + } + + VLayoutSlot slot = getSlotForChild(child); + if (!slot.isRelativeInDirection(!isVertical)) { + maxSize = Math.max(maxSize, + slot.getUsedSizeInDirection(!isVertical)); + } + } + + if (allocatedSize == -1) { + allocatedSize = maxSize; + } + + for (Widget child : this) { + if (child instanceof VCaption) { + continue; + } + + VLayoutSlot slot = getSlotForChild(child); + slot.positionInDirection(startPadding, allocatedSize, !isVertical); + } + + return allocatedSize; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayoutPaintable.java new file mode 100644 index 0000000000..0583be5ada --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayoutPaintable.java @@ -0,0 +1,253 @@ +package com.vaadin.terminal.gwt.client.ui; + +import java.util.HashSet; +import java.util.Iterator; + +import com.google.gwt.dom.client.Style; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.CalculatingLayout; +import com.vaadin.terminal.gwt.client.MeasuredSize; +import com.vaadin.terminal.gwt.client.UIDL; +import com.vaadin.terminal.gwt.client.VCaption; +import com.vaadin.terminal.gwt.client.VPaintableMap; +import com.vaadin.terminal.gwt.client.VPaintableWidget; +import com.vaadin.terminal.gwt.client.ValueMap; +import com.vaadin.terminal.gwt.client.ui.layout.VLayoutSlot; +import com.vaadin.terminal.gwt.client.ui.layout.VPaintableLayoutSlot; + +public abstract class VMeasuringOrderedLayoutPaintable extends + VAbstractPaintableWidgetContainer implements CalculatingLayout { + + public VMeasuringOrderedLayoutPaintable() { + getMeasuredSize().registerDependency( + getWidgetForPaintable().spacingMeasureElement); + } + + public void updateCaption(VPaintableWidget component, UIDL uidl) { + VMeasuringOrderedLayout layout = getWidgetForPaintable(); + if (VCaption.isNeeded(uidl)) { + VLayoutSlot layoutSlot = layout.getSlotForChild(component + .getWidgetForPaintable()); + VCaption caption = layoutSlot.getCaption(); + if (caption == null) { + caption = new VCaption(component, getConnection()); + + Widget widget = component.getWidgetForPaintable(); + + layout.setCaption(widget, caption); + } + caption.updateCaption(uidl); + } else { + layout.setCaption(component.getWidgetForPaintable(), null); + } + } + + @Override + public VMeasuringOrderedLayout getWidgetForPaintable() { + return (VMeasuringOrderedLayout) super.getWidgetForPaintable(); + } + + @Override + public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { + super.updateFromUIDL(uidl, client); + if (!isRealUpdate(uidl)) { + return; + } + + HashSet<VPaintableWidget> previousChildren = new HashSet<VPaintableWidget>( + getChildren()); + + VMeasuringOrderedLayout layout = getWidgetForPaintable(); + + ValueMap expandRatios = uidl.getMapAttribute("expandRatios"); + ValueMap alignments = uidl.getMapAttribute("alignments"); + + // TODO Support reordering elements! + for (final Iterator<Object> it = uidl.getChildIterator(); it.hasNext();) { + final UIDL childUIDL = (UIDL) it.next(); + final VPaintableWidget child = client.getPaintable(childUIDL); + Widget widget = child.getWidgetForPaintable(); + + VLayoutSlot slot = layout.getSlotForChild(widget); + + if (widget.getParent() != layout) { + slot = new VPaintableLayoutSlot(child); + layout.addSlot(slot); + } + + String pid = child.getId(); + + AlignmentInfo alignment; + if (alignments.containsKey(pid)) { + alignment = new AlignmentInfo(alignments.getInt(pid)); + } else { + alignment = AlignmentInfo.TOP_LEFT; + } + slot.setAlignment(alignment); + + double expandRatio; + if (expandRatios.containsKey(pid)) { + expandRatio = expandRatios.getRawNumber(pid); + } else { + expandRatio = 0; + } + slot.setExpandRatio(expandRatio); + + if (!childUIDL.getBooleanAttribute("cached")) { + child.updateFromUIDL(childUIDL, client); + } + + previousChildren.remove(child); + } + + for (VPaintableWidget child : previousChildren) { + Widget widget = child.getWidgetForPaintable(); + layout.removeSlot(layout.getSlotForChild(widget)); + + VPaintableMap vPaintableMap = VPaintableMap.get(client); + vPaintableMap.unregisterPaintable(child); + } + + int bitMask = uidl.getIntAttribute("margins"); + layout.updateMarginStyleNames(new VMarginInfo(bitMask)); + + layout.updateSpacingStyleName(uidl.getBooleanAttribute("spacing")); + + getMeasuredSize().setHeightNeedsUpdate(); + getMeasuredSize().setWidthNeedsUpdate(); + } + + private int getSizeForInnerSize(int size, boolean isVertical) { + MeasuredSize measuredSize = getMeasuredSize(); + if (isVertical) { + return size + measuredSize.getBorderHeight() + + measuredSize.getPaddingHeight(); + } else { + return size + measuredSize.getBorderWidth() + + measuredSize.getPaddingWidth(); + } + } + + private static String getSizeProperty(boolean isVertical) { + return isVertical ? "height" : "width"; + } + + private boolean isUndefinedInDirection(boolean isVertical) { + if (isVertical) { + return isUndefinedHeight(); + } else { + return isUndefinedWidth(); + } + } + + private int getInnerSizeInDirection(boolean isVertical) { + if (isVertical) { + return getMeasuredSize().getInnerHeight(); + } else { + return getMeasuredSize().getInnerWidth(); + } + } + + private void layoutPrimaryDirection() { + VMeasuringOrderedLayout layout = getWidgetForPaintable(); + boolean isVertical = layout.isVertical; + boolean isUndefined = isUndefinedInDirection(isVertical); + + int startPadding = getStartPadding(isVertical); + int spacingSize = getSpacingInDirection(isVertical); + int allocatedSize; + + if (isUndefined) { + allocatedSize = -1; + } else { + allocatedSize = getInnerSizeInDirection(isVertical); + } + + allocatedSize = layout.layoutPrimaryDirection(spacingSize, + allocatedSize, startPadding); + + Style ownStyle = getWidgetForPaintable().getElement().getStyle(); + if (isUndefined) { + ownStyle.setPropertyPx(getSizeProperty(isVertical), + getSizeForInnerSize(allocatedSize, isVertical)); + } else { + ownStyle.setProperty(getSizeProperty(isVertical), + getDefinedSize(isVertical)); + } + } + + private int getSpacingInDirection(boolean isVertical) { + if (isVertical) { + return getMeasuredSize().getDependencyOuterHeight( + getWidgetForPaintable().spacingMeasureElement); + } else { + return getMeasuredSize().getDependencyOuterWidth( + getWidgetForPaintable().spacingMeasureElement); + } + } + + private void layoutSecondaryDirection() { + VMeasuringOrderedLayout layout = getWidgetForPaintable(); + boolean isVertical = layout.isVertical; + boolean isUndefined = isUndefinedInDirection(!isVertical); + + int startPadding = getStartPadding(!isVertical); + + int allocatedSize; + if (isUndefined) { + allocatedSize = -1; + } else { + allocatedSize = getInnerSizeInDirection(!isVertical); + } + + allocatedSize = layout.layoutSecondaryDirection(allocatedSize, + startPadding); + + Style ownStyle = getWidgetForPaintable().getElement().getStyle(); + + if (isUndefined) { + ownStyle.setPropertyPx( + getSizeProperty(!getWidgetForPaintable().isVertical), + getSizeForInnerSize(allocatedSize, + !getWidgetForPaintable().isVertical)); + } else { + ownStyle.setProperty( + getSizeProperty(!getWidgetForPaintable().isVertical), + getDefinedSize(!getWidgetForPaintable().isVertical)); + } + } + + private String getDefinedSize(boolean isVertical) { + if (isVertical) { + return getDefinedHeight(); + } else { + return getDefinedWidth(); + } + } + + private int getStartPadding(boolean isVertical) { + if (isVertical) { + return getMeasuredSize().getPaddingTop(); + } else { + return getMeasuredSize().getPaddingLeft(); + } + } + + public void updateHorizontalSizes() { + if (getWidgetForPaintable().isVertical) { + layoutSecondaryDirection(); + } else { + layoutPrimaryDirection(); + } + } + + public void updateVerticalSizes() { + if (getWidgetForPaintable().isVertical) { + layoutPrimaryDirection(); + } else { + layoutSecondaryDirection(); + } + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java deleted file mode 100644 index 413eadb314..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java +++ /dev/null @@ -1,728 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.terminal.gwt.client.ui; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Set; - -import com.google.gwt.core.client.JsArrayString; -import com.google.gwt.dom.client.Style.Unit; -import com.google.gwt.user.client.Element; -import com.google.gwt.user.client.ui.Widget; -import com.vaadin.terminal.gwt.client.RenderInformation.Size; -import com.vaadin.terminal.gwt.client.RenderSpace; -import com.vaadin.terminal.gwt.client.UIDL; -import com.vaadin.terminal.gwt.client.Util; -import com.vaadin.terminal.gwt.client.VPaintableMap; -import com.vaadin.terminal.gwt.client.VPaintableWidget; -import com.vaadin.terminal.gwt.client.ValueMap; -import com.vaadin.terminal.gwt.client.ui.layout.CellBasedLayout; -import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer; - -public class VOrderedLayout extends CellBasedLayout { - - public static final String CLASSNAME = "v-orderedlayout"; - - int orientation; - - /** - * Size of the layout excluding any margins. - */ - Size activeLayoutSize = new Size(0, 0); - - boolean isRendering = false; - - private String width = ""; - - boolean sizeHasChangedDuringRendering = false; - - private ValueMap expandRatios; - - private double expandRatioSum; - - private double defaultExpandRatio; - - private ValueMap alignments; - - public VOrderedLayout() { - this(CLASSNAME, ORIENTATION_VERTICAL); - } - - protected VOrderedLayout(String className, int orientation) { - setStyleName(className); - this.orientation = orientation; - - STYLENAME_SPACING = className + "-spacing"; - STYLENAME_MARGIN_TOP = className + "-margin-top"; - STYLENAME_MARGIN_RIGHT = className + "-margin-right"; - STYLENAME_MARGIN_BOTTOM = className + "-margin-bottom"; - STYLENAME_MARGIN_LEFT = className + "-margin-left"; - } - - void layoutSizeMightHaveChanged() { - Size oldSize = new Size(activeLayoutSize.getWidth(), - activeLayoutSize.getHeight()); - calculateLayoutDimensions(); - - /* - * If layout dimension changes we must also update container sizes - */ - if (!oldSize.equals(activeLayoutSize)) { - calculateContainerSize(); - } - } - - void updateWidgetSizes() { - for (ChildComponentContainer childComponentContainer : widgetToComponentContainer - .values()) { - - /* - * Update widget size from DOM - */ - childComponentContainer.updateWidgetSize(); - } - } - - void recalculateLayout() { - - /* Calculate space for relative size components */ - int spaceForExpansion = calculateLayoutDimensions(); - - if (!widgetToComponentContainer.isEmpty()) { - /* Divide expansion space between component containers */ - expandComponentContainers(spaceForExpansion); - - /* Update container sizes */ - calculateContainerSize(); - } - - } - - private void expandComponentContainers(int spaceForExpansion) { - int remaining = spaceForExpansion; - for (ChildComponentContainer childComponentContainer : widgetToComponentContainer - .values()) { - remaining -= childComponentContainer.expand(orientation, - spaceForExpansion); - } - - if (remaining > 0) { - - // Some left-over pixels due to rounding errors - - // Add one pixel to each container until there are no pixels left - // FIXME extra pixels should be divided among expanded widgets if - // such a widgets exists - - Iterator<Widget> widgetIterator = iterator(); - while (widgetIterator.hasNext() && remaining-- > 0) { - ChildComponentContainer childComponentContainer = (ChildComponentContainer) widgetIterator - .next(); - childComponentContainer.expandExtra(orientation, 1); - } - } - - } - - /** - * Updated components with relative height in horizontal layouts and - * components with relative width in vertical layouts. This is only needed - * if the height (horizontal layout) or width (vertical layout) has not been - * specified. - */ - boolean updateRelativeSizesInNonMainDirection() { - int updateDirection = 1 - orientation; - if ((updateDirection == ORIENTATION_HORIZONTAL && !isDynamicWidth()) - || (updateDirection == ORIENTATION_VERTICAL && !isDynamicHeight())) { - return false; - } - - boolean updated = false; - for (ChildComponentContainer componentContainer : widgetToComponentContainer - .values()) { - if (componentContainer.isComponentRelativeSized(updateDirection)) { - client.handleComponentRelativeSize(componentContainer - .getWidget()); - } - - updated = true; - } - - return updated; - } - - private int calculateLayoutDimensions() { - int summedWidgetWidth = 0; - int summedWidgetHeight = 0; - - int maxWidgetWidth = 0; - int maxWidgetHeight = 0; - - // Calculate layout dimensions from component dimensions - for (ChildComponentContainer childComponentContainer : widgetToComponentContainer - .values()) { - - int widgetHeight = 0; - int widgetWidth = 0; - if (childComponentContainer.isComponentRelativeSized(orientation)) { - if (orientation == ORIENTATION_HORIZONTAL) { - widgetHeight = getWidgetHeight(childComponentContainer); - } else { - widgetWidth = getWidgetWidth(childComponentContainer); - } - } else { - widgetWidth = getWidgetWidth(childComponentContainer); - widgetHeight = getWidgetHeight(childComponentContainer); - } - - summedWidgetWidth += widgetWidth; - summedWidgetHeight += widgetHeight; - - maxWidgetHeight = Math.max(maxWidgetHeight, widgetHeight); - maxWidgetWidth = Math.max(maxWidgetWidth, widgetWidth); - } - - if (isHorizontal()) { - summedWidgetWidth += activeSpacing.hSpacing - * (widgetToComponentContainer.size() - 1); - } else { - summedWidgetHeight += activeSpacing.vSpacing - * (widgetToComponentContainer.size() - 1); - } - - Size layoutSize = updateLayoutDimensions(summedWidgetWidth, - summedWidgetHeight, maxWidgetWidth, maxWidgetHeight); - - int remainingSpace; - if (isHorizontal()) { - remainingSpace = layoutSize.getWidth() - summedWidgetWidth; - } else { - remainingSpace = layoutSize.getHeight() - summedWidgetHeight; - } - if (remainingSpace < 0) { - remainingSpace = 0; - } - - // ApplicationConnection.getConsole().log( - // "Layout size: " + activeLayoutSize); - return remainingSpace; - } - - private int getWidgetHeight(ChildComponentContainer childComponentContainer) { - Size s = childComponentContainer.getWidgetSize(); - return s.getHeight() - + childComponentContainer.getCaptionHeightAboveComponent(); - } - - private int getWidgetWidth(ChildComponentContainer childComponentContainer) { - Size s = childComponentContainer.getWidgetSize(); - int widgetWidth = s.getWidth() - + childComponentContainer.getCaptionWidthAfterComponent(); - - /* - * If the component does not have a specified size in the main direction - * the caption may determine the space used by the component - */ - if (!childComponentContainer.widgetHasSizeSpecified(orientation)) { - int captionWidth = childComponentContainer - .getCaptionRequiredWidth(); - - if (captionWidth > widgetWidth) { - widgetWidth = captionWidth; - } - } - - return widgetWidth; - } - - void calculateAlignments() { - int w = 0; - int h = 0; - - if (isHorizontal()) { - // HORIZONTAL - h = activeLayoutSize.getHeight(); - if (!isDynamicWidth()) { - w = -1; - } - - } else { - // VERTICAL - w = activeLayoutSize.getWidth(); - if (!isDynamicHeight()) { - h = -1; - } - } - - for (ChildComponentContainer childComponentContainer : widgetToComponentContainer - .values()) { - childComponentContainer.updateAlignments(w, h); - } - - } - - private void calculateContainerSize() { - - /* - * Container size here means the size the container gets from the - * component. The expansion size is not include in this but taken - * separately into account. - */ - int height = 0, width = 0; - Iterator<Widget> widgetIterator = iterator(); - if (isHorizontal()) { - height = activeLayoutSize.getHeight(); - int availableWidth = activeLayoutSize.getWidth(); - boolean first = true; - while (widgetIterator.hasNext()) { - ChildComponentContainer childComponentContainer = (ChildComponentContainer) widgetIterator - .next(); - if (!childComponentContainer - .isComponentRelativeSized(ORIENTATION_HORIZONTAL)) { - /* - * Only components with non-relative size in the main - * direction has a container size - */ - width = childComponentContainer.getWidgetSize().getWidth() - + childComponentContainer - .getCaptionWidthAfterComponent(); - - /* - * If the component does not have a specified size in the - * main direction the caption may determine the space used - * by the component - */ - if (!childComponentContainer - .widgetHasSizeSpecified(orientation)) { - int captionWidth = childComponentContainer - .getCaptionRequiredWidth(); - // ApplicationConnection.getConsole().log( - // "Component width: " + width - // + ", caption width: " + captionWidth); - if (captionWidth > width) { - width = captionWidth; - } - } - } else { - width = 0; - } - - if (!isDynamicWidth()) { - if (availableWidth == 0) { - /* - * Let the overflowing components overflow. IE has - * problems with zero sizes. - */ - // width = 0; - // height = 0; - } else if (width > availableWidth) { - width = availableWidth; - - if (!first) { - width -= activeSpacing.hSpacing; - } - availableWidth = 0; - } else { - availableWidth -= width; - if (!first) { - availableWidth -= activeSpacing.hSpacing; - } - } - - first = false; - } - - childComponentContainer.setContainerSize(width, height); - } - } else { - width = activeLayoutSize.getWidth(); - while (widgetIterator.hasNext()) { - ChildComponentContainer childComponentContainer = (ChildComponentContainer) widgetIterator - .next(); - - if (!childComponentContainer - .isComponentRelativeSized(ORIENTATION_VERTICAL)) { - /* - * Only components with non-relative size in the main - * direction has a container size - */ - height = childComponentContainer.getWidgetSize() - .getHeight() - + childComponentContainer - .getCaptionHeightAboveComponent(); - } else { - height = 0; - } - - childComponentContainer.setContainerSize(width, height); - } - - } - - } - - private Size updateLayoutDimensions(int totalComponentWidth, - int totalComponentHeight, int maxComponentWidth, - int maxComponentHeight) { - - /* Only need to calculate dynamic dimensions */ - if (!isDynamicHeight() && !isDynamicWidth()) { - return activeLayoutSize; - } - - int activeLayoutWidth = 0; - int activeLayoutHeight = 0; - - // Update layout dimensions - if (isHorizontal()) { - // Horizontal - if (isDynamicWidth()) { - activeLayoutWidth = totalComponentWidth; - } - - if (isDynamicHeight()) { - activeLayoutHeight = maxComponentHeight; - } - - } else { - // Vertical - if (isDynamicWidth()) { - activeLayoutWidth = maxComponentWidth; - } - - if (isDynamicHeight()) { - activeLayoutHeight = totalComponentHeight; - } - } - - if (isDynamicWidth()) { - setActiveLayoutWidth(activeLayoutWidth); - setOuterLayoutWidth(activeLayoutSize.getWidth()); - } - - if (isDynamicHeight()) { - setActiveLayoutHeight(activeLayoutHeight); - setOuterLayoutHeight(activeLayoutSize.getHeight()); - } - - return activeLayoutSize; - } - - private void setActiveLayoutWidth(int activeLayoutWidth) { - if (activeLayoutWidth < 0) { - activeLayoutWidth = 0; - } - activeLayoutSize.setWidth(activeLayoutWidth); - } - - private void setActiveLayoutHeight(int activeLayoutHeight) { - if (activeLayoutHeight < 0) { - activeLayoutHeight = 0; - } - activeLayoutSize.setHeight(activeLayoutHeight); - - } - - private void setOuterLayoutWidth(int activeLayoutWidth) { - // Don't call setWidth to avoid triggering all kinds of recalculations - // Also don't call super.setWidth to avoid messing with the - // dynamicWidth property - int newPixelWidth = (activeLayoutWidth + activeMargins.getHorizontal()); - getElement().getStyle().setWidth(newPixelWidth, Unit.PX); - } - - private void setOuterLayoutHeight(int activeLayoutHeight) { - // Don't call setHeight to avoid triggering all kinds of recalculations - // Also don't call super.setHeight to avoid messing with the - // dynamicHeight property - int newPixelHeight = (activeLayoutHeight + activeMargins.getVertical()); - getElement().getStyle().setHeight(newPixelHeight, Unit.PX); - } - - /** - * Updates the spacing between components. Needs to be done only when - * components are added/removed. - */ - void updateContainerMargins() { - ChildComponentContainer firstChildComponent = getFirstChildComponentContainer(); - if (firstChildComponent != null) { - firstChildComponent.setMarginLeft(0); - firstChildComponent.setMarginTop(0); - - for (ChildComponentContainer childComponent : widgetToComponentContainer - .values()) { - if (childComponent == firstChildComponent) { - continue; - } - - if (isHorizontal()) { - childComponent.setMarginLeft(activeSpacing.hSpacing); - } else { - childComponent.setMarginTop(activeSpacing.vSpacing); - } - } - } - } - - boolean isHorizontal() { - return orientation == ORIENTATION_HORIZONTAL; - } - - boolean isVertical() { - return orientation == ORIENTATION_VERTICAL; - } - - ChildComponentContainer createChildContainer(VPaintableWidget child) { - - // Create a container DIV for the child - ChildComponentContainer childComponent = new ChildComponentContainer( - child, orientation); - - return childComponent; - - } - - public RenderSpace getAllocatedSpace(Widget child) { - int width = 0; - int height = 0; - ChildComponentContainer childComponentContainer = getComponentContainer(child); - // WIDTH CALCULATION - if (isVertical()) { - width = activeLayoutSize.getWidth(); - width -= childComponentContainer.getCaptionWidthAfterComponent(); - } else if (!isDynamicWidth()) { - // HORIZONTAL - width = childComponentContainer.getContSize().getWidth(); - width -= childComponentContainer.getCaptionWidthAfterComponent(); - } - - // HEIGHT CALCULATION - if (isHorizontal()) { - height = activeLayoutSize.getHeight(); - height -= childComponentContainer.getCaptionHeightAboveComponent(); - } else if (!isDynamicHeight()) { - // VERTICAL - height = childComponentContainer.getContSize().getHeight(); - height -= childComponentContainer.getCaptionHeightAboveComponent(); - } - - // ApplicationConnection.getConsole().log( - // "allocatedSpace for " + Util.getSimpleName(child) + ": " - // + width + "," + height); - RenderSpace space = new RenderSpace(width, height); - return space; - } - - private void recalculateLayoutAndComponentSizes() { - recalculateLayout(); - - if (!(isDynamicHeight() && isDynamicWidth())) { - /* First update relative sized components */ - for (ChildComponentContainer componentContainer : widgetToComponentContainer - .values()) { - client.handleComponentRelativeSize(componentContainer - .getWidget()); - - // Update widget size from DOM - componentContainer.updateWidgetSize(); - } - } - - if (isDynamicHeight()) { - /* - * Height is not necessarily correct anymore as the height of - * components might have changed if the width has changed. - */ - - /* - * Get the new widget sizes from DOM and calculate new container - * sizes - */ - updateWidgetSizes(); - - /* Update layout dimensions based on widget sizes */ - recalculateLayout(); - } - - updateRelativeSizesInNonMainDirection(); - calculateAlignments(); - - setRootSize(); - } - - void setRootSize() { - root.getStyle().setPropertyPx("width", activeLayoutSize.getWidth()); - root.getStyle().setPropertyPx("height", activeLayoutSize.getHeight()); - } - - public boolean requestLayout(Set<Widget> children) { - for (Widget p : children) { - /* Update widget size from DOM */ - ChildComponentContainer componentContainer = getComponentContainer(p); - // This should no longer be needed (after #2563) - // if (isDynamicWidth()) { - // componentContainer.setUnlimitedContainerWidth(); - // } else { - // componentContainer.setLimitedContainerWidth(activeLayoutSize - // .getWidth()); - // } - - componentContainer.updateWidgetSize(); - - /* - * If this is the result of an caption icon onload event the caption - * size may have changed - */ - componentContainer.updateCaptionSize(); - } - - Size sizeBefore = new Size(activeLayoutSize.getWidth(), - activeLayoutSize.getHeight()); - - recalculateLayoutAndComponentSizes(); - boolean sameSize = (sizeBefore.equals(activeLayoutSize)); - if (!sameSize) { - /* Must inform child components about possible size updates */ - client.runDescendentsLayout(this); - } - - /* Automatically propagated upwards if the size has changed */ - - return sameSize; - } - - @Override - public void setHeight(String height) { - Size sizeBefore = new Size(activeLayoutSize.getWidth(), - activeLayoutSize.getHeight()); - - super.setHeight(height); - - if (height != null && !height.equals("")) { - setActiveLayoutHeight(getOffsetHeight() - - activeMargins.getVertical()); - } - - if (isRendering) { - sizeHasChangedDuringRendering = true; - } else { - recalculateLayoutAndComponentSizes(); - boolean sameSize = (sizeBefore.equals(activeLayoutSize)); - if (!sameSize) { - /* Must inform child components about possible size updates */ - client.runDescendentsLayout(this); - } - } - } - - @Override - public void setWidth(String width) { - if (this.width.equals(width) || !isVisible()) { - return; - } - Size sizeBefore = new Size(activeLayoutSize.getWidth(), - activeLayoutSize.getHeight()); - - super.setWidth(width); - this.width = width; - if (width != null && !width.equals("")) { - setActiveLayoutWidth(getOffsetWidth() - - activeMargins.getHorizontal()); - } - - if (isRendering) { - sizeHasChangedDuringRendering = true; - } else { - recalculateLayoutAndComponentSizes(); - boolean sameSize = (sizeBefore.equals(activeLayoutSize)); - if (!sameSize) { - /* Must inform child components about possible size updates */ - client.runDescendentsLayout(this); - } - /* - * If the height changes as a consequence of this we must inform the - * parent also - */ - if (isDynamicHeight() - && sizeBefore.getHeight() != activeLayoutSize.getHeight()) { - Util.notifyParentOfSizeChange(this, false); - } - - } - } - - protected void updateAlignmentsAndExpandRatios(UIDL uidl, - ArrayList<Widget> renderedWidgets) { - - /* - */ - alignments = uidl.getMapAttribute("alignments"); - - /* - * UIDL contains a map of paintable ids to expand ratios - */ - - expandRatios = uidl.getMapAttribute("expandRatios"); - expandRatioSum = -1.0; - - for (int i = 0; i < renderedWidgets.size(); i++) { - Widget widget = renderedWidgets.get(i); - String pid = VPaintableMap.get(client).getPid(widget); - - ChildComponentContainer container = getComponentContainer(widget); - - // Calculate alignment info - container.setAlignment(getAlignment(pid)); - - // Update expand ratio - container.setNormalizedExpandRatio(getExpandRatio(pid)); - } - } - - private AlignmentInfo getAlignment(String pid) { - if (alignments.containsKey(pid)) { - return new AlignmentInfo(alignments.getInt(pid)); - } else { - return AlignmentInfo.TOP_LEFT; - } - } - - private double getExpandRatio(String pid) { - if (expandRatioSum < 0) { - expandRatioSum = 0; - JsArrayString keyArray = expandRatios.getKeyArray(); - int length = keyArray.length(); - for (int i = 0; i < length; i++) { - expandRatioSum += expandRatios.getRawNumber(keyArray.get(i)); - } - if (expandRatioSum == 0) { - // by default split equally among components - defaultExpandRatio = 1.0 / widgetToComponentContainer.size(); - } else { - defaultExpandRatio = 0; - } - } - if (expandRatios.containsKey(pid)) { - return expandRatios.getRawNumber(pid) / expandRatioSum; - } else { - return defaultExpandRatio; - } - } - - /** - * Returns the deepest nested child component which contains "element". The - * child component is also returned if "element" is part of its caption. - * - * @param element - * An element that is a nested sub element of the root element in - * this layout - * @return The Paintable which the element is a part of. Null if the element - * belongs to the layout and not to a child. - */ - VPaintableWidget getComponent(Element element) { - return Util.getPaintableForElement(client, this, element); - } - -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayoutPaintable.java deleted file mode 100644 index 0d9f5c6263..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayoutPaintable.java +++ /dev/null @@ -1,256 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.terminal.gwt.client.ui; - -import java.util.ArrayList; -import java.util.Iterator; - -import com.google.gwt.event.dom.client.DomEvent.Type; -import com.google.gwt.event.shared.EventHandler; -import com.google.gwt.event.shared.HandlerRegistration; -import com.google.gwt.user.client.Element; -import com.google.gwt.user.client.ui.Widget; -import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.client.BrowserInfo; -import com.vaadin.terminal.gwt.client.EventId; -import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize; -import com.vaadin.terminal.gwt.client.UIDL; -import com.vaadin.terminal.gwt.client.Util; -import com.vaadin.terminal.gwt.client.VPaintableWidget; -import com.vaadin.terminal.gwt.client.ui.layout.CellBasedLayoutPaintable; -import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer; - -public abstract class VOrderedLayoutPaintable extends CellBasedLayoutPaintable { - - private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler( - this, EventId.LAYOUT_CLICK) { - - @Override - protected VPaintableWidget getChildComponent(Element element) { - return getWidgetForPaintable().getComponent(element); - } - - @Override - protected <H extends EventHandler> HandlerRegistration registerHandler( - H handler, Type<H> type) { - return getWidgetForPaintable().addDomHandler(handler, type); - } - }; - - public void updateCaption(VPaintableWidget paintable, UIDL uidl) { - Widget widget = paintable.getWidgetForPaintable(); - ChildComponentContainer componentContainer = getWidgetForPaintable() - .getComponentContainer(widget); - componentContainer.updateCaption(uidl, getConnection()); - if (!getWidgetForPaintable().isRendering) { - /* - * This was a component-only update and the possible size change - * must be propagated to the layout - */ - getConnection().captionSizeUpdated(widget); - } - } - - @Override - public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - getWidgetForPaintable().isRendering = true; - super.updateFromUIDL(uidl, client); - - // Only non-cached, visible UIDL:s can introduce changes - if (!isRealUpdate(uidl) || uidl.getBooleanAttribute("invisible")) { - getWidgetForPaintable().isRendering = false; - return; - } - - clickEventHandler.handleEventHandlerRegistration(client); - - // IStopWatch w = new IStopWatch("OrderedLayout.updateFromUIDL"); - - ArrayList<Widget> uidlWidgets = new ArrayList<Widget>( - uidl.getChildCount()); - ArrayList<ChildComponentContainer> relativeSizeComponents = new ArrayList<ChildComponentContainer>(); - ArrayList<UIDL> relativeSizeComponentUIDL = new ArrayList<UIDL>(); - - int pos = 0; - for (final Iterator<Object> it = uidl.getChildIterator(); it.hasNext();) { - final UIDL childUIDL = (UIDL) it.next(); - final VPaintableWidget childPaintable = client - .getPaintable(childUIDL); - Widget widget = childPaintable.getWidgetForPaintable(); - - // Create container for component - ChildComponentContainer childComponentContainer = getWidgetForPaintable() - .getComponentContainer(widget); - - if (childComponentContainer == null) { - // This is a new component - childComponentContainer = getWidgetForPaintable() - .createChildContainer(childPaintable); - } else { - /* - * The widget may be null if the same paintable has been - * rendered in a different component container while this has - * been invisible. Ensure the childComponentContainer has the - * widget attached. See e.g. #5372 - */ - childComponentContainer.setPaintable(childPaintable); - } - - getWidgetForPaintable().addOrMoveChild(childComponentContainer, - pos++); - - /* - * Components which are to be expanded in the same orientation as - * the layout are rendered later when it is clear how much space - * they can use - */ - if (isRealUpdate(childUIDL)) { - FloatSize relativeSize = Util.parseRelativeSize(childUIDL); - childComponentContainer.setRelativeSize(relativeSize); - } - - if (childComponentContainer - .isComponentRelativeSized(getWidgetForPaintable().orientation)) { - relativeSizeComponents.add(childComponentContainer); - relativeSizeComponentUIDL.add(childUIDL); - } else { - if (getWidgetForPaintable().isDynamicWidth()) { - childComponentContainer.renderChild(childUIDL, client, -1); - } else { - childComponentContainer - .renderChild(childUIDL, client, - getWidgetForPaintable().activeLayoutSize - .getWidth()); - } - if (getWidgetForPaintable().sizeHasChangedDuringRendering - && !isRealUpdate(childUIDL)) { - // notify cached relative sized component about size - // chance - client.handleComponentRelativeSize(childComponentContainer - .getWidget()); - } - } - - uidlWidgets.add(widget); - - } - - // w.mark("Rendering of " - // + (uidlWidgets.size() - relativeSizeComponents.size()) - // + " absolute size components done"); - - /* - * Remove any children after pos. These are the ones that previously - * were in the layout but have now been removed - */ - getWidgetForPaintable().removeChildrenAfter(pos); - - // w.mark("Old children removed"); - - /* Fetch alignments and expand ratio from UIDL */ - getWidgetForPaintable().updateAlignmentsAndExpandRatios(uidl, - uidlWidgets); - // w.mark("Alignments and expand ratios updated"); - - /* Fetch widget sizes from rendered components */ - getWidgetForPaintable().updateWidgetSizes(); - // w.mark("Widget sizes updated"); - - getWidgetForPaintable().recalculateLayout(); - // w.mark("Layout size calculated (" + activeLayoutSize + - // ") offsetSize: " - // + getOffsetWidth() + "," + getOffsetHeight()); - - /* Render relative size components */ - for (int i = 0; i < relativeSizeComponents.size(); i++) { - ChildComponentContainer childComponentContainer = relativeSizeComponents - .get(i); - UIDL childUIDL = relativeSizeComponentUIDL.get(i); - - if (getWidgetForPaintable().isDynamicWidth()) { - childComponentContainer.renderChild(childUIDL, client, -1); - } else { - childComponentContainer.renderChild(childUIDL, client, - getWidgetForPaintable().activeLayoutSize.getWidth()); - } - - if (!isRealUpdate(childUIDL)) { - /* - * We must update the size of the relative sized component if - * the expand ratio or something else in the layout changes - * which affects the size of a relative sized component - */ - client.handleComponentRelativeSize(childComponentContainer - .getWidget()); - } - - // childComponentContainer.updateWidgetSize(); - } - - // w.mark("Rendering of " + (relativeSizeComponents.size()) - // + " relative size components done"); - - /* Fetch widget sizes for relative size components */ - for (ChildComponentContainer childComponentContainer : getWidgetForPaintable() - .getComponentContainers()) { - - /* Update widget size from DOM */ - childComponentContainer.updateWidgetSize(); - } - - // w.mark("Widget sizes updated"); - - /* - * Components with relative size in main direction may affect the layout - * size in the other direction - */ - if ((getWidgetForPaintable().isHorizontal() && getWidgetForPaintable() - .isDynamicHeight()) - || (getWidgetForPaintable().isVertical() && getWidgetForPaintable() - .isDynamicWidth())) { - getWidgetForPaintable().layoutSizeMightHaveChanged(); - } - // w.mark("Layout dimensions updated"); - - /* Update component spacing */ - getWidgetForPaintable().updateContainerMargins(); - - /* - * Update component sizes for components with relative size in non-main - * direction - */ - if (getWidgetForPaintable().updateRelativeSizesInNonMainDirection()) { - // Sizes updated - might affect the other dimension so we need to - // recheck the widget sizes and recalculate layout dimensions - getWidgetForPaintable().updateWidgetSizes(); - getWidgetForPaintable().layoutSizeMightHaveChanged(); - } - getWidgetForPaintable().calculateAlignments(); - // w.mark("recalculateComponentSizesAndAlignments done"); - - getWidgetForPaintable().setRootSize(); - - if (BrowserInfo.get().isIE()) { - /* - * This should fix the issue with padding not always taken into - * account for the containers leading to no spacing between - * elements. - */ - getWidgetForPaintable().root.getStyle().setProperty("zoom", "1"); - } - - // w.mark("runDescendentsLayout done"); - getWidgetForPaintable().isRendering = false; - getWidgetForPaintable().sizeHasChangedDuringRendering = false; - } - - @Override - protected abstract VOrderedLayout createWidget(); - - @Override - public VOrderedLayout getWidgetForPaintable() { - return (VOrderedLayout) super.getWidgetForPaintable(); - } - -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VPanel.java index 82b362a385..45ded13d00 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VPanel.java @@ -4,8 +4,6 @@ package com.vaadin.terminal.gwt.client.ui; -import java.util.Set; - import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Document; import com.google.gwt.event.dom.client.TouchStartEvent; @@ -14,21 +12,14 @@ import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.SimplePanel; -import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.client.BrowserInfo; -import com.vaadin.terminal.gwt.client.Container; import com.vaadin.terminal.gwt.client.Focusable; -import com.vaadin.terminal.gwt.client.RenderInformation; -import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.UIDL; -import com.vaadin.terminal.gwt.client.Util; -import com.vaadin.terminal.gwt.client.VPaintableMap; import com.vaadin.terminal.gwt.client.VPaintableWidget; import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; -public class VPanel extends SimplePanel implements Container, - ShortcutActionHandlerOwner, Focusable { +public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner, + Focusable { public static final String CLASSNAME = "v-panel"; @@ -48,36 +39,16 @@ public class VPanel extends SimplePanel implements Container, private Element errorIndicatorElement; - private String height; - VPaintableWidget layout; ShortcutActionHandler shortcutHandler; private String width = ""; - private Element geckoCaptionMeter; - int scrollTop; int scrollLeft; - private RenderInformation renderInformation = new RenderInformation(); - - private int borderPaddingHorizontal = -1; - - private int borderPaddingVertical = -1; - - private int captionPaddingHorizontal = -1; - - private int captionMarginLeft = -1; - - boolean rendering; - - private int contentMarginLeft = -1; - - private String previousStyleName; - private TouchScrollDelegate touchScrollDelegate; public VPanel() { @@ -106,7 +77,6 @@ public class VPanel extends SimplePanel implements Container, setStyleName(CLASSNAME); DOM.sinkEvents(getElement(), Event.ONKEYDOWN); DOM.sinkEvents(contentNode, Event.ONSCROLL | Event.TOUCHEVENTS); - contentNode.getStyle().setProperty("position", "relative"); getElement().getStyle().setProperty("overflow", "hidden"); addHandler(new TouchStartHandler() { public void onTouchStart(TouchStartEvent event) { @@ -148,15 +118,6 @@ public class VPanel extends SimplePanel implements Container, DOM.setInnerHTML(captionText, text); } - @Override - public void setStyleName(String style) { - if (!style.equals(previousStyleName)) { - super.setStyleName(style); - detectContainerBorders(); - previousStyleName = style; - } - } - void handleError(UIDL uidl) { if (uidl.hasAttribute("error")) { if (errorIndicatorElement == null) { @@ -190,54 +151,6 @@ public class VPanel extends SimplePanel implements Container, } } - public void runHacks(boolean runGeckoFix) { - if ((BrowserInfo.get().isIE()) && (width == null || width.equals(""))) { - /* - * IE (what version??) needs width to be specified for the root DIV - * so we calculate that from the sizes of the caption and layout - */ - int captionWidth = captionText.getOffsetWidth() - + getCaptionMarginLeft() + getCaptionPaddingHorizontal(); - int layoutWidth = layout.getWidgetForPaintable().getOffsetWidth() - + getContainerBorderWidth(); - int width = layoutWidth; - if (captionWidth > width) { - width = captionWidth; - } - - super.setWidth(width + "px"); - } - - if (runGeckoFix && BrowserInfo.get().isGecko()) { - // workaround for #1764 - if (width == null || width.equals("")) { - if (geckoCaptionMeter == null) { - geckoCaptionMeter = DOM.createDiv(); - DOM.appendChild(captionNode, geckoCaptionMeter); - } - int captionWidth = DOM.getElementPropertyInt(captionText, - "offsetWidth"); - int availWidth = DOM.getElementPropertyInt(geckoCaptionMeter, - "offsetWidth"); - if (captionWidth == availWidth) { - /* - * Caption width defines panel width -> Gecko based browsers - * somehow fails to float things right, without the - * "noncode" below - */ - setWidth(getOffsetWidth() + "px"); - } else { - DOM.setStyleAttribute(captionNode, "width", ""); - } - } - } - - client.runDescendentsLayout(this); - - Util.runWebkitOverflowAutoFix(contentNode); - - } - @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); @@ -275,159 +188,6 @@ public class VPanel extends SimplePanel implements Container, } - @Override - public void setHeight(String height) { - this.height = height; - super.setHeight(height); - if (height != null && !"".equals(height)) { - final int targetHeight = getOffsetHeight(); - int containerHeight = targetHeight - - captionNode.getParentElement().getOffsetHeight() - - bottomDecoration.getOffsetHeight() - - getContainerBorderHeight(); - if (containerHeight < 0) { - containerHeight = 0; - } - DOM.setStyleAttribute(contentNode, "height", containerHeight + "px"); - } else { - DOM.setStyleAttribute(contentNode, "height", ""); - } - if (!rendering) { - runHacks(true); - } - } - - private int getCaptionMarginLeft() { - if (captionMarginLeft < 0) { - detectContainerBorders(); - } - return captionMarginLeft; - } - - private int getContentMarginLeft() { - if (contentMarginLeft < 0) { - detectContainerBorders(); - } - return contentMarginLeft; - } - - private int getCaptionPaddingHorizontal() { - if (captionPaddingHorizontal < 0) { - detectContainerBorders(); - } - return captionPaddingHorizontal; - } - - private int getContainerBorderHeight() { - if (borderPaddingVertical < 0) { - detectContainerBorders(); - } - return borderPaddingVertical; - } - - @Override - public void setWidth(String width) { - if (this.width.equals(width)) { - return; - } - - this.width = width; - super.setWidth(width); - if (!rendering) { - runHacks(true); - - if (height.equals("")) { - // Width change may affect height - Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this, - this); - } - - } - } - - private int getContainerBorderWidth() { - if (borderPaddingHorizontal < 0) { - detectContainerBorders(); - } - return borderPaddingHorizontal; - } - - private void detectContainerBorders() { - DOM.setStyleAttribute(contentNode, "overflow", "hidden"); - - borderPaddingHorizontal = Util.measureHorizontalBorder(contentNode); - borderPaddingVertical = Util.measureVerticalBorder(contentNode); - - DOM.setStyleAttribute(contentNode, "overflow", "auto"); - - captionPaddingHorizontal = Util.measureHorizontalPaddingAndBorder( - captionNode, 26); - - captionMarginLeft = Util.measureMarginLeft(captionNode); - contentMarginLeft = Util.measureMarginLeft(contentNode); - - } - - public boolean hasChildComponent(Widget component) { - if (component != null && component == layout) { - return true; - } else { - return false; - } - } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - // TODO This is untested as no layouts require this - if (oldComponent != layout.getWidgetForPaintable()) { - return; - } - - setWidget(newComponent); - layout = VPaintableMap.get(client).getPaintable(newComponent); - } - - public RenderSpace getAllocatedSpace(Widget child) { - int w = 0; - int h = 0; - - if (width != null && !width.equals("")) { - w = getOffsetWidth() - getContainerBorderWidth(); - if (w < 0) { - w = 0; - } - } - - if (height != null && !height.equals("")) { - h = contentNode.getOffsetHeight() - getContainerBorderHeight(); - if (h < 0) { - h = 0; - } - } - - return new RenderSpace(w, h, true); - } - - public boolean requestLayout(Set<Widget> children) { - // content size change might cause change to its available space - // (scrollbars) - client.handleComponentRelativeSize(layout.getWidgetForPaintable()); - if (height != null && height != "" && width != null && width != "") { - /* - * If the height and width has been specified the child components - * cannot make the size of the layout change - */ - return true; - } - runHacks(false); - return !renderInformation.updateSize(getElement()); - } - - @Override - protected void onAttach() { - super.onAttach(); - detectContainerBorders(); - } - public ShortcutActionHandler getShortcutActionHandler() { return shortcutHandler; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java index 9c34a68528..eade1d7d0e 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java @@ -4,18 +4,24 @@ package com.vaadin.terminal.gwt.client.ui; import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style; +import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.DomEvent.Type; import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.MeasuredSize; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.VPaintableWidget; -public class VPanelPaintable extends VAbstractPaintableWidgetContainer { +public class VPanelPaintable extends VAbstractPaintableWidgetContainer + implements ResizeRequired, LayoutPhaseListener { public static final String CLICK_EVENT_IDENTIFIER = "click"; + private Integer uidlScrollTop; + private ClickEventHandler clickEventHandler = new ClickEventHandler(this, CLICK_EVENT_IDENTIFIER) { @@ -26,14 +32,24 @@ public class VPanelPaintable extends VAbstractPaintableWidgetContainer { } }; + private Integer uidlScrollLeft; + + public VPanelPaintable() { + VPanel panel = getWidgetForPaintable(); + MeasuredSize measuredSize = getMeasuredSize(); + + measuredSize.registerDependency(panel.captionNode); + measuredSize.registerDependency(panel.bottomDecoration); + measuredSize.registerDependency(panel.contentNode); + } + @Override protected boolean delegateCaptionHandling() { return false; - }; + } @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - getWidgetForPaintable().rendering = true; if (isRealUpdate(uidl)) { // Handle caption displaying and style names, prior generics. @@ -86,7 +102,6 @@ public class VPanelPaintable extends VAbstractPaintableWidgetContainer { super.updateFromUIDL(uidl, client); if (!isRealUpdate(uidl)) { - getWidgetForPaintable().rendering = false; return; } @@ -130,42 +145,23 @@ public class VPanelPaintable extends VAbstractPaintableWidgetContainer { if (uidl.hasVariable("scrollTop") && uidl.getIntVariable("scrollTop") != getWidgetForPaintable().scrollTop) { - getWidgetForPaintable().scrollTop = uidl - .getIntVariable("scrollTop"); - getWidgetForPaintable().contentNode - .setScrollTop(getWidgetForPaintable().scrollTop); - // re-read the actual scrollTop in case invalid value was set - // (scrollTop != 0 when no scrollbar exists, other values would be - // caught by scroll listener), see #3784 - getWidgetForPaintable().scrollTop = getWidgetForPaintable().contentNode - .getScrollTop(); + // Sizes are not yet up to date, so changing the scroll position + // is deferred to after the layout phase + uidlScrollTop = new Integer(uidl.getIntVariable("scrollTop")); } if (uidl.hasVariable("scrollLeft") && uidl.getIntVariable("scrollLeft") != getWidgetForPaintable().scrollLeft) { - getWidgetForPaintable().scrollLeft = uidl - .getIntVariable("scrollLeft"); - getWidgetForPaintable().contentNode - .setScrollLeft(getWidgetForPaintable().scrollLeft); - // re-read the actual scrollTop in case invalid value was set - // (scrollTop != 0 when no scrollbar exists, other values would be - // caught by scroll listener), see #3784 - getWidgetForPaintable().scrollLeft = getWidgetForPaintable().contentNode - .getScrollLeft(); + // Sizes are not yet up to date, so changing the scroll position + // is deferred to after the layout phase + uidlScrollLeft = new Integer(uidl.getIntVariable("scrollLeft")); } - // Must be run after scrollTop is set as Webkit overflow fix re-sets the - // scrollTop - getWidgetForPaintable().runHacks(false); - // And apply tab index if (uidl.hasVariable("tabindex")) { getWidgetForPaintable().contentNode.setTabIndex(uidl .getIntVariable("tabindex")); } - - getWidgetForPaintable().rendering = false; - } public void updateCaption(VPaintableWidget component, UIDL uidl) { @@ -182,4 +178,66 @@ public class VPanelPaintable extends VAbstractPaintableWidgetContainer { return GWT.create(VPanel.class); } + public void onResize() { + updateSizes(); + } + + void updateSizes() { + MeasuredSize measuredSize = getMeasuredSize(); + VPanel panel = getWidgetForPaintable(); + + Style contentStyle = panel.contentNode.getStyle(); + if (isUndefinedHeight()) { + contentStyle.clearHeight(); + } else { + contentStyle.setHeight(100, Unit.PCT); + } + + if (isUndefinedWidth()) { + contentStyle.clearWidth(); + } else { + contentStyle.setWidth(100, Unit.PCT); + } + + int top = measuredSize.getDependencyOuterHeight(panel.captionNode); + int bottom = measuredSize + .getDependencyOuterHeight(panel.bottomDecoration); + + Style style = panel.getElement().getStyle(); + panel.captionNode.getStyle().setMarginTop(-top, Unit.PX); + panel.bottomDecoration.getStyle().setMarginBottom(-bottom, Unit.PX); + style.setPaddingTop(top, Unit.PX); + style.setPaddingBottom(bottom, Unit.PX); + + // Update scroll positions + panel.contentNode.setScrollTop(panel.scrollTop); + panel.contentNode.setScrollLeft(panel.scrollLeft); + // Read actual value back to ensure update logic is correct + panel.scrollTop = panel.contentNode.getScrollTop(); + panel.scrollLeft = panel.contentNode.getScrollLeft(); + } + + public void beforeLayout() { + // Nothing to do + } + + public void afterLayout() { + VPanel panel = getWidgetForPaintable(); + if (uidlScrollTop != null) { + panel.contentNode.setScrollTop(uidlScrollTop.intValue()); + // Read actual value back to ensure update logic is correct + // TODO Does this trigger reflows? + panel.scrollTop = panel.contentNode.getScrollTop(); + uidlScrollTop = null; + } + + if (uidlScrollLeft != null) { + panel.contentNode.setScrollLeft(uidlScrollLeft.intValue()); + // Read actual value back to ensure update logic is correct + // TODO Does this trigger reflows? + panel.scrollLeft = panel.contentNode.getScrollLeft(); + uidlScrollLeft = null; + } + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index a41fbe3ef9..07d9de5f20 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -59,10 +59,8 @@ import com.google.gwt.user.client.ui.UIObject; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; -import com.vaadin.terminal.gwt.client.Container; import com.vaadin.terminal.gwt.client.Focusable; import com.vaadin.terminal.gwt.client.MouseEventDetails; -import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.TooltipInfo; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; @@ -106,7 +104,7 @@ import com.vaadin.terminal.gwt.client.ui.label.VLabel; */ public class VScrollTable extends FlowPanel implements HasWidgets, ScrollHandler, VHasDropHandler, FocusHandler, BlurHandler, Focusable, - ActionOwner, Container { + ActionOwner { public enum SelectMode { NONE(0), SINGLE(1), MULTI(2); @@ -431,8 +429,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets, boolean recalcWidths = false; private final ArrayList<Panel> lazyUnregistryBag = new ArrayList<Panel>(); - private String height; - private String width = ""; boolean rendering = false; private boolean hasFocus = false; private int dragmode; @@ -1669,7 +1665,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, boolean willHaveScrollbarz = willHaveScrollbars(); // fix "natural" width if width not set - if (width == null || "".equals(width)) { + if (isDynamicWidth()) { int w = total; w += scrollBody.getCellExtraWidth() * visibleColOrder.length; if (willHaveScrollbarz) { @@ -1797,7 +1793,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * Fix "natural" height if height is not set. This must be after width * fixing so the components' widths have been adjusted. */ - if (height == null || "".equals(height)) { + if (isDynamicHeight()) { /* * We must force an update of the row height as this point as it * might have been (incorrectly) calculated earlier @@ -1878,7 +1874,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * @return true if content area will have scrollbars visible. */ protected boolean willHaveScrollbars() { - if (!(height != null && !height.equals(""))) { + if (isDynamicHeight()) { if (pageLength < totalRows) { return true; } @@ -5315,29 +5311,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets, return -1; } - public boolean hasChildComponent(Widget component) { - return childWidgets.contains(component); - } - - public void replaceChildComponent(Widget oldComponent, - Widget newComponent) { - com.google.gwt.dom.client.Element parentElement = oldComponent - .getElement().getParentElement(); - int index = childWidgets.indexOf(oldComponent); - oldComponent.removeFromParent(); - - parentElement.appendChild(newComponent.getElement()); - childWidgets.add(index, newComponent); - adopt(newComponent); - - } - - public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - // Should never be called, - // Component container interface faked here to get layouts - // render properly - } - public Widget getWidgetForPaintable() { return this; } @@ -5518,7 +5491,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, return; } - if (height == null || height.equals("")) { + if (isDynamicHeight()) { return; } @@ -5542,16 +5515,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets, scrollBodyPanel.setScrollPosition(scrollTop + 1); scrollBodyPanel.setScrollPosition(scrollTop - 1); } + + sizeInit(); } } } - @Override - public void setWidth(String width) { - if (this.width.equals(width)) { - return; - } + void updateWidth() { if (!isVisible()) { /* * Do not update size when the table is hidden as all column widths @@ -5561,9 +5532,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, return; } - this.width = width; - if (width != null && !"".equals(width)) { - super.setWidth(width); + if (!isDynamicWidth()) { int innerPixels = getOffsetWidth() - getBorderWidth(); if (innerPixels < 0) { innerPixels = 0; @@ -5575,9 +5544,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } else { - // Undefined width - super.setWidth(""); - // Readjust size of table sizeInit(); @@ -5693,8 +5659,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } } - if ((height == null || "".equals(height)) - && totalRows == pageLength) { + if (isDynamicHeight() && totalRows == pageLength) { // fix body height (may vary if lazy loading is offhorizontal // scrollbar appears/disappears) int bodyHeight = scrollBody.getRequiredHeight(); @@ -5766,7 +5731,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private int containerHeight; private void setContainerHeight() { - if (height != null && !"".equals(height)) { + if (!isDynamicHeight()) { containerHeight = getOffsetHeight(); containerHeight -= showColHeaders ? tHead.getOffsetHeight() : 0; containerHeight -= tFoot.getOffsetHeight(); @@ -5803,15 +5768,11 @@ public class VScrollTable extends FlowPanel implements HasWidgets, return contentAreaBorderHeight; } - @Override - public void setHeight(String height) { - this.height = height; - super.setHeight(height); + void updateHeight() { setContainerHeight(); - if (initializedAndAttached) { - updatePageLength(); - } + updatePageLength(); + if (!rendering) { // Webkit may sometimes get an odd rendering bug (white space // between header and body), see bug #3875. Running @@ -6687,6 +6648,18 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } } + private boolean isDynamicWidth() { + VPaintableWidget paintable = VPaintableMap.get(client).getPaintable( + this); + return paintable.isUndefinedWidth(); + } + + private boolean isDynamicHeight() { + VPaintableWidget paintable = VPaintableMap.get(client).getPaintable( + this); + return paintable.isUndefinedHeight(); + } + private void debug(String msg) { if (enableDebug) { VConsole.error(msg); @@ -6696,46 +6669,4 @@ public class VScrollTable extends FlowPanel implements HasWidgets, public Widget getWidgetForPaintable() { return this; } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - VScrollTableRow row = (VScrollTableRow) oldComponent.getParent(); - row.replaceChildComponent(oldComponent, newComponent); - - } - - public boolean hasChildComponent(Widget child) { - VScrollTableRow row = (VScrollTableRow) child.getParent(); - return row.hasChildComponent(child); - } - - public boolean requestLayout(Set<Widget> children) { - // row size should never change - return true; - } - - public RenderSpace getAllocatedSpace(Widget child) { - // Called by widgets attached to a row - VScrollTableRow row = (VScrollTableRow) child.getParent(); - int w = 0; - int i = row.getColIndexOf(child); - HeaderCell headerCell = tHead.getHeaderCell(i); - if (headerCell != null) { - if (initializedAndAttached) { - w = headerCell.getWidth(); - } else { - // header offset width is not absolutely correct value, - // but a best guess (expecting similar content in all - // columns -> - // if one component is relative width so are others) - w = headerCell.getOffsetWidth() - - scrollBody.getCellExtraWidth(); - } - } - return new RenderSpace(w, 0) { - @Override - public int getHeight() { - return (int) scrollBody.getRowHeight(); - } - }; - } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java index 23cf4925f8..38fb077637 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java @@ -10,11 +10,13 @@ import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; +import com.vaadin.terminal.gwt.client.CalculatingLayout; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VPaintableWidget; -public class VScrollTablePaintable extends VAbstractPaintableWidgetContainer { +public class VScrollTablePaintable extends VAbstractPaintableWidgetContainer + implements CalculatingLayout { /* * (non-Javadoc) @@ -259,4 +261,11 @@ public class VScrollTablePaintable extends VAbstractPaintableWidgetContainer { // NOP, not rendered } + public void updateVerticalSizes() { + getWidgetForPaintable().updateHeight(); + } + + public void updateHorizontalSizes() { + getWidgetForPaintable().updateWidth(); + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java index 9155f9932a..85b6e1b2e8 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java @@ -5,7 +5,6 @@ package com.vaadin.terminal.gwt.client.ui; import java.util.Iterator; -import java.util.Set; import com.google.gwt.core.client.Scheduler; import com.google.gwt.dom.client.DivElement; @@ -23,8 +22,6 @@ import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; -import com.vaadin.terminal.gwt.client.RenderInformation; -import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.TooltipInfo; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; @@ -485,15 +482,12 @@ public class VTabsheet extends VTabsheetBase { private final TabBar tb = new TabBar(this); final VTabsheetPanel tp = new VTabsheetPanel(); - private final Element contentNode, deco; + final Element contentNode; - private String height; - private String width; + private final Element deco; boolean waitingForResponse; - final RenderInformation renderInformation = new RenderInformation(); - /** * Previous visible widget is set invisible with CSS (not display: none, but * visibility: hidden), to avoid flickering during render process. Normal @@ -501,8 +495,6 @@ public class VTabsheet extends VTabsheetBase { */ private Widget previousVisibleWidget; - boolean rendering = false; - private String currentStyle; private void onTabSelected(final int tabIndex) { @@ -550,11 +542,15 @@ public class VTabsheet extends VTabsheetBase { } boolean isDynamicWidth() { - return width == null || width.equals(""); + VPaintableWidget paintable = VPaintableMap.get(client).getPaintable( + this); + return paintable.isUndefinedWidth(); } boolean isDynamicHeight() { - return height == null || height.equals(""); + VPaintableWidget paintable = VPaintableMap.get(client).getPaintable( + this); + return paintable.isUndefinedHeight(); } public VTabsheet() { @@ -860,22 +856,8 @@ public class VTabsheet extends VTabsheetBase { } } - @Override - public void setHeight(String height) { - super.setHeight(height); - this.height = height; - updateContentNodeHeight(); - - if (!rendering) { - updateOpenTabSize(); - iLayout(); - // TODO Check if this is needed - client.runDescendentsLayout(this); - } - } - void updateContentNodeHeight() { - if (height != null && !"".equals(height)) { + if (!isDynamicHeight()) { int contentHeight = getOffsetHeight(); contentHeight -= DOM.getElementPropertyInt(deco, "offsetHeight"); contentHeight -= tb.getOffsetHeight(); @@ -885,50 +867,9 @@ public class VTabsheet extends VTabsheetBase { // Set proper values for content element DOM.setStyleAttribute(contentNode, "height", contentHeight + "px"); - renderSpace.setHeight(contentHeight); } else { DOM.setStyleAttribute(contentNode, "height", ""); - renderSpace.setHeight(0); - } - } - - @Override - public void setWidth(String width) { - if ((this.width == null && width.equals("")) - || (this.width != null && this.width.equals(width))) { - return; } - - super.setWidth(width); - if (width.equals("")) { - width = null; - } - this.width = width; - if (width == null) { - renderSpace.setWidth(0); - contentNode.getStyle().setProperty("width", ""); - } else { - int contentWidth = getOffsetWidth() - getContentAreaBorderWidth(); - if (contentWidth < 0) { - contentWidth = 0; - } - contentNode.getStyle().setProperty("width", contentWidth + "px"); - renderSpace.setWidth(contentWidth); - } - - if (!rendering) { - if (isDynamicHeight()) { - Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, tp, - this); - } - - updateOpenTabSize(); - iLayout(); - // TODO Check if this is needed - client.runDescendentsLayout(this); - - } - } public void iLayout() { @@ -951,10 +892,10 @@ public class VTabsheet extends VTabsheetBase { int minWidth = 0; if (!isDynamicHeight()) { - height = renderSpace.getHeight(); + height = contentNode.getOffsetHeight(); } if (!isDynamicWidth()) { - width = renderSpace.getWidth(); + width = contentNode.getOffsetWidth(); } else { /* * If the tabbar is wider than the content we need to use the tabbar @@ -971,8 +912,10 @@ public class VTabsheet extends VTabsheetBase { * Layouts the tab-scroller elements, and applies styles. */ private void updateTabScroller() { - if (width != null) { - DOM.setStyleAttribute(tabs, "width", width); + if (!isDynamicWidth()) { + VPaintableWidget paintable = VPaintableMap.get(client) + .getPaintable(this); + DOM.setStyleAttribute(tabs, "width", paintable.getDefinedWidth()); } // Make sure scrollerIndex is valid @@ -1053,68 +996,15 @@ public class VTabsheet extends VTabsheetBase { return tp.iterator(); } - public boolean hasChildComponent(Widget component) { - if (tp.getWidgetIndex(component) < 0) { - return false; - } else { - return true; - } - } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - tp.replaceComponent(oldComponent, newComponent); - } - - public boolean requestLayout(Set<Widget> children) { - if (!isDynamicHeight() && !isDynamicWidth()) { - /* - * If the height and width has been specified for this container the - * child components cannot make the size of the layout change - */ - // layout size change may affect its available space (scrollbars) - for (Widget widget : children) { - client.handleComponentRelativeSize(widget); - } - return true; - } - - updateOpenTabSize(); - - if (renderInformation.updateSize(getElement())) { - /* - * Size has changed so we let the child components know about the - * new size. - */ - iLayout(); - client.runDescendentsLayout(this); - - return false; - } else { - /* - * Size has not changed so we do not need to propagate the event - * further - */ - return true; - } - - } - private int borderW = -1; - private int getContentAreaBorderWidth() { + int getContentAreaBorderWidth() { if (borderW < 0) { borderW = Util.measureHorizontalBorder(contentNode); } return borderW; } - private final RenderSpace renderSpace = new RenderSpace(0, 0, true); - - public RenderSpace getAllocatedSpace(Widget child) { - // All tabs have equal amount of space allocated - return renderSpace; - } - @Override protected int getTabCount() { return tb.getTabCount(); diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBase.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBase.java index 582452988a..8552f45bd9 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBase.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBase.java @@ -12,11 +12,10 @@ import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.client.Container; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.VPaintableWidget; -abstract class VTabsheetBase extends ComplexPanel implements Container { +abstract class VTabsheetBase extends ComplexPanel { String id; ApplicationConnection client; diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPaintable.java index 29e3e3d95c..7379362b3f 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPaintable.java @@ -10,11 +10,11 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.VPaintableWidget; -public class VTabsheetPaintable extends VTabsheetBasePaintable { +public class VTabsheetPaintable extends VTabsheetBasePaintable implements + ResizeRequired { @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - getWidgetForPaintable().rendering = true; if (isRealUpdate(uidl)) { // Handle stylename changes before generics (might affect size @@ -24,12 +24,11 @@ public class VTabsheetPaintable extends VTabsheetBasePaintable { super.updateFromUIDL(uidl, client); if (!isRealUpdate(uidl)) { - getWidgetForPaintable().rendering = false; return; } // tabs; push or not - if (!getWidgetForPaintable().isDynamicWidth()) { + if (!isUndefinedWidth()) { // FIXME: This makes tab sheet tabs go to 1px width on every update // and then back to original width // update width later, in updateTabScroller(); @@ -44,7 +43,7 @@ public class VTabsheetPaintable extends VTabsheetBasePaintable { getWidgetForPaintable().updateDynamicWidth(); } - if (!getWidgetForPaintable().isDynamicHeight()) { + if (!isUndefinedHeight()) { // Must update height after the styles have been set getWidgetForPaintable().updateContentNodeHeight(); getWidgetForPaintable().updateOpenTabSize(); @@ -61,11 +60,7 @@ public class VTabsheetPaintable extends VTabsheetBasePaintable { // Ignore, most likely empty tabsheet } - getWidgetForPaintable().renderInformation - .updateSize(getWidgetForPaintable().getElement()); - getWidgetForPaintable().waitingForResponse = false; - getWidgetForPaintable().rendering = false; } @Override @@ -82,4 +77,26 @@ public class VTabsheetPaintable extends VTabsheetBasePaintable { /* Tabsheet does not render its children's captions */ } + public void onResize() { + VTabsheet tabsheet = getWidgetForPaintable(); + + tabsheet.updateContentNodeHeight(); + + if (isUndefinedWidth()) { + tabsheet.contentNode.getStyle().setProperty("width", ""); + } else { + int contentWidth = tabsheet.getOffsetWidth() + - tabsheet.getContentAreaBorderWidth(); + if (contentWidth < 0) { + contentWidth = 0; + } + tabsheet.contentNode.getStyle().setProperty("width", + contentWidth + "px"); + } + + tabsheet.updateOpenTabSize(); + tabsheet.iLayout(); + + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java b/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java index f0c284c2d0..34c2a8b866 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java @@ -26,7 +26,6 @@ import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.ComputedStyle; -import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.ui.VTreeTable.VTreeTableScrollBody.VTreeTableRow; @@ -802,26 +801,4 @@ public class VTreeTable extends VScrollTable { setTotalRows(newTotalRows); } - @Override - public RenderSpace getAllocatedSpace(Widget child) { - VTreeTableRow row = (VTreeTableRow) child.getParent(); - if (row.widgetInHierarchyColumn == child) { - final int hierarchyAndIconWidth = row.getHierarchyAndIconWidth(); - final RenderSpace allocatedSpace = super.getAllocatedSpace(child); - return new RenderSpace() { - @Override - public int getWidth() { - return allocatedSpace.getWidth() - hierarchyAndIconWidth; - } - - @Override - public int getHeight() { - return allocatedSpace.getHeight(); - } - - }; - } - return super.getAllocatedSpace(child); - } - } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayout.java index fe5749ec8b..03b71321b2 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayout.java @@ -3,12 +3,12 @@ */ package com.vaadin.terminal.gwt.client.ui; -public class VVerticalLayout extends VOrderedLayout { +public class VVerticalLayout extends VMeasuringOrderedLayout { public static final String CLASSNAME = "v-verticallayout"; public VVerticalLayout() { - super(CLASSNAME, ORIENTATION_VERTICAL); + super(CLASSNAME, true); } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayoutPaintable.java index 71c6d91c69..2de30d4cc3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayoutPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayoutPaintable.java @@ -5,7 +5,7 @@ package com.vaadin.terminal.gwt.client.ui; import com.google.gwt.core.client.GWT; -public class VVerticalLayoutPaintable extends VOrderedLayoutPaintable { +public class VVerticalLayoutPaintable extends VMeasuringOrderedLayoutPaintable { @Override public VVerticalLayout getWidgetForPaintable() { diff --git a/src/com/vaadin/terminal/gwt/client/ui/VView.java b/src/com/vaadin/terminal/gwt/client/ui/VView.java index ea5610cdaa..fb53085606 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VView.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VView.java @@ -6,15 +6,9 @@ package com.vaadin.terminal.gwt.client.ui; import java.util.ArrayList; import java.util.LinkedHashSet; -import java.util.Set; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; -import com.google.gwt.dom.client.DivElement; -import com.google.gwt.dom.client.Document; -import com.google.gwt.dom.client.Element; -import com.google.gwt.dom.client.Style; -import com.google.gwt.dom.client.Style.Display; import com.google.gwt.event.logical.shared.ResizeEvent; import com.google.gwt.event.logical.shared.ResizeHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; @@ -27,12 +21,9 @@ import com.google.gwt.user.client.History; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.SimplePanel; -import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; -import com.vaadin.terminal.gwt.client.Container; import com.vaadin.terminal.gwt.client.Focusable; -import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VConsole; @@ -42,7 +33,7 @@ import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHan /** * */ -public class VView extends SimplePanel implements Container, ResizeHandler, +public class VView extends SimplePanel implements ResizeHandler, Window.ClosingHandler, ShortcutActionHandlerOwner, Focusable { public static final String FRAGMENT_VARIABLE = "fragment"; @@ -97,12 +88,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler, */ public static final String RESIZE_LAZY = "rL"; - /** - * Reference to the parent frame/iframe. Null if there is no parent (i)frame - * or if the application and parent frame are in different domains. - */ - Element parentFrame; - private HandlerRegistration historyHandlerRegistration; /** @@ -183,10 +168,11 @@ public class VView extends SimplePanel implements Container, ResizeHandler, } if (changed) { VConsole.log("Running layout functions due to window resize"); - connection.runDescendentsLayout(VView.this); Util.runWebkitOverflowAutoFix(getElement()); sendClientResized(); + + connection.doLayout(false); } } @@ -336,134 +322,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler, VTextField.flushChangesFromFocusedTextField(); } - private final RenderSpace myRenderSpace = new RenderSpace() { - private int excessHeight = -1; - private int excessWidth = -1; - - @Override - public int getHeight() { - return getElement().getOffsetHeight() - getExcessHeight(); - } - - private int getExcessHeight() { - if (excessHeight < 0) { - detectExcessSize(); - } - return excessHeight; - } - - private void detectExcessSize() { - // TODO define that iview cannot be themed and decorations should - // get to parent element, then get rid of this expensive and error - // prone function - final String overflow = getElement().getStyle().getProperty( - "overflow"); - getElement().getStyle().setProperty("overflow", "hidden"); - if (BrowserInfo.get().isIE() - && getElement().getPropertyInt("clientWidth") == 0) { - // can't detect possibly themed border/padding width in some - // situations (with some layout configurations), use empty div - // to measure width properly - DivElement div = Document.get().createDivElement(); - div.setInnerHTML(" "); - div.getStyle().setProperty("overflow", "hidden"); - div.getStyle().setProperty("height", "1px"); - getElement().appendChild(div); - excessWidth = getElement().getOffsetWidth() - - div.getOffsetWidth(); - getElement().removeChild(div); - } else { - excessWidth = getElement().getOffsetWidth() - - getElement().getPropertyInt("clientWidth"); - } - excessHeight = getElement().getOffsetHeight() - - getElement().getPropertyInt("clientHeight"); - - getElement().getStyle().setProperty("overflow", overflow); - } - - @Override - public int getWidth() { - if (connection.getConfiguration().isStandalone()) { - return getElement().getOffsetWidth() - getExcessWidth(); - } - - // If not running standalone, there might be multiple Vaadin apps - // that won't shrink with the browser window as the components have - // calculated widths (#3125) - - // Find all Vaadin applications on the page - ArrayList<String> vaadinApps = new ArrayList<String>(); - loadAppIdListFromDOM(vaadinApps); - - // Store original styles here so they can be restored - ArrayList<String> originalDisplays = new ArrayList<String>( - vaadinApps.size()); - - String ownAppId = connection.getConfiguration().getRootPanelId(); - - // Hiding elements causes browser to forget scroll position -> must - // save values and restore when the elements are visible again #7976 - int originalScrollTop = Window.getScrollTop(); - int originalScrollLeft = Window.getScrollLeft(); - - // Set display: none for all Vaadin apps - for (int i = 0; i < vaadinApps.size(); i++) { - String appId = vaadinApps.get(i); - Element targetElement; - if (appId.equals(ownAppId)) { - // Only hide the contents of current application - targetElement = layout.getWidgetForPaintable().getElement(); - } else { - // Hide everything for other applications - targetElement = Document.get().getElementById(appId); - } - Style layoutStyle = targetElement.getStyle(); - - originalDisplays.add(i, layoutStyle.getDisplay()); - layoutStyle.setDisplay(Display.NONE); - } - - int w = getElement().getOffsetWidth() - getExcessWidth(); - - // Then restore the old display style before returning - for (int i = 0; i < vaadinApps.size(); i++) { - String appId = vaadinApps.get(i); - Element targetElement; - if (appId.equals(ownAppId)) { - targetElement = layout.getWidgetForPaintable().getElement(); - } else { - targetElement = Document.get().getElementById(appId); - } - Style layoutStyle = targetElement.getStyle(); - String originalDisplay = originalDisplays.get(i); - - if (originalDisplay.length() == 0) { - layoutStyle.clearDisplay(); - } else { - layoutStyle.setProperty("display", originalDisplay); - } - } - - // Scroll back to original location - Window.scrollTo(originalScrollLeft, originalScrollTop); - - return w; - } - - private int getExcessWidth() { - if (excessWidth < 0) { - detectExcessSize(); - } - return excessWidth; - } - - @Override - public int getScrollbarSize() { - return Util.getNativeScrollbarSize(); - } - }; - private native static void loadAppIdListFromDOM(ArrayList<String> list) /*-{ var j; @@ -472,65 +330,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler, } }-*/; - public RenderSpace getAllocatedSpace(Widget child) { - return myRenderSpace; - } - - public boolean hasChildComponent(Widget component) { - return (component != null && component == layout); - } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - // TODO This is untested as no layouts require this - if (oldComponent != layout) { - return; - } - - setWidget(newComponent); - layout = (VPaintableWidget) newComponent; - } - - public boolean requestLayout(Set<Widget> children) { - /* - * Can never propagate further and we do not want need to re-layout the - * layout which has caused this request. - */ - updateParentFrameSize(); - - // layout size change may affect its available space (scrollbars) - connection.handleComponentRelativeSize(layout.getWidgetForPaintable()); - - return true; - - } - - void updateParentFrameSize() { - if (parentFrame == null) { - return; - } - - int childHeight = Util.getRequiredHeight(getWidget().getElement()); - int childWidth = Util.getRequiredWidth(getWidget().getElement()); - - parentFrame.getStyle().setPropertyPx("width", childWidth); - parentFrame.getStyle().setPropertyPx("height", childHeight); - } - - static native Element getParentFrame() - /*-{ - try { - var frameElement = $wnd.frameElement; - if (frameElement == null) { - return null; - } - if (frameElement.getAttribute("autoResize") == "true") { - return frameElement; - } - } catch (e) { - } - return null; - }-*/; - /** * Return an iterator for current subwindows. This method is meant for * testing purposes only. diff --git a/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java index 890fdd3e13..c81797e4be 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java @@ -144,9 +144,6 @@ public class VViewPaintable extends VAbstractPaintableWidgetContainer { } getWidgetForPaintable().layout.updateFromUIDL(childUidl, client); - if (isRealUpdate(childUidl)) { - getWidgetForPaintable().updateParentFrameSize(); - } // Save currently open subwindows to track which will need to be closed final HashSet<VWindow> removedSubWindows = new HashSet<VWindow>( @@ -308,8 +305,6 @@ public class VViewPaintable extends VAbstractPaintableWidgetContainer { // side-effects from focusing (scrollIntoView). getWidgetForPaintable().getElement().focus(); } - - getWidgetForPaintable().parentFrame = VView.getParentFrame(); } private ClickEventHandler clickEventHandler = new ClickEventHandler(this, diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java index d4c8f74605..c4dfb47091 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java @@ -7,7 +7,6 @@ package com.vaadin.terminal.gwt.client.ui; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; -import java.util.Set; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; @@ -30,10 +29,8 @@ import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.Console; -import com.vaadin.terminal.gwt.client.Container; import com.vaadin.terminal.gwt.client.EventId; import com.vaadin.terminal.gwt.client.Focusable; -import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VPaintableWidget; import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; @@ -43,9 +40,8 @@ import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHan * * @author Vaadin Ltd */ -public class VWindow extends VOverlay implements Container, - ShortcutActionHandlerOwner, ScrollHandler, KeyDownHandler, - FocusHandler, BlurHandler, Focusable { +public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, + ScrollHandler, KeyDownHandler, FocusHandler, BlurHandler, Focusable { /** * Minimum allowed height of a window. This refers to the content area, not @@ -150,9 +146,6 @@ public class VWindow extends VOverlay implements Container, // resizes the window. boolean centered = false; - private RenderSpace renderSpace = new RenderSpace(MIN_CONTENT_AREA_WIDTH, - MIN_CONTENT_AREA_HEIGHT, true); - private String width; private String height; @@ -759,6 +752,7 @@ public class VWindow extends VOverlay implements Container, } Util.runWebkitOverflowAutoFix(contentPanel.getElement()); + client.doLayout(false); } @Override @@ -804,8 +798,6 @@ public class VWindow extends VOverlay implements Container, DOM.setStyleAttribute(getElement(), "width", rootWidth + "px"); } - renderSpace.setWidth(contentAreaInnerWidth); - updateShadowSizeAndPosition(); } } @@ -830,10 +822,6 @@ public class VWindow extends VOverlay implements Container, if (height == null || "".equals(height)) { getElement().getStyle().clearHeight(); contentPanel.getElement().getStyle().clearHeight(); - // Reset to default, the exact value does not actually - // matter as an undefined-height parent should not have - // a relative-height child anyway. - renderSpace.setHeight(MIN_CONTENT_AREA_HEIGHT); } else { getElement().getStyle().setProperty("height", height); int contentHeight = getElement().getOffsetHeight() @@ -844,7 +832,6 @@ public class VWindow extends VOverlay implements Container, getElement().getStyle() .setProperty("height", rootHeight + "px"); } - renderSpace.setHeight(contentHeight); contentPanel.getElement().getStyle() .setProperty("height", contentHeight + "px"); } @@ -852,11 +839,8 @@ public class VWindow extends VOverlay implements Container, updateShadowSizeAndPosition(); } - private int extraH = 0; - int getExtraHeight() { - extraH = header.getOffsetHeight() + footer.getOffsetHeight(); - return extraH; + return header.getOffsetHeight() + footer.getOffsetHeight(); } private void onDragEvent(Event event) { @@ -974,38 +958,12 @@ public class VWindow extends VOverlay implements Container, setHeight(height); } - public RenderSpace getAllocatedSpace(Widget child) { - if (child == layout.getWidgetForPaintable()) { - return renderSpace; - } else { - // Exception ?? - return null; - } - } - - public boolean hasChildComponent(Widget component) { - if (component == layout.getWidgetForPaintable()) { - return true; - } else { - return false; - } - } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - contentPanel.setWidget(newComponent); - } - - public boolean requestLayout(Set<Widget> children) { + void requestLayout() { if (dynamicWidth && !layoutRelativeWidth) { setNaturalWidth(); } - if (centered) { - center(); - } - updateShadowSizeAndPosition(); // layout size change may affect its available space (scrollbars) client.handleComponentRelativeSize(layout.getWidgetForPaintable()); - return true; } public ShortcutActionHandler getShortcutActionHandler() { diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java index e77aefc25b..a79379746c 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java @@ -19,7 +19,8 @@ import com.vaadin.terminal.gwt.client.VPaintableWidget; import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener; public class VWindowPaintable extends VAbstractPaintableWidgetContainer - implements BeforeShortcutActionListener { + implements BeforeShortcutActionListener, ResizeRequired, + LayoutPhaseListener { private static final String CLICK_EVENT_IDENTIFIER = VPanelPaintable.CLICK_EVENT_IDENTIFIER; @@ -303,4 +304,20 @@ public class VWindowPaintable extends VAbstractPaintableWidgetContainer return GWT.create(VWindow.class); } + public void onResize() { + getWidgetForPaintable().requestLayout(); + } + + public void beforeLayout() { + + } + + public void afterLayout() { + VWindow window = getWidgetForPaintable(); + if (window.centered) { + window.center(); + window.updateShadowSizeAndPosition(); + } + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/label/VLabel.java b/src/com/vaadin/terminal/gwt/client/ui/label/VLabel.java index 8828582b57..357711d2f4 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/label/VLabel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/label/VLabel.java @@ -4,6 +4,7 @@ package com.vaadin.terminal.gwt.client.ui.label; +import com.google.gwt.dom.client.Style.Display; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.HTML; import com.vaadin.terminal.gwt.client.BrowserInfo; @@ -15,9 +16,6 @@ public class VLabel extends HTML { public static final String CLASSNAME = "v-label"; private static final String CLASSNAME_UNDEFINED_WIDTH = "v-label-undef-w"; - private int verticalPaddingBorder = 0; - private int horizontalPaddingBorder = 0; - public VLabel() { super(); setStyleName(CLASSNAME); @@ -41,19 +39,14 @@ public class VLabel extends HTML { } @Override - public void setHeight(String height) { - verticalPaddingBorder = Util.setHeightExcludingPaddingAndBorder(this, - height, verticalPaddingBorder); - } - - @Override public void setWidth(String width) { - horizontalPaddingBorder = Util.setWidthExcludingPaddingAndBorder(this, - width, horizontalPaddingBorder); + super.setWidth(width); if (width == null || width.equals("")) { setStyleName(getElement(), CLASSNAME_UNDEFINED_WIDTH, true); + getElement().getStyle().setDisplay(Display.INLINE_BLOCK); } else { setStyleName(getElement(), CLASSNAME_UNDEFINED_WIDTH, false); + getElement().getStyle().clearDisplay(); } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayout.java b/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayout.java deleted file mode 100644 index 9b38ba23ae..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayout.java +++ /dev/null @@ -1,343 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.terminal.gwt.client.ui.layout; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import com.google.gwt.dom.client.DivElement; -import com.google.gwt.dom.client.Document; -import com.google.gwt.dom.client.Node; -import com.google.gwt.dom.client.NodeList; -import com.google.gwt.dom.client.Style; -import com.google.gwt.user.client.ui.ComplexPanel; -import com.google.gwt.user.client.ui.Widget; -import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.client.BrowserInfo; -import com.vaadin.terminal.gwt.client.Container; -import com.vaadin.terminal.gwt.client.VPaintableMap; -import com.vaadin.terminal.gwt.client.VPaintableWidget; -import com.vaadin.terminal.gwt.client.ui.VMarginInfo; - -public abstract class CellBasedLayout extends ComplexPanel implements Container { - - protected Map<Widget, ChildComponentContainer> widgetToComponentContainer = new HashMap<Widget, ChildComponentContainer>(); - - protected ApplicationConnection client = null; - - public DivElement root; - - public static final int ORIENTATION_VERTICAL = 0; - public static final int ORIENTATION_HORIZONTAL = 1; - - protected Margins activeMargins = new Margins(0, 0, 0, 0); - protected VMarginInfo activeMarginsInfo = new VMarginInfo(-1); - - protected boolean spacingEnabled = false; - protected final Spacing spacingFromCSS = new Spacing(12, 12); - protected final Spacing activeSpacing = new Spacing(0, 0); - - boolean dynamicWidth; - - boolean dynamicHeight; - - private final DivElement clearElement = Document.get().createDivElement(); - - private String lastStyleName = ""; - - boolean marginsNeedsRecalculation = false; - - protected String STYLENAME_SPACING = ""; - protected String STYLENAME_MARGIN_TOP = ""; - protected String STYLENAME_MARGIN_RIGHT = ""; - protected String STYLENAME_MARGIN_BOTTOM = ""; - protected String STYLENAME_MARGIN_LEFT = ""; - - public static class Spacing { - - public int hSpacing = 0; - public int vSpacing = 0; - - public Spacing(int hSpacing, int vSpacing) { - this.hSpacing = hSpacing; - this.vSpacing = vSpacing; - } - - @Override - public String toString() { - return "Spacing [hSpacing=" + hSpacing + ",vSpacing=" + vSpacing - + "]"; - } - - } - - public CellBasedLayout() { - super(); - - setElement(Document.get().createDivElement()); - getElement().getStyle().setProperty("overflow", "hidden"); - if (BrowserInfo.get().isIE()) { - getElement().getStyle().setProperty("position", "relative"); - getElement().getStyle().setProperty("zoom", "1"); - } - - root = Document.get().createDivElement(); - root.getStyle().setProperty("overflow", "hidden"); - if (BrowserInfo.get().isIE()) { - root.getStyle().setProperty("position", "relative"); - } - - getElement().appendChild(root); - - Style style = clearElement.getStyle(); - style.setProperty("width", "0px"); - style.setProperty("height", "0px"); - style.setProperty("clear", "both"); - style.setProperty("overflow", "hidden"); - root.appendChild(clearElement); - - } - - public boolean hasChildComponent(Widget component) { - return widgetToComponentContainer.containsKey(component); - } - - @Override - public void setStyleName(String styleName) { - super.setStyleName(styleName); - - if (isAttached() && marginsNeedsRecalculation - || !lastStyleName.equals(styleName)) { - measureMarginsAndSpacing(); - lastStyleName = styleName; - marginsNeedsRecalculation = false; - } - - } - - @Override - public void setWidth(String width) { - super.setWidth(width); - - /* - * Ensure the the dynamic width stays up to date even if size is altered - * only on client side. - */ - if (width == null || width.equals("")) { - dynamicWidth = true; - } else { - dynamicWidth = false; - } - } - - @Override - public void setHeight(String height) { - super.setHeight(height); - - /* - * Ensure the the dynamic height stays up to date even if size is - * altered only on client side. - */ - if (height == null || height.equals("")) { - dynamicHeight = true; - } else { - dynamicHeight = false; - } - } - - public void addOrMoveChild(ChildComponentContainer childComponent, - int position) { - if (childComponent.getParent() == this) { - if (getWidgetIndex(childComponent) != position) { - // Detach from old position child. - childComponent.removeFromParent(); - - // Logical attach. - getChildren().insert(childComponent, position); - - root.insertBefore(childComponent.getElement(), root - .getChildNodes().getItem(position)); - - adopt(childComponent); - } - } else { - widgetToComponentContainer.put(childComponent.getWidget(), - childComponent); - - // Logical attach. - getChildren().insert(childComponent, position); - - // avoid inserts (they are slower than appends) - boolean insert = true; - if (widgetToComponentContainer.size() == position) { - insert = false; - } - if (insert) { - root.insertBefore(childComponent.getElement(), root - .getChildNodes().getItem(position)); - } else { - root.insertBefore(childComponent.getElement(), clearElement); - } - // Adopt. - adopt(childComponent); - - } - - } - - public Collection<ChildComponentContainer> getComponentContainers() { - return widgetToComponentContainer.values(); - } - - public ChildComponentContainer getComponentContainer(Widget child) { - return widgetToComponentContainer.get(child); - } - - public boolean isDynamicWidth() { - return dynamicWidth; - } - - public boolean isDynamicHeight() { - return dynamicHeight; - } - - private static DivElement measurement; - private static DivElement measurement2; - private static DivElement measurement3; - private static DivElement helper; - - static { - helper = Document.get().createDivElement(); - helper.setInnerHTML("<div style=\"position:absolute;top:0;left:0;height:0;visibility:hidden;overflow:hidden;\">" - + "<div style=\"width:0;height:0;visibility:hidden;overflow:hidden;\">" - + "</div></div>" - + "<div style=\"position:absolute;height:0;overflow:hidden;\"></div>"); - NodeList<Node> childNodes = helper.getChildNodes(); - measurement = (DivElement) childNodes.getItem(0); - measurement2 = (DivElement) measurement.getFirstChildElement(); - measurement3 = (DivElement) childNodes.getItem(1); - } - - protected boolean measureMarginsAndSpacing() { - if (!isAttached()) { - return false; - } - - // Measure spacing (actually CSS padding) - measurement3.setClassName(STYLENAME_SPACING - + (spacingEnabled ? "-on" : "-off")); - - String sn = getStylePrimaryName() + "-margin"; - - if (activeMarginsInfo.hasTop()) { - sn += " " + STYLENAME_MARGIN_TOP; - } - if (activeMarginsInfo.hasBottom()) { - sn += " " + STYLENAME_MARGIN_BOTTOM; - } - if (activeMarginsInfo.hasLeft()) { - sn += " " + STYLENAME_MARGIN_LEFT; - } - if (activeMarginsInfo.hasRight()) { - sn += " " + STYLENAME_MARGIN_RIGHT; - } - - // Measure top and left margins (actually CSS padding) - measurement.setClassName(sn); - - root.appendChild(helper); - - activeSpacing.vSpacing = measurement3.getOffsetHeight(); - activeSpacing.hSpacing = measurement3.getOffsetWidth(); - - activeMargins.setMarginTop(measurement2.getOffsetTop()); - activeMargins.setMarginLeft(measurement2.getOffsetLeft()); - activeMargins.setMarginRight(measurement.getOffsetWidth() - - activeMargins.getMarginLeft()); - activeMargins.setMarginBottom(measurement.getOffsetHeight() - - activeMargins.getMarginTop()); - - // ApplicationConnection.getConsole().log("Margins: " + activeMargins); - // ApplicationConnection.getConsole().log("Spacing: " + activeSpacing); - // Util.alert("Margins: " + activeMargins); - root.removeChild(helper); - - // apply margin - Style style = root.getStyle(); - style.setPropertyPx("marginLeft", activeMargins.getMarginLeft()); - style.setPropertyPx("marginRight", activeMargins.getMarginRight()); - style.setPropertyPx("marginTop", activeMargins.getMarginTop()); - style.setPropertyPx("marginBottom", activeMargins.getMarginBottom()); - - return true; - } - - protected ChildComponentContainer getFirstChildComponentContainer() { - int size = getChildren().size(); - if (size < 1) { - return null; - } - - return (ChildComponentContainer) getChildren().get(0); - } - - public void removeChildrenAfter(int pos) { - // Remove all children after position "pos" but leave the clear element - // in place - - int toRemove = getChildren().size() - pos; - while (toRemove-- > 0) { - /* flag to not if widget has been moved and rendered elsewhere */ - boolean relocated = false; - ChildComponentContainer child = (ChildComponentContainer) getChildren() - .get(pos); - Widget widget = child.getWidget(); - if (widget == null) { - // a rare case where child component has been relocated and - // rendered elsewhere - // clean widgetToComponentContainer map by iterating the correct - // mapping - Iterator<Widget> iterator = widgetToComponentContainer.keySet() - .iterator(); - while (iterator.hasNext()) { - Widget key = iterator.next(); - if (widgetToComponentContainer.get(key) == child) { - widget = key; - relocated = true; - break; - } - } - if (widget == null) { - throw new NullPointerException(); - } - } - // ChildComponentContainer remove = - widgetToComponentContainer.remove(widget); - remove(child); - if (!relocated) { - VPaintableMap paintableMap = VPaintableMap.get(client); - VPaintableWidget p = paintableMap.getPaintable(widget); - paintableMap.unregisterPaintable(p); - } - } - - } - - public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - ChildComponentContainer componentContainer = widgetToComponentContainer - .remove(oldComponent); - if (componentContainer == null) { - return; - } - - componentContainer.setPaintable(VPaintableMap.get(client).getPaintable( - newComponent)); - client.unregisterPaintable(VPaintableMap.get(client).getPaintable( - oldComponent)); - widgetToComponentContainer.put(newComponent, componentContainer); - } - -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayoutPaintable.java deleted file mode 100644 index 752462dcf6..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayoutPaintable.java +++ /dev/null @@ -1,83 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.terminal.gwt.client.ui.layout; - -import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.client.UIDL; -import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidgetContainer; -import com.vaadin.terminal.gwt.client.ui.VMarginInfo; - -public abstract class CellBasedLayoutPaintable extends - VAbstractPaintableWidgetContainer { - - @Override - public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - getWidgetForPaintable().client = client; - - // Only non-cached UIDL:s can introduce changes - if (isCachedUpdate(uidl)) { - return; - } - - /** - * Margin and spacind detection depends on classNames and must be set - * before setting size. Here just update the details from UIDL and from - * overridden setStyleName run actual margin detections. - */ - updateMarginAndSpacingInfo(uidl); - - /* - * This call should be made first. Ensure correct implementation, handle - * size etc. - */ - super.updateFromUIDL(uidl, client); - - handleDynamicDimensions(uidl); - } - - private void handleDynamicDimensions(UIDL uidl) { - String w = uidl.hasAttribute("width") ? uidl - .getStringAttribute("width") : ""; - - String h = uidl.hasAttribute("height") ? uidl - .getStringAttribute("height") : ""; - - if (w.equals("")) { - getWidgetForPaintable().dynamicWidth = true; - } else { - getWidgetForPaintable().dynamicWidth = false; - } - - if (h.equals("")) { - getWidgetForPaintable().dynamicHeight = true; - } else { - getWidgetForPaintable().dynamicHeight = false; - } - - } - - void updateMarginAndSpacingInfo(UIDL uidl) { - if (!uidl.hasAttribute("invisible")) { - int bitMask = uidl.getIntAttribute("margins"); - if (getWidgetForPaintable().activeMarginsInfo.getBitMask() != bitMask) { - getWidgetForPaintable().activeMarginsInfo = new VMarginInfo( - bitMask); - getWidgetForPaintable().marginsNeedsRecalculation = true; - } - boolean spacing = uidl.getBooleanAttribute("spacing"); - if (spacing != getWidgetForPaintable().spacingEnabled) { - getWidgetForPaintable().marginsNeedsRecalculation = true; - getWidgetForPaintable().spacingEnabled = spacing; - } - } - } - - @Override - protected abstract CellBasedLayout createWidget(); - - @Override - public CellBasedLayout getWidgetForPaintable() { - return (CellBasedLayout) super.getWidgetForPaintable(); - } -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/ChildComponentContainer.java b/src/com/vaadin/terminal/gwt/client/ui/layout/ChildComponentContainer.java index 92464cd459..dffb418660 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/layout/ChildComponentContainer.java +++ b/src/com/vaadin/terminal/gwt/client/ui/layout/ChildComponentContainer.java @@ -9,6 +9,7 @@ import java.util.NoSuchElementException; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.Style.Display; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; @@ -24,6 +25,9 @@ import com.vaadin.terminal.gwt.client.ui.AlignmentInfo; public class ChildComponentContainer extends Panel { + public static final int ORIENTATION_VERTICAL = 0; + public static final int ORIENTATION_HORIZONTAL = 1; + /** * Size of the container DIV excluding any margins and also excluding the * expansion amount (containerExpansion) @@ -79,7 +83,6 @@ public class ChildComponentContainer extends Panel { widgetDIV = Document.get().createDivElement(); - setFloat(widgetDIV, "left"); setElement(containerDIV); containerDIV.getStyle().setProperty("height", "0"); containerDIV.getStyle().setProperty("width", "0px"); @@ -131,6 +134,7 @@ public class ChildComponentContainer extends Panel { // Physical attach. widgetDIV.appendChild(widget.getElement()); adopt(w); + w.getElement().getStyle().setDisplay(Display.INLINE_BLOCK); } } @@ -151,7 +155,7 @@ public class ChildComponentContainer extends Panel { } public void setOrientation(int orientation) { - if (orientation == CellBasedLayout.ORIENTATION_HORIZONTAL) { + if (orientation == ORIENTATION_HORIZONTAL) { setFloat(getElement(), "left"); } else { setFloat(getElement(), ""); @@ -617,7 +621,7 @@ public class ChildComponentContainer extends Panel { */ public boolean widgetHasSizeSpecified(int orientation) { String size; - if (orientation == CellBasedLayout.ORIENTATION_HORIZONTAL) { + if (orientation == ORIENTATION_HORIZONTAL) { size = widget.getElement().getStyle().getProperty("width"); } else { size = widget.getElement().getStyle().getProperty("height"); @@ -629,7 +633,7 @@ public class ChildComponentContainer extends Panel { if (relativeSize == null) { return false; } - if (orientation == CellBasedLayout.ORIENTATION_HORIZONTAL) { + if (orientation == ORIENTATION_HORIZONTAL) { return relativeSize.getWidth() >= 0; } else { return relativeSize.getHeight() >= 0; @@ -665,7 +669,7 @@ public class ChildComponentContainer extends Panel { public int expand(int orientation, int spaceForExpansion) { int expansionAmount = (int) (spaceForExpansion * expandRatio); - if (orientation == CellBasedLayout.ORIENTATION_HORIZONTAL) { + if (orientation == ORIENTATION_HORIZONTAL) { // HORIZONTAL containerExpansion.setWidth(expansionAmount); } else { @@ -677,7 +681,7 @@ public class ChildComponentContainer extends Panel { } public void expandExtra(int orientation, int extra) { - if (orientation == CellBasedLayout.ORIENTATION_HORIZONTAL) { + if (orientation == ORIENTATION_HORIZONTAL) { // HORIZONTAL containerExpansion.setWidth(containerExpansion.getWidth() + extra); } else { diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/VLayoutSlot.java b/src/com/vaadin/terminal/gwt/client/ui/layout/VLayoutSlot.java new file mode 100644 index 0000000000..4567fcaad2 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/layout/VLayoutSlot.java @@ -0,0 +1,196 @@ +package com.vaadin.terminal.gwt.client.ui.layout; + +import com.google.gwt.dom.client.Document; +import com.google.gwt.dom.client.Style; +import com.google.gwt.dom.client.Style.Position; +import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.terminal.gwt.client.VCaption; +import com.vaadin.terminal.gwt.client.ui.AlignmentInfo; + +public abstract class VLayoutSlot { + + private final Element wrapper = Document.get().createDivElement().cast(); + + private AlignmentInfo alignment; + private VCaption caption; + private final Widget widget; + + private double expandRatio; + + public VLayoutSlot(Widget widget) { + this.widget = widget; + + wrapper.getStyle().setPosition(Position.ABSOLUTE); + } + + public VCaption getCaption() { + return caption; + } + + public void setCaption(VCaption caption) { + if (this.caption != null) { + this.caption.removeFromParent(); + } + this.caption = caption; + if (caption != null) { + // Physical attach. + DOM.insertBefore(wrapper, caption.getElement(), widget.getElement()); + caption.getElement().getStyle().setPosition(Position.ABSOLUTE); + } + } + + public AlignmentInfo getAlignment() { + return alignment; + } + + public Widget getWidget() { + return widget; + } + + public void setAlignment(AlignmentInfo alignment) { + this.alignment = alignment; + } + + public void positionHorizontally(double currentLocation, + double allocatedSpace) { + Style style = wrapper.getStyle(); + + if (isRelativeWidth()) { + style.setPropertyPx("width", (int) allocatedSpace); + style.clearProperty("minWidth"); + } else { + style.clearProperty("width"); + style.setPropertyPx("minWidth", getCaptionWidth()); + } + + VCaption caption = getCaption(); + Style captionStyle = caption != null ? caption.getElement().getStyle() + : null; + + AlignmentInfo alignment = getAlignment(); + if (!alignment.isLeft()) { + double usedWidth = getWidgetWidth(); + if (alignment.isHorizontalCenter()) { + currentLocation += (allocatedSpace - usedWidth) / 2d; + if (captionStyle != null) { + double captionWidth = getCaptionWidth(); + captionStyle.setLeft(usedWidth / 2 - (captionWidth / 2), + Unit.PX); + captionStyle.clearRight(); + } + } else { + currentLocation += (allocatedSpace - usedWidth); + if (captionStyle != null) { + captionStyle.clearLeft(); + captionStyle.setRight(0, Unit.PX); + } + } + } else { + if (captionStyle != null) { + captionStyle.setLeft(0, Unit.PX); + captionStyle.clearRight(); + } + } + + style.setLeft(currentLocation, Unit.PX); + } + + public void positionVertically(double currentLocation, double allocatedSpace) { + Style style = wrapper.getStyle(); + + VCaption caption = getCaption(); + double captionHeight = caption != null ? getCaptionHeight() : 0; + double contentHeight = allocatedSpace - captionHeight; + + if (isRelativeHeight()) { + style.setHeight(contentHeight, Unit.PX); + } else { + style.clearHeight(); + } + + if (caption != null) { + style.setPaddingTop(getCaptionHeight(), Unit.PX); + caption.getElement().getStyle().setTop(0, Unit.PX); + } else { + style.clearPaddingTop(); + } + + AlignmentInfo alignment = getAlignment(); + if (!alignment.isTop()) { + double actualHeight = getWidgetHeight() + captionHeight; + if (alignment.isVerticalCenter()) { + currentLocation += (allocatedSpace - actualHeight) / 2d; + } else { + currentLocation += (allocatedSpace - actualHeight); + } + } + + style.setTop(currentLocation, Unit.PX); + } + + public void positionInDirection(double currentLocation, + double allocatedSpace, boolean isVertical) { + if (isVertical) { + positionVertically(currentLocation, allocatedSpace); + } else { + positionHorizontally(currentLocation, allocatedSpace); + } + } + + public int getWidgetSizeInDirection(boolean isVertical) { + return isVertical ? getWidgetHeight() : getWidgetWidth(); + } + + public int getUsedWidth() { + int captionWidth = (caption != null ? getCaptionWidth() : 0); + return Math.max(captionWidth, getWidgetWidth()); + } + + public int getUsedHeight() { + int captionHeight = (caption != null ? getCaptionHeight() : 0); + return getWidgetHeight() + captionHeight; + } + + public int getUsedSizeInDirection(boolean isVertical) { + return isVertical ? getUsedHeight() : getUsedWidth(); + } + + protected abstract int getCaptionHeight(); + + protected abstract int getCaptionWidth(); + + public abstract int getWidgetHeight(); + + public abstract int getWidgetWidth(); + + public abstract boolean isUndefinedHeight(); + + public abstract boolean isUndefinedWidth(); + + public boolean isUndefinedInDirection(boolean isVertical) { + return isVertical ? isUndefinedHeight() : isUndefinedWidth(); + } + + public abstract boolean isRelativeHeight(); + + public abstract boolean isRelativeWidth(); + + public boolean isRelativeInDirection(boolean isVertical) { + return isVertical ? isRelativeHeight() : isRelativeWidth(); + } + + public Element getWrapperElement() { + return wrapper; + } + + public void setExpandRatio(double expandRatio) { + this.expandRatio = expandRatio; + } + + public double getExpandRatio() { + return expandRatio; + } +}
\ No newline at end of file diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/VPaintableLayoutSlot.java b/src/com/vaadin/terminal/gwt/client/ui/layout/VPaintableLayoutSlot.java new file mode 100644 index 0000000000..17afab0fe8 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/layout/VPaintableLayoutSlot.java @@ -0,0 +1,79 @@ +package com.vaadin.terminal.gwt.client.ui.layout; + +import com.vaadin.terminal.gwt.client.MeasuredSize; +import com.vaadin.terminal.gwt.client.VCaption; +import com.vaadin.terminal.gwt.client.VPaintableWidget; + +public class VPaintableLayoutSlot extends VLayoutSlot { + + final VPaintableWidget paintable; + + public VPaintableLayoutSlot(VPaintableWidget paintable) { + super(paintable.getWidgetForPaintable()); + this.paintable = paintable; + } + + public VPaintableWidget getPaintable() { + return paintable; + } + + @Override + protected int getCaptionHeight() { + VCaption caption = getCaption(); + return caption != null ? getParentSize().getDependencyOuterHeight( + caption.getElement()) : 0; + } + + private MeasuredSize getParentSize() { + return paintable.getParent().getMeasuredSize(); + } + + @Override + protected int getCaptionWidth() { + VCaption caption = getCaption(); + return caption != null ? getParentSize().getDependencyOuterWidth( + caption.getElement()) : 0; + } + + @Override + public void setCaption(VCaption caption) { + VCaption oldCaption = getCaption(); + if (oldCaption != null) { + getParentSize().deRegisterDependency(oldCaption.getElement()); + } + super.setCaption(caption); + if (caption != null) { + getParentSize().registerDependency(caption.getElement()); + } + } + + @Override + public int getWidgetHeight() { + return paintable.getMeasuredSize().getOuterHeight(); + } + + @Override + public int getWidgetWidth() { + return paintable.getMeasuredSize().getOuterWidth(); + } + + @Override + public boolean isUndefinedHeight() { + return paintable.isUndefinedHeight(); + } + + @Override + public boolean isUndefinedWidth() { + return paintable.isUndefinedWidth(); + } + + @Override + public boolean isRelativeHeight() { + return paintable.isRelativeHeight(); + } + + @Override + public boolean isRelativeWidth() { + return paintable.isRelativeWidth(); + } +} |