diff options
102 files changed, 2697 insertions, 5440 deletions
diff --git a/WebContent/VAADIN/themes/base/caption/caption.css b/WebContent/VAADIN/themes/base/caption/caption.css index 549d4f9cef..364b68a226 100644 --- a/WebContent/VAADIN/themes/base/caption/caption.css +++ b/WebContent/VAADIN/themes/base/caption/caption.css @@ -6,32 +6,18 @@ white-space: nowrap; } .v-errorindicator { - float: left; + display: inline-block; } .v-caption .v-icon { - float: left; + display: inline-block; padding-right: 2px; vertical-align: middle; } .v-caption .v-captiontext { - float: left; + display: inline-block; overflow: hidden; vertical-align: middle; } .v-caption .v-required-field-indicator { - float: left; + display: inline-block; } - -.v-caption-clearelem { - clear: both; - width: 0; - height: 0; - overflow: hidden; -} - -.v-ie9 .v-gridlayout-margin>div>div>.v-caption, -.v-ie9 .v-verticallayout>div>div>.v-caption, -.v-ie9 .v-horizontallayout>div>div>.v-caption { - /* Fix possible sub pixel rounding errors that cause error indicators to drop */ - margin-right:-0.5px; -}
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/base/common/common.css b/WebContent/VAADIN/themes/base/common/common.css index 27bc57dd00..62780fcc8e 100644 --- a/WebContent/VAADIN/themes/base/common/common.css +++ b/WebContent/VAADIN/themes/base/common/common.css @@ -90,7 +90,14 @@ div.v-app-loading { border: none; padding: 0; margin: 0; + height: 100%; +} +.v-form-content { + height: 100%; + box-sizing: border-box; + -moz-box-sizing: border-box; } + /* Field modified */ /* Disabled by default .v-modified, .v-richtextarea.v-modified iframe.gwt-RichTextArea, diff --git a/WebContent/VAADIN/themes/base/csslayout/csslayout.css b/WebContent/VAADIN/themes/base/csslayout/csslayout.css index 1f85d6f460..ec0ccc1f84 100644 --- a/WebContent/VAADIN/themes/base/csslayout/csslayout.css +++ b/WebContent/VAADIN/themes/base/csslayout/csslayout.css @@ -1,6 +1,18 @@ .v-csslayout { overflow: hidden; } +.v-csslayout-margin, .v-csslayout-container { + height: 100%; + width: 100%; + box-sizing: border-box; + -moz-box-sizing: border-box; +} +.v-undefined-width > .v-csslayout-margin, .v-undefined-width > .v-csslayout-margin > .v-csslayout-container { + width: auto; +} +.v-undefined-height > .v-csslayout-margin, .v-undefined-height > .v-csslayout-margin > .v-csslayout-container { + height: auto; +} .v-csslayout-margin-top { padding-top: 12px; } diff --git a/WebContent/VAADIN/themes/base/gridlayout/gridlayout.css b/WebContent/VAADIN/themes/base/gridlayout/gridlayout.css index 38e2bb3aed..9edaf152a0 100644 --- a/WebContent/VAADIN/themes/base/gridlayout/gridlayout.css +++ b/WebContent/VAADIN/themes/base/gridlayout/gridlayout.css @@ -1,3 +1,9 @@ +.v-gridlayout { + position: relative; +} +.v-gridlayout-slot { + position: absolute; +} .v-gridlayout-margin-top { padding-top: 12px; } diff --git a/WebContent/VAADIN/themes/base/orderedlayout/orderedlayout.css b/WebContent/VAADIN/themes/base/orderedlayout/orderedlayout.css index 6ed04d8f06..83fcc0b84f 100644 --- a/WebContent/VAADIN/themes/base/orderedlayout/orderedlayout.css +++ b/WebContent/VAADIN/themes/base/orderedlayout/orderedlayout.css @@ -1,3 +1,10 @@ +.v-orderedlayout, +.v-horizontallayout, +.v-verticallayout { + overflow: hidden; + position: relative; +} + .v-orderedlayout-margin-top, .v-horizontallayout-margin-top, .v-verticallayout-margin-top { @@ -31,3 +38,8 @@ padding-top: 0; padding-left: 0; } + +.v-horizontallayout-slot, .v-verticallayout-slot { + position: absolute; + overflow: hidden; +} diff --git a/WebContent/VAADIN/themes/base/paintable/paintable.css b/WebContent/VAADIN/themes/base/paintable/paintable.css new file mode 100644 index 0000000000..1de0b70c38 --- /dev/null +++ b/WebContent/VAADIN/themes/base/paintable/paintable.css @@ -0,0 +1,4 @@ +.v-paintable { + box-sizing: border-box; + -moz-box-sizing: border-box; +}
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/base/panel/panel.css b/WebContent/VAADIN/themes/base/panel/panel.css index 126d3da91c..5ef0d91e49 100644 --- a/WebContent/VAADIN/themes/base/panel/panel.css +++ b/WebContent/VAADIN/themes/base/panel/panel.css @@ -30,6 +30,8 @@ } .v-panel-content { overflow: auto; + box-sizing: border-box; + -moz-box-sizing: border-box; } .v-panel-deco { }
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/base/select/select.css b/WebContent/VAADIN/themes/base/select/select.css index 4487bc6a4e..fe50b98ce6 100644 --- a/WebContent/VAADIN/themes/base/select/select.css +++ b/WebContent/VAADIN/themes/base/select/select.css @@ -56,6 +56,7 @@ .v-filterselect { white-space: nowrap; text-align: left; + display: inline-block; } .v-filterselect .v-icon { float: left; @@ -63,15 +64,18 @@ .v-app .v-filterselect-input, .v-window .v-filterselect-input, .v-popupview-popup .v-filterselect-input { + margin: 0; float: left; -webkit-border-radius: 0px; + box-sizing: border-box; + -moz-box-sizing: border-box; } .v-filterselect-prompt .v-filterselect-input { color: #999; font-style: italic; } .v-filterselect-button { - float: right; + display: inline-block; cursor: pointer; width: 1em; height: 1em; diff --git a/WebContent/VAADIN/themes/chameleon/components/textfield/textfield.css b/WebContent/VAADIN/themes/chameleon/components/textfield/textfield.css index 42bd986cef..a7601bb649 100644 --- a/WebContent/VAADIN/themes/chameleon/components/textfield/textfield.css +++ b/WebContent/VAADIN/themes/chameleon/components/textfield/textfield.css @@ -21,11 +21,15 @@ textarea.v-textarea, padding: .2em; } -input.v-textfield[type="text"], -.v-filterselect { +input.v-textfield[type="text"] { height: 1.2em; } +input.v-paintable.v-textfield[type="text"], +.v-filterselect { + height: 1.6em; + } + body input.v-textfield, body textarea.v-textarea, body input.v-filterselect-input { diff --git a/WebContent/VAADIN/themes/reindeer/datefield/datefield.css b/WebContent/VAADIN/themes/reindeer/datefield/datefield.css index 1dbc59257a..9ca90fd733 100644 --- a/WebContent/VAADIN/themes/reindeer/datefield/datefield.css +++ b/WebContent/VAADIN/themes/reindeer/datefield/datefield.css @@ -45,6 +45,7 @@ span.v-datefield-calendarpanel-month { } .v-datefield-popupcalendar { min-width: 0; + padding-right: 24px; } .v-datefield-year .v-datefield-calendarpanel { width: 100px; @@ -224,17 +225,23 @@ td.v-datefield-calendarpanel-nextyear { .v-op .v-datefield-popup { background: rgba(255,255,255,.95); } -.v-datefield-year .v-datefield-textfield { - width: 4em; +.v-datefield-textfield { + width: 100%; +} +.v-undefined-width > .v-datefield-textfield { + width: auto; } -.v-datefield-month .v-datefield-textfield { - width: 5em; +.v-datefield-year.v-undefined-width > .v-datefield-textfield { + width: 4.5em; } -.v-datefield-day .v-datefield-textfield { +.v-datefield-month.v-undefined-width > .v-datefield-textfield { width: 5.5em; } -.v-datefield-full .v-datefield-textfield { - width: 12em; +.v-datefield-day.v-undefined-width > .v-datefield-textfield { + width: 6em; +} +.v-datefield-full.v-undefined-width >.v-datefield-textfield { + width: 12.5em; } .v-datefield-popupcalendar input.v-datefield-textfield { border-right-width: 0; @@ -242,7 +249,9 @@ td.v-datefield-calendarpanel-nextyear { -moz-border-radius-bottomright: 0; -webkit-border-top-right-radius: 0; -webkit-border-bottom-right-radius: 0; - height: 14px; + height: 23px; + box-sizing: border-box; + -moz-box-sizing: border-box; } .v-datefield.v-readonly input.v-datefield-textfield { border-right-width: 1px; @@ -256,6 +265,7 @@ td.v-datefield-calendarpanel-nextyear { } .v-datefield-popupcalendar .v-datefield-button { width: 24px; + margin-right: -24px; height: 23px; background: transparent; border: none; diff --git a/WebContent/VAADIN/themes/reindeer/panel/panel.css b/WebContent/VAADIN/themes/reindeer/panel/panel.css index ac0074a9e0..08f130271d 100644 --- a/WebContent/VAADIN/themes/reindeer/panel/panel.css +++ b/WebContent/VAADIN/themes/reindeer/panel/panel.css @@ -35,6 +35,7 @@ .v-panel-content > div { background: #fff; min-height: 100%; + overflow: visible; /* min-height causes problems with borders and paddings if overflow is e.g. hidden */ } .blue .v-panel-deco { border-color: #92a3ac; diff --git a/WebContent/VAADIN/themes/reindeer/select/select.css b/WebContent/VAADIN/themes/reindeer/select/select.css index a685e3322a..903066e4ab 100644 --- a/WebContent/VAADIN/themes/reindeer/select/select.css +++ b/WebContent/VAADIN/themes/reindeer/select/select.css @@ -3,6 +3,7 @@ background-repeat: no-repeat; background-image: url(img/left.png); /** sprite-ref: verticals; sprite-margin-bottom: 1px */ padding-left: 2px; + padding-right: 25px; /* Space for the button */ } .v-app .v-filterselect-input, .v-window .v-filterselect-input, @@ -10,13 +11,15 @@ background: transparent repeat-x; background-image: url(img/center.png); /** sprite-ref: verticals; sprite-alignment: repeat; sprite-margin-bottom: 1px */ border: none; - height: 16px; + height: 24px; } /* More specific selector to override padding */ .v-app input.v-filterselect-input, .v-window input.v-filterselect-input, .v-popupview-popup input.v-filterselect-input { padding: 4px 0 4px 2px; + box-sizing: border-box; + -moz-box-sizing: border-box; } .v-filterselect-prompt .v-filterselect-input { font-style: normal; @@ -36,6 +39,7 @@ height: 24px; background-image: url(img/right.png); /** sprite-ref: verticals ; sprite-margin-bottom: 1px */ cursor: default; + margin-right: -25px; } .v-filterselect-button:hover { background-image: url(img/right-hover.png); /** sprite-ref: verticals */ diff --git a/WebContent/VAADIN/themes/reindeer/textfield/textfield.css b/WebContent/VAADIN/themes/reindeer/textfield/textfield.css index eeec6bdfb1..dce5dffba0 100644 --- a/WebContent/VAADIN/themes/reindeer/textfield/textfield.css +++ b/WebContent/VAADIN/themes/reindeer/textfield/textfield.css @@ -20,7 +20,7 @@ -webkit-border-radius: 3px; border-radius: 3px; margin: 0; - height: 15px; + height: 23px; line-height: normal; } .v-textarea, @@ -35,6 +35,10 @@ .v-window textarea.v-textarea { padding: 3px 3px 4px; } +.v-app input.v-textfield.v-paintable, +.v-window input.v-textfield.v-paintable { + height: 24px; +} .v-app .v-textfield-focus, .v-window .v-textfield-focus, .v-popupview-popup .v-textfield-focus, @@ -62,7 +66,8 @@ textarea.v-textarea-prompt { .v-app textarea.v-textarea-small { font-size: 11px; } -.v-table input.v-textfield { +.v-app .v-table input.v-textfield.v-paintable, +.v-window .v-table input.v-textfield.v-paintable { padding: 1px 2px; height: auto; line-height: normal; diff --git a/WebContent/VAADIN/themes/runo/select/select.css b/WebContent/VAADIN/themes/runo/select/select.css index 5ea1dad783..5c66cf81db 100644 --- a/WebContent/VAADIN/themes/runo/select/select.css +++ b/WebContent/VAADIN/themes/runo/select/select.css @@ -22,7 +22,7 @@ .v-popupview-popup .v-filterselect .v-filterselect-input { background: transparent url(img/bg-center-filter.png) no-repeat 1px 0; border: none; - height: 20px; + height: 23px; margin: 0; padding: 2px 0 1px 2px; font-size: 13px; diff --git a/WebContent/VAADIN/themes/runo/textfield/textfield.css b/WebContent/VAADIN/themes/runo/textfield/textfield.css index f4ac207ea1..af4443c80f 100644 --- a/WebContent/VAADIN/themes/runo/textfield/textfield.css +++ b/WebContent/VAADIN/themes/runo/textfield/textfield.css @@ -12,7 +12,7 @@ input.v-textfield, input[type=text].v-textfield, textarea.v-textarea { font-size: 12px; - height: 16px; + height: 22px; padding: 2px; } textarea.v-textarea { @@ -39,7 +39,7 @@ input.v-textfield-small, input[type=text].v-textfield-small, textarea.v-textarea-small { font-size: 11px; - height: 14px; + height: 18px; line-height: 12px; padding: 1px 2px; }
\ No newline at end of file diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index cecfcfd39a..372a7a39f5 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -12,6 +12,7 @@ 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; @@ -32,7 +33,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.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; @@ -157,7 +157,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; @@ -168,6 +167,8 @@ public class ApplicationConnection { private Set<VPaintableWidget> zeroHeightComponents = null; + private final LayoutManager layoutManager = new LayoutManager(this); + public ApplicationConnection() { view = GWT.create(VViewPaintable.class); view.setConnection(this); @@ -1002,9 +1003,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(); // create paintables if necessary @@ -1093,26 +1095,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); - - 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); - } - - } + VConsole.log("updateFromUidl: " + + updateDuration.elapsedMillis() + " ms"); - Util.componentSizeUpdated(sizeUpdatedWidgets); + doLayout(false); if (meta != null) { if (meta.containsKey("appError")) { @@ -1590,71 +1576,6 @@ public class ApplicationConnection { return result.toString(); } - public void updateComponentSize(VPaintableWidget paintable) { - SharedState state = paintable.getState(); - String w = ""; - String h = ""; - if (null != state || !(state instanceof ComponentState)) { - ComponentState componentState = (ComponentState) state; - // TODO move logging to VUIDLBrowser and VDebugConsole - // VConsole.log("Paintable state for " - // + getPaintableMap().getPid(paintable) + ": " - // + String.valueOf(state.getState())); - h = componentState.getHeight(); - w = componentState.getWidth(); - } else { - // TODO move logging to VUIDLBrowser and VDebugConsole - VConsole.log("No state for paintable " - + getPaintableMap().getPid(paintable) - + " in ApplicationConnection.updateComponentSize()"); - } - - 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; /** @@ -1676,13 +1597,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(); + + layoutManager.foceLayout(); + + VConsole.log("forceLayout in " + duration.elapsedMillis() + " ms"); } private void internalRunDescendentsLayout(HasWidgets container) { @@ -1724,144 +1643,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; } /** @@ -1876,17 +1658,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. @@ -2237,4 +2008,25 @@ public class ApplicationConnection { eventIdentifier); } + private boolean layoutScheduled = false; + private ScheduledCommand layoutCommand = new ScheduledCommand() { + public void execute() { + layoutScheduled = false; + + layoutManager.doLayout(); + } + }; + + public void doLayout(boolean lazy) { + if (!lazy) { + layoutCommand.execute(); + } else if (!layoutScheduled) { + layoutScheduled = true; + Scheduler.get().scheduleDeferred(layoutCommand); + } + } + + LayoutManager getLayoutManager() { + return layoutManager; + } } 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/ComponentLocator.java b/src/com/vaadin/terminal/gwt/client/ComponentLocator.java index f49f99a477..3b4821cc0f 100644 --- a/src/com/vaadin/terminal/gwt/client/ComponentLocator.java +++ b/src/com/vaadin/terminal/gwt/client/ComponentLocator.java @@ -12,6 +12,8 @@ import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ui.SubPartAware; +import com.vaadin.terminal.gwt.client.ui.VGridLayout; +import com.vaadin.terminal.gwt.client.ui.VMeasuringOrderedLayout; import com.vaadin.terminal.gwt.client.ui.VView; import com.vaadin.terminal.gwt.client.ui.VWindow; @@ -457,6 +459,61 @@ public class ComponentLocator { int widgetPosition = Integer.parseInt(indexString.substring(0, indexString.length() - 1)); + // AbsolutePanel in GridLayout has been removed -> skip it + if (w instanceof VGridLayout + && "AbsolutePanel".equals(widgetClassName)) { + continue; + } + + /* + * The new grid and ordered layotus do not contain + * ChildComponentContainer widgets. This is instead simulated by + * constructing a path step that would find the desired widget + * from the layout and injecting it as the next search step + * (which would originally have found the widget inside the + * ChildComponentContainer) + */ + if ((w instanceof VMeasuringOrderedLayout || w instanceof VGridLayout) + && "ChildComponentContainer".equals(widgetClassName) + && i + 1 < parts.length) { + + HasWidgets layout = (HasWidgets) w; + + String nextPart = parts[i + 1]; + String[] nextSplit = nextPart.split("\\[", 2); + String nextWidgetClassName = nextSplit[0]; + + // Find the n:th child and count the number of children with + // the same type before it + int nextIndex = 0; + for (Widget child : layout) { + boolean matchingType = nextWidgetClassName.equals(Util + .getSimpleName(child)); + if (matchingType && widgetPosition == 0) { + // This is the n:th child that we looked for + break; + } else if (widgetPosition < 0) { + // Error if we're past the desired position without + // a match + return null; + } else if (matchingType) { + // If this was another child of the expected type, + // increase the count for the next step + nextIndex++; + } + + // Don't count captions + if (!(child instanceof VCaption)) { + widgetPosition--; + } + } + + // Advance to the next step, this time checking for the + // actual child widget + parts[i + 1] = nextWidgetClassName + '[' + nextIndex + ']'; + continue; + } + // Locate the child Iterator<? extends Widget> iterator; 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/DirectionalManagedLayout.java b/src/com/vaadin/terminal/gwt/client/DirectionalManagedLayout.java new file mode 100644 index 0000000000..296fbb22ff --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/DirectionalManagedLayout.java @@ -0,0 +1,12 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client; + +import com.vaadin.terminal.gwt.client.ui.ManagedLayout; + +public interface DirectionalManagedLayout extends ManagedLayout { + public void layoutVertically(); + + public void layoutHorizontally(); +}
\ No newline at end of file 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..05ed8addc8 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/FastStringSet.java @@ -0,0 +1,60 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +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) { + if (this.hasOwnProperty(string)) { + array.push(string); + } + } + return array; + }-*/; + + public native void remove(String string) + /*-{ + delete this[string]; + }-*/; + + public native boolean isEmpty() + /*-{ + for(var string in this) { + if (this.hasOwnProperty(string)) { + return false; + } + } + return true; + }-*/; + + public static FastStringSet create() { + return JavaScriptObject.createObject().cast(); + } +}
\ No newline at end of file diff --git a/src/com/vaadin/terminal/gwt/client/LayoutManager.java b/src/com/vaadin/terminal/gwt/client/LayoutManager.java new file mode 100644 index 0000000000..d125543c2d --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/LayoutManager.java @@ -0,0 +1,334 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client; + +import java.util.HashSet; +import java.util.Set; + +import com.google.gwt.core.client.Duration; +import com.google.gwt.core.client.JsArrayString; +import com.google.gwt.dom.client.Element; +import com.vaadin.terminal.gwt.client.ui.ManagedLayout; +import com.vaadin.terminal.gwt.client.ui.PostLayoutListener; +import com.vaadin.terminal.gwt.client.ui.SimpleManagedLayout; + +public class LayoutManager { + private final ApplicationConnection connection; + private final Set<Element> nonPaintableElements = new HashSet<Element>(); + private final MeasuredSize nullSize = new MeasuredSize(); + + public LayoutManager(ApplicationConnection connection) { + this.connection = connection; + } + + public static LayoutManager get(ApplicationConnection connection) { + return connection.getLayoutManager(); + } + + public void registerDependency(ManagedLayout owner, Element element) { + MeasuredSize measuredSize = ensureMeasured(element); + + MeasuredSize ownerSize = getMeasuredSize(owner); + if (measuredSize.isHeightNeedsUpdate()) { + ownerSize.setHeightNeedsUpdate(); + } + if (measuredSize.isWidthNeedsUpdate()) { + ownerSize.setWidthNeedsUpdate(); + } + measuredSize.addDependent(owner.getId()); + } + + private MeasuredSize ensureMeasured(Element element) { + MeasuredSize measuredSize = getMeasuredSize(element, null); + if (measuredSize == null) { + measuredSize = new MeasuredSize(); + + if (VPaintableMap.get(connection).getPaintable(element) == null) { + nonPaintableElements.add(element); + } + setMeasuredSize(element, measuredSize); + } + return measuredSize; + } + + private boolean needsMeasure(Element e) { + if (connection.getPaintableMap().getPid(e) != null) { + return true; + } else if (getMeasuredSize(e, nullSize).hasDependents()) { + return true; + } else { + return false; + } + } + + private static native void setMeasuredSize(Element element, + MeasuredSize measuredSize) + /*-{ + if (measuredSize) { + element.vMeasuredSize = measuredSize; + } else { + delete element.vMeasuredSize; + } + }-*/; + + private static native final MeasuredSize getMeasuredSize(Element element, + MeasuredSize defaultSize) + /*-{ + return element.vMeasuredSize || defaultSize; + }-*/; + + private static final MeasuredSize getMeasuredSize(VPaintableWidget paintable) { + Element element = paintable.getWidgetForPaintable().getElement(); + MeasuredSize measuredSize = getMeasuredSize(element, null); + if (measuredSize == null) { + measuredSize = new MeasuredSize(); + setMeasuredSize(element, measuredSize); + } + return measuredSize; + } + + public void unregisterDependency(ManagedLayout owner, Element element) { + MeasuredSize measuredSize = getMeasuredSize(element, null); + if (measuredSize == null) { + return; + } + measuredSize.removeDependent(owner.getId()); + if (!needsMeasure(element)) { + nonPaintableElements.remove(element); + setMeasuredSize(element, null); + } + } + + public void doLayout() { + VPaintableMap paintableMap = connection.getPaintableMap(); + VPaintableWidget[] paintableWidgets = paintableMap + .getRegisteredPaintableWidgets(); + + int passes = 0; + Duration totalDuration = new Duration(); + + while (true) { + Duration passDuration = new Duration(); + passes++; + measureElements(paintableWidgets); + + FastStringSet needsHeightUpdate = FastStringSet.create(); + FastStringSet needsWidthUpdate = FastStringSet.create(); + + for (VPaintableWidget paintable : paintableWidgets) { + MeasuredSize measuredSize = getMeasuredSize(paintable); + 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 DirectionalManagedLayout) { + DirectionalManagedLayout cl = (DirectionalManagedLayout) paintable; + cl.layoutHorizontally(); + } else if (paintable instanceof SimpleManagedLayout) { + SimpleManagedLayout rr = (SimpleManagedLayout) paintable; + rr.layout(); + 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 DirectionalManagedLayout) { + DirectionalManagedLayout cl = (DirectionalManagedLayout) paintable; + cl.layoutVertically(); + } else if (paintable instanceof SimpleManagedLayout) { + SimpleManagedLayout rr = (SimpleManagedLayout) paintable; + rr.layout(); + } + 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 PostLayoutListener) { + ((PostLayoutListener) vPaintableWidget).postLayout(); + } + } + + VConsole.log("Total layout time: " + totalDuration.elapsedMillis() + + "ms"); + } + + private void measureElements(VPaintableWidget[] paintableWidgets) { + + for (VPaintableWidget paintableWidget : paintableWidgets) { + Element element = paintableWidget.getWidgetForPaintable() + .getElement(); + MeasuredSize measuredSize = getMeasuredSize(paintableWidget); + measuredAndUpdate(element, measuredSize); + } + + for (Element element : nonPaintableElements) { + MeasuredSize measuredSize = getMeasuredSize(element, null); + measuredAndUpdate(element, measuredSize); + } + } + + private void measuredAndUpdate(Element element, MeasuredSize measuredSize) { + if (measuredSize.measure(element)) { + JsArrayString dependents = measuredSize.getDependents(); + for (int i = 0; i < dependents.length(); i++) { + String pid = dependents.get(i); + VPaintableWidget dependent = (VPaintableWidget) connection + .getPaintableMap().getPaintable(pid); + if (dependent != null) { + MeasuredSize dependentSize = getMeasuredSize(dependent); + if (measuredSize.isHeightNeedsUpdate()) { + dependentSize.setHeightNeedsUpdate(); + } + if (measuredSize.isWidthNeedsUpdate()) { + dependentSize.setWidthNeedsUpdate(); + } + } + } + } + } + + private static boolean isNotifiableType(VPaintableWidget paintable) { + return paintable instanceof SimpleManagedLayout + || paintable instanceof DirectionalManagedLayout; + } + + public void foceLayout() { + VPaintableMap paintableMap = connection.getPaintableMap(); + VPaintableWidget[] paintableWidgets = paintableMap + .getRegisteredPaintableWidgets(); + for (VPaintableWidget vPaintableWidget : paintableWidgets) { + MeasuredSize measuredSize = getMeasuredSize(vPaintableWidget); + measuredSize.setHeightNeedsUpdate(); + measuredSize.setWidthNeedsUpdate(); + } + doLayout(); + } + + public final void setNeedsUpdate(ManagedLayout layout) { + setWidthNeedsUpdate(layout); + setHeightNeedsUpdate(layout); + } + + public final void setWidthNeedsUpdate(ManagedLayout layout) { + getMeasuredSize(layout).setWidthNeedsUpdate(); + } + + public final void setHeightNeedsUpdate(ManagedLayout layout) { + getMeasuredSize(layout).setHeightNeedsUpdate(); + } + + public boolean isMeasured(Element element) { + return getMeasuredSize(element, nullSize) != nullSize; + } + + public final int getOuterHeight(Element element) { + return getMeasuredSize(element, nullSize).getOuterHeight(); + } + + public final int getOuterWidth(Element element) { + return getMeasuredSize(element, nullSize).getOuterWidth(); + } + + public final int getInnerHeight(Element element) { + return getMeasuredSize(element, nullSize).getInnerHeight(); + } + + public final int getInnerWidth(Element element) { + return getMeasuredSize(element, nullSize).getInnerWidth(); + } + + public final int getBorderHeight(Element element) { + return getMeasuredSize(element, nullSize).getBorderHeight(); + } + + public int getPaddingHeight(Element element) { + return getMeasuredSize(element, nullSize).getPaddingHeight(); + } + + public int getBorderWidth(Element element) { + return getMeasuredSize(element, nullSize).getBorderWidth(); + } + + public int getPaddingWidth(Element element) { + return getMeasuredSize(element, nullSize).getPaddingWidth(); + } + + public int getPaddingTop(Element element) { + return getMeasuredSize(element, nullSize).getPaddingTop(); + } + + public int getPaddingLeft(Element element) { + return getMeasuredSize(element, nullSize).getPaddingLeft(); + } +} 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..9a70ff06d3 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/MeasuredSize.java @@ -0,0 +1,222 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client; + +import com.google.gwt.core.client.JsArrayString; +import com.google.gwt.dom.client.Element; + +public 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 boolean heightChanged = true; + private boolean widthChanged = true; + + private FastStringSet dependents = FastStringSet.create(); + + public int getOuterHeight() { + return height; + } + + public int getOuterWidth() { + return width; + } + + public void addDependent(String pid) { + dependents.add(pid); + } + + public void removeDependent(String pid) { + dependents.remove(pid); + } + + public boolean hasDependents() { + return !dependents.isEmpty(); + } + + public JsArrayString getDependents() { + return dependents.dump(); + } + + 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 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]; + } + + boolean measure(Element element) { + boolean wasHeightChanged = heightChanged; + boolean wasWidthChanged = widthChanged; + + ComputedStyle computedStyle = new ComputedStyle(element); + + 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 requiredHeight = Util.getRequiredHeight(element); + int marginHeight = sumHeights(margins); + setOuterHeight(requiredHeight + marginHeight); + + int requiredWidth = Util.getRequiredWidth(element); + int marginWidth = sumWidths(margins); + setOuterWidth(requiredWidth + marginWidth); + + return wasHeightChanged != heightChanged + || wasWidthChanged != widthChanged; + } + + 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 be78959830..a563a534d5 100644 --- a/src/com/vaadin/terminal/gwt/client/Util.java +++ b/src/com/vaadin/terminal/gwt/client/Util.java @@ -6,11 +6,7 @@ package com.vaadin.terminal.gwt.client; import java.util.ArrayList; import java.util.Arrays; -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; @@ -25,7 +21,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; @@ -67,30 +62,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 @@ -108,58 +79,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) { @@ -175,26 +128,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(); /** @@ -605,20 +538,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( @@ -707,62 +627,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/VCaption.java b/src/com/vaadin/terminal/gwt/client/VCaption.java index 6e2c4a02d2..21f1e453b8 100644 --- a/src/com/vaadin/terminal/gwt/client/VCaption.java +++ b/src/com/vaadin/terminal/gwt/client/VCaption.java @@ -26,15 +26,18 @@ public class VCaption extends HTML { private Element captionText; - private Element clearElement; - private final ApplicationConnection client; private boolean placedAfterComponent = false; private int maxWidth = -1; - private static final String CLASSNAME_CLEAR = CLASSNAME + "-clearelem"; + protected static final String ATTRIBUTE_ICON = "icon"; + protected static final String ATTRIBUTE_CAPTION = "caption"; + protected static final String ATTRIBUTE_DESCRIPTION = "description"; + protected static final String ATTRIBUTE_REQUIRED = "required"; + protected static final String ATTRIBUTE_ERROR = "error"; + protected static final String ATTRIBUTE_HIDEERRORS = "hideErrors"; private enum InsertPosition { ICON, CAPTION, REQUIRED, ERROR @@ -218,12 +221,6 @@ public class VCaption extends HTML { errorIndicatorElement = null; } - if (clearElement == null) { - clearElement = DOM.createDiv(); - clearElement.setClassName(CLASSNAME_CLEAR); - getElement().appendChild(clearElement); - } - return (wasPlacedAfterComponent != placedAfterComponent); } @@ -360,12 +357,6 @@ public class VCaption extends HTML { errorIndicatorElement = null; } - if (clearElement == null) { - clearElement = DOM.createDiv(); - clearElement.setClassName(CLASSNAME_CLEAR); - getElement().appendChild(clearElement); - } - return (wasPlacedAfterComponent != placedAfterComponent); } 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 37ddc6dd9a..78dcdef05a 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; @@ -12,11 +13,10 @@ import java.util.Map; import java.util.Set; import com.google.gwt.core.client.GWT; -import com.google.gwt.user.client.Element; +import com.google.gwt.dom.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) { @@ -306,34 +321,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 0be1d5050c..2eee3cc98d 100644 --- a/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java +++ b/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java @@ -34,4 +34,60 @@ public interface VPaintableWidget extends VPaintable { * @return */ public VPaintableWidgetContainer getParent(); + + public LayoutManager getLayoutManager(); + + /** + * 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 getDeclaredWidth(); + + /** + * Gets the height of this paintable as defined on the server. + * + * @return the server side height definition + */ + public String getDeclaredHeight(); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/ManagedLayout.java b/src/com/vaadin/terminal/gwt/client/ui/ManagedLayout.java new file mode 100644 index 0000000000..3c6c246a1e --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/ManagedLayout.java @@ -0,0 +1,7 @@ +package com.vaadin.terminal.gwt.client.ui; + +import com.vaadin.terminal.gwt.client.VPaintableWidget; + +public interface ManagedLayout extends VPaintableWidget { + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/PostLayoutListener.java b/src/com/vaadin/terminal/gwt/client/ui/PostLayoutListener.java new file mode 100644 index 0000000000..feb7494f87 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/PostLayoutListener.java @@ -0,0 +1,8 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui; + +public interface PostLayoutListener { + public void postLayout(); +} 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/SimpleManagedLayout.java b/src/com/vaadin/terminal/gwt/client/ui/SimpleManagedLayout.java new file mode 100644 index 0000000000..e8ab688db0 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/SimpleManagedLayout.java @@ -0,0 +1,9 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui; + + +public interface SimpleManagedLayout extends ManagedLayout { + public void layout(); +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java index 663c309321..bce3e4e844 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; @@ -285,7 +190,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..2677ea0f75 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.DirectionalManagedLayout; 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 DirectionalManagedLayout { 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 layoutVertically() { + 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 layoutHorizontally() { + 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 bff6f8ea3b..ed45751312 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java @@ -10,8 +10,10 @@ 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.ComponentState; +import com.vaadin.terminal.gwt.client.LayoutManager; import com.vaadin.terminal.gwt.client.TooltipInfo; import com.vaadin.terminal.gwt.client.UIDL; +import com.vaadin.terminal.gwt.client.VConsole; import com.vaadin.terminal.gwt.client.VPaintableMap; import com.vaadin.terminal.gwt.client.VPaintableWidget; import com.vaadin.terminal.gwt.client.VPaintableWidgetContainer; @@ -44,6 +46,9 @@ public abstract class VAbstractPaintableWidget implements VPaintableWidget { // shared state from the server to the client private ComponentState state; + private String declaredWidth = ""; + private String declaredHeight = ""; + /** * Default constructor */ @@ -235,7 +240,79 @@ public abstract class VAbstractPaintableWidget implements VPaintableWidget { * taken into account */ - getConnection().updateComponentSize(this); + updateComponentSize(); + } + + private void updateComponentSize() { + SharedState state = getState(); + + String w = ""; + String h = ""; + if (null != state || !(state instanceof ComponentState)) { + ComponentState componentState = (ComponentState) state; + // TODO move logging to VUIDLBrowser and VDebugConsole + // VConsole.log("Paintable state for " + // + getPaintableMap().getPid(paintable) + ": " + // + String.valueOf(state.getState())); + h = componentState.getHeight(); + w = componentState.getWidth(); + } else { + // TODO move logging to VUIDLBrowser and VDebugConsole + VConsole.log("No state for paintable " + getId() + + " in VAbstractPaintableWidget.updateComponentSize()"); + } + + // Parent should be updated if either dimension changed between relative + // and non-relative + if (w.endsWith("%") != declaredWidth.endsWith("%")) { + VPaintableWidgetContainer parent = getParent(); + if (parent instanceof ManagedLayout) { + getLayoutManager().setWidthNeedsUpdate((ManagedLayout) parent); + } + } + + if (h.endsWith("%") != declaredHeight.endsWith("%")) { + VPaintableWidgetContainer parent = getParent(); + if (parent instanceof ManagedLayout) { + getLayoutManager().setHeightNeedsUpdate((ManagedLayout) parent); + } + } + + declaredWidth = w; + declaredHeight = h; + + // Set defined sizes + Widget component = getWidgetForPaintable(); + + component.setStyleName("v-undefined-width", isUndefinedWidth()); + component.setStyleName("v-undefined-height", isUndefinedHeight()); + + component.setHeight(h); + component.setWidth(w); + } + + public boolean isRelativeHeight() { + return declaredHeight.endsWith("%"); + } + + public boolean isRelativeWidth() { + return declaredWidth.endsWith("%"); + } + + public boolean isUndefinedHeight() { + return declaredHeight.length() == 0; + } + + public boolean isUndefinedWidth() { + return declaredWidth.length() == 0; + } + + public String getDeclaredHeight() { + return declaredHeight; + } + + public String getDeclaredWidth() { + return declaredWidth; } /** @@ -320,6 +397,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) { @@ -391,4 +469,8 @@ public abstract class VAbstractPaintableWidget implements VPaintableWidget { getConnection()); return clientToServerRpc; } + + public LayoutManager getLayoutManager() { + return LayoutManager.get(connection); + } } 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 cdbb895f2c..c795479dd9 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 SimpleManagedLayout { 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 = getState().isImmediate(); super.updateFromUIDL(uidl, client); if (!isRealUpdate(uidl)) { - getWidgetForPaintable().rendering = false; return; } getWidgetForPaintable().setEnabled(!getState().isDisabled()); @@ -95,8 +93,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)); @@ -122,15 +118,17 @@ 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; + getLayoutManager().setNeedsUpdate(this); + } + public void layout() { + 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 1d536c83ee..25af6396cc 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(); } @@ -517,12 +465,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 @@ -531,65 +483,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..809eb1167b 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 + SimpleManagedLayout { @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 layout() { + 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 2d613ee808..9ac9201639 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 0300064dd2..18421b34ae 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..e5cc917aea 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 SimpleManagedLayout { /** 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 layout() { + 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 b77c9b7a2d..3f64874843 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/VFilterSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java index 0c581efa68..d9c7cadcd9 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java @@ -13,6 +13,8 @@ import java.util.List; import java.util.Set; import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.dom.client.Style; +import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.ClickEvent; @@ -50,6 +52,8 @@ import com.vaadin.terminal.gwt.client.Focusable; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VConsole; +import com.vaadin.terminal.gwt.client.VPaintableMap; +import com.vaadin.terminal.gwt.client.VPaintableWidget; import com.vaadin.terminal.gwt.client.VTooltip; /** @@ -919,9 +923,6 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, // This handles the special case where are not filtering yet and the // selected value has changed on the server-side. See #2119 protected boolean popupOpenerClicked; - private String width = null; - private int textboxPadding = -1; - private int componentPadding = -1; protected int suggestionPopupMinWidth = 0; private int popupWidth = -1; /* @@ -930,7 +931,6 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, */ protected String lastNewItemString; protected boolean focused = false; - private int horizPaddingAndBorder = 2; /** * If set to false, the component should not allow entering text to the @@ -1076,22 +1076,6 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, tb.setText(text); } - /* - * (non-Javadoc) - * - * @see com.google.gwt.user.client.ui.Composite#onAttach() - */ - @Override - protected void onAttach() { - super.onAttach(); - - /* - * We need to recalculate the root width when the select is attached, so - * #2974 won't happen. - */ - updateRootWidth(); - } - /** * Turns prompting on. When prompting is turned on a command prompt is shown * in the text box if nothing has been entered. @@ -1578,60 +1562,14 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, tb.setFocus(true); } - /* - * (non-Javadoc) - * - * @see com.google.gwt.user.client.ui.UIObject#setWidth(java.lang.String) - */ - @Override - public void setWidth(String width) { - if (width == null || width.equals("")) { - this.width = null; - } else { - this.width = width; - } - - horizPaddingAndBorder = Util.setWidthExcludingPaddingAndBorder(this, - width, horizPaddingAndBorder); - - if (initDone) { - updateRootWidth(); - } - } - - /* - * (non-Javadoc) - * - * @see com.google.gwt.user.client.ui.UIObject#setHeight(java.lang.String) - */ - @Override - public void setHeight(String height) { - super.setHeight(height); - Util.setHeightExcludingPaddingAndBorder(tb, height, 3); - } - /** * Calculates the width of the select if the select has undefined width. * Should be called when the width changes or when the icon changes. */ protected void updateRootWidth() { - if (width == null) { - /* - * When the width is not specified we must specify width for root - * div so the popupopener won't wrap to the next line and also so - * the size of the combobox won't change over time. - */ - int tbWidth = Util.getRequiredWidth(tb); - - /* - * Note: iconWidth is here calculated as a negative pixel value so - * you should consider this in further calculations. - */ - int iconWidth = selectedItemIcon.isAttached() ? Util - .measureMarginLeft(tb.getElement()) - - Util.measureMarginLeft(selectedItemIcon.getElement()) : 0; - - int w = tbWidth + getPopUpOpenerWidth() + iconWidth; + VPaintableWidget paintable = VPaintableMap.get(client).getPaintable( + this); + if (paintable.isUndefinedWidth()) { /* * When the select has a undefined with we need to check that we are @@ -1640,45 +1578,37 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * when the popup is used to view longer items than the text box is * wide. */ + int w = Util.getRequiredWidth(this); if ((!initDone || currentPage + 1 < 0) && suggestionPopupMinWidth > w) { - setTextboxWidth(suggestionPopupMinWidth); - w = suggestionPopupMinWidth; - } else { /* - * Firefox3 has its own way of doing rendering so we need to - * specify the width for the TextField to make sure it actually - * is rendered as wide as FF3 says it is + * We want to compensate for the paddings just to preserve the + * exact size as in Vaadin 6.x, but we get here before + * MeasuredSize has been initialized. + * Util.measureHorizontalPaddingAndBorder does not work with + * border-box, so we must do this the hard way. */ - tb.setWidth((tbWidth - getTextboxPadding()) + "px"); + Style style = getElement().getStyle(); + String originalPadding = style.getPadding(); + String originalBorder = style.getBorderWidth(); + style.setPaddingLeft(0, Unit.PX); + style.setBorderWidth(0, Unit.PX); + int offset = w - Util.getRequiredWidth(this); + style.setProperty("padding", originalPadding); + style.setProperty("borderWidth", originalBorder); + + setWidth(suggestionPopupMinWidth + offset + "px"); } - super.setWidth((w) + "px"); - // Freeze the initial width, so that it won't change even if the - // icon size changes - width = w + "px"; - } else { /* - * When the width is specified we also want to explicitly specify - * widths for textbox and popupopener + * Lock the textbox width to its current value if it's not already + * locked */ - setTextboxWidth(getMainWidth() - getComponentPadding()); - - } - } - - /** - * Only use the first page popup width so the textbox will not get resized - * whenever the popup is resized. This also resolves issue where toggling - * combo box between read only and normal state makes it grow larger. - * - * @return Width of popup opener - */ - private int getPopUpOpenerWidth() { - if (popupWidth < 0) { - popupWidth = Util.getRequiredWidth(popupOpener); + if (!tb.getElement().getStyle().getWidth().endsWith("px")) { + tb.setWidth((tb.getOffsetWidth() - selectedItemIcon + .getOffsetWidth()) + "px"); + } } - return popupWidth; } /** @@ -1691,51 +1621,12 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, return getOffsetWidth(); } - /** - * Sets the text box width in pixels. - * - * @param componentWidth - * The width of the text box in pixels - */ - private void setTextboxWidth(int componentWidth) { - int padding = getTextboxPadding(); - int iconWidth = selectedItemIcon.isAttached() ? Util - .getRequiredWidth(selectedItemIcon) : 0; - - int textboxWidth = componentWidth - padding - getPopUpOpenerWidth() - - iconWidth; - if (textboxWidth < 0) { - textboxWidth = 0; - } - tb.setWidth(textboxWidth + "px"); - } - - /** - * Gets the horizontal padding of the text box in pixels. The measurement - * includes the border width. - * - * @return The padding in pixels - */ - private int getTextboxPadding() { - if (textboxPadding < 0) { - textboxPadding = Util.measureHorizontalPaddingAndBorder( - tb.getElement(), 4); - } - return textboxPadding; - } - - /** - * Gets the horizontal padding of the select. The measurement includes the - * border width. - * - * @return The padding in pixels - */ - private int getComponentPadding() { - if (componentPadding < 0) { - componentPadding = Util.measureHorizontalPaddingAndBorder( - getElement(), 3); + @Override + public void setWidth(String width) { + super.setWidth(width); + if (width.length() != 0) { + tb.setWidth("100%"); } - return componentPadding; } /** diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelectPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelectPaintable.java index 4c5389d51f..33f5818b0c 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelectPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelectPaintable.java @@ -12,7 +12,8 @@ import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.ui.VFilterSelect.FilterSelectSuggestion; -public class VFilterSelectPaintable extends VAbstractPaintableWidget { +public class VFilterSelectPaintable extends VAbstractPaintableWidget implements + SimpleManagedLayout { /* * (non-Javadoc) @@ -245,4 +246,11 @@ public class VFilterSelectPaintable extends VAbstractPaintableWidget { public VFilterSelect getWidgetForPaintable() { return (VFilterSelect) super.getWidgetForPaintable(); } + + public void layout() { + VFilterSelect widget = getWidgetForPaintable(); + if (widget.initDone) { + widget.updateRootWidth(); + } + } } 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 f54c6dc05d..15ac97cd1c 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; @@ -22,12 +21,9 @@ 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.ComponentState; -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; @@ -35,18 +31,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); @@ -144,14 +135,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"; @@ -182,55 +178,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()); @@ -245,21 +192,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) * @@ -280,18 +212,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); - } - // TODO why duplicated here? public class Caption extends HTML { @@ -476,55 +396,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 727febc6d5..1845cdd87f 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java @@ -4,6 +4,7 @@ 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; @@ -11,7 +12,14 @@ 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 + SimpleManagedLayout { + + @Override + public void init() { + VForm form = getWidgetForPaintable(); + getLayoutManager().registerDependency(this, form.footerContainer); + } @Override protected boolean delegateCaptionHandling() { @@ -20,13 +28,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 +89,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 +110,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 +139,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 +160,6 @@ public class VFormPaintable extends VAbstractPaintableWidgetContainer { getWidgetForPaintable().shortcutHandler = null; getWidgetForPaintable().keyDownRegistration = null; } - - getWidgetForPaintable().rendering = false; } public void updateCaption(VPaintableWidget component, UIDL uidl) { @@ -180,4 +177,14 @@ public class VFormPaintable extends VAbstractPaintableWidgetContainer { return GWT.create(VForm.class); } + public void layout() { + VForm form = getWidgetForPaintable(); + + int footerHeight = getLayoutManager().getOuterHeight( + 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 c8a0f813f3..82176dd353 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java @@ -4,56 +4,42 @@ package com.vaadin.terminal.gwt.client.ui; -import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.Set; 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.dom.client.Style.Unit; import com.google.gwt.user.client.Element; -import com.google.gwt.user.client.ui.AbsolutePanel; -import com.google.gwt.user.client.ui.SimplePanel; +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.ComponentState; -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.LayoutManager; 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; -import com.vaadin.terminal.gwt.client.ui.layout.CellBasedLayout; -import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer; +import com.vaadin.terminal.gwt.client.ui.layout.VLayoutSlot; +import com.vaadin.terminal.gwt.client.ui.layout.VPaintableLayoutSlot; -public class VGridLayout extends SimplePanel implements Container { +public class VGridLayout extends ComplexPanel { public static final String CLASSNAME = "v-gridlayout"; - private DivElement margin = Document.get().createDivElement(); - - final AbsolutePanel canvas = new AbsolutePanel(); - ApplicationConnection client; - protected HashMap<Widget, ChildComponentContainer> widgetToComponentContainer = new HashMap<Widget, ChildComponentContainer>(); - HashMap<Widget, Cell> widgetToCell = new HashMap<Widget, Cell>(); - private int spacingPixelsHorizontal; - private int spacingPixelsVertical; - int[] columnWidths; int[] rowHeights; - private String height; - - private String width; - int[] colExpandRatioArray; int[] rowExpandRatioArray; @@ -62,22 +48,22 @@ public class VGridLayout extends SimplePanel implements Container { private int[] minRowHeights; - boolean rendering; - - HashMap<Widget, ChildComponentContainer> nonRenderedWidgets; - - boolean sizeChangedDuringRendering = false; + DivElement spacingMeasureElement; public VGridLayout() { super(); - getElement().appendChild(margin); + setElement(Document.get().createDivElement()); + + spacingMeasureElement = Document.get().createDivElement(); + Style spacingStyle = spacingMeasureElement.getStyle(); + spacingStyle.setPosition(Position.ABSOLUTE); + getElement().appendChild(spacingMeasureElement); + setStyleName(CLASSNAME); - setWidget(canvas); } - @Override - protected Element getContainerElement() { - return margin.cast(); + private VPaintableWidget getPaintable() { + return VPaintableMap.get(client).getPaintable(this); } /** @@ -104,7 +90,7 @@ public class VGridLayout extends SimplePanel implements Container { * @return */ protected int getHorizontalSpacing() { - return spacingPixelsHorizontal; + return LayoutManager.get(client).getOuterWidth(spacingMeasureElement); } /** @@ -113,7 +99,7 @@ public class VGridLayout extends SimplePanel implements Container { * @return */ protected int getVerticalSpacing() { - return spacingPixelsVertical; + return LayoutManager.get(client).getOuterHeight(spacingMeasureElement); } static int[] cloneArray(int[] toBeCloned) { @@ -125,12 +111,14 @@ public class VGridLayout extends SimplePanel implements Container { } void expandRows() { - if (!"".equals(height)) { + if (!isUndefinedHeight()) { int usedSpace = minRowHeights[0]; + int verticalSpacing = getVerticalSpacing(); for (int i = 1; i < minRowHeights.length; i++) { - usedSpace += spacingPixelsVertical + minRowHeights[i]; + usedSpace += verticalSpacing + minRowHeights[i]; } - int availableSpace = getOffsetHeight() - marginTopAndBottom; + int availableSpace = LayoutManager.get(client).getInnerHeight( + getElement()); int excessSpace = availableSpace - usedSpace; int distributed = 0; if (excessSpace > 0) { @@ -150,127 +138,37 @@ public class VGridLayout extends SimplePanel implements Container { } } - @Override - public void setHeight(String height) { - super.setHeight(height); - if (!height.equals(this.height)) { - this.height = height; - if (rendering) { - sizeChangedDuringRendering = true; - } else { - expandRows(); - layoutCells(); - for (Widget w : widgetToCell.keySet()) { - client.handleComponentRelativeSize(w); - } - } - } + void updateHeight() { + // Detect minimum heights & calculate spans + detectRowHeights(); + + // Expand + expandRows(); + + // Position + layoutCellsVertically(); } - @Override - public void setWidth(String width) { - super.setWidth(width); - if (!width.equals(this.width)) { - this.width = width; - if (rendering) { - sizeChangedDuringRendering = true; - } else { - int[] oldWidths = cloneArray(columnWidths); - expandColumns(); - boolean heightChanged = false; - HashSet<Integer> dirtyRows = null; - for (int i = 0; i < oldWidths.length; i++) { - if (columnWidths[i] != oldWidths[i]) { - Cell[] column = cells[i]; - for (int j = 0; j < column.length; j++) { - Cell c = column[j]; - if (c != null && c.cc != null - && c.widthCanAffectHeight()) { - c.cc.setContainerSize(c.getAvailableWidth(), - c.getAvailableHeight()); - client.handleComponentRelativeSize(c.cc - .getWidget()); - c.cc.updateWidgetSize(); - int newHeight = c.getHeight(); - if (columnWidths[i] < oldWidths[i] - && newHeight > minRowHeights[j] - && c.rowspan == 1) { - /* - * The width of this column was reduced and - * this affected the height. The height is - * now greater than the previously - * calculated minHeight for the row. - */ - minRowHeights[j] = newHeight; - if (newHeight > rowHeights[j]) { - /* - * The new height is greater than the - * previously calculated rowHeight -> we - * need to recalculate heights later on - */ - rowHeights[j] = newHeight; - heightChanged = true; - } - } else if (newHeight < minRowHeights[j]) { - /* - * The new height of the component is less - * than the previously calculated min row - * height. The min row height may be - * affected and must thus be recalculated - */ - if (dirtyRows == null) { - dirtyRows = new HashSet<Integer>(); - } - dirtyRows.add(j); - } - } - } - } - } - if (dirtyRows != null) { - /* flag indicating that there is a potential row shrinking */ - boolean rowMayShrink = false; - for (Integer rowIndex : dirtyRows) { - int oldMinimum = minRowHeights[rowIndex]; - int newMinimum = 0; - for (int colIndex = 0; colIndex < columnWidths.length; colIndex++) { - Cell cell = cells[colIndex][rowIndex]; - if (cell != null && !cell.hasRelativeHeight() - && cell.getHeight() > newMinimum) { - newMinimum = cell.getHeight(); - } - } - if (newMinimum < oldMinimum) { - minRowHeights[rowIndex] = rowHeights[rowIndex] = newMinimum; - rowMayShrink = true; - } - } - if (rowMayShrink) { - distributeRowSpanHeights(); - minRowHeights = cloneArray(rowHeights); - heightChanged = true; - } + void updateWidth() { + // Detect widths & calculate spans + detectColWidths(); + // Expand + expandColumns(); + // Position + layoutCellsHorizontally(); - } - layoutCells(); - for (Widget w : widgetToCell.keySet()) { - client.handleComponentRelativeSize(w); - } - if (heightChanged && "".equals(height)) { - Util.notifyParentOfSizeChange(this, false); - } - } - } } void expandColumns() { - if (!"".equals(width)) { + if (!isUndefinedWidth()) { int usedSpace = minColumnWidths[0]; + int horizontalSpacing = getHorizontalSpacing(); for (int i = 1; i < minColumnWidths.length; i++) { - usedSpace += spacingPixelsHorizontal + minColumnWidths[i]; + usedSpace += horizontalSpacing + minColumnWidths[i]; } - canvas.setWidth(""); - int availableSpace = canvas.getOffsetWidth(); + + int availableSpace = LayoutManager.get(client).getInnerWidth( + getElement()); int excessSpace = availableSpace - usedSpace; int distributed = 0; if (excessSpace > 0) { @@ -290,70 +188,62 @@ public class VGridLayout extends SimplePanel implements Container { } } - void layoutCells() { - int x = 0; + void layoutCellsVertically() { + int verticalSpacing = getVerticalSpacing(); int y = 0; for (int i = 0; i < cells.length; i++) { y = 0; for (int j = 0; j < cells[i].length; j++) { Cell cell = cells[i][j]; if (cell != null) { - cell.layout(x, y); + cell.layoutVertically(y); } - y += rowHeights[j] + spacingPixelsVertical; + y += rowHeights[j] + verticalSpacing; } - x += columnWidths[i] + spacingPixelsHorizontal; } - if (isUndefinedWidth()) { - canvas.setWidth((x - spacingPixelsHorizontal) + "px"); - } else { - // main element defines width - canvas.setWidth(""); + if (isUndefinedHeight()) { + int innerHeight = y - verticalSpacing; + getElement().getStyle().setHeight(innerHeight, Unit.PX); } + } - int canvasHeight; - if (isUndefinedHeight()) { - canvasHeight = y - spacingPixelsVertical; - } else { - canvasHeight = getOffsetHeight() - marginTopAndBottom; - if (canvasHeight < 0) { - canvasHeight = 0; + void layoutCellsHorizontally() { + int x = 0; + int horizontalSpacing = getHorizontalSpacing(); + for (int i = 0; i < cells.length; i++) { + for (int j = 0; j < cells[i].length; j++) { + Cell cell = cells[i][j]; + if (cell != null) { + cell.layoutHorizontally(x); + } } + x += columnWidths[i] + horizontalSpacing; + } + + if (isUndefinedWidth()) { + getElement().getStyle().setWidth((x - horizontalSpacing), Unit.PX); } - canvas.setHeight(canvasHeight + "px"); } private boolean isUndefinedHeight() { - return "".equals(height); + return getPaintable().isUndefinedHeight(); } private boolean isUndefinedWidth() { - return "".equals(width); + return getPaintable().isUndefinedWidth(); } - void renderRemainingComponents(LinkedList<Cell> pendingCells) { - for (Cell cell : pendingCells) { - cell.render(); + private void detectRowHeights() { + for (int i = 0; i < rowHeights.length; i++) { + rowHeights[i] = 0; } - } - - void detectRowHeights() { // collect min rowheight from non-rowspanned cells for (int i = 0; i < cells.length; i++) { for (int j = 0; j < cells[i].length; j++) { Cell cell = cells[i][j]; if (cell != null) { - /* - * Setting fixing container width may in some situations - * affect height. Example: Label with wrapping text without - * or with relative width. - */ - if (cell.cc != null && cell.widthCanAffectHeight()) { - cell.cc.setWidth(cell.getAvailableWidth() + "px"); - cell.cc.updateWidgetSize(); - } if (cell.rowspan == 1) { if (!cell.hasRelativeHeight() && rowHeights[j] < cell.getHeight()) { @@ -371,6 +261,33 @@ public class VGridLayout extends SimplePanel implements Container { minRowHeights = cloneArray(rowHeights); } + private void detectColWidths() { + // collect min colwidths from non-colspanned cells + for (int i = 0; i < columnWidths.length; i++) { + columnWidths[i] = 0; + } + + for (int i = 0; i < cells.length; i++) { + for (int j = 0; j < cells[i].length; j++) { + Cell cell = cells[i][j]; + if (cell != null) { + if (cell.colspan == 1) { + if (!cell.hasRelativeWidth() + && columnWidths[i] < cell.getWidth()) { + columnWidths[i] = cell.getWidth(); + } + } else { + storeColSpannedCell(cell); + } + } + } + } + + distributeColSpanWidths(); + + minColumnWidths = cloneArray(columnWidths); + } + private void storeRowSpannedCell(Cell cell) { SpanList l = null; for (SpanList list : rowSpans) { @@ -393,20 +310,6 @@ public class VGridLayout extends SimplePanel implements Container { l.cells.add(cell); } - void renderRemainingComponentsWithNoRelativeHeight( - LinkedList<Cell> pendingCells) { - - for (Iterator<Cell> iterator = pendingCells.iterator(); iterator - .hasNext();) { - Cell cell = iterator.next(); - if (!cell.hasRelativeHeight()) { - cell.render(); - iterator.remove(); - } - } - - } - /** * Iterates colspanned cells, ensures cols have enough space to accommodate * them @@ -418,7 +321,7 @@ public class VGridLayout extends SimplePanel implements Container { // subsequent renders int width = cell.hasRelativeWidth() ? 0 : cell.getWidth(); distributeSpanSize(columnWidths, cell.col, cell.colspan, - spacingPixelsHorizontal, width, colExpandRatioArray); + getHorizontalSpacing(), width, colExpandRatioArray); } } } @@ -434,7 +337,7 @@ public class VGridLayout extends SimplePanel implements Container { // subsequent renders int height = cell.hasRelativeHeight() ? 0 : cell.getHeight(); distributeSpanSize(rowHeights, cell.row, cell.rowspan, - spacingPixelsVertical, height, rowExpandRatioArray); + getVerticalSpacing(), height, rowExpandRatioArray); } } } @@ -494,8 +397,6 @@ public class VGridLayout extends SimplePanel implements Container { private LinkedList<SpanList> colSpans = new LinkedList<SpanList>(); private LinkedList<SpanList> rowSpans = new LinkedList<SpanList>(); - private int marginTopAndBottom; - private class SpanList { final int span; List<Cell> cells = new LinkedList<Cell>(); @@ -528,250 +429,28 @@ public class VGridLayout extends SimplePanel implements Container { l.cells.add(cell); } - void detectSpacing(UIDL uidl) { - DivElement spacingmeter = Document.get().createDivElement(); - spacingmeter.setClassName(CLASSNAME + "-" + "spacing-" - + (uidl.getBooleanAttribute("spacing") ? "on" : "off")); - spacingmeter.getStyle().setProperty("width", "0"); - spacingmeter.getStyle().setProperty("height", "0"); - canvas.getElement().appendChild(spacingmeter); - spacingPixelsHorizontal = spacingmeter.getOffsetWidth(); - spacingPixelsVertical = spacingmeter.getOffsetHeight(); - canvas.getElement().removeChild(spacingmeter); - } - - void handleMargins(UIDL uidl) { - final VMarginInfo margins = new VMarginInfo( - uidl.getIntAttribute("margins")); - - String styles = CLASSNAME + "-margin"; - if (margins.hasTop()) { - styles += " " + CLASSNAME + "-" + StyleConstants.MARGIN_TOP; - } - if (margins.hasRight()) { - styles += " " + CLASSNAME + "-" + StyleConstants.MARGIN_RIGHT; - } - if (margins.hasBottom()) { - styles += " " + CLASSNAME + "-" + StyleConstants.MARGIN_BOTTOM; - } - if (margins.hasLeft()) { - styles += " " + CLASSNAME + "-" + StyleConstants.MARGIN_LEFT; - } - margin.setClassName(styles); - - marginTopAndBottom = margin.getOffsetHeight() - - 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)) { - needsLayout = true; - } - ArrayList<Integer> dirtyColumns = new ArrayList<Integer>(); - ArrayList<Integer> dirtyRows = new ArrayList<Integer>(); - for (Widget widget : changedChildren) { - - Cell cell = widgetToCell.get(widget); - if (!cell.hasRelativeHeight() || !cell.hasRelativeWidth()) { - // cell sizes will only stay still if only relatively - // sized components - // check if changed child affects min col widths - assert cell.cc != null; - cell.cc.setWidth(""); - cell.cc.setHeight(""); - - cell.cc.updateWidgetSize(); - - /* - * If this is the result of an caption icon onload event the - * caption size may have changed - */ - cell.cc.updateCaptionSize(); - - int width = cell.getWidth(); - int allocated = columnWidths[cell.col]; - for (int i = 1; i < cell.colspan; i++) { - allocated += spacingPixelsHorizontal - + columnWidths[cell.col + i]; - } - if (allocated < width) { - needsLayout = true; - if (cell.colspan == 1) { - // do simple column width expansion - columnWidths[cell.col] = minColumnWidths[cell.col] = width; - } else { - // mark that col span expansion is needed - reDistributeColSpanWidths = true; - } - } else if (allocated != width) { - // size is smaller thant allocated, column might - // shrink - dirtyColumns.add(cell.col); - } - - int height = cell.getHeight(); - - allocated = rowHeights[cell.row]; - for (int i = 1; i < cell.rowspan; i++) { - allocated += spacingPixelsVertical - + rowHeights[cell.row + i]; - } - if (allocated < height) { - needsLayout = true; - if (cell.rowspan == 1) { - // do simple row expansion - rowHeights[cell.row] = minRowHeights[cell.row] = height; - } else { - // mark that row span expansion is needed - reDistributeRowSpanHeights = true; - } - } else if (allocated != height) { - // size is smaller than allocated, row might shrink - dirtyRows.add(cell.row); - } - } - } - - if (dirtyColumns.size() > 0) { - for (Integer colIndex : dirtyColumns) { - int colW = 0; - for (int i = 0; i < rowHeights.length; i++) { - Cell cell = cells[colIndex][i]; - if (cell != null && cell.getChildUIDL() != null - && !cell.hasRelativeWidth() && cell.colspan == 1) { - int width = cell.getWidth(); - if (width > colW) { - colW = width; - } - } - } - minColumnWidths[colIndex] = colW; - } - needsLayout = true; - // ensure colspanned columns have enough space - columnWidths = cloneArray(minColumnWidths); - distributeColSpanWidths(); - reDistributeColSpanWidths = false; - } - - if (reDistributeColSpanWidths) { - distributeColSpanWidths(); - } - - if (dirtyRows.size() > 0) { - needsLayout = true; - for (Integer rowIndex : dirtyRows) { - // recalculate min row height - int rowH = minRowHeights[rowIndex] = 0; - // loop all columns on row rowIndex - for (int i = 0; i < columnWidths.length; i++) { - Cell cell = cells[i][rowIndex]; - if (cell != null && cell.getChildUIDL() != null - && !cell.hasRelativeHeight() && cell.rowspan == 1) { - int h = cell.getHeight(); - if (h > rowH) { - rowH = h; - } - } - } - minRowHeights[rowIndex] = rowH; - } - // TODO could check only some row spans - rowHeights = cloneArray(minRowHeights); - distributeRowSpanHeights(); - reDistributeRowSpanHeights = false; - } - - if (reDistributeRowSpanHeights) { - distributeRowSpanHeights(); - } - - if (needsLayout) { - expandColumns(); - expandRows(); - layoutCells(); - // loop all relative sized components and update their size - for (int i = 0; i < cells.length; i++) { - for (int j = 0; j < cells[i].length; j++) { - Cell cell = cells[i][j]; - if (cell != null - && cell.cc != null - && (cell.hasRelativeHeight() || cell - .hasRelativeWidth())) { - client.handleComponentRelativeSize(cell.cc.getWidget()); - } - } - } - } - if (canvas.getOffsetHeight() != offsetHeight - || canvas.getOffsetWidth() != offsetWidth) { - return false; - } else { - return true; - } - } - - public RenderSpace getAllocatedSpace(Widget child) { - Cell cell = widgetToCell.get(child); - assert cell != null; - return cell.getAllocatedSpace(); - } - Cell[][] cells; /** * Private helper class. */ class Cell { - private boolean relHeight = false; - private boolean relWidth = false; - private boolean widthCanAffectHeight = false; - public Cell(UIDL c) { row = c.getIntAttribute("y"); col = c.getIntAttribute("x"); - setUidl(c); + updateFromUidl(c); } - public boolean widthCanAffectHeight() { - return widthCanAffectHeight; + public boolean hasContent() { + return hasContent; } public boolean hasRelativeHeight() { - return relHeight; - } - - public RenderSpace getAllocatedSpace() { - return new RenderSpace(getAvailableWidth() - - cc.getCaptionWidthAfterComponent(), getAvailableHeight() - - cc.getCaptionHeightAboveComponent()); - } - - public boolean hasContent() { - return childUidl != null; + if (slot != null) { + return slot.getPaintable().isRelativeHeight(); + } else { + return true; + } } /** @@ -780,7 +459,7 @@ public class VGridLayout extends SimplePanel implements Container { private int getAvailableWidth() { int width = columnWidths[col]; for (int i = 1; i < colspan; i++) { - width += spacingPixelsHorizontal + columnWidths[col + i]; + width += getHorizontalSpacing() + columnWidths[col + i]; } return width; } @@ -791,110 +470,65 @@ public class VGridLayout extends SimplePanel implements Container { private int getAvailableHeight() { int height = rowHeights[row]; for (int i = 1; i < rowspan; i++) { - height += spacingPixelsVertical + rowHeights[row + i]; + height += getVerticalSpacing() + rowHeights[row + i]; } return height; } - public void layout(int x, int y) { - if (cc != null && cc.isAttached()) { - canvas.setWidgetPosition(cc, x, y); - cc.setContainerSize(getAvailableWidth(), getAvailableHeight()); - cc.setAlignment(new AlignmentInfo(alignment)); - cc.updateAlignments(getAvailableWidth(), getAvailableHeight()); + public void layoutHorizontally(int x) { + if (slot != null) { + slot.positionHorizontally(x, getAvailableWidth()); } } - public int getWidth() { - if (cc != null) { - int w = cc.getWidgetSize().getWidth() - + cc.getCaptionWidthAfterComponent(); - return w; - } else { - return 0; + public void layoutVertically(int y) { + if (slot != null) { + slot.positionVertically(y, getAvailableHeight()); } } - public int getHeight() { - if (cc != null) { - return cc.getWidgetSize().getHeight() - + cc.getCaptionHeightAboveComponent(); + public int getWidth() { + if (slot != null) { + return slot.getUsedWidth(); } else { return 0; } } - public boolean renderIfNoRelativeWidth() { - if (childUidl == null) { - return false; - } - if (!hasRelativeWidth()) { - render(); - return true; + public int getHeight() { + if (slot != null) { + return slot.getUsedHeight(); } else { - return false; + return 0; } } protected boolean hasRelativeWidth() { - return relWidth; - } - - protected void render() { - assert childUidl != null; - - VPaintableWidget paintable = client.getPaintable(childUidl); - Widget w = paintable.getWidgetForPaintable(); - assert paintable != null; - if (cc == null || cc.getWidget() != w) { - if (widgetToComponentContainer.containsKey(w)) { - // Component moving from one place to another - cc = widgetToComponentContainer.get(w); - cc.setWidth(""); - cc.setHeight(""); - /* - * Widget might not be set if moving from another component - * and this layout has been hidden when moving out, see - * #5372 - */ - cc.setPaintable(paintable); - } else { - // A new component - cc = new ChildComponentContainer(paintable, - CellBasedLayout.ORIENTATION_VERTICAL); - widgetToComponentContainer.put(w, cc); - cc.setWidth(""); - canvas.add(cc, 0, 0); - } - widgetToCell.put(w, this); - } - cc.renderChild(childUidl, client, -1); - if (sizeChangedDuringRendering && Util.isCached(childUidl)) { - client.handleComponentRelativeSize(cc.getWidget()); + if (slot != null) { + return slot.getPaintable().isRelativeWidth(); + } else { + return true; } - cc.updateWidgetSize(); - nonRenderedWidgets.remove(w); - } - - public UIDL getChildUIDL() { - return childUidl; } final int row; final int col; int colspan = 1; int rowspan = 1; - UIDL childUidl; - int alignment; - // may be null after setUidl() if content has vanished or changed, set - // in render() - ChildComponentContainer cc; - public void setUidl(UIDL c) { + private boolean hasContent; + + private AlignmentInfo alignment; + + VPaintableLayoutSlot slot; + + public void updateFromUidl(UIDL cellUidl) { // Set cell width - colspan = c.hasAttribute("w") ? c.getIntAttribute("w") : 1; + colspan = cellUidl.hasAttribute("w") ? cellUidl + .getIntAttribute("w") : 1; // Set cell height - rowspan = c.hasAttribute("h") ? c.getIntAttribute("h") : 1; + rowspan = cellUidl.hasAttribute("h") ? cellUidl + .getIntAttribute("h") : 1; // ensure we will lose reference to old cells, now overlapped by // this cell for (int i = 0; i < colspan; i++) { @@ -905,50 +539,32 @@ public class VGridLayout extends SimplePanel implements Container { } } - c = c.getChildUIDL(0); // we are interested about childUidl - if (childUidl != null) { - if (c == null) { - // content has vanished, old content will be removed from - // canvas later during the render phase - cc = null; - } else if (cc != null - && cc.getWidget() != client.getPaintable(c) - .getWidgetForPaintable()) { - // content has changed - cc = null; - VPaintableWidget paintable = client.getPaintable(c); - Widget w = paintable.getWidgetForPaintable(); - if (widgetToComponentContainer.containsKey(w)) { - // cc exist for this component (moved) use that for this - // cell - cc = widgetToComponentContainer.get(w); - cc.setWidth(""); - cc.setHeight(""); - widgetToCell.put(w, this); + UIDL childUidl = cellUidl.getChildUIDL(0); // we are interested + // about childUidl + hasContent = childUidl != null; + if (hasContent) { + VPaintableWidget paintable = client.getPaintable(childUidl); + + if (slot == null || slot.getPaintable() != paintable) { + slot = new VPaintableLayoutSlot(CLASSNAME, paintable); + Element slotWrapper = slot.getWrapperElement(); + getElement().appendChild(slotWrapper); + + Widget widget = paintable.getWidgetForPaintable(); + insert(widget, slotWrapper, getWidgetCount(), false); + Cell oldCell = widgetToCell.put(widget, this); + if (oldCell != null) { + oldCell.slot.getWrapperElement().removeFromParent(); + oldCell.slot = null; } } - } - childUidl = c; - if (null != c) { - VPaintableWidget paintable = client.getPaintable(c); - updateRelSizeStatus(paintable.getState(), - c.getBooleanAttribute("cached")); + + paintable.updateFromUIDL(childUidl, client); } } - protected void updateRelSizeStatus(ComponentState state, boolean cached) { - if (state != null && !cached) { - boolean widthDefined = !state.isUndefinedWidth(); - boolean heightDefined = !state.isUndefinedHeight(); - - relHeight = state.getHeight().contains("%"); - relWidth = state.getWidth().contains("%"); - if (widthDefined) { - widthCanAffectHeight = (relWidth && !heightDefined); - } else { - widthCanAffectHeight = !heightDefined; - } - } + public void setAlignment(AlignmentInfo alignmentInfo) { + slot.setAlignment(alignmentInfo); } } @@ -960,7 +576,7 @@ public class VGridLayout extends SimplePanel implements Container { cell = new Cell(c); cells[col][row] = cell; } else { - cell.setUidl(c); + cell.updateFromUidl(c); } return cell; } @@ -979,4 +595,47 @@ public class VGridLayout extends SimplePanel implements Container { return Util.getPaintableForElement(client, this, element); } + void setCaption(Widget widget, VCaption caption) { + VLayoutSlot slot = widgetToCell.get(widget).slot; + + 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); + } + } + + 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"); + } + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java index 24d33fc155..43dbdc9f61 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java @@ -3,9 +3,8 @@ */ package com.vaadin.terminal.gwt.client.ui; -import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.DomEvent.Type; @@ -14,14 +13,17 @@ 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.DirectionalManagedLayout; import com.vaadin.terminal.gwt.client.EventId; 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.ui.VGridLayout.Cell; -import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer; +import com.vaadin.terminal.gwt.client.ui.layout.VLayoutSlot; -public class VGridLayoutPaintable extends VAbstractPaintableWidgetContainer { +public class VGridLayoutPaintable extends VAbstractPaintableWidgetContainer + implements DirectionalManagedLayout { private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler( this, EventId.LAYOUT_CLICK) { @@ -38,52 +40,48 @@ public class VGridLayoutPaintable extends VAbstractPaintableWidgetContainer { }; @Override + public void init() { + getLayoutManager().registerDependency(this, + getWidgetForPaintable().spacingMeasureElement); + } + + @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - getWidgetForPaintable().rendering = true; - getWidgetForPaintable().client = client; + VGridLayout layout = getWidgetForPaintable(); + layout.client = client; super.updateFromUIDL(uidl, client); if (!isRealUpdate(uidl)) { - getWidgetForPaintable().rendering = false; return; } clickEventHandler.handleEventHandlerRegistration(client); - getWidgetForPaintable().canvas.setWidth("0px"); - - getWidgetForPaintable().handleMargins(uidl); - getWidgetForPaintable().detectSpacing(uidl); - int cols = uidl.getIntAttribute("w"); int rows = uidl.getIntAttribute("h"); - getWidgetForPaintable().columnWidths = new int[cols]; - getWidgetForPaintable().rowHeights = new int[rows]; + layout.columnWidths = new int[cols]; + layout.rowHeights = new int[rows]; - if (getWidgetForPaintable().cells == null) { - getWidgetForPaintable().cells = new Cell[cols][rows]; - } else if (getWidgetForPaintable().cells.length != cols - || getWidgetForPaintable().cells[0].length != rows) { + if (layout.cells == null) { + layout.cells = new Cell[cols][rows]; + } else if (layout.cells.length != cols + || layout.cells[0].length != rows) { Cell[][] newCells = new Cell[cols][rows]; - for (int i = 0; i < getWidgetForPaintable().cells.length; i++) { - for (int j = 0; j < getWidgetForPaintable().cells[i].length; j++) { + for (int i = 0; i < layout.cells.length; i++) { + for (int j = 0; j < layout.cells[i].length; j++) { if (i < cols && j < rows) { - newCells[i][j] = getWidgetForPaintable().cells[i][j]; + newCells[i][j] = layout.cells[i][j]; } } } - getWidgetForPaintable().cells = newCells; + layout.cells = newCells; } - getWidgetForPaintable().nonRenderedWidgets = (HashMap<Widget, ChildComponentContainer>) getWidgetForPaintable().widgetToComponentContainer - .clone(); - final int[] alignments = uidl.getIntArrayAttribute("alignments"); int alignmentIndex = 0; - LinkedList<Cell> pendingCells = new LinkedList<Cell>(); - - LinkedList<Cell> relativeHeighted = new LinkedList<Cell>(); + HashSet<Widget> nonRenderedWidgets = new HashSet<Widget>( + layout.widgetToCell.keySet()); for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) { final UIDL r = (UIDL) i.next(); @@ -91,97 +89,58 @@ public class VGridLayoutPaintable extends VAbstractPaintableWidgetContainer { for (final Iterator<?> j = r.getChildIterator(); j.hasNext();) { final UIDL c = (UIDL) j.next(); if ("gc".equals(c.getTag())) { - Cell cell = getWidgetForPaintable().getCell(c); + Cell cell = layout.getCell(c); if (cell.hasContent()) { - boolean rendered = cell.renderIfNoRelativeWidth(); - cell.alignment = alignments[alignmentIndex++]; - if (!rendered) { - pendingCells.add(cell); - } - - if (cell.colspan > 1) { - getWidgetForPaintable().storeColSpannedCell( - cell); - } else if (rendered) { - // strore non-colspanned widths to columnWidth - // array - if (getWidgetForPaintable().columnWidths[cell.col] < cell - .getWidth()) { - getWidgetForPaintable().columnWidths[cell.col] = cell - .getWidth(); - } - } - if (cell.hasRelativeHeight()) { - relativeHeighted.add(cell); - } + cell.setAlignment(new AlignmentInfo( + alignments[alignmentIndex++])); + nonRenderedWidgets.remove(cell.slot.getWidget()); } } } } } - getWidgetForPaintable().colExpandRatioArray = uidl - .getIntArrayAttribute("colExpand"); - getWidgetForPaintable().rowExpandRatioArray = uidl - .getIntArrayAttribute("rowExpand"); - getWidgetForPaintable().distributeColSpanWidths(); - - getWidgetForPaintable().minColumnWidths = VGridLayout - .cloneArray(getWidgetForPaintable().columnWidths); - getWidgetForPaintable().expandColumns(); - - getWidgetForPaintable().renderRemainingComponentsWithNoRelativeHeight( - pendingCells); - - getWidgetForPaintable().detectRowHeights(); - - getWidgetForPaintable().expandRows(); - - getWidgetForPaintable().renderRemainingComponents(pendingCells); - - for (Cell cell : relativeHeighted) { - // rendering done above so cell.cc should not be null - Widget widget2 = cell.cc.getWidget(); - client.handleComponentRelativeSize(widget2); - cell.cc.updateWidgetSize(); - } - - getWidgetForPaintable().layoutCells(); + layout.colExpandRatioArray = uidl.getIntArrayAttribute("colExpand"); + layout.rowExpandRatioArray = uidl.getIntArrayAttribute("rowExpand"); // clean non rendered components - for (Widget w : getWidgetForPaintable().nonRenderedWidgets.keySet()) { - ChildComponentContainer childComponentContainer = getWidgetForPaintable().widgetToComponentContainer - .get(w); - getWidgetForPaintable().widgetToCell.remove(w); - getWidgetForPaintable().widgetToComponentContainer.remove(w); - childComponentContainer.removeFromParent(); - VPaintableMap paintableMap = VPaintableMap.get(client); - paintableMap.unregisterPaintable(paintableMap.getPaintable(w)); + for (Widget w : nonRenderedWidgets) { + Cell cell = layout.widgetToCell.remove(w); + cell.slot.setCaption(null); + + if (w.getParent() == layout) { + w.removeFromParent(); + VPaintableMap paintableMap = VPaintableMap.get(client); + paintableMap.unregisterPaintable(paintableMap.getPaintable(w)); + } + cell.slot.getWrapperElement().removeFromParent(); } - getWidgetForPaintable().nonRenderedWidgets = null; - getWidgetForPaintable().rendering = false; - getWidgetForPaintable().sizeChangedDuringRendering = false; + int bitMask = uidl.getIntAttribute("margins"); + layout.updateMarginStyleNames(new VMarginInfo(bitMask)); + + layout.updateSpacingStyleName(uidl.getBooleanAttribute("spacing")); + getLayoutManager().setNeedsUpdate(this); } public void updateCaption(VPaintableWidget paintable, UIDL uidl) { - Widget widget = paintable.getWidgetForPaintable(); - ChildComponentContainer cc = getWidgetForPaintable().widgetToComponentContainer - .get(widget); - if (cc != null) { - cc.updateCaption(uidl, getConnection()); - } - if (!getWidgetForPaintable().rendering) { - // ensure rel size details are updated - boolean cached = uidl.getBooleanAttribute("cached"); - getWidgetForPaintable().widgetToCell.get(widget) - .updateRelSizeStatus(paintable.getState(), cached); - /* - * This was a component-only update and the possible size change - * must be propagated to the layout - */ - getConnection().captionSizeUpdated(widget); + VGridLayout layout = getWidgetForPaintable(); + if (VCaption.isNeeded(uidl, paintable.getState())) { + Cell cell = layout.widgetToCell.get(paintable + .getWidgetForPaintable()); + VLayoutSlot layoutSlot = cell.slot; + VCaption caption = layoutSlot.getCaption(); + if (caption == null) { + caption = new VCaption(paintable, getConnection()); + + Widget widget = paintable.getWidgetForPaintable(); + + layout.setCaption(widget, caption); + } + caption.updateCaption(uidl); + } else { + layout.setCaption(paintable.getWidgetForPaintable(), null); } } @@ -195,4 +154,11 @@ public class VGridLayoutPaintable extends VAbstractPaintableWidgetContainer { return GWT.create(VGridLayout.class); } + public void layoutVertically() { + getWidgetForPaintable().updateHeight(); + } + + public void layoutHorizontally() { + getWidgetForPaintable().updateWidth(); + } } 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..3c0e9af26d --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayout.java @@ -0,0 +1,196 @@ +/* +@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.Node; +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 addOrMove(VLayoutSlot layoutSlot, int index) { + Widget widget = layoutSlot.getWidget(); + Element wrapperElement = layoutSlot.getWrapperElement(); + + Element containerElement = getElement(); + Node childAtIndex = containerElement.getChild(index); + if (childAtIndex != wrapperElement) { + // Insert at correct location not attached or at wrong location + containerElement.insertBefore(wrapperElement, childAtIndex); + insert(widget, wrapperElement, index, false); + } + + 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..141726b90d --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayoutPaintable.java @@ -0,0 +1,290 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui; + +import java.util.HashSet; +import java.util.Iterator; + +import com.google.gwt.dom.client.Node; +import com.google.gwt.dom.client.Style; +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.DirectionalManagedLayout; +import com.vaadin.terminal.gwt.client.LayoutManager; +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 DirectionalManagedLayout { + + @Override + public void init() { + getLayoutManager().registerDependency(this, + getWidgetForPaintable().spacingMeasureElement); + } + + public void updateCaption(VPaintableWidget component, UIDL uidl) { + VMeasuringOrderedLayout layout = getWidgetForPaintable(); + if (VCaption.isNeeded(uidl, component.getState())) { + 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"); + + int currentIndex = 0; + // 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(getWidgetForPaintable() + .getStylePrimaryName(), child); + } + layout.addOrMove(slot, currentIndex++); + + 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(); + + // Don't remove and unregister if it has been moved to a different + // parent. Slot element will be left behind, but that is taken care + // of later + if (widget.getParent() == getWidgetForPaintable()) { + layout.removeSlot(layout.getSlotForChild(widget)); + + VPaintableMap vPaintableMap = VPaintableMap.get(client); + vPaintableMap.unregisterPaintable(child); + } + } + + // Remove empty layout slots left behind after children have moved to + // other paintables + while (true) { + int childCount = layout.getElement().getChildCount(); + if (childCount <= 1) { + // Stop if no more slots (spacing element is always present) + break; + } + + Node lastSlot = layout.getElement().getChild(childCount - 2); + if (lastSlot.getChildCount() == 0) { + // Remove if empty + lastSlot.removeFromParent(); + } else { + // Stop searching when last slot is not empty + break; + } + } + + int bitMask = uidl.getIntAttribute("margins"); + layout.updateMarginStyleNames(new VMarginInfo(bitMask)); + + layout.updateSpacingStyleName(uidl.getBooleanAttribute("spacing")); + + getLayoutManager().setNeedsUpdate(this); + } + + private int getSizeForInnerSize(int size, boolean isVertical) { + LayoutManager layoutManager = getLayoutManager(); + Element element = getWidgetForPaintable().getElement(); + if (isVertical) { + return size + layoutManager.getBorderHeight(element) + + layoutManager.getPaddingHeight(element); + } else { + return size + layoutManager.getBorderWidth(element) + + layoutManager.getPaddingWidth(element); + } + } + + 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 getLayoutManager().getInnerHeight( + getWidgetForPaintable().getElement()); + } else { + return getLayoutManager().getInnerWidth( + getWidgetForPaintable().getElement()); + } + } + + 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 getLayoutManager().getOuterHeight( + getWidgetForPaintable().spacingMeasureElement); + } else { + return getLayoutManager().getOuterWidth( + 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 getDeclaredHeight(); + } else { + return getDeclaredWidth(); + } + } + + private int getStartPadding(boolean isVertical) { + if (isVertical) { + return getLayoutManager().getPaddingTop( + getWidgetForPaintable().getElement()); + } else { + return getLayoutManager().getPaddingLeft( + getWidgetForPaintable().getElement()); + } + } + + public void layoutHorizontally() { + if (getWidgetForPaintable().isVertical) { + layoutSecondaryDirection(); + } else { + layoutPrimaryDirection(); + } + } + + public void layoutVertically() { + if (getWidgetForPaintable().isVertical) { + layoutPrimaryDirection(); + } else { + layoutSecondaryDirection(); + } + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java index f5cab6a643..b49bac3338 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java @@ -32,15 +32,14 @@ import com.google.gwt.user.client.ui.RootPanel; 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.ContainerResizedListener; import com.vaadin.terminal.gwt.client.TooltipInfo; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VTooltip; public class VMenuBar extends SimpleFocusablePanel implements - CloseHandler<PopupPanel>, ContainerResizedListener, KeyPressHandler, - KeyDownHandler, FocusHandler, SubPartAware { + CloseHandler<PopupPanel>, KeyPressHandler, KeyDownHandler, + FocusHandler, SubPartAware { // The hierarchy of VMenuBar is a bit weird as VMenuBar is the Paintable, // used for the root menu but also used for the sub menus. @@ -149,16 +148,8 @@ public class VMenuBar extends SimpleFocusablePanel implements } } - @Override - public void setWidth(String width) { - if (Util.equals(this.width, width)) { - return; - } - - this.width = width; - - Util.setWidthExcludingPaddingAndBorder(this, width, 0); - + void updateSize() { + // Take from setWidth if (!subMenu) { // Only needed for root level menu hideChildren(); @@ -958,6 +949,7 @@ public class VMenuBar extends SimpleFocusablePanel implements public void iLayout() { iLayout(false); + updateSize(); } public void iLayout(boolean iconLoadEvent) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java index ce0de7512e..52eda29b00 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java @@ -14,7 +14,8 @@ import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.ui.VMenuBar.CustomMenuItem; -public class VMenuBarPaintable extends VAbstractPaintableWidget { +public class VMenuBarPaintable extends VAbstractPaintableWidget implements + SimpleManagedLayout { /** * This method must be implemented to update the client-side component from * UIDL data received from server. @@ -162,4 +163,7 @@ public class VMenuBarPaintable extends VAbstractPaintableWidget { return (VMenuBar) super.getWidgetForPaintable(); } + public void layout() { + getWidgetForPaintable().iLayout(); + } } 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 58d93fccc6..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayoutPaintable.java +++ /dev/null @@ -1,257 +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 (null != childPaintable.getState()) { - FloatSize relativeSize = Util.parseRelativeSize(childPaintable - .getState()); - 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 c7b36a2e3d..543973220c 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) { @@ -192,54 +153,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); @@ -277,159 +190,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 a9b181da83..5787321cd4 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.LayoutManager; 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 SimpleManagedLayout, PostLayoutListener { public static final String CLICK_EVENT_IDENTIFIER = "click"; + private Integer uidlScrollTop; + private ClickEventHandler clickEventHandler = new ClickEventHandler(this, CLICK_EVENT_IDENTIFIER) { @@ -26,14 +32,25 @@ public class VPanelPaintable extends VAbstractPaintableWidgetContainer { } }; + private Integer uidlScrollLeft; + + @Override + public void init() { + VPanel panel = getWidgetForPaintable(); + LayoutManager layoutManager = getLayoutManager(); + + layoutManager.registerDependency(this, panel.captionNode); + layoutManager.registerDependency(this, panel.bottomDecoration); + layoutManager.registerDependency(this, 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. @@ -82,7 +99,6 @@ public class VPanelPaintable extends VAbstractPaintableWidgetContainer { super.updateFromUIDL(uidl, client); if (!isRealUpdate(uidl)) { - getWidgetForPaintable().rendering = false; return; } @@ -126,42 +142,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) { @@ -178,4 +175,61 @@ public class VPanelPaintable extends VAbstractPaintableWidgetContainer { return GWT.create(VPanel.class); } + public void layout() { + updateSizes(); + } + + void updateSizes() { + 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); + } + + LayoutManager layoutManager = getLayoutManager(); + int top = layoutManager.getOuterHeight(panel.captionNode); + int bottom = layoutManager.getOuterHeight(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 postLayout() { + 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/VPopupCalendar.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java index 1c0b937e05..cbd3a7af8f 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java @@ -277,20 +277,6 @@ public class VPopupCalendar extends VTextualDate implements Field, /* * (non-Javadoc) * - * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#getFieldExtraWidth() - */ - @Override - protected int getFieldExtraWidth() { - if (fieldExtraWidth < 0) { - fieldExtraWidth = super.getFieldExtraWidth(); - fieldExtraWidth += calendarToggle.getOffsetWidth(); - } - return fieldExtraWidth; - } - - /* - * (non-Javadoc) - * * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#buildDate() */ @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendarPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendarPaintable.java index 3bf7f844e8..62168cb64f 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendarPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendarPaintable.java @@ -115,15 +115,6 @@ public class VPopupCalendarPaintable extends VTextualDatePaintable { + "-button-readonly"); } - if (lastReadOnlyState != getWidgetForPaintable().readonly - || lastEnabledState != getWidgetForPaintable().isEnabled()) { - // Enabled or readonly state changed. Differences in theming might - // affect the width (for instance if the popup button is hidden) so - // we have to recalculate the width (IF the width of the field is - // fixed) - getWidgetForPaintable().updateWidth(); - } - getWidgetForPaintable().calendarToggle.setEnabled(true); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index b4499cd2d5..c4651ee626 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -60,10 +60,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.ComponentState; -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; @@ -107,7 +105,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); @@ -432,8 +430,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; @@ -1670,7 +1666,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) { @@ -1798,7 +1794,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 @@ -1879,7 +1875,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; } @@ -5316,29 +5312,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; } @@ -5519,7 +5492,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, return; } - if (height == null || height.equals("")) { + if (isDynamicHeight()) { return; } @@ -5543,16 +5516,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 @@ -5562,9 +5533,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; @@ -5576,9 +5545,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } else { - // Undefined width - super.setWidth(""); - // Readjust size of table sizeInit(); @@ -5694,8 +5660,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(); @@ -5767,7 +5732,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(); @@ -5804,15 +5769,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 @@ -6688,6 +6649,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); @@ -6697,46 +6670,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 63a02879e8..c6fcc67cb2 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.DirectionalManagedLayout; 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 DirectionalManagedLayout { /* * (non-Javadoc) @@ -258,4 +260,11 @@ public class VScrollTablePaintable extends VAbstractPaintableWidgetContainer { // NOP, not rendered } + public void layoutVertically() { + getWidgetForPaintable().updateHeight(); + } + + public void layoutHorizontally() { + 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 c126e81aec..9b154c0d91 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; @@ -24,8 +23,6 @@ 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.ComponentState; -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; @@ -490,15 +487,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 @@ -506,8 +500,6 @@ public class VTabsheet extends VTabsheetBase { */ private Widget previousVisibleWidget; - boolean rendering = false; - private String currentStyle; private void onTabSelected(final int tabIndex) { @@ -555,11 +547,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() { @@ -865,22 +861,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(); @@ -890,50 +872,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() { @@ -956,10 +897,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 @@ -976,8 +917,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.getDeclaredWidth()); } // Make sure scrollerIndex is valid @@ -1058,68 +1001,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 2b3e38576b..80affa8177 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 + SimpleManagedLayout { @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 layout() { + 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/VTextualDate.java b/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java index a3bf985925..dac9665675 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java @@ -14,7 +14,6 @@ import com.google.gwt.event.dom.client.FocusEvent; import com.google.gwt.event.dom.client.FocusHandler; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.TextBox; -import com.vaadin.terminal.gwt.client.ContainerResizedListener; import com.vaadin.terminal.gwt.client.EventId; import com.vaadin.terminal.gwt.client.Focusable; import com.vaadin.terminal.gwt.client.LocaleNotLoadedException; @@ -22,7 +21,7 @@ import com.vaadin.terminal.gwt.client.LocaleService; import com.vaadin.terminal.gwt.client.VConsole; public class VTextualDate extends VDateField implements Field, ChangeHandler, - ContainerResizedListener, Focusable, SubPartAware { + Focusable, SubPartAware { private static final String PARSE_ERROR_CLASSNAME = CLASSNAME + "-parseerror"; @@ -31,12 +30,6 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler, protected String formatStr; - private String width; - - private boolean needLayout; - - protected int fieldExtraWidth = -1; - protected boolean lenient; private static final String CLASSNAME_PROMPT = "prompt"; @@ -295,72 +288,6 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler, return format.trim(); } - @Override - public void setWidth(String newWidth) { - if (!"".equals(newWidth) - && (isUndefinedWidth() || !newWidth.equals(width))) { - needLayout = true; - width = newWidth; - super.setWidth(width); - iLayout(); - if (newWidth.indexOf("%") < 0) { - needLayout = false; - } - } else { - if ("".equals(newWidth) && !isUndefinedWidth()) { - super.setWidth(""); - iLayout(true); - width = null; - } - } - } - - protected boolean isUndefinedWidth() { - return width == null || "".equals(width); - } - - /** - * Returns pixels in x-axis reserved for other than textfield content. - * - * @return extra width in pixels - */ - protected int getFieldExtraWidth() { - if (fieldExtraWidth < 0) { - text.setWidth("0"); - fieldExtraWidth = text.getOffsetWidth(); - } - return fieldExtraWidth; - } - - /** - * Force an recalculation of the width of the component IF the width has - * been defined. Does nothing if width is undefined as the width will be - * automatically adjusted by the browser. - */ - public void updateWidth() { - if (isUndefinedWidth()) { - return; - } - needLayout = true; - fieldExtraWidth = -1; - iLayout(true); - } - - public void iLayout() { - iLayout(false); - } - - public void iLayout(boolean force) { - if (needLayout || force) { - int textFieldWidth = getOffsetWidth() - getFieldExtraWidth(); - if (textFieldWidth < 0) { - // Field can never be smaller than 0 (causes exception in IE) - textFieldWidth = 0; - } - text.setWidth(textFieldWidth + "px"); - } - } - public void focus() { text.setFocus(true); } 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 c8403b429a..aa739f6549 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java @@ -142,9 +142,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>( @@ -306,8 +303,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 3ab8438365..edd02860da 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 d5758ea5a5..2d722fc995 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, SimpleManagedLayout, + PostLayoutListener { private static final String CLICK_EVENT_IDENTIFIER = VPanelPaintable.CLICK_EVENT_IDENTIFIER; @@ -303,4 +304,16 @@ public class VWindowPaintable extends VAbstractPaintableWidgetContainer return GWT.create(VWindow.class); } + public void layout() { + getWidgetForPaintable().requestLayout(); + } + + public void postLayout() { + 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 433907eb04..bc2e27db0b 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.ApplicationConnection; @@ -15,9 +16,7 @@ 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; + private ApplicationConnection connection; public VLabel() { @@ -46,19 +45,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 e41a1175b9..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayoutPaintable.java +++ /dev/null @@ -1,63 +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; - - if (isRealUpdate(uidl)) { - /** - * Margin and spacing 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); - - if (isRealUpdate(uidl)) { - handleDynamicDimensions(); - } - } - - private void handleDynamicDimensions() { - getWidgetForPaintable().dynamicWidth = getState().isUndefinedWidth(); - getWidgetForPaintable().dynamicHeight = getState().isUndefinedHeight(); - } - - void updateMarginAndSpacingInfo(UIDL uidl) { - 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 deleted file mode 100644 index 6568bfcf97..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/layout/ChildComponentContainer.java +++ /dev/null @@ -1,737 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.terminal.gwt.client.ui.layout; - -import java.util.Iterator; -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.user.client.ui.Panel; -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.FloatSize; -import com.vaadin.terminal.gwt.client.RenderInformation.Size; -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.VConsole; -import com.vaadin.terminal.gwt.client.VPaintableWidget; -import com.vaadin.terminal.gwt.client.ui.AlignmentInfo; - -public class ChildComponentContainer extends Panel { - - /** - * Size of the container DIV excluding any margins and also excluding the - * expansion amount (containerExpansion) - */ - private Size contSize = new Size(0, 0); - - /** - * Size of the widget inside the container DIV - */ - private Size widgetSize = new Size(0, 0); - /** - * Size of the caption - */ - private int captionRequiredWidth = 0; - private int captionWidth = 0; - private int captionHeight = 0; - - /** - * - * Padding added to the container when it is larger than the component. - */ - private Size containerExpansion = new Size(0, 0); - - private double expandRatio; - - // private int containerMarginLeft = 0; - private int containerMarginTop = 0; - - AlignmentInfo alignment = AlignmentInfo.TOP_LEFT; - - private int alignmentLeftOffsetForWidget = 0; - private int alignmentLeftOffsetForCaption = 0; - /** - * Top offset for implementing alignment. Top offset is set to the container - * DIV as it otherwise would have to be set to either the Caption or the - * Widget depending on whether there is a caption and where the caption is - * located. - */ - private int alignmentTopOffset = 0; - - // private Margins alignmentOffset = new Margins(0, 0, 0, 0); - private VCaption caption = null; - private DivElement containerDIV; - private DivElement widgetDIV; - private VPaintableWidget paintable; - private Widget widget; - private FloatSize relativeSize = null; - - public ChildComponentContainer(VPaintableWidget child, int orientation) { - super(); - - containerDIV = Document.get().createDivElement(); - - widgetDIV = Document.get().createDivElement(); - - setFloat(widgetDIV, "left"); - setElement(containerDIV); - containerDIV.getStyle().setProperty("height", "0"); - containerDIV.getStyle().setProperty("width", "0px"); - containerDIV.getStyle().setProperty("overflow", "hidden"); - - if (BrowserInfo.get().isIE()) { - /* - * IE requires position: relative on overflow:hidden elements if - * they should hide position:relative elements. Without this e.g. a - * 1000x1000 Panel inside an 500x500 OrderedLayout will not be - * clipped but fully shown. - */ - containerDIV.getStyle().setProperty("position", "relative"); - widgetDIV.getStyle().setProperty("position", "relative"); - } - - containerDIV.appendChild(widgetDIV); - - setOrientation(orientation); - - setPaintable(child); - } - - public void setPaintable(VPaintableWidget childPaintable) { - paintable = childPaintable; - setWidget(childPaintable.getWidgetForPaintable()); - } - - private void setWidget(Widget w) { - // Validate - if (w == widget) { - return; - } - - // Detach new child. - if (w != null) { - w.removeFromParent(); - } - - // Remove old child. - if (widget != null) { - remove(widget); - } - - // Logical attach. - widget = w; - - if (w != null) { - // Physical attach. - widgetDIV.appendChild(widget.getElement()); - adopt(w); - } - } - - private static void setFloat(Element div, String floatString) { - if (BrowserInfo.get().isIE()) { - div.getStyle().setProperty("styleFloat", floatString); - // IE requires display:inline for margin-left to work together - // with float:left - if (floatString.equals("left")) { - div.getStyle().setProperty("display", "inline"); - } else { - div.getStyle().setProperty("display", "block"); - } - - } else { - div.getStyle().setProperty("cssFloat", floatString); - } - } - - public void setOrientation(int orientation) { - if (orientation == CellBasedLayout.ORIENTATION_HORIZONTAL) { - setFloat(getElement(), "left"); - } else { - setFloat(getElement(), ""); - } - setHeight("0px"); - // setWidth("0px"); - contSize.setHeight(0); - contSize.setWidth(0); - // containerMarginLeft = 0; - containerMarginTop = 0; - containerDIV.getStyle().setProperty("paddingLeft", "0"); - containerDIV.getStyle().setProperty("paddingTop", "0"); - - containerExpansion.setHeight(0); - containerExpansion.setWidth(0); - - // Clear old alignments - clearAlignments(); - - } - - public void renderChild(UIDL childUIDL, ApplicationConnection client, - int fixedWidth) { - /* - * Must remove width specification from container before rendering to - * allow components to grow in horizontal direction. - * - * For fixed width layouts we specify the width directly so that height - * is automatically calculated correctly (e.g. for Labels). - */ - /* - * This should no longer be needed (after #2563) as all components are - * such that they can be rendered inside a 0x0 DIV. - * - * The exception seems to be complex components (Tree and Table) on - * Opera (#3444). - */ - if (fixedWidth < 0 && BrowserInfo.get().isOpera()) { - setUnlimitedContainerWidth(); - } - paintable.updateFromUIDL(childUIDL, client); - } - - public void setUnlimitedContainerWidth() { - setLimitedContainerWidth(1000000); - } - - public void setLimitedContainerWidth(int width) { - containerDIV.getStyle().setProperty("width", width + "px"); - } - - public void updateWidgetSize() { - /* - * Widget wrapper includes margin which the widget offsetWidth/Height - * does not include - */ - int w = Util.getRequiredWidth(widgetDIV); - int h = Util.getRequiredHeight(widgetDIV); - - widgetSize.setWidth(w); - widgetSize.setHeight(h); - - // ApplicationConnection.getConsole().log( - // Util.getSimpleName(widget) + " size is " + w + "," + h); - - } - - public void setMarginLeft(int marginLeft) { - // containerMarginLeft = marginLeft; - containerDIV.getStyle().setPropertyPx("paddingLeft", marginLeft); - } - - public void setMarginTop(int marginTop) { - containerMarginTop = marginTop; - containerDIV.getStyle().setPropertyPx("paddingTop", - marginTop + alignmentTopOffset); - - updateContainerDOMSize(); - } - - public void updateAlignments(int parentWidth, int parentHeight) { - if (parentHeight == -1) { - parentHeight = contSize.getHeight(); - } - if (parentWidth == -1) { - parentWidth = contSize.getWidth(); - } - - alignmentTopOffset = calculateVerticalAlignmentTopOffset(parentHeight); - - calculateHorizontalAlignment(parentWidth); - - applyAlignments(); - - } - - private void applyAlignments() { - - // Update top margin to take alignment into account - setMarginTop(containerMarginTop); - - if (caption != null) { - caption.getElement().getStyle() - .setPropertyPx("marginLeft", alignmentLeftOffsetForCaption); - } - widgetDIV.getStyle().setPropertyPx("marginLeft", - alignmentLeftOffsetForWidget); - } - - public int getCaptionRequiredWidth() { - if (caption == null) { - return 0; - } - - return captionRequiredWidth; - } - - public int getCaptionWidth() { - if (caption == null) { - return 0; - } - - return captionWidth; - } - - public int getCaptionHeight() { - if (caption == null) { - return 0; - } - - return captionHeight; - } - - public int getCaptionWidthAfterComponent() { - if (caption == null || !caption.shouldBePlacedAfterComponent()) { - return 0; - } - - return getCaptionWidth(); - } - - public int getCaptionHeightAboveComponent() { - if (caption == null || caption.shouldBePlacedAfterComponent()) { - return 0; - } - - return getCaptionHeight(); - } - - private int calculateVerticalAlignmentTopOffset(int emptySpace) { - if (alignment.isTop()) { - return 0; - } - - if (caption != null) { - if (caption.shouldBePlacedAfterComponent()) { - /* - * Take into account the rare case that the caption on the right - * side of the component AND is higher than the component - */ - emptySpace -= Math.max(widgetSize.getHeight(), - caption.getHeight()); - } else { - emptySpace -= widgetSize.getHeight(); - emptySpace -= getCaptionHeight(); - } - } else { - /* - * There is no caption and thus we do not need to take anything but - * the widget into account - */ - emptySpace -= widgetSize.getHeight(); - } - - int top = 0; - if (alignment.isVerticalCenter()) { - top = emptySpace / 2; - } else if (alignment.isBottom()) { - top = emptySpace; - } - - if (top < 0) { - top = 0; - } - return top; - } - - private void calculateHorizontalAlignment(int emptySpace) { - alignmentLeftOffsetForCaption = 0; - alignmentLeftOffsetForWidget = 0; - - if (alignment.isLeft()) { - return; - } - - int captionSpace = emptySpace; - int widgetSpace = emptySpace; - - if (caption != null) { - // There is a caption - if (caption.shouldBePlacedAfterComponent()) { - /* - * The caption is after component. In this case the caption - * needs no alignment. - */ - captionSpace = 0; - widgetSpace -= widgetSize.getWidth(); - widgetSpace -= getCaptionWidth(); - } else { - /* - * The caption is above the component. Caption and widget needs - * separate alignment offsets. - */ - widgetSpace -= widgetSize.getWidth(); - captionSpace -= getCaptionWidth(); - } - } else { - /* - * There is no caption and thus we do not need to take anything but - * the widget into account - */ - captionSpace = 0; - widgetSpace -= widgetSize.getWidth(); - } - - if (alignment.isHorizontalCenter()) { - alignmentLeftOffsetForCaption = captionSpace / 2; - alignmentLeftOffsetForWidget = widgetSpace / 2; - } else if (alignment.isRight()) { - alignmentLeftOffsetForCaption = captionSpace; - alignmentLeftOffsetForWidget = widgetSpace; - } - - if (alignmentLeftOffsetForCaption < 0) { - alignmentLeftOffsetForCaption = 0; - } - if (alignmentLeftOffsetForWidget < 0) { - alignmentLeftOffsetForWidget = 0; - } - - } - - public void setAlignment(AlignmentInfo alignmentInfo) { - alignment = alignmentInfo; - } - - public Size getWidgetSize() { - return widgetSize; - } - - public void updateCaption(UIDL uidl, ApplicationConnection client) { - if (VCaption.isNeeded(uidl, paintable.getState())) { - // We need a caption - - VCaption newCaption = caption; - - if (newCaption == null) { - newCaption = new VCaption(paintable, client); - // Set initial height to avoid Safari flicker - newCaption.setHeight("18px"); - // newCaption.setHeight(newCaption.getHeight()); // This might - // be better... ?? - if (BrowserInfo.get().isIE()) { - /* - * Must attach caption here so IE sends an immediate onload - * event for images coming from the cache - */ - setCaption(newCaption); - } - } - - boolean positionChanged = newCaption.updateCaption(uidl); - - if (newCaption != caption || positionChanged) { - setCaption(newCaption); - } - - } else { - // Caption is not needed - if (caption != null) { - remove(caption); - } - - } - - updateCaptionSize(); - } - - public void updateCaptionSize() { - captionWidth = 0; - captionHeight = 0; - - if (caption != null) { - captionWidth = caption.getRenderedWidth(); - captionHeight = caption.getHeight(); - captionRequiredWidth = caption.getRequiredWidth(); - - /* - * ApplicationConnection.getConsole().log( - * "Caption rendered width: " + captionWidth + - * ", caption required width: " + captionRequiredWidth + - * ", caption height: " + captionHeight); - */ - } - - } - - private void setCaption(VCaption newCaption) { - // Validate - // if (newCaption == caption) { - // return; - // } - - // Detach new child. - if (newCaption != null) { - newCaption.removeFromParent(); - } - - // Remove old child. - if (caption != null && newCaption != caption) { - remove(caption); - } - - // Logical attach. - caption = newCaption; - - if (caption != null) { - // Physical attach. - if (caption.shouldBePlacedAfterComponent()) { - Util.setFloat(caption.getElement(), "left"); - containerDIV.appendChild(caption.getElement()); - } else { - Util.setFloat(caption.getElement(), ""); - containerDIV.insertBefore(caption.getElement(), widgetDIV); - } - - adopt(caption); - } - - } - - @Override - public boolean remove(Widget child) { - // Validate - if (child != caption && child != widget) { - return false; - } - - // Orphan - orphan(child); - - // Physical && Logical Detach - if (child == caption) { - containerDIV.removeChild(child.getElement()); - caption = null; - } else { - widgetDIV.removeChild(child.getElement()); - widget = null; - } - - return true; - } - - public Iterator<Widget> iterator() { - return new ChildComponentContainerIterator<Widget>(); - } - - public class ChildComponentContainerIterator<T> implements Iterator<Widget> { - private int id = 0; - - public boolean hasNext() { - return (id < size()); - } - - public Widget next() { - Widget w = get(id); - id++; - return w; - } - - private Widget get(int i) { - if (i == 0) { - if (widget != null) { - return widget; - } else if (caption != null) { - return caption; - } else { - throw new NoSuchElementException(); - } - } else if (i == 1) { - if (widget != null && caption != null) { - return caption; - } else { - throw new NoSuchElementException(); - } - } else { - throw new NoSuchElementException(); - } - } - - public void remove() { - int toRemove = id - 1; - if (toRemove == 0) { - if (widget != null) { - ChildComponentContainer.this.remove(widget); - } else if (caption != null) { - ChildComponentContainer.this.remove(caption); - } else { - throw new IllegalStateException(); - } - - } else if (toRemove == 1) { - if (widget != null && caption != null) { - ChildComponentContainer.this.remove(caption); - } else { - throw new IllegalStateException(); - } - } else { - throw new IllegalStateException(); - } - - id--; - } - } - - public int size() { - if (widget != null) { - if (caption != null) { - return 2; - } else { - return 1; - } - } else { - if (caption != null) { - return 1; - } else { - return 0; - } - } - } - - public Widget getWidget() { - return widget; - } - - /** - * Return true if the size of the widget has been specified in the selected - * orientation. - * - * @return - */ - public boolean widgetHasSizeSpecified(int orientation) { - String size; - if (orientation == CellBasedLayout.ORIENTATION_HORIZONTAL) { - size = widget.getElement().getStyle().getProperty("width"); - } else { - size = widget.getElement().getStyle().getProperty("height"); - } - return (size != null && !size.equals("")); - } - - public boolean isComponentRelativeSized(int orientation) { - if (relativeSize == null) { - return false; - } - if (orientation == CellBasedLayout.ORIENTATION_HORIZONTAL) { - return relativeSize.getWidth() >= 0; - } else { - return relativeSize.getHeight() >= 0; - } - } - - public void setRelativeSize(FloatSize relativeSize) { - this.relativeSize = relativeSize; - } - - public Size getContSize() { - return contSize; - } - - public void clearAlignments() { - alignmentLeftOffsetForCaption = 0; - alignmentLeftOffsetForWidget = 0; - alignmentTopOffset = 0; - applyAlignments(); - - } - - /** - * Sets the normalized expand ratio of this slot. The fraction that this - * slot will use of "excess space". - * - * @param expandRatio - */ - public void setNormalizedExpandRatio(double expandRatio) { - this.expandRatio = expandRatio; - } - - public int expand(int orientation, int spaceForExpansion) { - int expansionAmount = (int) (spaceForExpansion * expandRatio); - - if (orientation == CellBasedLayout.ORIENTATION_HORIZONTAL) { - // HORIZONTAL - containerExpansion.setWidth(expansionAmount); - } else { - // VERTICAL - containerExpansion.setHeight(expansionAmount); - } - - return expansionAmount; - } - - public void expandExtra(int orientation, int extra) { - if (orientation == CellBasedLayout.ORIENTATION_HORIZONTAL) { - // HORIZONTAL - containerExpansion.setWidth(containerExpansion.getWidth() + extra); - } else { - // VERTICAL - containerExpansion - .setHeight(containerExpansion.getHeight() + extra); - } - - } - - public void setContainerSize(int widgetAndCaptionWidth, - int widgetAndCaptionHeight) { - - int containerWidth = widgetAndCaptionWidth; - containerWidth += containerExpansion.getWidth(); - - int containerHeight = widgetAndCaptionHeight; - containerHeight += containerExpansion.getHeight(); - - // ApplicationConnection.getConsole().log( - // "Setting container size for " + Util.getSimpleName(widget) - // + " to " + containerWidth + "," + containerHeight); - - if (containerWidth < 0) { - VConsole.log("containerWidth should never be negative: " - + containerWidth); - containerWidth = 0; - } - if (containerHeight < 0) { - VConsole.log("containerHeight should never be negative: " - + containerHeight); - containerHeight = 0; - } - - contSize.setWidth(containerWidth); - contSize.setHeight(containerHeight); - - updateContainerDOMSize(); - } - - public void updateContainerDOMSize() { - int width = contSize.getWidth(); - int height = contSize.getHeight() - alignmentTopOffset; - if (width < 0) { - width = 0; - } - if (height < 0) { - height = 0; - } - - setWidth(width + "px"); - setHeight(height + "px"); - - // Also update caption max width - if (caption != null) { - if (caption.shouldBePlacedAfterComponent()) { - caption.setMaxWidth(captionWidth); - } else { - caption.setMaxWidth(width); - } - captionWidth = caption.getRenderedWidth(); - - // Remove initial height - caption.setHeight(""); - } - - } - -} 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..d60486aa70 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/layout/VLayoutSlot.java @@ -0,0 +1,239 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +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(String baseClassName, Widget widget) { + this.widget = widget; + + wrapper.setClassName(baseClassName + "-slot"); + } + + 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()); + Style style = caption.getElement().getStyle(); + style.setPosition(Position.ABSOLUTE); + style.setTop(0, Unit.PX); + } + } + + 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(); + + double availableWidth = allocatedSpace; + + VCaption caption = getCaption(); + Style captionStyle = caption != null ? caption.getElement().getStyle() + : null; + int captionWidth = getCaptionWidth(); + + boolean captionAboveCompnent; + if (caption == null) { + captionAboveCompnent = false; + style.clearPaddingRight(); + } else { + captionAboveCompnent = !caption.shouldBePlacedAfterComponent(); + if (!captionAboveCompnent) { + style.setPaddingRight(captionWidth, Unit.PX); + availableWidth -= captionWidth; + captionStyle.clearLeft(); + captionStyle.setRight(0, Unit.PX); + } else { + style.clearPaddingRight(); + captionStyle.setLeft(0, Unit.PX); + captionStyle.clearRight(); + } + } + + if (isRelativeWidth()) { + style.setPropertyPx("width", (int) availableWidth); + style.clearProperty("minWidth"); + style.clearProperty("maxWidth"); + } else { + style.clearProperty("width"); + if (caption != null && captionAboveCompnent) { + style.setPropertyPx("minWidth", captionWidth); + } else { + style.clearProperty("minWidth"); + } + style.setPropertyPx("maxWidth", (int) availableWidth); + } + + AlignmentInfo alignment = getAlignment(); + if (!alignment.isLeft()) { + double usedWidth = getWidgetWidth(); + if (alignment.isHorizontalCenter()) { + currentLocation += (allocatedSpace - usedWidth) / 2d; + if (captionAboveCompnent) { + captionStyle.setLeft(usedWidth / 2 - (captionWidth / 2d), + Unit.PX); + captionStyle.clearRight(); + } + } else { + currentLocation += (allocatedSpace - usedWidth); + if (captionAboveCompnent) { + captionStyle.clearLeft(); + captionStyle.setRight(0, Unit.PX); + } + } + } else { + if (captionAboveCompnent) { + captionStyle.setLeft(0, Unit.PX); + captionStyle.clearRight(); + } + } + + style.setLeft(currentLocation, Unit.PX); + } + + public void positionVertically(double currentLocation, double allocatedSpace) { + Style style = wrapper.getStyle(); + + double contentHeight = allocatedSpace; + + VCaption caption = getCaption(); + if (caption == null || caption.shouldBePlacedAfterComponent()) { + style.clearPaddingTop(); + } else { + int captionHeight = getCaptionHeight(); + contentHeight -= captionHeight; + style.setPaddingTop(captionHeight, Unit.PX); + } + + if (isRelativeHeight()) { + style.setHeight(contentHeight, Unit.PX); + } else { + style.clearHeight(); + } + + AlignmentInfo alignment = getAlignment(); + if (!alignment.isTop()) { + int usedHeight = getUsedHeight(); + if (alignment.isVerticalCenter()) { + currentLocation += (allocatedSpace - usedHeight) / 2d; + } else { + currentLocation += (allocatedSpace - usedHeight); + } + } + + 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 widgetWidth = getWidgetWidth(); + if (caption == null) { + return widgetWidth; + } else if (caption.shouldBePlacedAfterComponent()) { + return widgetWidth + getCaptionWidth(); + } else { + return Math.max(widgetWidth, getCaptionWidth()); + } + } + + public int getUsedHeight() { + int widgetHeight = getWidgetHeight(); + if (caption == null) { + return widgetHeight; + } else if (caption.shouldBePlacedAfterComponent()) { + return Math.max(widgetHeight, getCaptionHeight()); + } else { + return widgetHeight + getCaptionHeight(); + } + } + + 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..13bfcaf5e2 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/layout/VPaintableLayoutSlot.java @@ -0,0 +1,87 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui.layout; + +import com.vaadin.terminal.gwt.client.LayoutManager; +import com.vaadin.terminal.gwt.client.VCaption; +import com.vaadin.terminal.gwt.client.VPaintableWidget; +import com.vaadin.terminal.gwt.client.ui.ManagedLayout; + +public class VPaintableLayoutSlot extends VLayoutSlot { + + final VPaintableWidget paintable; + private LayoutManager layoutManager; + + public VPaintableLayoutSlot(String baseClassName, VPaintableWidget paintable) { + super(baseClassName, paintable.getWidgetForPaintable()); + this.paintable = paintable; + layoutManager = paintable.getLayoutManager(); + } + + public VPaintableWidget getPaintable() { + return paintable; + } + + @Override + protected int getCaptionHeight() { + VCaption caption = getCaption(); + return caption != null ? layoutManager.getOuterHeight(caption + .getElement()) : 0; + } + + @Override + protected int getCaptionWidth() { + VCaption caption = getCaption(); + return caption != null ? layoutManager.getOuterWidth(caption + .getElement()) : 0; + } + + @Override + public void setCaption(VCaption caption) { + VCaption oldCaption = getCaption(); + if (oldCaption != null) { + layoutManager.unregisterDependency( + (ManagedLayout) paintable.getParent(), + oldCaption.getElement()); + } + super.setCaption(caption); + if (caption != null) { + layoutManager + .registerDependency((ManagedLayout) paintable.getParent(), + caption.getElement()); + } + } + + @Override + public int getWidgetHeight() { + return layoutManager.getOuterHeight(paintable.getWidgetForPaintable() + .getElement()); + } + + @Override + public int getWidgetWidth() { + return layoutManager.getOuterWidth(paintable.getWidgetForPaintable() + .getElement()); + } + + @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(); + } +} diff --git a/src/com/vaadin/ui/LoginForm.java b/src/com/vaadin/ui/LoginForm.java index 7eaeb824c9..69c373cc7c 100644 --- a/src/com/vaadin/ui/LoginForm.java +++ b/src/com/vaadin/ui/LoginForm.java @@ -158,11 +158,11 @@ public class LoginForm extends CustomComponent { + "<div>" + usernameCaption + "</div><div >" - + "<input class='v-textfield' style='display:block;' type='text' name='username'></div>" + + "<input class='v-textfield v-paintable' style='display:block;' type='text' name='username'></div>" + "<div>" + passwordCaption + "</div>" - + "<div><input class='v-textfield' style='display:block;' type='password' name='password'></div>" + + "<div><input class='v-textfield v-paintable' style='display:block;' type='password' name='password'></div>" + "<div><div onclick=\"document.forms[0].submit();\" tabindex=\"0\" class=\"v-button\" role=\"button\" ><span class=\"v-button-wrap\"><span class=\"v-button-caption\">" + loginButtonCaption + "</span></span></div></div></form></div>" + "</body></html>") diff --git a/tests/testbench/com/vaadin/tests/components/button/ButtonUndefinedWidth.html b/tests/testbench/com/vaadin/tests/components/button/ButtonUndefinedWidth.html index 28fe12f5a2..0aaa01f05b 100644 --- a/tests/testbench/com/vaadin/tests/components/button/ButtonUndefinedWidth.html +++ b/tests/testbench/com/vaadin/tests/components/button/ButtonUndefinedWidth.html @@ -63,7 +63,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsbuttonButtonUndefinedWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentsbuttonButtonUndefinedWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[2]</td> <td>636,149</td> </tr> <tr> diff --git a/tests/testbench/com/vaadin/tests/components/datefield/CustomDateFormats.html b/tests/testbench/com/vaadin/tests/components/datefield/CustomDateFormats.html index 61ff29d1c5..1acdded4cb 100644 --- a/tests/testbench/com/vaadin/tests/components/datefield/CustomDateFormats.html +++ b/tests/testbench/com/vaadin/tests/components/datefield/CustomDateFormats.html @@ -161,12 +161,12 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldCustomDateFormats::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[11]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldCustomDateFormats::/VVerticalLayout[0]/VVerticalLayout[0]/VGridLayout[0]/VLabel[11]</td> <td>10 maalis 1999</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldCustomDateFormats::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[15]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldCustomDateFormats::/VVerticalLayout[0]/VVerticalLayout[0]/VGridLayout[0]/VLabel[14]</td> <td>26 syyskuu 1980</td> </tr> <tr> @@ -211,7 +211,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldCustomDateFormats::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[43]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldCustomDateFormats::/VVerticalLayout[0]/VVerticalLayout[0]/VGridLayout[0]/VLabel[35]</td> <td>10. tammikuuta 2011</td> </tr> <tr> diff --git a/tests/testbench/com/vaadin/tests/components/datefield/DateFieldEmptyValid.html b/tests/testbench/com/vaadin/tests/components/datefield/DateFieldEmptyValid.html index 751c7ba9bd..f387695b5f 100644 --- a/tests/testbench/com/vaadin/tests/components/datefield/DateFieldEmptyValid.html +++ b/tests/testbench/com/vaadin/tests/components/datefield/DateFieldEmptyValid.html @@ -98,7 +98,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldEmptyValid::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldEmptyValid::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[2]</td> <td>208,5</td> </tr> <tr> @@ -128,7 +128,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldEmptyValid::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldEmptyValid::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[2]</td> <td>186,10</td> </tr> <tr> diff --git a/tests/testbench/com/vaadin/tests/components/datefield/DateFieldRangeValidation.html b/tests/testbench/com/vaadin/tests/components/datefield/DateFieldRangeValidation.html index 6cc9b08e30..444f8e3bac 100644 --- a/tests/testbench/com/vaadin/tests/components/datefield/DateFieldRangeValidation.html +++ b/tests/testbench/com/vaadin/tests/components/datefield/DateFieldRangeValidation.html @@ -30,7 +30,7 @@ <!--should not be error--> <tr> <td>assertElementNotPresent</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldRangeValidation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[4]/domChild[1]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldRangeValidation::/VVerticalLayout[0]/VVerticalLayout[0]/domChild[4]/domChild[1]</td> <td></td> </tr> <tr> @@ -41,7 +41,7 @@ <!--should be error--> <tr> <td>assertElementPresent</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldRangeValidation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[4]/domChild[1]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldRangeValidation::/VVerticalLayout[0]/VVerticalLayout[0]/domChild[4]/domChild[1]</td> <td></td> </tr> <!--select 3.12.2011--> @@ -58,7 +58,7 @@ <!--should be error--> <tr> <td>assertElementPresent</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldRangeValidation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[4]/domChild[1]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldRangeValidation::/VVerticalLayout[0]/VVerticalLayout[0]/domChild[4]/domChild[1]</td> <td></td> </tr> <!--change to 4.12.2011 by writing--> @@ -75,7 +75,7 @@ <!--should not be error--> <tr> <td>assertElementNotPresent</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldRangeValidation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[4]/domChild[1]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldRangeValidation::/VVerticalLayout[0]/VVerticalLayout[0]/domChild[4]/domChild[1]</td> <td></td> </tr> <!--no longer include start date--> @@ -87,7 +87,7 @@ <!--should be error--> <tr> <td>assertElementPresent</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldRangeValidation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[4]/domChild[1]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldDateFieldRangeValidation::/VVerticalLayout[0]/VVerticalLayout[0]/domChild[4]/domChild[1]</td> <td></td> </tr> diff --git a/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldDisabledReadonly.html b/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldDisabledReadonly.html index fcd2ddf573..009ca0aaf9 100644 --- a/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldDisabledReadonly.html +++ b/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldDisabledReadonly.html @@ -39,7 +39,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[4]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[4]</td> <td>759,5</td> </tr> <tr> @@ -59,7 +59,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[2]/domChild[0]</td> <td>566,9</td> </tr> <tr> @@ -84,7 +84,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[4]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[4]</td> <td>699,43</td> </tr> <tr> @@ -109,7 +109,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[3]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[3]</td> <td>630,30</td> </tr> <tr> diff --git a/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldMonth.html b/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldMonth.html index 440de7c952..9111388f5a 100644 --- a/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldMonth.html +++ b/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldMonth.html @@ -23,7 +23,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldCustomDateFormats::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[2]/VPopupCalendar[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldCustomDateFormats::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[5]/VPopupCalendar[0]/domChild[1]</td> <td>10,14</td> </tr> <tr> @@ -33,12 +33,12 @@ </tr> <tr> <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldCustomDateFormats::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[2]/VPopupCalendar[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldCustomDateFormats::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[5]/VPopupCalendar[0]/domChild[0]</td> <td>1 1 2010</td> </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldCustomDateFormats::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[2]/VPopupCalendar[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldCustomDateFormats::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[5]/VPopupCalendar[0]/domChild[1]</td> <td>14,13</td> </tr> <tr> diff --git a/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldResolutions.html b/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldResolutions.html index 730cc895a4..8ecf9a4731 100644 --- a/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldResolutions.html +++ b/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldResolutions.html @@ -340,7 +340,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[1]</td> <td>202,40</td> </tr> <tr> @@ -390,7 +390,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[1]</td> <td>129,26</td> </tr> <!--Check resolution month functionality--> @@ -481,7 +481,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[1]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[1]/domChild[0]</td> <td>174,3</td> </tr> <tr> @@ -491,7 +491,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[1]</td> <td>129,26</td> </tr> <!--Check resolution day functionality--> @@ -507,7 +507,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[2]</td> <td>478,1</td> </tr> <tr> @@ -557,7 +557,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[1]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[1]/domChild[0]</td> <td>193,12</td> </tr> <tr> @@ -797,7 +797,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[1]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[1]/domChild[0]</td> <td>185,8</td> </tr> <tr> @@ -827,7 +827,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[1]</td> <td>364,32</td> </tr> <!--Also check finnish locale--> @@ -863,7 +863,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[7]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[7]/domChild[0]</td> <td>286,10</td> </tr> <tr> @@ -1019,7 +1019,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[7]</td> + <td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFields::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[7]</td> <td>291,3</td> </tr> <tr> diff --git a/tests/testbench/com/vaadin/tests/components/form/FormCaptionClickFocusing.html b/tests/testbench/com/vaadin/tests/components/form/FormCaptionClickFocusing.html index ab0aa25c44..14dbc6d4c8 100644 --- a/tests/testbench/com/vaadin/tests/components/form/FormCaptionClickFocusing.html +++ b/tests/testbench/com/vaadin/tests/components/form/FormCaptionClickFocusing.html @@ -28,7 +28,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsformFormCaptionClickFocusing::/VVerticalLayout[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentsformFormCaptionClickFocusing::/VVerticalLayout[0]/domChild[1]</td> <td>161,159</td> </tr> <tr> diff --git a/tests/testbench/com/vaadin/tests/components/menubar/MenuBarToolTips.html b/tests/testbench/com/vaadin/tests/components/menubar/MenuBarToolTips.html index 28bcc3a221..f7c57baf1f 100644 --- a/tests/testbench/com/vaadin/tests/components/menubar/MenuBarToolTips.html +++ b/tests/testbench/com/vaadin/tests/components/menubar/MenuBarToolTips.html @@ -63,7 +63,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsmenubarMenuBarToolTips::/VVerticalLayout[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentsmenubarMenuBarToolTips::/VVerticalLayout[0]/domChild[1]</td> <td>830,200</td> </tr> <tr> @@ -88,7 +88,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsmenubarMenuBarToolTips::/VVerticalLayout[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentsmenubarMenuBarToolTips::/VVerticalLayout[0]/domChild[1]</td> <td>625,184</td> </tr> <tr> diff --git a/tests/testbench/com/vaadin/tests/components/orderedlayout/LayoutClickListenerTest.html b/tests/testbench/com/vaadin/tests/components/orderedlayout/LayoutClickListenerTest.html index 6b850fb52a..ea0a039dbe 100644 --- a/tests/testbench/com/vaadin/tests/components/orderedlayout/LayoutClickListenerTest.html +++ b/tests/testbench/com/vaadin/tests/components/orderedlayout/LayoutClickListenerTest.html @@ -53,7 +53,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[3]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[3]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[1]</td> <td></td> </tr> <tr> @@ -78,7 +78,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/domChild[0]</td> <td></td> </tr> <tr> diff --git a/tests/testbench/com/vaadin/tests/components/orderedlayout/OrderedLayoutCases.java b/tests/testbench/com/vaadin/tests/components/orderedlayout/OrderedLayoutCases.java index f9a7d572e3..172e808070 100644 --- a/tests/testbench/com/vaadin/tests/components/orderedlayout/OrderedLayoutCases.java +++ b/tests/testbench/com/vaadin/tests/components/orderedlayout/OrderedLayoutCases.java @@ -114,9 +114,9 @@ public class OrderedLayoutCases extends AbstractTestRoot { .injectCSS( getRoot(), ".sampleChild, .theLayout {border: 1px solid black;}" - + ".theLayout > div > div:first-child {background: aqua;}" - + ".theLayout > div > div:first-child + div {background: yellow;}" - + ".theLayout > div > div:first-child + div + div {background: lightgrey;}"); + + ".theLayout > div:first-child {background: aqua;}" + + ".theLayout > div:first-child + div {background: yellow;}" + + ".theLayout > div:first-child + div + div {background: lightgrey;}"); currentLayout = new HorizontalLayout(); for (int i = 0; i < 3; i++) { diff --git a/tests/testbench/com/vaadin/tests/components/panel/BasicPanelTest.java b/tests/testbench/com/vaadin/tests/components/panel/BasicPanelTest.java new file mode 100644 index 0000000000..d23e317572 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/panel/BasicPanelTest.java @@ -0,0 +1,88 @@ +package com.vaadin.tests.components.panel; + +import java.util.Map; + +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.Panel; +import com.vaadin.ui.TextArea; +import com.vaadin.ui.themes.Reindeer; + +public class BasicPanelTest extends TestBase { + private final Label scrollPosition = new Label(); + private final Panel panel = new Panel("Panel caption") { + @Override + public void changeVariables(Object source, Map<String, Object> variables) { + super.changeVariables(source, variables); + updateLabelText(); + } + }; + + @Override + protected void setup() { + getLayout().setWidth("600px"); + getLayout().setHeight("100%"); + + HorizontalLayout actions = new HorizontalLayout(); + actions.setSpacing(true); + + actions.addComponent(scrollPosition); + actions.addComponent(new Button("Sync")); + + final CheckBox heightSelection = new CheckBox("Undefined height"); + heightSelection.setImmediate(true); + heightSelection.addListener(new ValueChangeListener() { + public void valueChange(ValueChangeEvent event) { + if (heightSelection.getValue() == Boolean.TRUE) { + panel.setHeight(null); + } else { + panel.setHeight("100%"); + } + } + }); + actions.addComponent(heightSelection); + + panel.setWidth("200px"); + panel.setHeight("100%"); + panel.setStyleName(Reindeer.PANEL_LIGHT); + + panel.getContent().setCaption("Content caption"); + + TextArea textArea = new TextArea("TextArea caption"); + textArea.setWidth("300px"); + textArea.setHeight("500px"); + panel.addComponent(textArea); + + getLayout().addComponent(actions); + getLayout().addComponent(panel); + getLayout().setExpandRatio(panel, 1); + + panel.setScrollable(true); + panel.setScrollTop(50); + panel.setScrollLeft(50); + panel.setImmediate(true); + + updateLabelText(); + } + + private void updateLabelText() { + scrollPosition.setValue("Scrolled to " + panel.getScrollTop()); + } + + @Override + protected String getDescription() { + return "Simple test for basic panel functionality"; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/root/RootInitException.java b/tests/testbench/com/vaadin/tests/components/root/RootInitException.java new file mode 100644 index 0000000000..b4cfa2a28d --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/root/RootInitException.java @@ -0,0 +1,23 @@ +package com.vaadin.tests.components.root; + +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.tests.components.AbstractTestRoot; + +public class RootInitException extends AbstractTestRoot { + + @Override + protected void setup(WrappedRequest request) { + throw new RuntimeException("Catch me if you can"); + } + + @Override + protected String getTestDescription() { + return "Throwing an exception in application code during a browser details request should show a sensible message in the client"; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(8243); + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/select/SelectDisplaysOldValue.html b/tests/testbench/com/vaadin/tests/components/select/SelectDisplaysOldValue.html index 4594130bda..122e90e140 100644 --- a/tests/testbench/com/vaadin/tests/components/select/SelectDisplaysOldValue.html +++ b/tests/testbench/com/vaadin/tests/components/select/SelectDisplaysOldValue.html @@ -131,7 +131,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsselectSelectDisplaysOldValue::/VVerticalLayout[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentsselectSelectDisplaysOldValue::/VVerticalLayout[0]/domChild[1]</td> <td>58,163</td> </tr> <tr> diff --git a/tests/testbench/com/vaadin/tests/components/table/ItemClickEvents.html b/tests/testbench/com/vaadin/tests/components/table/ItemClickEvents.html index 2c40672c0d..1d7b2b6bf9 100644 --- a/tests/testbench/com/vaadin/tests/components/table/ItemClickEvents.html +++ b/tests/testbench/com/vaadin/tests/components/table/ItemClickEvents.html @@ -130,12 +130,12 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableItemClickEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[5]</td> + <td>vaadin=runcomvaadintestscomponentstableItemClickEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[5]</td> <td>195,142</td> </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableItemClickEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[5]</td> + <td>vaadin=runcomvaadintestscomponentstableItemClickEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[5]</td> <td>582,1</td> </tr> <tr> diff --git a/tests/testbench/com/vaadin/tests/fieldgroup/IntegerRangeValidator.html b/tests/testbench/com/vaadin/tests/fieldgroup/IntegerRangeValidator.html index 5860c99061..078aede82f 100644 --- a/tests/testbench/com/vaadin/tests/fieldgroup/IntegerRangeValidator.html +++ b/tests/testbench/com/vaadin/tests/fieldgroup/IntegerRangeValidator.html @@ -44,7 +44,7 @@ </tr> <tr> <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[5]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/VVerticalLayout[0]/domChild[5]/domChild[0]/domChild[1]</td> <td>v-errorindicator</td> </tr> <!--10 -> age--> @@ -54,8 +54,8 @@ <td>10</td> </tr> <tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[5]/domChild[0]/domChild[1]</td> + <td>assertElementNotPresent</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/VVerticalLayout[0]/domChild[5]/domChild[0]/domChild[1]</td> <td>v-errorindicator</td> </tr> <!---1--> @@ -71,7 +71,7 @@ </tr> <tr> <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[5]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/VVerticalLayout[0]/domChild[5]/domChild[0]/domChild[1]</td> <td>v-errorindicator</td> </tr> <tr> |