From ff9b8ceb3a15fb7e931f8d49acb2934ed08ffef2 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 2 Dec 2008 08:57:47 +0000 Subject: [PATCH] Fix for #2254 - Form size problems svn changeset:6060/svn branch:trunk --- .../toolkit/terminal/gwt/client/Util.java | 34 ++- .../toolkit/terminal/gwt/client/ui/IForm.java | 33 ++- .../terminal/gwt/client/ui/IFormLayout.java | 261 ++++++++++++------ 3 files changed, 232 insertions(+), 96 deletions(-) diff --git a/src/com/itmill/toolkit/terminal/gwt/client/Util.java b/src/com/itmill/toolkit/terminal/gwt/client/Util.java index 8f54716578..cd446bb59a 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/Util.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/Util.java @@ -6,6 +6,7 @@ package com.itmill.toolkit.terminal.gwt.client; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -14,6 +15,7 @@ import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; import com.itmill.toolkit.terminal.gwt.client.RenderInformation.FloatSize; @@ -46,8 +48,8 @@ public class Util { Map> childWidgets = new HashMap>(); for (Widget widget : widgets) { - // ApplicationConnection.getConsole().log( - // "Widget " + Util.getSimpleName(widget) + " size updated"); + ApplicationConnection.getConsole().log( + "Widget " + Util.getSimpleName(widget) + " size updated"); Widget parent = widget.getParent(); while (parent != null && !(parent instanceof Container)) { parent = parent.getParent(); @@ -500,4 +502,32 @@ public class Util { } } + public static boolean equals(Object a, Object b) { + if (a == null) { + return b == null; + } + + return a.equals(b); + } + + public static void updateRelativeChildrenAndSendSizeUpdateEvent( + ApplicationConnection client, HasWidgets container) { + /* + * Relative sized children must be updated first so the component has + * the correct outer dimensions when signaling a size change to the + * parent. + */ + Iterator childIterator = container.iterator(); + while (childIterator.hasNext()) { + Widget w = childIterator.next(); + // alert("Update relative size for " + getSimpleName(w)); + client.handleComponentRelativeSize(w); + } + + // alert("abc"); + HashSet widgets = new HashSet(); + widgets.add((Widget) container); + Util.componentSizeUpdated(widgets); + } + } diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IForm.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IForm.java index 1f4025fe3f..23193f5d1d 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IForm.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IForm.java @@ -12,19 +12,18 @@ import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.Widget; import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection; import com.itmill.toolkit.terminal.gwt.client.Container; -import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener; import com.itmill.toolkit.terminal.gwt.client.IErrorMessage; import com.itmill.toolkit.terminal.gwt.client.Paintable; import com.itmill.toolkit.terminal.gwt.client.RenderInformation; import com.itmill.toolkit.terminal.gwt.client.RenderSpace; import com.itmill.toolkit.terminal.gwt.client.UIDL; +import com.itmill.toolkit.terminal.gwt.client.Util; -public class IForm extends ComplexPanel implements Container, - ContainerResizedListener { +public class IForm extends ComplexPanel implements Container { - private String height; + private String height = ""; - private String width; + private String width = ""; public static final String CLASSNAME = "i-form"; @@ -122,7 +121,7 @@ public class IForm extends ComplexPanel implements Container, DOM.setInnerHTML(desc, ""); } - iLayout(); + updateSize(); // TODO Check if this is needed client.runDescendentsLayout(this); @@ -161,7 +160,7 @@ public class IForm extends ComplexPanel implements Container, } } - public void iLayout() { + public void updateSize() { renderInformation.updateSize(getElement()); @@ -184,7 +183,9 @@ public class IForm extends ComplexPanel implements Container, hPixels -= desc.getOffsetHeight(); } - return new RenderSpace(fieldContainer.getOffsetWidth(), 0); + + return new RenderSpace(renderInformation.getContentAreaSize() + .getWidth(), hPixels); } else if (child == footer) { return new RenderSpace(footerContainer.getOffsetWidth(), 0); } else { @@ -240,14 +241,30 @@ public class IForm extends ComplexPanel implements Container, @Override public void setHeight(String height) { + if (this.height.equals(height)) { + return; + } + this.height = height; super.setHeight(height); + updateSize(); } @Override public void setWidth(String width) { + if (Util.equals(this.width, width)) { + return; + } + this.width = width; super.setWidth(width); + + updateSize(); + + if (height.equals("")) { + // Width might affect height + Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this); + } } } diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IFormLayout.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IFormLayout.java index 9504edcae7..05b42e89cf 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IFormLayout.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IFormLayout.java @@ -13,6 +13,7 @@ import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection; import com.itmill.toolkit.terminal.gwt.client.Container; @@ -25,122 +26,174 @@ import com.itmill.toolkit.terminal.gwt.client.Util; /** * Two col Layout that places caption on left col and field on right col */ -public class IFormLayout extends FlexTable implements Container { +public class IFormLayout extends SimplePanel implements Container { private final static String CLASSNAME = "i-formlayout"; - HashMap componentToCaption = new HashMap(); private ApplicationConnection client; - private HashMap componentToError = new HashMap(); + private IFormLayoutTable table; + + private String width = ""; + private String height = ""; public IFormLayout() { super(); setStylePrimaryName(CLASSNAME); - DOM.setElementProperty(getElement(), "cellPadding", "0"); - DOM.setElementProperty(getElement(), "cellSpacing", "0"); + table = new IFormLayoutTable(); + setWidget(table); } - public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - this.client = client; + public class IFormLayoutTable extends FlexTable { - if (client.updateComponent(this, uidl, true)) { - return; + private HashMap componentToCaption = new HashMap(); + private HashMap componentToError = new HashMap(); + + public IFormLayoutTable() { + DOM.setElementProperty(getElement(), "cellPadding", "0"); + DOM.setElementProperty(getElement(), "cellSpacing", "0"); } - final MarginInfo margins = new MarginInfo(uidl - .getIntAttribute("margins")); - - Element margin = getElement(); - setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_TOP, - margins.hasTop()); - setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_RIGHT, - margins.hasRight()); - setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_BOTTOM, - margins.hasBottom()); - setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_LEFT, - margins.hasLeft()); - - setStyleName(margin, CLASSNAME + "-" + "spacing", uidl - .hasAttribute("spacing")); - - int i = 0; - for (final Iterator it = uidl.getChildIterator(); it.hasNext(); i++) { - prepareCell(i, 1); - final UIDL childUidl = (UIDL) it.next(); - final Paintable p = client.getPaintable(childUidl); - Caption caption = (Caption) componentToCaption.get(p); - if (caption == null) { - caption = new Caption(p, client); - componentToCaption.put(p, caption); + public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { + final MarginInfo margins = new MarginInfo(uidl + .getIntAttribute("margins")); + + Element margin = getElement(); + setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_TOP, + margins.hasTop()); + setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_RIGHT, + margins.hasRight()); + setStyleName(margin, + CLASSNAME + "-" + StyleConstants.MARGIN_BOTTOM, margins + .hasBottom()); + setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_LEFT, + margins.hasLeft()); + + setStyleName(margin, CLASSNAME + "-" + "spacing", uidl + .hasAttribute("spacing")); + + int i = 0; + for (final Iterator it = uidl.getChildIterator(); it.hasNext(); i++) { + prepareCell(i, 1); + final UIDL childUidl = (UIDL) it.next(); + final Paintable p = client.getPaintable(childUidl); + Caption caption = (Caption) componentToCaption.get(p); + if (caption == null) { + caption = new Caption(p, client); + componentToCaption.put(p, caption); + } + ErrorFlag error = (ErrorFlag) componentToError.get(p); + if (error == null) { + error = new ErrorFlag(); + componentToError.put(p, error); + } + prepareCell(i, 2); + final Paintable oldComponent = (Paintable) getWidget(i, 2); + if (oldComponent == null) { + setWidget(i, 2, (Widget) p); + } else if (oldComponent != p) { + client.unregisterPaintable(oldComponent); + setWidget(i, 2, (Widget) p); + } + getCellFormatter().setStyleName(i, 2, + CLASSNAME + "-contentcell"); + getCellFormatter().setStyleName(i, 0, + CLASSNAME + "-captioncell"); + setWidget(i, 0, caption); + + getCellFormatter().setStyleName(i, 1, CLASSNAME + "-errorcell"); + setWidget(i, 1, error); + + p.updateFromUIDL(childUidl, client); + + String rowstyles = CLASSNAME + "-row"; + if (i == 0) { + rowstyles += " " + CLASSNAME + "-firstrow"; + } + if (!it.hasNext()) { + rowstyles += " " + CLASSNAME + "-lastrow"; + } + + getRowFormatter().setStyleName(i, rowstyles); + } - ErrorFlag error = (ErrorFlag) componentToError.get(p); - if (error == null) { - error = new ErrorFlag(); - componentToError.put(p, error); + + while (getRowCount() > i) { + final Paintable p = (Paintable) getWidget(i, 2); + client.unregisterPaintable(p); + componentToCaption.remove(p); + removeRow(i); } - prepareCell(i, 2); - final Paintable oldComponent = (Paintable) getWidget(i, 2); - if (oldComponent == null) { - setWidget(i, 2, (Widget) p); - } else if (oldComponent != p) { - client.unregisterPaintable(oldComponent); - setWidget(i, 2, (Widget) p); + + } + + public void replaceChildComponent(Widget oldComponent, + Widget newComponent) { + int i; + for (i = 0; i < getRowCount(); i++) { + if (oldComponent == getWidget(i, 1)) { + final Caption newCap = new Caption( + (Paintable) newComponent, client); + setWidget(i, 0, newCap); + setWidget(i, 1, newComponent); + break; + } } - getCellFormatter().setStyleName(i, 2, CLASSNAME + "-contentcell"); - getCellFormatter().setStyleName(i, 0, CLASSNAME + "-captioncell"); - setWidget(i, 0, caption); - getCellFormatter().setStyleName(i, 1, CLASSNAME + "-errorcell"); - setWidget(i, 1, error); + } - p.updateFromUIDL(childUidl, client); + public boolean hasChildComponent(Widget component) { + return componentToCaption.containsKey(component); + } - String rowstyles = CLASSNAME + "-row"; - if (i == 0) { - rowstyles += " " + CLASSNAME + "-firstrow"; + public void updateCaption(Paintable component, UIDL uidl) { + final Caption c = (Caption) componentToCaption.get(component); + if (c != null) { + c.updateCaption(uidl); } - if (!it.hasNext()) { - rowstyles += " " + CLASSNAME + "-lastrow"; + final ErrorFlag e = (ErrorFlag) componentToError.get(component); + if (e != null) { + e.updateFromUIDL(uidl, component); } - getRowFormatter().setStyleName(i, rowstyles); + } + + public int getAllocatedWidth(Widget child, int availableWidth) { + Caption caption = (Caption) componentToCaption.get(child); + ErrorFlag error = (ErrorFlag) componentToError.get(child); + int width = availableWidth; + if (caption != null) { + width -= DOM.getParent(caption.getElement()).getOffsetWidth(); + } + if (error != null) { + width -= DOM.getParent(error.getElement()).getOffsetWidth(); + } + + return width; } - while (getRowCount() > i) { - final Paintable p = (Paintable) getWidget(i, 2); - client.unregisterPaintable(p); - componentToCaption.remove(p); - removeRow(i); + } + + public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { + this.client = client; + + if (client.updateComponent(this, uidl, true)) { + return; } + + table.updateFromUIDL(uidl, client); } public boolean hasChildComponent(Widget component) { - return componentToCaption.containsKey(component); + return table.hasChildComponent(component); } public void replaceChildComponent(Widget oldComponent, Widget newComponent) { - int i; - for (i = 0; i < getRowCount(); i++) { - if (oldComponent == getWidget(i, 1)) { - final Caption newCap = new Caption((Paintable) newComponent, - client); - setWidget(i, 0, newCap); - setWidget(i, 1, newComponent); - break; - } - } + table.replaceChildComponent(oldComponent, newComponent); } public void updateCaption(Paintable component, UIDL uidl) { - final Caption c = (Caption) componentToCaption.get(component); - if (c != null) { - c.updateCaption(uidl); - } - final ErrorFlag e = (ErrorFlag) componentToError.get(component); - if (e != null) { - e.updateFromUIDL(uidl, component); - } + table.updateCaption(component, uidl); } public class Caption extends HTML { @@ -305,14 +358,50 @@ public class IFormLayout extends FlexTable implements Container { } public boolean requestLayout(Set child) { - // TODO Auto-generated method stub - return false; + if (height.equals("") || width.equals("")) { + // A dynamic size might change due to children changes + return false; + } + + return true; } public RenderSpace getAllocatedSpace(Widget child) { - com.google.gwt.dom.client.Element pe = child.getElement() - .getParentElement(); - return new RenderSpace(pe.getOffsetWidth(), pe.getOffsetHeight(), false); + int width = 0; + int height = 0; + + if (!this.width.equals("")) { + int availableWidth = getOffsetWidth(); + width = table.getAllocatedWidth(child, availableWidth); + } + + return new RenderSpace(width, height, false); + } + + @Override + public void setHeight(String height) { + if (this.height.equals(height)) { + return; + } + + this.height = height; + super.setHeight(height); + } + + @Override + public void setWidth(String width) { + if (this.width.equals(width)) { + return; + } + + this.width = width; + super.setWidth(width); + + if (height.equals("")) { + // Width might affect height + Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this); + } + } } -- 2.39.5