diff options
Diffstat (limited to 'client/src/com')
-rw-r--r-- | client/src/com/vaadin/client/ui/VFormLayout.java | 2 | ||||
-rw-r--r-- | client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java | 145 |
2 files changed, 145 insertions, 2 deletions
diff --git a/client/src/com/vaadin/client/ui/VFormLayout.java b/client/src/com/vaadin/client/ui/VFormLayout.java index bcbb3ebf7b..3719688f2b 100644 --- a/client/src/com/vaadin/client/ui/VFormLayout.java +++ b/client/src/com/vaadin/client/ui/VFormLayout.java @@ -86,7 +86,7 @@ public class VFormLayout extends SimplePanel { private static final int COLUMN_CAPTION = 0; private static final int COLUMN_ERRORFLAG = 1; - private static final int COLUMN_WIDGET = 2; + public static final int COLUMN_WIDGET = 2; private HashMap<Widget, Caption> widgetToCaption = new HashMap<Widget, Caption>(); private HashMap<Widget, ErrorFlag> widgetToError = new HashMap<Widget, ErrorFlag>(); diff --git a/client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java b/client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java index 9517619cf3..febbb5d6a2 100644 --- a/client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java @@ -15,26 +15,124 @@ */ package com.vaadin.client.ui.formlayout; +import java.util.HashMap; +import java.util.Map; + import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ComponentConnector; import com.vaadin.client.ConnectorHierarchyChangeEvent; +import com.vaadin.client.LayoutManager; import com.vaadin.client.TooltipInfo; import com.vaadin.client.WidgetUtil; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.ui.AbstractFieldConnector; import com.vaadin.client.ui.AbstractLayoutConnector; +import com.vaadin.client.ui.PostLayoutListener; import com.vaadin.client.ui.VFormLayout; import com.vaadin.client.ui.VFormLayout.Caption; import com.vaadin.client.ui.VFormLayout.ErrorFlag; import com.vaadin.client.ui.VFormLayout.VFormLayoutTable; +import com.vaadin.client.ui.layout.ElementResizeEvent; +import com.vaadin.client.ui.layout.ElementResizeListener; import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutState; import com.vaadin.ui.FormLayout; @Connect(FormLayout.class) -public class FormLayoutConnector extends AbstractLayoutConnector { +public class FormLayoutConnector extends AbstractLayoutConnector implements + PostLayoutListener { + + private Map<ComponentConnector, String> oldMaxWidths = null; + + private static final ElementResizeListener dummyFirstCellResizeListener = new ElementResizeListener() { + @Override + public void onElementResize(ElementResizeEvent e) { + // Ignore event, listener added just to make measurements available + } + }; + + // Detects situations when there's something inside the FormLayout that + // prevents it from shrinking + private ElementResizeListener resizeListener = new ElementResizeListener() { + @Override + public void onElementResize(ElementResizeEvent e) { + LayoutManager layoutManager = getLayoutManager(); + double tableWidth = layoutManager + .getOuterWidthDouble(getWidget().table.getElement()); + double ownWidth = layoutManager.getInnerWidthDouble(getWidget() + .getElement()); + if (ownWidth < tableWidth) { + // Something inside the table prevents it from shrinking, + // temporarily force column widths + double excessWidth = tableWidth - ownWidth; + + // All td elements in the component column have the same width, + // so we only need to check the width of the first one to know + // how wide the column is. + Element firstComponentTd = findFirstComponentTd(); + if (firstComponentTd == null) { + // Can't do anything if there are no rows + return; + } + + double componentColWidth = layoutManager + .getOuterWidthDouble(firstComponentTd); + + if (componentColWidth == -1) { + // Didn't get a proper width reading, best to not touch + // anything + return; + } + + // Restrict content td width + // Round down to prevent interactions with fractional sizes of + // other columns + int targetWidth = (int) Math.floor(componentColWidth + - excessWidth); + + // Target might be negative if captions are wider than the total + // available width + targetWidth = Math.max(0, targetWidth); + + if (oldMaxWidths == null) { + oldMaxWidths = new HashMap<ComponentConnector, String>(); + } + + for (ComponentConnector child : getChildComponents()) { + Element childElement = child.getWidget().getElement(); + if (!oldMaxWidths.containsKey(child)) { + oldMaxWidths.put(child, + childElement.getPropertyString("maxWidth")); + } + childElement.getStyle().setPropertyPx("maxWidth", + targetWidth); + layoutManager.reportOuterWidth(child, targetWidth); + } + } + } + }; + + @Override + protected void init() { + super.init(); + getLayoutManager().addElementResizeListener( + getWidget().table.getElement(), resizeListener); + getLayoutManager().addElementResizeListener(getWidget().getElement(), + resizeListener); + addComponentCellListener(); + } + + @Override + public void onUnregister() { + getLayoutManager().removeElementResizeListener( + getWidget().table.getElement(), resizeListener); + getLayoutManager().removeElementResizeListener( + getWidget().getElement(), resizeListener); + removeComponentCellListener(); + super.onUnregister(); + } @Override public AbstractOrderedLayoutState getState() { @@ -57,6 +155,8 @@ public class FormLayoutConnector extends AbstractLayoutConnector { VFormLayout formLayout = getWidget(); VFormLayoutTable formLayoutTable = getWidget().table; + removeComponentCellListener(); + int childId = 0; formLayoutTable.setRowCount(getChildComponents().size()); @@ -87,6 +187,33 @@ public class FormLayoutConnector extends AbstractLayoutConnector { formLayoutTable.cleanReferences(oldChild.getWidget()); } + addComponentCellListener(); + } + + private void addComponentCellListener() { + Element td = findFirstComponentTd(); + if (td != null) { + getLayoutManager().addElementResizeListener(td, + dummyFirstCellResizeListener); + } + } + + private void removeComponentCellListener() { + Element td = findFirstComponentTd(); + if (td != null) { + getLayoutManager().removeElementResizeListener(td, + dummyFirstCellResizeListener); + } + } + + private Element findFirstComponentTd() { + VFormLayoutTable table = getWidget().table; + if (table.getRowCount() == 0) { + return null; + } else { + return table.getCellFormatter().getElement(0, + VFormLayoutTable.COLUMN_WIDGET); + } } @Override @@ -148,4 +275,20 @@ public class FormLayoutConnector extends AbstractLayoutConnector { return true; } + @Override + public void postLayout() { + if (oldMaxWidths != null) { + for (ComponentConnector child : getChildComponents()) { + Element childNode = child.getWidget().getElement(); + String oldValue = oldMaxWidths.get(child); + if (oldValue == null) { + childNode.getStyle().clearProperty("maxWidth"); + } else { + childNode.getStyle().setProperty("maxWidth", oldValue); + } + } + oldMaxWidths = null; + } + } + } |