aboutsummaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorJohn Ahlroos <john@vaadin.com>2012-09-05 17:58:12 +0300
committerJohn Ahlroos <john@vaadin.com>2012-09-05 17:58:12 +0300
commit2fd07a0bd26754d72e77810bc280c6abac740f29 (patch)
treee21a237d4bedd04e5a3566cbb7316c4bd1aeddc2 /client
parent223fc1421dea2e1fd6c80ce4b859c17ca0a428e9 (diff)
downloadvaadin-framework-2fd07a0bd26754d72e77810bc280c6abac740f29.tar.gz
vaadin-framework-2fd07a0bd26754d72e77810bc280c6abac740f29.zip
Refactored and cleaned up the newly add ordered layouts
Diffstat (limited to 'client')
-rw-r--r--client/src/com/vaadin/client/ComponentLocator.java25
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/AbstractBoxLayoutConnector.java607
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java658
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/HorizontalBoxLayoutConnector.java19
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/HorizontalLayoutConnector.java16
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/VHorizontalLayout.java13
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/VMeasuringOrderedLayout.java253
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/VOrderedLayout.java (renamed from client/src/com/vaadin/client/ui/orderedlayout/VBoxLayout.java)395
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/VVerticalLayout.java13
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/VerticalBoxLayoutConnector.java19
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/VerticalLayoutConnector.java16
11 files changed, 831 insertions, 1203 deletions
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<ComponentConnector> hasVerticalAlignment = new HashSet<ComponentConnector>();
-
- /**
- * For bookkeeping. Used to determine if extra calculations are needed for
- * horizontal layout.
- */
- private HashSet<ComponentConnector> hasRelativeHeight = new HashSet<ComponentConnector>();
-
- /**
- * For bookkeeping. Used to determine if extra calculations are needed for
- * horizontal layout.
- */
- private HashSet<ComponentConnector> hasExpandRatio = new HashSet<ComponentConnector>();
-
- /**
- * For bookkeeping. Used in extra calculations for horizontal layout.
- */
- private HashSet<Element> needsMeasure = new HashSet<Element>();
-
- /**
- * For bookkeeping. Used in extra calculations for horizontal layout.
- */
- // private HashMap<Element, Integer> childElementHeight = new
- // HashMap<Element, Integer>();
-
- /**
- * For bookkeeping. Used in extra calculations for horizontal layout.
- */
- private HashMap<Element, Integer> childCaptionElementHeight = new HashMap<Element, Integer>();
-
- @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<String> 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<ComponentConnector> 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<ComponentConnector> hasVerticalAlignment = new HashSet<ComponentConnector>();
+
+ /**
+ * For bookkeeping. Used to determine if extra calculations are needed for
+ * horizontal layout.
+ */
+ private HashSet<ComponentConnector> hasRelativeHeight = new HashSet<ComponentConnector>();
+
+ /**
+ * For bookkeeping. Used to determine if extra calculations are needed for
+ * horizontal layout.
+ */
+ private HashSet<ComponentConnector> hasExpandRatio = new HashSet<ComponentConnector>();
+
+ /**
+ * For bookkeeping. Used in extra calculations for horizontal layout.
+ */
+ private HashSet<Element> needsMeasure = new HashSet<Element>();
+
+ /**
+ * For bookkeeping. Used in extra calculations for horizontal layout.
+ */
+ private HashMap<Element, Integer> childCaptionElementHeight = new HashMap<Element, Integer>();
+
+ /*
+ * (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<String> 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<ComponentConnector> 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<ComponentConnector> 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<Widget, VLayoutSlot> widgetToSlot = new HashMap<Widget, VLayoutSlot>();
-
- 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
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<Widget, Slot> widgetToSlot = new HashMap<Widget, Slot>();
+ 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<String> 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();