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
+ for (int i = 0; i < length; i++) {
+ try {
+ final UIDL change = changes.get(i).cast();
+ final UIDL uidl = change.getChildUIDL(0);
+ VPaintable paintable = paintableMap.getPaintable(uidl
+ .getId());
+ if (null == paintable
+ && !uidl.getTag().equals(
+ configuration.getEncodedWindowTag())) {
+ // create, initialize and register the paintable
+ getPaintable(uidl);
+ }
+ } catch (final Throwable e) {
+ VConsole.error(e);
+ }
+ }
+
+ // set states for all paintables mentioned in "state"
+ ValueMap states = json.getValueMap("state");
+ JsArrayString keyArray = states.getKeyArray();
+ for (int i = 0; i < keyArray.length(); i++) {
+ try {
+ String paintableId = keyArray.get(i);
+ VPaintable paintable = paintableMap
+ .getPaintable(paintableId);
+ if (null != paintable) {
+
+ JSONArray stateDataAndType = new JSONArray(
+ states.getJavaScriptObject(paintableId));
+
+ Object state = JsonDecoder.convertValue(
+ stateDataAndType, paintableMap);
+
+ paintable.setState((SharedState) state);
+ }
+ } catch (final Throwable e) {
+ VConsole.error(e);
+ }
+ }
+
+ // update paintables
for (int i = 0; i < length; i++) {
try {
final UIDL change = changes.get(i).cast();
package com.vaadin.terminal.gwt.client;
import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.Map;
- import java.util.Set;
+import java.util.Arrays;
+ import java.util.List;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
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
+ }
+
+ /**
+ * Creates a caption that is not linked to a {@link VPaintableWidget}.
+ *
+ * When using this constructor, {@link #getOwner()} returns null.
+ *
+ * @param client
+ * ApplicationConnection
+ * @deprecated all captions should be associated with a paintable widget and
+ * be updated from shared state, not UIDL
+ */
+ @Deprecated
+ public VCaption(ApplicationConnection client) {
+ super();
+ this.client = client;
+ owner = null;
+
+ setStyleName(CLASSNAME);
+ sinkEvents(VTooltip.TOOLTIP_EVENTS);
+
+ }
+
/**
+ * Creates a caption for a {@link VPaintableWidget}.
*
* @param component
- * optional owner of caption. If not set, getOwner will return
- * null
+ * owner of caption, not null
* @param client
+ * ApplicationConnection
*/
public VCaption(VPaintableWidget component, ApplicationConnection client) {
super();
}
- if (clearElement == null) {
- clearElement = DOM.createDiv();
- clearElement.setClassName(CLASSNAME_CLEAR);
- getElement().appendChild(clearElement);
- }
-
+ @Deprecated
+ public boolean updateCaptionWithoutOwner(UIDL uidl, String caption,
+ boolean disabled, boolean hasDescription) {
+ // TODO temporary method, needed because some tabsheet and accordion
+ // internal captions do not have an owner or shared state. Simplified to
+ // only support those cases
+ setVisible(!uidl.getBooleanAttribute("invisible"));
+
+ boolean wasPlacedAfterComponent = placedAfterComponent;
+
+ // Caption is placed after component unless there is some part which
+ // moves it above.
+ placedAfterComponent = true;
+
+ String style = VCaption.CLASSNAME;
+ if (disabled) {
+ style += " " + ApplicationConnection.DISABLED_CLASSNAME;
+ }
+ setStyleName(style);
+ if (hasDescription) {
+ if (captionText != null) {
+ addStyleDependentName("hasdescription");
+ } else {
+ removeStyleDependentName("hasdescription");
+ }
+ }
+ boolean hasIcon = uidl
+ .hasAttribute(VAbstractPaintableWidget.ATTRIBUTE_ICON);
+ boolean showError = uidl
+ .hasAttribute(VAbstractPaintableWidget.ATTRIBUTE_ERROR)
+ && !uidl.getBooleanAttribute(VAbstractPaintableWidget.ATTRIBUTE_HIDEERRORS);
+
+ if (hasIcon) {
+ if (icon == null) {
+ icon = new Icon(client);
+ icon.setWidth("0");
+ icon.setHeight("0");
+
+ DOM.insertChild(getElement(), icon.getElement(),
+ getInsertPosition(InsertPosition.ICON));
+ }
+ // Icon forces the caption to be above the component
+ placedAfterComponent = false;
+
+ icon.setUri(uidl
+ .getStringAttribute(VAbstractPaintableWidget.ATTRIBUTE_ICON));
+
+ } else if (icon != null) {
+ // Remove existing
+ DOM.removeChild(getElement(), icon.getElement());
+ icon = null;
+ }
+
+ if (caption != null) {
+ // A caption text should be shown if the attribute is set
+ // If the caption is null the ATTRIBUTE_CAPTION should not be set to
+ // avoid ending up here.
+
+ if (captionText == null) {
+ captionText = DOM.createDiv();
+ captionText.setClassName("v-captiontext");
+
+ DOM.insertChild(getElement(), captionText,
+ getInsertPosition(InsertPosition.CAPTION));
+ }
+
+ // Update caption text
+ // A text forces the caption to be above the component.
+ placedAfterComponent = false;
+ if (caption.trim().equals("")) {
+ // This is required to ensure that the caption uses space in all
+ // browsers when it is set to the empty string. If there is an
+ // icon, error indicator or required indicator they will ensure
+ // that space is reserved.
+ if (!hasIcon && !showError) {
+ captionText.setInnerHTML(" ");
+ }
+ } else {
+ DOM.setInnerText(captionText, caption);
+ }
+
+ } else if (captionText != null) {
+ // Remove existing
+ DOM.removeChild(getElement(), captionText);
+ captionText = null;
+ }
+
+ if (showError) {
+ if (errorIndicatorElement == null) {
+ errorIndicatorElement = DOM.createDiv();
+ DOM.setInnerHTML(errorIndicatorElement, " ");
+ DOM.setElementProperty(errorIndicatorElement, "className",
+ "v-errorindicator");
+
+ DOM.insertChild(getElement(), errorIndicatorElement,
+ getInsertPosition(InsertPosition.ERROR));
+ }
+ } else if (errorIndicatorElement != null) {
+ // Remove existing
+ getElement().removeChild(errorIndicatorElement);
+ errorIndicatorElement = null;
+ }
+
+ return (wasPlacedAfterComponent != placedAfterComponent);
+ }
+
@Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
*
* @return
*/
- // FIXME: Rename to getParent()
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();
}
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;
private boolean enabled = true;
private boolean visible = true;
+ // shared state from the server to the client
+ private ComponentState state;
+
+ private String declaredWidth = "";
+ private String declaredHeight = "";
+
/**
* Default constructor
*/
* taken into account
*/
- getConnection().updateComponentSize(this);
- updateComponentSize(uidl);
++ updateComponentSize();
+ }
+
- private void updateComponentSize(UIDL uidl) {
- String w = uidl.hasAttribute("width") ? uidl
- .getStringAttribute("width") : "";
-
- String h = uidl.hasAttribute("height") ? uidl
- .getStringAttribute("height") : "";
++ 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;
}
/**
return styleBuf.toString();
}
+ /**
+ * Sets the shared state for the paintable widget.
+ *
+ * @param new shared state (must be compatible with the return value of
+ * {@link #getState()} - {@link ComponentState} if
+ * {@link #getState()} is not overridden
+ */
+ public final void setState(SharedState state) {
+ this.state = (ComponentState) state;
+ }
+
+ /**
+ * Initialize the given RPC proxy object so it is connected to this
+ * paintable.
+ *
+ * @param clientToServerRpc
+ * The RPC instance to initialize. Must have been created using
+ * GWT.create().
+ */
+ protected <T extends ClientToServerRpc> T initRPC(T clientToServerRpc) {
+ ((InitializableClientToServerRpc) clientToServerRpc).initRpc(getId(),
+ getConnection());
+ return clientToServerRpc;
+ }
++
+ public LayoutManager getLayoutManager() {
+ return LayoutManager.get(connection);
+ }
}
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
getWidgetForPaintable().client = client;
getWidgetForPaintable().id = uidl.getId();
- getWidgetForPaintable().rendering = true;
- getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
+ getWidgetForPaintable().immediate = getState().isImmediate();
super.updateFromUIDL(uidl, client);
if (!isRealUpdate(uidl)) {
- getWidgetForPaintable().rendering = false;
return;
}
- getWidgetForPaintable().setEnabled(
- !uidl.getBooleanAttribute("disabled"));
+ getWidgetForPaintable().setEnabled(!getState().isDisabled());
clickEventHandler.handleEventHandlerRegistration(client);
- if (uidl.hasAttribute("style")) {
- getWidgetForPaintable().componentStyleNames = uidl
- .getStringAttribute("style").split(" ");
+ if (getState().hasStyles()) {
+ getWidgetForPaintable().componentStyleNames = getState().getStyle()
+ .split(" ");
} else {
getWidgetForPaintable().componentStyleNames = new String[0];
}
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.ComponentState;
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;
}
}
- 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 {
public static final String CLASSNAME = "v-caption";
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.Container;
+import com.vaadin.terminal.gwt.client.ComponentState;
+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";
}
}
- 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 component, UIDL uidl) {
+ 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)) {
- Cell cell = layout.widgetToCell.get(component
++ 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(component, getConnection());
++ caption = new VCaption(paintable, getConnection());
+
- Widget widget = component.getWidgetForPaintable();
++ Widget widget = paintable.getWidgetForPaintable();
+
+ layout.setCaption(widget, caption);
+ }
+ caption.updateCaption(uidl);
+ } else {
- layout.setCaption(component.getWidgetForPaintable(), null);
++ layout.setCaption(paintable.getWidgetForPaintable(), null);
}
}
--- /dev/null
- if (VCaption.isNeeded(uidl)) {
+ /*
+ @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();
+ }
+ }
+
+ }
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.ComponentState;
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;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
- import com.vaadin.terminal.gwt.client.RenderInformation;
- import com.vaadin.terminal.gwt.client.RenderSpace;
+import com.vaadin.terminal.gwt.client.ComponentState;
import com.vaadin.terminal.gwt.client.TooltipInfo;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;