summaryrefslogtreecommitdiffstats
path: root/client/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/com')
-rw-r--r--client/src/com/vaadin/client/ui/VFormLayout.java2
-rw-r--r--client/src/com/vaadin/client/ui/formlayout/FormLayoutConnector.java145
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;
+ }
+ }
+
}