summaryrefslogtreecommitdiffstats
path: root/client/src/com/vaadin
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2015-08-28 21:47:26 +0300
committerTeemu Suo-Anttila <teemusa@vaadin.com>2015-11-05 13:06:42 +0200
commit8018ec184131d63911ce9fe8f8a398cab029ca82 (patch)
treefa66233cb684377e94b7b67497fe34ef6f3e92a6 /client/src/com/vaadin
parent6da674f2dfae2e2bc5de22b89a0b7e7648d52ed7 (diff)
downloadvaadin-framework-7.5.9.tar.gz
vaadin-framework-7.5.9.zip
Force FormLayout children to shrink with the layout (#11154)7.5.9
The <table> used by the FormLayout doesn't reduce its size if any child component has locked its own size (which is the case with e.g. Table and some other components doing explicit pixel calculations). To work around this, we need to detect the situation, force the <table> to reduce its width by temporarily assigning explicit widths to the cells and then remove the forced size after all children have adjusted. Change-Id: Iacef62979acf24c869a5cbeb82efb0c1e537ec95
Diffstat (limited to 'client/src/com/vaadin')
-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;
+ }
+ }
+
}