From 2fd07a0bd26754d72e77810bc280c6abac740f29 Mon Sep 17 00:00:00 2001 From: John Ahlroos Date: Wed, 5 Sep 2012 17:58:12 +0300 Subject: [PATCH] Refactored and cleaned up the newly add ordered layouts --- .../com/vaadin/client/ComponentLocator.java | 25 +- .../AbstractBoxLayoutConnector.java | 607 ---------------- .../AbstractOrderedLayoutConnector.java | 658 ++++++++++++------ .../HorizontalBoxLayoutConnector.java | 19 - .../HorizontalLayoutConnector.java | 16 +- .../ui/orderedlayout/VHorizontalLayout.java | 13 +- .../VMeasuringOrderedLayout.java | 253 ------- .../{VBoxLayout.java => VOrderedLayout.java} | 395 +++++++++-- .../ui/orderedlayout/VVerticalLayout.java | 13 +- .../VerticalBoxLayoutConnector.java | 19 - .../VerticalLayoutConnector.java | 16 +- 11 files changed, 831 insertions(+), 1203 deletions(-) delete mode 100644 client/src/com/vaadin/client/ui/orderedlayout/AbstractBoxLayoutConnector.java delete mode 100644 client/src/com/vaadin/client/ui/orderedlayout/HorizontalBoxLayoutConnector.java delete mode 100644 client/src/com/vaadin/client/ui/orderedlayout/VMeasuringOrderedLayout.java rename client/src/com/vaadin/client/ui/orderedlayout/{VBoxLayout.java => VOrderedLayout.java} (71%) delete mode 100644 client/src/com/vaadin/client/ui/orderedlayout/VerticalBoxLayoutConnector.java diff --git a/client/src/com/vaadin/client/ComponentLocator.java b/client/src/com/vaadin/client/ComponentLocator.java index 42b54ca49c..ce3ac43812 100644 --- a/client/src/com/vaadin/client/ComponentLocator.java +++ b/client/src/com/vaadin/client/ComponentLocator.java @@ -27,8 +27,7 @@ import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ui.SubPartAware; import com.vaadin.client.ui.gridlayout.VGridLayout; -import com.vaadin.client.ui.orderedlayout.VBoxLayout; -import com.vaadin.client.ui.orderedlayout.VMeasuringOrderedLayout; +import com.vaadin.client.ui.orderedlayout.VOrderedLayout; import com.vaadin.client.ui.tabsheet.VTabsheetPanel; import com.vaadin.client.ui.ui.VUI; import com.vaadin.client.ui.window.VWindow; @@ -270,7 +269,7 @@ public class ComponentLocator { String childIndexString = part.substring("domChild[".length(), part.length() - 1); - if (Util.findWidget(baseElement, null) instanceof VBoxLayout) { + if (Util.findWidget(baseElement, null) instanceof VOrderedLayout) { if (element.hasChildNodes()) { Element e = element.getFirstChildElement().cast(); String cn = e.getClassName(); @@ -508,14 +507,9 @@ public class ComponentLocator { continue; } - if ("VVerticalLayout".equals(widgetClassName) - || "VHorizontalLayout".equals(widgetClassName)) { - widgetClassName = "VBoxLayout"; - } - - if (w instanceof VBoxLayout + if (w instanceof VOrderedLayout && "ChildComponentContainer".equals(widgetClassName)) { - widgetClassName = "VBoxLayout$Slot"; + widgetClassName = "VOrderedLayout$Slot"; } if (w instanceof VTabsheetPanel && widgetPosition != 0) { @@ -532,7 +526,7 @@ public class ComponentLocator { * (which would originally have found the widget inside the * ChildComponentContainer) */ - if ((w instanceof VMeasuringOrderedLayout || w instanceof VGridLayout) + if ((w instanceof VGridLayout) && "ChildComponentContainer".equals(widgetClassName) && i + 1 < parts.length) { @@ -542,11 +536,6 @@ public class ComponentLocator { String[] nextSplit = nextPart.split("\\[", 2); String nextWidgetClassName = nextSplit[0]; - if ("VVerticalLayout".equals(nextWidgetClassName) - || "VHorizontalLayout".equals(nextWidgetClassName)) { - nextWidgetClassName = "VBoxLayout"; - } - // Find the n:th child and count the number of children with // the same type before it int nextIndex = 0; @@ -616,8 +605,8 @@ public class ComponentLocator { } widgetPosition--; - } else if (w instanceof VBoxLayout - && "VBoxLayout$Slot".equals(simpleName2)) { + } else if (w instanceof VOrderedLayout + && "VOrderedLayout$Slot".equals(simpleName2)) { child = ((SimplePanel) child).getWidget(); simpleName2 = Util.getSimpleName(child); if (widgetClassName.equals(simpleName2)) { diff --git a/client/src/com/vaadin/client/ui/orderedlayout/AbstractBoxLayoutConnector.java b/client/src/com/vaadin/client/ui/orderedlayout/AbstractBoxLayoutConnector.java deleted file mode 100644 index 6402d0696f..0000000000 --- a/client/src/com/vaadin/client/ui/orderedlayout/AbstractBoxLayoutConnector.java +++ /dev/null @@ -1,607 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.client.ui.orderedlayout; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; - -import com.google.gwt.dom.client.Style.Unit; -import com.google.gwt.user.client.Element; -import com.vaadin.client.ComponentConnector; -import com.vaadin.client.ConnectorHierarchyChangeEvent; -import com.vaadin.client.Util; -import com.vaadin.client.communication.RpcProxy; -import com.vaadin.client.communication.StateChangeEvent; -import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler; -import com.vaadin.client.ui.AbstractFieldConnector; -import com.vaadin.client.ui.AbstractLayoutConnector; -import com.vaadin.client.ui.LayoutClickEventHandler; -import com.vaadin.client.ui.layout.ElementResizeEvent; -import com.vaadin.client.ui.layout.ElementResizeListener; -import com.vaadin.client.ui.orderedlayout.VBoxLayout.CaptionPosition; -import com.vaadin.client.ui.orderedlayout.VBoxLayout.Slot; -import com.vaadin.shared.AbstractFieldState; -import com.vaadin.shared.ComponentConstants; -import com.vaadin.shared.communication.URLReference; -import com.vaadin.shared.ui.AlignmentInfo; -import com.vaadin.shared.ui.LayoutClickRpc; -import com.vaadin.shared.ui.MarginInfo; -import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutServerRpc; -import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutState; - -public abstract class AbstractBoxLayoutConnector extends - AbstractLayoutConnector /* implements PostLayoutListener */{ - - AbstractOrderedLayoutServerRpc rpc; - - private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler( - this) { - - @Override - protected ComponentConnector getChildComponent(Element element) { - return Util.getConnectorForElement(getConnection(), getWidget(), - element); - } - - @Override - protected LayoutClickRpc getLayoutClickRPC() { - return rpc; - }; - - }; - - @Override - public void init() { - super.init(); - rpc = RpcProxy.create(AbstractOrderedLayoutServerRpc.class, this); - getWidget().setLayoutManager(getLayoutManager()); - } - - @Override - public AbstractOrderedLayoutState getState() { - return (AbstractOrderedLayoutState) super.getState(); - } - - @Override - public VBoxLayout getWidget() { - return (VBoxLayout) super.getWidget(); - } - - /** - * For bookkeeping. Used to determine if extra calculations are needed for - * horizontal layout. - */ - private HashSet hasVerticalAlignment = new HashSet(); - - /** - * For bookkeeping. Used to determine if extra calculations are needed for - * horizontal layout. - */ - private HashSet hasRelativeHeight = new HashSet(); - - /** - * For bookkeeping. Used to determine if extra calculations are needed for - * horizontal layout. - */ - private HashSet hasExpandRatio = new HashSet(); - - /** - * For bookkeeping. Used in extra calculations for horizontal layout. - */ - private HashSet needsMeasure = new HashSet(); - - /** - * For bookkeeping. Used in extra calculations for horizontal layout. - */ - // private HashMap childElementHeight = new - // HashMap(); - - /** - * For bookkeeping. Used in extra calculations for horizontal layout. - */ - private HashMap childCaptionElementHeight = new HashMap(); - - @Override - public void updateCaption(ComponentConnector child) { - Slot slot = getWidget().getSlot(child); - - - String caption = child.getState().caption; - URLReference iconUrl = child.getState().resources - .get(ComponentConstants.ICON_RESOURCE); - String iconUrlString = iconUrl != null ? iconUrl.toString() : null; - List styles = child.getState().styles; - String error = child.getState().errorMessage; - boolean showError = error != null; - if (child.getState() instanceof AbstractFieldState) { - AbstractFieldState abstractFieldState = (AbstractFieldState) child - .getState(); - showError = showError && !abstractFieldState.hideErrors; - } - boolean required = false; - if (child instanceof AbstractFieldConnector) { - required = ((AbstractFieldConnector) child).isRequired(); - } - boolean enabled = child.getState().enabled; - - slot.setCaption(caption, iconUrlString, styles, error, showError, - required, - enabled); - - slot.setRelativeWidth(child.isRelativeWidth()); - slot.setRelativeHeight(child.isRelativeHeight()); - - if (slot.hasCaption()) { - CaptionPosition pos = slot.getCaptionPosition(); - getLayoutManager().addElementResizeListener( - slot.getCaptionElement(), slotCaptionResizeListener); - if (child.isRelativeHeight() - && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) { - getWidget().updateCaptionOffset(slot.getCaptionElement()); - } else if (child.isRelativeWidth() - && (pos == CaptionPosition.LEFT || pos == CaptionPosition.RIGHT)) { - getWidget().updateCaptionOffset(slot.getCaptionElement()); - } - } else { - childCaptionElementHeight.remove(child.getWidget().getElement()); - } - - updateLayoutHeight(); - - if (needsExpand()) { - updateExpand(); - } - } - - @Override - public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent event) { - super.onConnectorHierarchyChange(event); - - List previousChildren = event.getOldChildren(); - int currentIndex = 0; - VBoxLayout layout = getWidget(); - - for (ComponentConnector child : getChildComponents()) { - Slot slot = layout.getSlot(child); - if (slot.getParent() != layout) { - child.addStateChangeHandler(childStateChangeHandler); - } - layout.addOrMoveSlot(slot, currentIndex++); - } - - for (ComponentConnector child : previousChildren) { - if (child.getParent() != this) { - Slot slot = layout.getSlot(child); - hasVerticalAlignment.remove(child); - hasRelativeHeight.remove(child); - hasExpandRatio.remove(child); - needsMeasure.remove(child.getWidget().getElement()); - // childElementHeight.remove(child.getWidget().getElement()); - childCaptionElementHeight - .remove(child.getWidget().getElement()); - getLayoutManager().removeElementResizeListener( - child.getWidget().getElement(), - childComponentResizeListener); - if (slot.hasCaption()) { - getLayoutManager() - .removeElementResizeListener( - slot.getCaptionElement(), - slotCaptionResizeListener); - } - if (slot.getSpacingElement() != null) { - getLayoutManager().removeElementResizeListener( - slot.getSpacingElement(), spacingResizeListener); - } - child.removeStateChangeHandler(childStateChangeHandler); - layout.removeSlot(child.getWidget()); - } - } - - // If some component is added/removed, we need to recalculate the expand - if (needsExpand()) { - updateExpand(); - } else { - getWidget().clearExpand(); - } - - } - - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - - clickEventHandler.handleEventHandlerRegistration(); - getWidget().setMargin(new MarginInfo(getState().marginsBitmask)); - getWidget().setSpacing(getState().spacing); - - hasExpandRatio.clear(); - hasVerticalAlignment.clear(); - hasRelativeHeight.clear(); - needsMeasure.clear(); - - boolean equalExpandRatio = getWidget().vertical ? !isUndefinedHeight() - : !isUndefinedWidth(); - for (ComponentConnector child : getChildComponents()) { - double expandRatio = getState().childData.get(child).expandRatio; - if (expandRatio > 0) { - equalExpandRatio = false; - break; - } - } - - for (ComponentConnector child : getChildComponents()) { - Slot slot = getWidget().getSlot(child); - - AlignmentInfo alignment = new AlignmentInfo( - getState().childData.get(child).alignmentBitmask); - slot.setAlignment(alignment); - - double expandRatio = getState().childData.get(child).expandRatio; - - if (equalExpandRatio) { - expandRatio = 1; - } else if (expandRatio == 0) { - expandRatio = -1; - } - slot.setExpandRatio(expandRatio); - - // Bookkeeping to identify special cases that need extra - // calculations - if (alignment.isVerticalCenter() || alignment.isBottom()) { - hasVerticalAlignment.add(child); - } - - if (expandRatio > 0) { - hasExpandRatio.add(child); - } - - // if (child.getState().isRelativeHeight()) { - // hasRelativeHeight.add(child); - // } else { - // needsMeasure.add(child.getWidget().getElement()); - // } - } - - updateAllSlotListeners(); - - updateLayoutHeight(); - } - - StateChangeHandler childStateChangeHandler = new StateChangeHandler() { - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - - ComponentConnector child = (ComponentConnector) stateChangeEvent - .getConnector(); - - // We need to update the slot size if the component size is changed - // to relative - Slot slot = getWidget().getSlot(child); - slot.setRelativeWidth(child.isRelativeWidth()); - slot.setRelativeHeight(child.isRelativeHeight()); - - // For relative sized widgets, we need to set the caption offset - // if (slot.hasCaption()) { - // CaptionPosition pos = slot.getCaptionPosition(); - // if (child.isRelativeHeight() - // && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) - // { - // getWidget().updateCaptionOffset(slot.getCaptionElement()); - // } else if (child.isRelativeWidth() - // && (pos == CaptionPosition.LEFT || pos == CaptionPosition.RIGHT)) - // { - // getWidget().updateCaptionOffset(slot.getCaptionElement()); - // } - // } - - updateSlotListeners(child); - // updateAllSlotListeners(); - - updateLayoutHeight(); - } - }; - - private boolean needsFixedHeight() { - if (!getWidget().vertical - && isUndefinedHeight() - && (hasRelativeHeight.size() > 0 || (hasVerticalAlignment - .size() > 0 && hasVerticalAlignment.size() < getChildren() - .size()))) { - return true; - } - return false; - } - - private boolean needsExpand() { - boolean canApplyExpand = (getWidget().vertical && !isUndefinedHeight()) - || (!getWidget().vertical && !isUndefinedWidth()); - return hasExpandRatio.size() > 0 && canApplyExpand; - } - - private void updateAllSlotListeners() { - for (ComponentConnector child : getChildComponents()) { - updateSlotListeners(child); - } - // if (needsFixedHeight()) { - // getWidget().clearHeight(); - // setLayoutHeightListener(true); - // getLayoutManager().setNeedsMeasure(AbstractBoxLayoutConnector.this); - // } else { - // setLayoutHeightListener(false); - // } - } - - /** - * Add/remove necessary ElementResizeListeners for one slot. This should be - * called after each update to the slot's or it's widget. - */ - private void updateSlotListeners(ComponentConnector child) { - Slot slot = getWidget().getSlot(child); - - // Clear all possible listeners first - dontListen(slot.getWidget().getElement(), childComponentResizeListener); - if (slot.hasCaption()) { - dontListen(slot.getCaptionElement(), slotCaptionResizeListener); - } - if (slot.hasSpacing()) { - dontListen(slot.getSpacingElement(), spacingResizeListener); - } - - // Add all necessary listeners - if (needsFixedHeight()) { - listen(slot.getWidget().getElement(), childComponentResizeListener); - if (slot.hasCaption()) { - listen(slot.getCaptionElement(), slotCaptionResizeListener); - } - } else if ((child.isRelativeHeight() || child.isRelativeWidth()) - && slot.hasCaption()) { - // If the slot has caption, we need to listen for it's size changes - // in order to update the padding/margin offset for relative sized - // components - listen(slot.getCaptionElement(), slotCaptionResizeListener); - } - - if (needsExpand()) { - listen(slot.getWidget().getElement(), childComponentResizeListener); - if (slot.hasSpacing()) { - listen(slot.getSpacingElement(), spacingResizeListener); - } - } - - if (child.isRelativeHeight()) { - hasRelativeHeight.add(child); - needsMeasure.remove(child.getWidget().getElement()); - } else { - hasRelativeHeight.remove(child); - needsMeasure.add(child.getWidget().getElement()); - } - - } - - // public void postLayout() { - // if (needsFixedHeight()) { - // // Re-measure all elements that are available - // for (Element el : needsMeasure) { - // childElementHeight.put(el, getLayoutManager() - // .getOuterHeight(el)); - // - // Element captionElement = el.getParentElement() - // .getFirstChildElement().cast(); - // if (captionElement.getClassName().contains("v-caption")) { - // childCaptionElementHeight.put(el, getLayoutManager() - // .getOuterHeight(captionElement)); - // } - // } - // // System.out.println(" ### Child sizes: " - // // + childElementHeight.values().toString()); - // // System.out.println(" ### Caption sizes: " - // // + childCaptionElementHeight.values().toString()); - // - // int height = getMaxHeight() - // + getLayoutManager().getBorderHeight( - // getWidget().getElement()) - // + getLayoutManager().getPaddingHeight( - // getWidget().getElement()); - // getWidget().getElement().getStyle().setHeight(height, Unit.PX); - // } - // } - - // private ElementResizeListener layoutResizeListener = new - // ElementResizeListener() { - // public void onElementResize(ElementResizeEvent e) { - // updateLayoutHeight(); - // if (needsExpand() && (isUndefinedHeight() || isUndefinedWidth())) { - // updateExpand(); - // } - // } - // }; - - private ElementResizeListener slotCaptionResizeListener = new ElementResizeListener() { - @Override - public void onElementResize(ElementResizeEvent e) { - - // Get all needed element references - Element captionElement = (Element) e.getElement().cast(); - - // Caption position determines if the widget element is the first or - // last child inside the caption wrap - CaptionPosition pos = getWidget().getCaptionPositionFromElement( - (Element) captionElement.getParentElement().cast()); - - // The default is the last child - Element widgetElement = captionElement.getParentElement() - .getLastChild().cast(); - - // ...but if caption position is bottom or right, the widget is the - // first child - if (pos == CaptionPosition.BOTTOM || pos == CaptionPosition.RIGHT) { - widgetElement = captionElement.getParentElement() - .getFirstChildElement().cast(); - } - - if (captionElement == widgetElement) { - // Caption element already detached - dontListen(captionElement, slotCaptionResizeListener); - childCaptionElementHeight.remove(widgetElement); - return; - } - - String widgetWidth = widgetElement.getStyle().getWidth(); - String widgetHeight = widgetElement.getStyle().getHeight(); - - if (widgetHeight.endsWith("%") - && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) { - getWidget().updateCaptionOffset(captionElement); - } else if (widgetWidth.endsWith("%") - && (pos == CaptionPosition.LEFT || pos == CaptionPosition.RIGHT)) { - getWidget().updateCaptionOffset(captionElement); - } - - int h = getLayoutManager().getOuterHeight(captionElement) - - getLayoutManager().getMarginHeight(captionElement); - childCaptionElementHeight.put(widgetElement, h); - - // if (needsFixedHeight()) { - // getWidget().clearHeight(); - // getLayoutManager().setNeedsMeasure( - // AbstractBoxLayoutConnector.this); - // } - - updateLayoutHeight(); - - if (needsExpand()) { - updateExpand(); - } - } - }; - - private ElementResizeListener childComponentResizeListener = new ElementResizeListener() { - @Override - public void onElementResize(ElementResizeEvent e) { - // int h = getLayoutManager().getOuterHeight(e.getElement()); - // childElementHeight.put((Element) e.getElement().cast(), h); - updateLayoutHeight(); - - if (needsExpand()) { - updateExpand(); - } - } - }; - - private ElementResizeListener spacingResizeListener = new ElementResizeListener() { - @Override - public void onElementResize(ElementResizeEvent e) { - if (needsExpand()) { - updateExpand(); - } - } - }; - - private void updateLayoutHeight() { - if (needsFixedHeight()) { - int h = getMaxHeight(); - h += getLayoutManager().getBorderHeight(getWidget().getElement()) - + getLayoutManager().getPaddingHeight( - getWidget().getElement()); - getWidget().getElement().getStyle().setHeight(h, Unit.PX); - getLayoutManager().setNeedsMeasure(this); - } - } - - private void updateExpand() { - // System.out.println("All sizes: " - // + childElementHeight.values().toString() + " - Caption sizes: " - // + childCaptionElementHeight.values().toString()); - getWidget().updateExpand(); - } - - private int getMaxHeight() { - int highestNonRelative = -1; - int highestRelative = -1; - - for (ComponentConnector child : getChildComponents()) { - // TODO would be more efficient to measure the slot element if both - // caption and child widget elements need to be measured. Keeping - // track of what to measure is the most difficult part of this - // layout. - Element el = child.getWidget().getElement(); - CaptionPosition pos = getWidget().getCaptionPositionFromElement( - (Element) el.getParentElement().cast()); - if (needsMeasure.contains(el)) { - int h = getLayoutManager().getOuterHeight(el); - String sHeight = el.getStyle().getHeight(); - // Only add the caption size to the height of the slot if - // coption position is top or bottom - if (childCaptionElementHeight.containsKey(el) - && (sHeight == null || !sHeight.endsWith("%")) - && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) { - h += childCaptionElementHeight.get(el); - } - if (h > highestNonRelative) { - highestNonRelative = h; - } - } else { - int h = getLayoutManager().getOuterHeight(el); - if (childCaptionElementHeight.containsKey(el) - && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) { - h += childCaptionElementHeight.get(el); - } - if (h > highestRelative) { - highestRelative = h; - } - } - } - return highestNonRelative > -1 ? highestNonRelative : highestRelative; - } - - @Override - public void onUnregister() { - // Cleanup all ElementResizeListeners - - // dontListen(getWidget().getElement(), layoutResizeListener); - - for (ComponentConnector child : getChildComponents()) { - Slot slot = getWidget().getSlot(child); - if (slot.hasCaption()) { - dontListen(slot.getCaptionElement(), slotCaptionResizeListener); - } - - if (slot.getSpacingElement() != null) { - dontListen(slot.getSpacingElement(), spacingResizeListener); - } - - dontListen(slot.getWidget().getElement(), - childComponentResizeListener); - } - - super.onUnregister(); - } - - // private void setLayoutHeightListener(boolean add) { - // if (add) { - // listen(getWidget().getElement(), layoutResizeListener); - // } else { - // dontListen(getWidget().getElement(), layoutResizeListener); - // if (!needsExpand()) { - // System.out.println("Clearing element sizes"); - // childElementHeight.clear(); - // childCaptionElementHeight.clear(); - // } - // } - // } - - /* - * Convenience methods - */ - - private void listen(Element el, ElementResizeListener listener) { - getLayoutManager().addElementResizeListener(el, listener); - } - - private void dontListen(Element el, ElementResizeListener listener) { - getLayoutManager().removeElementResizeListener(el, listener); - } - -} diff --git a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java index 5b1462b33c..8807fcfbc0 100644 --- a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java @@ -15,35 +15,46 @@ */ package com.vaadin.client.ui.orderedlayout; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; -import com.google.gwt.dom.client.Style; 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.client.ComponentConnector; import com.vaadin.client.ConnectorHierarchyChangeEvent; -import com.vaadin.client.DirectionalManagedLayout; -import com.vaadin.client.LayoutManager; import com.vaadin.client.Util; -import com.vaadin.client.VCaption; import com.vaadin.client.communication.RpcProxy; import com.vaadin.client.communication.StateChangeEvent; +import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler; +import com.vaadin.client.ui.AbstractFieldConnector; import com.vaadin.client.ui.AbstractLayoutConnector; import com.vaadin.client.ui.LayoutClickEventHandler; -import com.vaadin.client.ui.layout.ComponentConnectorLayoutSlot; -import com.vaadin.client.ui.layout.VLayoutSlot; +import com.vaadin.client.ui.layout.ElementResizeEvent; +import com.vaadin.client.ui.layout.ElementResizeListener; +import com.vaadin.client.ui.orderedlayout.VOrderedLayout.CaptionPosition; +import com.vaadin.client.ui.orderedlayout.VOrderedLayout.Slot; +import com.vaadin.shared.AbstractFieldState; +import com.vaadin.shared.ComponentConstants; +import com.vaadin.shared.communication.URLReference; import com.vaadin.shared.ui.AlignmentInfo; import com.vaadin.shared.ui.LayoutClickRpc; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutServerRpc; import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutState; +/** + * Base class for vertical and horizontal ordered layouts + */ public abstract class AbstractOrderedLayoutConnector extends - AbstractLayoutConnector implements DirectionalManagedLayout { + AbstractLayoutConnector { AbstractOrderedLayoutServerRpc rpc; + /* + * Handlers & Listeners + */ + private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler( this) { @@ -57,275 +68,522 @@ public abstract class AbstractOrderedLayoutConnector extends protected LayoutClickRpc getLayoutClickRPC() { return rpc; }; + }; + + private StateChangeHandler childStateChangeHandler = new StateChangeHandler() { + @Override + public void onStateChanged(StateChangeEvent stateChangeEvent) { + + ComponentConnector child = (ComponentConnector) stateChangeEvent + .getConnector(); + + // We need to update the slot size if the component size is changed + // to relative + Slot slot = getWidget().getSlot(child.getWidget()); + slot.setRelativeWidth(child.isRelativeWidth()); + slot.setRelativeHeight(child.isRelativeHeight()); + + updateSlotListeners(child); + // updateAllSlotListeners(); + + updateLayoutHeight(); + } + }; + + private ElementResizeListener slotCaptionResizeListener = new ElementResizeListener() { + @Override + public void onElementResize(ElementResizeEvent e) { + + // Get all needed element references + Element captionElement = (Element) e.getElement().cast(); + + // Caption position determines if the widget element is the first or + // last child inside the caption wrap + CaptionPosition pos = getWidget().getCaptionPositionFromElement( + (Element) captionElement.getParentElement().cast()); + + // The default is the last child + Element widgetElement = captionElement.getParentElement() + .getLastChild().cast(); + + // ...but if caption position is bottom or right, the widget is the + // first child + if (pos == CaptionPosition.BOTTOM || pos == CaptionPosition.RIGHT) { + widgetElement = captionElement.getParentElement() + .getFirstChildElement().cast(); + } + + if (captionElement == widgetElement) { + // Caption element already detached + rmeoveResizeListener(captionElement, slotCaptionResizeListener); + childCaptionElementHeight.remove(widgetElement); + return; + } + String widgetWidth = widgetElement.getStyle().getWidth(); + String widgetHeight = widgetElement.getStyle().getHeight(); + + if (widgetHeight.endsWith("%") + && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) { + getWidget().updateCaptionOffset(captionElement); + } else if (widgetWidth.endsWith("%") + && (pos == CaptionPosition.LEFT || pos == CaptionPosition.RIGHT)) { + getWidget().updateCaptionOffset(captionElement); + } + + int h = getLayoutManager().getOuterHeight(captionElement) + - getLayoutManager().getMarginHeight(captionElement); + childCaptionElementHeight.put(widgetElement, h); + + updateLayoutHeight(); + + if (needsExpand()) { + getWidget().updateExpand(); + } + } + }; + + private ElementResizeListener childComponentResizeListener = new ElementResizeListener() { + @Override + public void onElementResize(ElementResizeEvent e) { + updateLayoutHeight(); + if (needsExpand()) { + getWidget().updateExpand(); + } + } }; + private ElementResizeListener spacingResizeListener = new ElementResizeListener() { + @Override + public void onElementResize(ElementResizeEvent e) { + if (needsExpand()) { + getWidget().updateExpand(); + } + } + }; + + /* + * (non-Javadoc) + * + * @see com.vaadin.client.ui.AbstractComponentConnector#init() + */ @Override public void init() { super.init(); rpc = RpcProxy.create(AbstractOrderedLayoutServerRpc.class, this); - getLayoutManager().registerDependency(this, - getWidget().spacingMeasureElement); + getWidget().setLayoutManager(getLayoutManager()); } + /* + * (non-Javadoc) + * + * @see com.vaadin.client.ui.AbstractLayoutConnector#getState() + */ @Override - public void onUnregister() { - LayoutManager lm = getLayoutManager(); - - VMeasuringOrderedLayout layout = getWidget(); - lm.unregisterDependency(this, layout.spacingMeasureElement); + public AbstractOrderedLayoutState getState() { + return (AbstractOrderedLayoutState) super.getState(); + } - // Unregister child caption listeners - for (ComponentConnector child : getChildComponents()) { - VLayoutSlot slot = layout.getSlotForChild(child.getWidget()); - slot.setCaption(null); - } + /* + * (non-Javadoc) + * + * @see com.vaadin.client.ui.AbstractComponentConnector#getWidget() + */ + @Override + public VOrderedLayout getWidget() { + return (VOrderedLayout) super.getWidget(); } + /** + * For bookkeeping. Used to determine if extra calculations are needed for + * horizontal layout. + */ + private HashSet hasVerticalAlignment = new HashSet(); + + /** + * For bookkeeping. Used to determine if extra calculations are needed for + * horizontal layout. + */ + private HashSet hasRelativeHeight = new HashSet(); + + /** + * For bookkeeping. Used to determine if extra calculations are needed for + * horizontal layout. + */ + private HashSet hasExpandRatio = new HashSet(); + + /** + * For bookkeeping. Used in extra calculations for horizontal layout. + */ + private HashSet needsMeasure = new HashSet(); + + /** + * For bookkeeping. Used in extra calculations for horizontal layout. + */ + private HashMap childCaptionElementHeight = new HashMap(); + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.client.ComponentContainerConnector#updateCaption(com.vaadin + * .client.ComponentConnector) + */ @Override - public AbstractOrderedLayoutState getState() { - return (AbstractOrderedLayoutState) super.getState(); + public void updateCaption(ComponentConnector child) { + Slot slot = getWidget().getSlot(child.getWidget()); + + String caption = child.getState().caption; + URLReference iconUrl = child.getState().resources + .get(ComponentConstants.ICON_RESOURCE); + String iconUrlString = iconUrl != null ? iconUrl.toString() : null; + List styles = child.getState().styles; + String error = child.getState().errorMessage; + boolean showError = error != null; + if (child.getState() instanceof AbstractFieldState) { + AbstractFieldState abstractFieldState = (AbstractFieldState) child + .getState(); + showError = showError && !abstractFieldState.hideErrors; + } + boolean required = false; + if (child instanceof AbstractFieldConnector) { + required = ((AbstractFieldConnector) child).isRequired(); + } + boolean enabled = child.getState().enabled; + + slot.setCaption(caption, iconUrlString, styles, error, showError, + required, + enabled); + + slot.setRelativeWidth(child.isRelativeWidth()); + slot.setRelativeHeight(child.isRelativeHeight()); + + if (slot.hasCaption()) { + CaptionPosition pos = slot.getCaptionPosition(); + getLayoutManager().addElementResizeListener( + slot.getCaptionElement(), slotCaptionResizeListener); + if (child.isRelativeHeight() + && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) { + getWidget().updateCaptionOffset(slot.getCaptionElement()); + } else if (child.isRelativeWidth() + && (pos == CaptionPosition.LEFT || pos == CaptionPosition.RIGHT)) { + getWidget().updateCaptionOffset(slot.getCaptionElement()); + } + } else { + childCaptionElementHeight.remove(child.getWidget().getElement()); + } + + updateLayoutHeight(); + + if (needsExpand()) { + getWidget().updateExpand(); + } } + /* + * (non-Javadoc) + * + * @see com.vaadin.client.ui.AbstractComponentContainerConnector# + * onConnectorHierarchyChange + * (com.vaadin.client.ConnectorHierarchyChangeEvent) + */ @Override - public void updateCaption(ComponentConnector component) { - VMeasuringOrderedLayout layout = getWidget(); - if (VCaption.isNeeded(component.getState())) { - VLayoutSlot layoutSlot = layout.getSlotForChild(component - .getWidget()); - VCaption caption = layoutSlot.getCaption(); - if (caption == null) { - caption = new VCaption(component, getConnection()); - - Widget widget = component.getWidget(); - - layout.setCaption(widget, caption); + public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent event) { + super.onConnectorHierarchyChange(event); + + List previousChildren = event.getOldChildren(); + int currentIndex = 0; + VOrderedLayout layout = getWidget(); + + for (ComponentConnector child : getChildComponents()) { + Slot slot = layout.getSlot(child.getWidget()); + if (slot.getParent() != layout) { + child.addStateChangeHandler(childStateChangeHandler); + } + layout.addOrMoveSlot(slot, currentIndex++); + } + + for (ComponentConnector child : previousChildren) { + if (child.getParent() != this) { + Slot slot = layout.getSlot(child.getWidget()); + hasVerticalAlignment.remove(child); + hasRelativeHeight.remove(child); + hasExpandRatio.remove(child); + needsMeasure.remove(child.getWidget().getElement()); + childCaptionElementHeight + .remove(child.getWidget().getElement()); + getLayoutManager().removeElementResizeListener( + child.getWidget().getElement(), + childComponentResizeListener); + if (slot.hasCaption()) { + getLayoutManager() + .removeElementResizeListener( + slot.getCaptionElement(), + slotCaptionResizeListener); + } + if (slot.getSpacingElement() != null) { + getLayoutManager().removeElementResizeListener( + slot.getSpacingElement(), spacingResizeListener); + } + child.removeStateChangeHandler(childStateChangeHandler); + layout.removeWidget(child.getWidget()); } - caption.updateCaption(); + } + + // If some component is added/removed, we need to recalculate the expand + if (needsExpand()) { + getWidget().updateExpand(); } else { - layout.setCaption(component.getWidget(), null); - getLayoutManager().setNeedsLayout(this); + getWidget().clearExpand(); } - } - @Override - public VMeasuringOrderedLayout getWidget() { - return (VMeasuringOrderedLayout) super.getWidget(); } + /* + * (non-Javadoc) + * + * @see + * com.vaadin.client.ui.AbstractComponentConnector#onStateChanged(com.vaadin + * .client.communication.StateChangeEvent) + */ @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { super.onStateChanged(stateChangeEvent); clickEventHandler.handleEventHandlerRegistration(); + getWidget().setMargin(new MarginInfo(getState().marginsBitmask)); + getWidget().setSpacing(getState().spacing); - VMeasuringOrderedLayout layout = getWidget(); + hasExpandRatio.clear(); + hasVerticalAlignment.clear(); + hasRelativeHeight.clear(); + needsMeasure.clear(); + boolean equalExpandRatio = getWidget().vertical ? !isUndefinedHeight() + : !isUndefinedWidth(); for (ComponentConnector child : getChildComponents()) { - VLayoutSlot slot = layout.getSlotForChild(child.getWidget()); + double expandRatio = getState().childData.get(child).expandRatio; + if (expandRatio > 0) { + equalExpandRatio = false; + break; + } + } + + for (ComponentConnector child : getChildComponents()) { + Slot slot = getWidget().getSlot(child.getWidget()); AlignmentInfo alignment = new AlignmentInfo( getState().childData.get(child).alignmentBitmask); slot.setAlignment(alignment); double expandRatio = getState().childData.get(child).expandRatio; - slot.setExpandRatio(expandRatio); - } - layout.updateMarginStyleNames(new MarginInfo(getState().marginsBitmask)); - layout.updateSpacingStyleName(getState().spacing); + if (equalExpandRatio) { + expandRatio = 1; + } else if (expandRatio == 0) { + expandRatio = -1; + } + slot.setExpandRatio(expandRatio); - getLayoutManager().setNeedsLayout(this); - } + // Bookkeeping to identify special cases that need extra + // calculations + if (alignment.isVerticalCenter() || alignment.isBottom()) { + hasVerticalAlignment.add(child); + } - private int getSizeForInnerSize(int size, boolean isVertical) { - LayoutManager layoutManager = getLayoutManager(); - Element element = getWidget().getElement(); - if (isVertical) { - return size + layoutManager.getBorderHeight(element) - + layoutManager.getPaddingHeight(element); - } else { - return size + layoutManager.getBorderWidth(element) - + layoutManager.getPaddingWidth(element); + if (expandRatio > 0) { + hasExpandRatio.add(child); + } } - } - - private static String getSizeProperty(boolean isVertical) { - return isVertical ? "height" : "width"; - } - private boolean isUndefinedInDirection(boolean isVertical) { - if (isVertical) { - return isUndefinedHeight(); - } else { - return isUndefinedWidth(); - } - } + updateAllSlotListeners(); - private int getInnerSizeInDirection(boolean isVertical) { - if (isVertical) { - return getLayoutManager().getInnerHeight(getWidget().getElement()); - } else { - return getLayoutManager().getInnerWidth(getWidget().getElement()); - } + updateLayoutHeight(); } - private void layoutPrimaryDirection() { - VMeasuringOrderedLayout layout = getWidget(); - boolean isVertical = layout.isVertical; - boolean isUndefined = isUndefinedInDirection(isVertical); - int startPadding = getStartPadding(isVertical); - int endPadding = getEndPadding(isVertical); - int spacingSize = getSpacingInDirection(isVertical); - int allocatedSize; - - if (isUndefined) { - allocatedSize = -1; - } else { - allocatedSize = getInnerSizeInDirection(isVertical); - } - - allocatedSize = layout.layoutPrimaryDirection(spacingSize, - allocatedSize, startPadding, endPadding); - - Style ownStyle = getWidget().getElement().getStyle(); - if (isUndefined) { - int outerSize = getSizeForInnerSize(allocatedSize, isVertical); - ownStyle.setPropertyPx(getSizeProperty(isVertical), outerSize); - reportUndefinedSize(outerSize, isVertical); - } else { - ownStyle.setProperty(getSizeProperty(isVertical), - getDefinedSize(isVertical)); + /** + * Does the layout need a fixed height? + */ + private boolean needsFixedHeight() { + if (!getWidget().vertical + && isUndefinedHeight() + && (hasRelativeHeight.size() > 0 || (hasVerticalAlignment + .size() > 0 && hasVerticalAlignment.size() < getChildren() + .size()))) { + return true; } + return false; } - private void reportUndefinedSize(int outerSize, boolean isVertical) { - if (isVertical) { - getLayoutManager().reportOuterHeight(this, outerSize); - } else { - getLayoutManager().reportOuterWidth(this, outerSize); - } + /** + * Does the layout need to expand? + */ + private boolean needsExpand() { + boolean canApplyExpand = (getWidget().vertical && !isUndefinedHeight()) + || (!getWidget().vertical && !isUndefinedWidth()); + return hasExpandRatio.size() > 0 && canApplyExpand; } - private int getSpacingInDirection(boolean isVertical) { - if (isVertical) { - return getLayoutManager().getOuterHeight( - getWidget().spacingMeasureElement); - } else { - return getLayoutManager().getOuterWidth( - getWidget().spacingMeasureElement); + /** + * Add slot listeners + */ + private void updateAllSlotListeners() { + for (ComponentConnector child : getChildComponents()) { + updateSlotListeners(child); } } - private void layoutSecondaryDirection() { - VMeasuringOrderedLayout layout = getWidget(); - boolean isVertical = layout.isVertical; - boolean isUndefined = isUndefinedInDirection(!isVertical); - - int startPadding = getStartPadding(!isVertical); - int endPadding = getEndPadding(!isVertical); - - int allocatedSize; - if (isUndefined) { - allocatedSize = -1; - } else { - allocatedSize = getInnerSizeInDirection(!isVertical); + /** + * Add/remove necessary ElementResizeListeners for one slot. This should be + * called after each update to the slot's or it's widget. + */ + private void updateSlotListeners(ComponentConnector child) { + Slot slot = getWidget().getSlot(child.getWidget()); + + // Clear all possible listeners first + rmeoveResizeListener(slot.getWidget().getElement(), childComponentResizeListener); + if (slot.hasCaption()) { + rmeoveResizeListener(slot.getCaptionElement(), slotCaptionResizeListener); } - - allocatedSize = layout.layoutSecondaryDirection(allocatedSize, - startPadding, endPadding); - - Style ownStyle = getWidget().getElement().getStyle(); - - if (isUndefined) { - int outerSize = getSizeForInnerSize(allocatedSize, - !getWidget().isVertical); - ownStyle.setPropertyPx(getSizeProperty(!getWidget().isVertical), - outerSize); - reportUndefinedSize(outerSize, !isVertical); - } else { - ownStyle.setProperty(getSizeProperty(!getWidget().isVertical), - getDefinedSize(!getWidget().isVertical)); + if (slot.hasSpacing()) { + rmeoveResizeListener(slot.getSpacingElement(), spacingResizeListener); } - } - private String getDefinedSize(boolean isVertical) { - if (isVertical) { - return getState().height == null ? "" : getState().height; - } else { - return getState().width == null ? "" : getState().width; + // Add all necessary listeners + if (needsFixedHeight()) { + addResizeListener(slot.getWidget().getElement(), childComponentResizeListener); + if (slot.hasCaption()) { + addResizeListener(slot.getCaptionElement(), slotCaptionResizeListener); + } + } else if ((child.isRelativeHeight() || child.isRelativeWidth()) + && slot.hasCaption()) { + // If the slot has caption, we need to listen for it's size changes + // in order to update the padding/margin offset for relative sized + // components + addResizeListener(slot.getCaptionElement(), slotCaptionResizeListener); } - } - private int getStartPadding(boolean isVertical) { - if (isVertical) { - return getLayoutManager().getPaddingTop(getWidget().getElement()); - } else { - return getLayoutManager().getPaddingLeft(getWidget().getElement()); + if (needsExpand()) { + addResizeListener(slot.getWidget().getElement(), childComponentResizeListener); + if (slot.hasSpacing()) { + addResizeListener(slot.getSpacingElement(), spacingResizeListener); + } } - } - private int getEndPadding(boolean isVertical) { - if (isVertical) { - return getLayoutManager() - .getPaddingBottom(getWidget().getElement()); + if (child.isRelativeHeight()) { + hasRelativeHeight.add(child); + needsMeasure.remove(child.getWidget().getElement()); } else { - return getLayoutManager().getPaddingRight(getWidget().getElement()); + hasRelativeHeight.remove(child); + needsMeasure.add(child.getWidget().getElement()); } + } - @Override - public void layoutHorizontally() { - if (getWidget().isVertical) { - layoutSecondaryDirection(); - } else { - layoutPrimaryDirection(); + /** + * Re-calculate the layout height + */ + private void updateLayoutHeight() { + if (needsFixedHeight()) { + int h = getMaxHeight(); + h += getLayoutManager().getBorderHeight(getWidget().getElement()) + + getLayoutManager().getPaddingHeight( + getWidget().getElement()); + getWidget().getElement().getStyle().setHeight(h, Unit.PX); + getLayoutManager().setNeedsMeasure(this); } } - @Override - public void layoutVertically() { - if (getWidget().isVertical) { - layoutPrimaryDirection(); - } else { - layoutSecondaryDirection(); + /** + * Measures the maximum height of the layout in pixels + */ + private int getMaxHeight() { + int highestNonRelative = -1; + int highestRelative = -1; + + for (ComponentConnector child : getChildComponents()) { + // TODO would be more efficient to measure the slot element if both + // caption and child widget elements need to be measured. Keeping + // track of what to measure is the most difficult part of this + // layout. + Element el = child.getWidget().getElement(); + CaptionPosition pos = getWidget().getCaptionPositionFromElement( + (Element) el.getParentElement().cast()); + if (needsMeasure.contains(el)) { + int h = getLayoutManager().getOuterHeight(el); + String sHeight = el.getStyle().getHeight(); + // Only add the caption size to the height of the slot if + // coption position is top or bottom + if (childCaptionElementHeight.containsKey(el) + && (sHeight == null || !sHeight.endsWith("%")) + && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) { + h += childCaptionElementHeight.get(el); + } + if (h > highestNonRelative) { + highestNonRelative = h; + } + } else { + int h = getLayoutManager().getOuterHeight(el); + if (childCaptionElementHeight.containsKey(el) + && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) { + h += childCaptionElementHeight.get(el); + } + if (h > highestRelative) { + highestRelative = h; + } + } } + return highestNonRelative > -1 ? highestNonRelative : highestRelative; } + /* + * (non-Javadoc) + * + * @see com.vaadin.client.ui.AbstractComponentConnector#onUnregister() + */ @Override - public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent event) { - super.onConnectorHierarchyChange(event); - List previousChildren = event.getOldChildren(); - int currentIndex = 0; - VMeasuringOrderedLayout layout = getWidget(); - + public void onUnregister() { + // Cleanup all ElementResizeListeners for (ComponentConnector child : getChildComponents()) { - Widget childWidget = child.getWidget(); - VLayoutSlot slot = layout.getSlotForChild(childWidget); - - if (childWidget.getParent() != layout) { - // If the child widget was previously attached to another - // AbstractOrderedLayout a slot might be found that belongs to - // another AbstractOrderedLayout. In this case we discard it and - // create a new slot. - slot = new ComponentConnectorLayoutSlot(getWidget() - .getStylePrimaryName(), child, this); - } - layout.addOrMove(slot, currentIndex++); - if (child.isRelativeWidth()) { - slot.getWrapperElement().getStyle().setWidth(100, Unit.PCT); + Slot slot = getWidget().getSlot(child.getWidget()); + if (slot.hasCaption()) { + rmeoveResizeListener(slot.getCaptionElement(), slotCaptionResizeListener); } - } - for (ComponentConnector child : previousChildren) { - if (child.getParent() != this) { - // Remove slot if the connector is no longer a child of this - // layout - layout.removeSlotForWidget(child.getWidget()); + if (slot.getSpacingElement() != null) { + rmeoveResizeListener(slot.getSpacingElement(), spacingResizeListener); } + + rmeoveResizeListener(slot.getWidget().getElement(), + childComponentResizeListener); } - }; + super.onUnregister(); + } + + /** + * Helper method to add a resize listener to an element + * + * @param el + * The element to add the resize listener to + * @param listener + * The listener to add + */ + private void addResizeListener(Element el, ElementResizeListener listener) { + getLayoutManager().addElementResizeListener(el, listener); + } + + /** + * Helper method to remove a resize listener to an element + * + * @param el + * The element from where the resize listener should be removed + * @param listener + * THe listener to remove + */ + private void rmeoveResizeListener(Element el, ElementResizeListener listener) { + getLayoutManager().removeElementResizeListener(el, listener); + } } diff --git a/client/src/com/vaadin/client/ui/orderedlayout/HorizontalBoxLayoutConnector.java b/client/src/com/vaadin/client/ui/orderedlayout/HorizontalBoxLayoutConnector.java deleted file mode 100644 index 13e133dfa7..0000000000 --- a/client/src/com/vaadin/client/ui/orderedlayout/HorizontalBoxLayoutConnector.java +++ /dev/null @@ -1,19 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.client.ui.orderedlayout; - -import com.vaadin.shared.ui.Connect; -import com.vaadin.shared.ui.Connect.LoadStyle; -import com.vaadin.ui.HorizontalLayout; - -@Connect(value = HorizontalLayout.class, loadStyle = LoadStyle.EAGER) -public class HorizontalBoxLayoutConnector extends AbstractBoxLayoutConnector { - - @Override - public void init() { - super.init(); - getWidget().setVertical(false); - } - -} diff --git a/client/src/com/vaadin/client/ui/orderedlayout/HorizontalLayoutConnector.java b/client/src/com/vaadin/client/ui/orderedlayout/HorizontalLayoutConnector.java index a86baf9cea..aa33e99f45 100644 --- a/client/src/com/vaadin/client/ui/orderedlayout/HorizontalLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/orderedlayout/HorizontalLayoutConnector.java @@ -15,10 +15,24 @@ */ package com.vaadin.client.ui.orderedlayout; +import com.vaadin.shared.ui.Connect; +import com.vaadin.shared.ui.Connect.LoadStyle; +import com.vaadin.ui.HorizontalLayout; -//@Connect(value = HorizontalLayout.class, loadStyle = LoadStyle.EAGER) +/** + * Connects the client widget {@link VHorizontalLayout} with the Vaadin server + * side counterpart {@link HorizontalLayout} + */ +@Connect(value = HorizontalLayout.class, loadStyle = LoadStyle.EAGER) public class HorizontalLayoutConnector extends AbstractOrderedLayoutConnector { + /* + * (non-Javadoc) + * + * @see + * com.vaadin.client.ui.orderedlayout.AbstractOrderedLayoutConnector#getWidget + * () + */ @Override public VHorizontalLayout getWidget() { return (VHorizontalLayout) super.getWidget(); diff --git a/client/src/com/vaadin/client/ui/orderedlayout/VHorizontalLayout.java b/client/src/com/vaadin/client/ui/orderedlayout/VHorizontalLayout.java index c72c44262b..543eeafe88 100644 --- a/client/src/com/vaadin/client/ui/orderedlayout/VHorizontalLayout.java +++ b/client/src/com/vaadin/client/ui/orderedlayout/VHorizontalLayout.java @@ -15,12 +15,15 @@ */ package com.vaadin.client.ui.orderedlayout; -public class VHorizontalLayout extends VMeasuringOrderedLayout { - - public static final String CLASSNAME = "v-horizontallayout"; +/** + * Represents a layout where the children is ordered vertically + */ +public class VHorizontalLayout extends VOrderedLayout { + /** + * Default constructor + */ public VHorizontalLayout() { - super(CLASSNAME, false); + setVertical(false); } - } diff --git a/client/src/com/vaadin/client/ui/orderedlayout/VMeasuringOrderedLayout.java b/client/src/com/vaadin/client/ui/orderedlayout/VMeasuringOrderedLayout.java deleted file mode 100644 index 94dfe2242e..0000000000 --- a/client/src/com/vaadin/client/ui/orderedlayout/VMeasuringOrderedLayout.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 2011 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.client.ui.orderedlayout; - -import java.util.HashMap; -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.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.google.gwt.user.client.ui.WidgetCollection; -import com.vaadin.client.VCaption; -import com.vaadin.client.ui.layout.VLayoutSlot; -import com.vaadin.shared.ui.MarginInfo; - -public class VMeasuringOrderedLayout extends ComplexPanel { - - final boolean isVertical; - - final DivElement spacingMeasureElement; - - private Map widgetToSlot = new HashMap(); - - 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); - } - - widgetToSlot.put(widget, layoutSlot); - } - - private void togglePrefixedStyleName(String name, boolean enabled) { - if (enabled) { - addStyleDependentName(name); - } else { - removeStyleDependentName(name); - } - } - - void updateMarginStyleNames(MarginInfo 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 removeSlotForWidget(Widget widget) { - VLayoutSlot slot = getSlotForChild(widget); - VCaption caption = slot.getCaption(); - if (caption != null) { - // Must remove using setCaption to ensure dependencies (layout -> - // caption) are unregistered - slot.setCaption(null); - } - - remove(slot.getWidget()); - getElement().removeChild(slot.getWrapperElement()); - widgetToSlot.remove(widget); - } - - public VLayoutSlot getSlotForChild(Widget widget) { - return widgetToSlot.get(widget); - } - - 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 endPadding) { - 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; - - WidgetCollection children = getChildren(); - for (int i = 0; i < children.size(); i++) { - Widget child = children.get(i); - 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 endLocation = currentLocation + extraPixels; - if (!slot.isRelativeInDirection(isVertical)) { - endLocation += slot.getUsedSizeInDirection(isVertical); - } - - /* - * currentLocation and allocatedSpace are used with full precision - * to avoid missing pixels in the end. The pixel dimensions passed - * to the DOM are still rounded. Otherwise e.g. 10.5px start - * position + 10.5px space might be cause the component to go 1px - * beyond the edge as the effect of the browser's rounding may cause - * something similar to 11px + 11px. - * - * It's most efficient to use doubles all the way because native - * javascript emulates other number types using doubles. - */ - double roundedLocation = Math.round(currentLocation); - - /* - * Space is calculated as the difference between rounded start and - * end locations. Just rounding the space would cause e.g. 10.5px + - * 10.5px = 21px -> 11px + 11px = 22px but in this way we get 11px + - * 10px = 21px. - */ - double roundedSpace = Math.round(endLocation) - roundedLocation; - - // Reserve room for the padding if we're at the end - double slotEndMargin; - if (i == children.size() - 1) { - slotEndMargin = endPadding; - } else { - slotEndMargin = 0; - } - - slot.positionInDirection(roundedLocation, roundedSpace, - slotEndMargin, isVertical); - - currentLocation = endLocation + spacingSize; - } - - return allocatedSize; - } - - public int layoutSecondaryDirection(int allocatedSize, int startPadding, - int endPadding) { - 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, endPadding, - !isVertical); - } - - return allocatedSize; - } -} diff --git a/client/src/com/vaadin/client/ui/orderedlayout/VBoxLayout.java b/client/src/com/vaadin/client/ui/orderedlayout/VOrderedLayout.java similarity index 71% rename from client/src/com/vaadin/client/ui/orderedlayout/VBoxLayout.java rename to client/src/com/vaadin/client/ui/orderedlayout/VOrderedLayout.java index 4df4ce6524..9c45680d92 100644 --- a/client/src/com/vaadin/client/ui/orderedlayout/VBoxLayout.java +++ b/client/src/com/vaadin/client/ui/orderedlayout/VOrderedLayout.java @@ -1,5 +1,17 @@ /* -@VaadinApache2LicenseForJavaFiles@ + * Copyright 2011 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. */ package com.vaadin.client.ui.orderedlayout; @@ -19,13 +31,16 @@ import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.UIObject; import com.google.gwt.user.client.ui.Widget; -import com.vaadin.client.ComponentConnector; import com.vaadin.client.LayoutManager; +import com.vaadin.client.Util; import com.vaadin.shared.ui.AlignmentInfo; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.ui.themes.BaseTheme; -public class VBoxLayout extends FlowPanel { +/** + * Base class for ordered layouts + */ +public class VOrderedLayout extends FlowPanel { public static final String CLASSNAME = "v-boxlayout"; @@ -39,15 +54,28 @@ public class VBoxLayout extends FlowPanel { private Map widgetToSlot = new HashMap(); + private Element expandWrapper; + private LayoutManager layoutManager; - public VBoxLayout() { + /** + * Constructor + */ + public VOrderedLayout() { setStyleName(CLASSNAME); setVertical(true); } - public void setVertical(boolean isVertical) { - vertical = isVertical; + /** + * Does the layout order its children horizontally or vertically + * + * @param vertical + * true to order the childer vertically, false to order them + * horizontally + * + */ + protected void setVertical(boolean vertical) { + this.vertical = vertical; if (vertical) { addStyleName("v-vertical"); removeStyleName("v-horizontal"); @@ -57,7 +85,15 @@ public class VBoxLayout extends FlowPanel { } } - public void addOrMoveSlot(Slot slot, int index) { + /** + * Add or move a slot to another index + * + * @param slot + * The slot to move or add + * @param index + * The index where the slot should be placed + */ + void addOrMoveSlot(Slot slot, int index) { if (slot.getParent() == this) { int currentIndex = getWidgetIndex(slot); if (index == currentIndex) { @@ -67,6 +103,9 @@ public class VBoxLayout extends FlowPanel { insert(slot, index); } + /** + * {@inheritDoc} + */ @Override protected void insert(Widget child, Element container, int beforeIndex, boolean domInsert) { @@ -93,56 +132,93 @@ public class VBoxLayout extends FlowPanel { adopt(child); } - public Slot removeSlot(Widget widget) { + /** + * Remove a slot from the layout + * + * @param widget + * @return + */ + public void removeWidget(Widget widget) { Slot slot = widgetToSlot.get(widget); remove(slot); widgetToSlot.remove(widget); - return slot; } - public Slot getSlot(ComponentConnector connector) { - Slot slot = widgetToSlot.get(connector.getWidget()); + /** + * Get the containing slot for a widget + * + * @param widget + * The widget whose slot you want to get + * + * @return + */ + public Slot getSlot(Widget widget) { + Slot slot = widgetToSlot.get(widget); if (slot == null) { - slot = new Slot(connector); - widgetToSlot.put(connector.getWidget(), slot); + slot = new Slot(widget, this); + widgetToSlot.put(widget, slot); } return slot; } + /** + * Defines where the caption should be placed + */ public enum CaptionPosition { TOP, RIGHT, BOTTOM, LEFT } - protected class Slot extends SimplePanel { - - private ComponentConnector connector; + /** + * Represents a slot which contains the actual widget in the layout. + */ + public static final class Slot extends SimplePanel { private Element spacer; - private Element captionWrap; private Element caption; private Element captionText; private Icon icon; private Element errorIcon; private Element requiredIcon; + private final VOrderedLayout layout; // Caption is placed after component unless there is some part which // moves it above. private CaptionPosition captionPosition = CaptionPosition.RIGHT; private AlignmentInfo alignment; + private double expandRatio = -1; - public Slot(ComponentConnector connector) { - this.connector = connector; - setWidget(connector.getWidget()); + /** + * Constructor + * + * @param widget + * The widget to put in the slot + * + * @param layoutManager + * The layout manager used by the layout + */ + private Slot(Widget widget, VOrderedLayout layout) { + this.layout = layout; + setWidget(widget); setStylePrimaryName("v-slot"); } + /** + * Returns the alignment for the slot + * + */ public AlignmentInfo getAlignment() { return alignment; } + /** + * Sets how the widget is aligned inside the slot + * + * @param alignment + * The alignment inside the slot + */ public void setAlignment(AlignmentInfo alignment) { this.alignment = alignment; @@ -168,14 +244,34 @@ public class VBoxLayout extends FlowPanel { } } + /** + * Set how the slot should be expanded relative to the other slots + * + * @param expandRatio + * The ratio of the space the slot should occupy + * + */ public void setExpandRatio(double expandRatio) { this.expandRatio = expandRatio; } + /** + * Get the expand ratio for the slot. The expand ratio describes how the + * slot should be resized compared to other slots in the layout + * + * @return + */ public double getExpandRatio() { return expandRatio; } + /** + * Set the spacing for the slot. The spacing determines if there should + * be empty space around the slot when the slot. + * + * @param spacing + * Should spacing be enabled + */ public void setSpacing(boolean spacing) { if (spacing && spacer == null) { spacer = DOM.createDiv(); @@ -188,39 +284,58 @@ public class VBoxLayout extends FlowPanel { } } + /** + * Get the element which is added to make the spacing + * + * @return + */ public Element getSpacingElement() { return spacer; } + /** + * Does the slot have spacing + */ public boolean hasSpacing() { return getSpacingElement() != null; } - protected int getSpacingSize(boolean vertical) { + /** + * Get the vertical amount in pixels of the spacing + */ + protected int getVerticalSpacing() { if (spacer == null) { return 0; + } else if (layout.getLayoutManager() != null) { + return layout.getLayoutManager().getOuterHeight(spacer); } + return spacer.getOffsetHeight(); + } - if (layoutManager != null) { - if (vertical) { - return layoutManager.getOuterHeight(spacer); - } else { - return layoutManager.getOuterWidth(spacer); - } + /** + * Get the horizontal amount of pixels of the spacing + * + * @return + */ + protected int getHorizontalSpacing() { + if (spacer == null) { + return 0; + } else if (layout.getLayoutManager() != null) { + return layout.getLayoutManager().getOuterWidth(spacer); } - // TODO place for optimization (in expense of theme - // flexibility): only measure one of the elements and cache the - // value - return vertical ? spacer.getOffsetHeight() : spacer - .getOffsetWidth(); - // } + return spacer.getOffsetWidth(); } + /** + * Set the position of the caption relative to the slot + * + * @param captionPosition + * The position of the caption + */ public void setCaptionPosition(CaptionPosition captionPosition) { if (caption == null) { return; } - captionWrap.removeClassName("v-caption-on-" + this.captionPosition.name().toLowerCase()); @@ -236,12 +351,31 @@ public class VBoxLayout extends FlowPanel { + captionPosition.name().toLowerCase()); } + /** + * Get the position of the caption relative to the slot + */ public CaptionPosition getCaptionPosition() { return captionPosition; } - // TODO refactor VCaption and use that instead: creates a tight coupling - // between this layout and Vaadin, but it's already coupled + /** + * Set the caption of the slot + * + * @param captionText + * The text of the caption + * @param iconUrl + * The icon URL + * @param styles + * The style names + * @param error + * The error message + * @param showError + * Should the error message be shown + * @param required + * Is the (field) required + * @param enabled + * Is the component enabled + */ public void setCaption(String captionText, String iconUrl, List styles, String error, boolean showError, boolean required, boolean enabled) { @@ -288,11 +422,8 @@ public class VBoxLayout extends FlowPanel { if (iconUrl != null) { if (icon == null) { icon = new Icon(); - // icon = DOM.createImg(); - // icon.setClassName("v-icon"); caption.insertFirst(icon.getElement()); } - // icon.setAttribute("src", iconUrl); icon.setUri(iconUrl); } else if (icon != null) { icon.getElement().removeFromParent(); @@ -349,27 +480,56 @@ public class VBoxLayout extends FlowPanel { setCaptionPosition(CaptionPosition.RIGHT); } } - - // TODO theme flexibility: add extra styles to captionWrap as well? - } + /** + * Does the slot have a caption + */ public boolean hasCaption() { return caption != null; } + /** + * Get the slots caption element + */ public Element getCaptionElement() { return caption; } - public void setRelativeWidth(boolean relativeWidth) { + /** + * Set if the slot has a relative width + * + * @param relativeWidth + * True if slot uses relative width, false if the slot has a + * static width + */ + private boolean relativeWidth = false; + protected void setRelativeWidth(boolean relativeWidth) { + this.relativeWidth = relativeWidth; updateRelativeSize(relativeWidth, "width"); } - public void setRelativeHeight(boolean relativeHeight) { + /** + * Set if the slot has a relative height + * + * @param relativeHeight + * Trie if the slot uses a relative height, false if the slot + * has a static height + */ + private boolean relativeHeight = false; + protected void setRelativeHeight(boolean relativeHeight) { + this.relativeHeight = relativeHeight; updateRelativeSize(relativeHeight, "height"); } + /** + * Updates the captions size if the slot is relative + * + * @param isRelativeSize + * Is the slot relatived sized + * @param direction + * The directorion of the caption + */ private void updateRelativeSize(boolean isRelativeSize, String direction) { if (isRelativeSize && hasCaption()) { captionWrap.getStyle().setProperty( @@ -395,19 +555,31 @@ public class VBoxLayout extends FlowPanel { } } + /* + * (non-Javadoc) + * + * @see + * com.google.gwt.user.client.ui.Widget#onBrowserEvent(com.google.gwt + * .user.client.Event) + */ @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); if (DOM.eventGetType(event) == Event.ONLOAD && icon.getElement() == DOM.eventGetTarget(event)) { - if (layoutManager != null) { - layoutManager.layoutLater(); + if (layout.getLayoutManager() != null) { + layout.getLayoutManager().layoutLater(); } else { - updateCaptionOffset(caption); + layout.updateCaptionOffset(caption); } } } + /* + * (non-Javadoc) + * + * @see com.google.gwt.user.client.ui.SimplePanel#getContainerElement() + */ @Override protected Element getContainerElement() { if (captionWrap == null) { @@ -417,6 +589,11 @@ public class VBoxLayout extends FlowPanel { } } + /* + * (non-Javadoc) + * + * @see com.google.gwt.user.client.ui.Widget#onDetach() + */ @Override protected void onDetach() { if (spacer != null) { @@ -425,6 +602,11 @@ public class VBoxLayout extends FlowPanel { super.onDetach(); } + /* + * (non-Javadoc) + * + * @see com.google.gwt.user.client.ui.Widget#onAttach() + */ @Override protected void onAttach() { super.onAttach(); @@ -433,19 +615,32 @@ public class VBoxLayout extends FlowPanel { getElement()); } } - } - protected class Icon extends UIObject { + /** + * The icon for each widget. Located in the caption of the slot. + */ + public static class Icon extends UIObject { + public static final String CLASSNAME = "v-icon"; + private String myUrl; + /** + * Constructor + */ public Icon() { setElement(DOM.createImg()); DOM.setElementProperty(getElement(), "alt", ""); setStyleName(CLASSNAME); } + /** + * Set the URL where the icon is located + * + * @param url + * A fully qualified URL + */ public void setUri(String url) { if (!url.equals(myUrl)) { /* @@ -459,17 +654,37 @@ public class VBoxLayout extends FlowPanel { myUrl = url; } } - } - void setLayoutManager(LayoutManager manager) { + /** + * Set the layout manager for the layout + * + * @param manager + * The layout manager to use + */ + public void setLayoutManager(LayoutManager manager) { layoutManager = manager; } + + /** + * Get the layout manager used by this layout + * + */ + public LayoutManager getLayoutManager() { + return layoutManager; + } - private static final RegExp captionPositionRegexp = RegExp - .compile("v-caption-on-(\\S+)"); - + /** + * Deducts the caption position by examining the wrapping element + * + * @param captionWrap + * The wrapping element + * + * @return The caption position + */ CaptionPosition getCaptionPositionFromElement(Element captionWrap) { + RegExp captionPositionRegexp = RegExp.compile("v-caption-on-(\\S+)"); + // Get caption position from the classname MatchResult matcher = captionPositionRegexp.exec(captionWrap .getClassName()); @@ -482,6 +697,12 @@ public class VBoxLayout extends FlowPanel { return captionPosition; } + /** + * Update the offset off the caption relative to the slot + * + * @param caption + * The caption element + */ void updateCaptionOffset(Element caption) { Element captionWrap = caption.getParentElement().cast(); @@ -541,22 +762,39 @@ public class VBoxLayout extends FlowPanel { } } - void setMargin(MarginInfo marginInfo) { - setStyleName("v-margin-top", marginInfo.hasTop()); - setStyleName("v-margin-right", marginInfo.hasRight()); - setStyleName("v-margin-bottom", marginInfo.hasBottom()); - setStyleName("v-margin-left", marginInfo.hasLeft()); + /** + * Set the margin of the layout + * + * @param marginInfo + * The margin information + */ + public void setMargin(MarginInfo marginInfo) { + if (marginInfo != null) { + setStyleName("v-margin-top", marginInfo.hasTop()); + setStyleName("v-margin-right", marginInfo.hasRight()); + setStyleName("v-margin-bottom", marginInfo.hasBottom()); + setStyleName("v-margin-left", marginInfo.hasLeft()); + } } - protected void setSpacing(boolean spacingEnabled) { - spacing = spacingEnabled; + /** + * Turn on or off spacing in the layout + * + * @param spacing + * True if spacing should be used, false if not + */ + public void setSpacing(boolean spacing) { + this.spacing = spacing; for (Slot slot : widgetToSlot.values()) { if (getWidgetIndex(slot) > 0) { - slot.setSpacing(spacingEnabled); + slot.setSpacing(spacing); } } } + /** + * Triggers a recalculation of the expand width and heights + */ private void recalculateExpands() { double total = 0; for (Slot slot : widgetToSlot.values()) { @@ -575,21 +813,22 @@ public class VBoxLayout extends FlowPanel { if (vertical) { slot.setHeight((100 * (slot.getExpandRatio() / total)) + "%"); - if (slot.connector.isRelativeHeight()) { - layoutManager.setNeedsMeasure(slot.connector); + if (slot.relativeHeight) { + Util.notifyParentOfSizeChange(this, true); } } else { slot.setWidth((100 * (slot.getExpandRatio() / total)) + "%"); - if (slot.connector.isRelativeWidth()) { - layoutManager.setNeedsMeasure(slot.connector); + if (slot.relativeWidth) { + Util.notifyParentOfSizeChange(this, true); } } } } } - private Element expandWrapper; - + /** + * Removes elements used to expand a slot + */ void clearExpand() { if (expandWrapper != null) { for (; expandWrapper.getChildCount() > 0;) { @@ -608,6 +847,9 @@ public class VBoxLayout extends FlowPanel { } } + /** + * Adds elements used to expand a slot + */ public void updateExpand() { boolean isExpanding = false; for (Widget slot : getChildren()) { @@ -639,6 +881,7 @@ public class VBoxLayout extends FlowPanel { for (Widget w : getChildren()) { Slot slot = (Slot) w; if (slot.getExpandRatio() == -1) { + if (layoutManager != null) { // TODO check caption position if (vertical) { @@ -678,7 +921,8 @@ public class VBoxLayout extends FlowPanel { } } // TODO fails in Opera, always returns 0 - int spacingSize = slot.getSpacingSize(vertical); + int spacingSize = vertical ? slot.getVerticalSpacing() : slot + .getHorizontalSpacing(); if (spacingSize > 0) { totalSize += spacingSize; } @@ -702,6 +946,9 @@ public class VBoxLayout extends FlowPanel { } } + /** + * Perform a recalculation of the layout height + */ public void recalculateLayoutHeight() { // Only needed if a horizontal layout is undefined high, and contains // relative height children or vertical alignments @@ -732,16 +979,14 @@ public class VBoxLayout extends FlowPanel { } else { newHeight = getElement().getOffsetHeight(); } - VBoxLayout.this.getElement().getStyle() + VOrderedLayout.this.getElement().getStyle() .setHeight(newHeight, Unit.PX); } - - } - - void clearHeight() { - getElement().getStyle().clearHeight(); } + /** + * {@inheritDoc} + */ @Override public void setHeight(String height) { super.setHeight(height); diff --git a/client/src/com/vaadin/client/ui/orderedlayout/VVerticalLayout.java b/client/src/com/vaadin/client/ui/orderedlayout/VVerticalLayout.java index 76e5910bed..3e597afec1 100644 --- a/client/src/com/vaadin/client/ui/orderedlayout/VVerticalLayout.java +++ b/client/src/com/vaadin/client/ui/orderedlayout/VVerticalLayout.java @@ -15,12 +15,15 @@ */ package com.vaadin.client.ui.orderedlayout; -public class VVerticalLayout extends VMeasuringOrderedLayout { - - public static final String CLASSNAME = "v-verticallayout"; +/** + * Represents a layout where the children is ordered vertically + */ +public class VVerticalLayout extends VOrderedLayout { + /** + * Default constructor + */ public VVerticalLayout() { - super(CLASSNAME, true); + setVertical(true); } - } diff --git a/client/src/com/vaadin/client/ui/orderedlayout/VerticalBoxLayoutConnector.java b/client/src/com/vaadin/client/ui/orderedlayout/VerticalBoxLayoutConnector.java deleted file mode 100644 index 5d1e1d9eee..0000000000 --- a/client/src/com/vaadin/client/ui/orderedlayout/VerticalBoxLayoutConnector.java +++ /dev/null @@ -1,19 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.client.ui.orderedlayout; - -import com.vaadin.shared.ui.Connect; -import com.vaadin.shared.ui.Connect.LoadStyle; -import com.vaadin.ui.VerticalLayout; - -@Connect(value = VerticalLayout.class, loadStyle = LoadStyle.EAGER) -public class VerticalBoxLayoutConnector extends AbstractBoxLayoutConnector { - - @Override - public void init() { - super.init(); - getWidget().setVertical(true); - } - -} diff --git a/client/src/com/vaadin/client/ui/orderedlayout/VerticalLayoutConnector.java b/client/src/com/vaadin/client/ui/orderedlayout/VerticalLayoutConnector.java index 455c645144..13e9b3ecf7 100644 --- a/client/src/com/vaadin/client/ui/orderedlayout/VerticalLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/orderedlayout/VerticalLayoutConnector.java @@ -15,10 +15,24 @@ */ package com.vaadin.client.ui.orderedlayout; +import com.vaadin.shared.ui.Connect; +import com.vaadin.shared.ui.Connect.LoadStyle; +import com.vaadin.ui.VerticalLayout; -//@Connect(value = VerticalLayout.class, loadStyle = LoadStyle.EAGER) +/** + * Connects the client widget {@link VVerticalLayout} with the Vaadin server + * side counterpart {@link VerticalLayout} + */ +@Connect(value = VerticalLayout.class, loadStyle = LoadStyle.EAGER) public class VerticalLayoutConnector extends AbstractOrderedLayoutConnector { + /* + * (non-Javadoc) + * + * @see + * com.vaadin.client.ui.orderedlayout.AbstractOrderedLayoutConnector#getWidget + * () + */ @Override public VVerticalLayout getWidget() { return (VVerticalLayout) super.getWidget(); -- 2.39.5