Browse Source

Added method for a component to notify its parent container when its size change


svn changeset:5453/svn branch:trunk
tags/6.7.0.beta1
Artur Signell 15 years ago
parent
commit
9db9cd325d

+ 16
- 0
src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java View File

@@ -6,7 +6,9 @@ package com.itmill.toolkit.terminal.gwt.client;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import com.google.gwt.core.client.GWT;
@@ -503,6 +505,9 @@ public class ApplicationConnection {
// Process changes
final JSONArray changes = (JSONArray) ((JSONObject) json)
.get("changes");

Set<Widget> sizeUpdatedWidgets = new HashSet<Widget>();

for (int i = 0; i < changes.size(); i++) {
try {
final UIDL change = new UIDL((JSONArray) changes.get(i));
@@ -517,7 +522,16 @@ public class ApplicationConnection {
final UIDL uidl = change.getChildUIDL(0);
final Paintable paintable = getPaintable(uidl.getId());
if (paintable != null) {
Widget widget = (Widget) paintable;
int w = widget.getOffsetWidth();
int h = widget.getOffsetHeight();

paintable.updateFromUIDL(uidl, this);

if (w != widget.getOffsetWidth()
|| h != widget.getOffsetHeight()) {
sizeUpdatedWidgets.add((Widget) paintable);
}
} else {
if (!uidl.getTag().equals("window")) {
ClientExceptionHandler
@@ -534,6 +548,8 @@ public class ApplicationConnection {
}
}

Util.componentSizeUpdated(sizeUpdatedWidgets);

if (meta != null) {
if (meta.containsKey("focus")) {
final String focusPid = meta.get("focus").isString()

+ 8
- 0
src/com/itmill/toolkit/terminal/gwt/client/Container.java View File

@@ -49,4 +49,12 @@ public interface Container extends Paintable {
*/
void updateCaption(Paintable component, UIDL uidl);

/**
* Called when a child components size has been updated in the rendering
* phase.
*
* @return true if the size of the Container remains the same, false if the
* event need to be propagated to the Containers parent
*/
boolean childComponentSizesUpdated();
}

+ 6
- 0
src/com/itmill/toolkit/terminal/gwt/client/ContainerResizedListener.java View File

@@ -21,6 +21,12 @@ public interface ContainerResizedListener {
* these numbers. If the parent container does not know (has not calculated)
* or cannot produce (undefined dimensions) one of these numbers -1 is
* passed.
*
* Note that these numbers should not be considered the maximum size for the
* widget if the layout has undefined dimension. In that case the currently
* allocated space is passed (eg. OrderedLayout with undefined width might
* pass availableWidth 100 if the widest component in the layout is 100 but
* it will still stretch if another 200 pixel wide component is rendered)
*/
public void iLayout(int availableWidth, int availableHeight);
}

+ 39
- 0
src/com/itmill/toolkit/terminal/gwt/client/Util.java View File

@@ -4,7 +4,9 @@

package com.itmill.toolkit.terminal.gwt.client;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
@@ -37,6 +39,43 @@ public class Util {
el.oncontextmenu = null;
}-*/;

/**
* Called when the size of one or more widgets have changed during
* rendering. Finds parent container and notifies them of the size change.
*
* @param widgets
*/
public static void componentSizeUpdated(Set<Widget> widgets) {
if (widgets.isEmpty()) {
return;
}

Set<Container> parents = new HashSet<Container>();

for (Widget widget : widgets) {
/* ApplicationConnection.getConsole().log(
"Size changed for widget: "
+ widget.toString().split(">")[0]);
*/
Widget parent = widget.getParent();
while (parent != null && !(parent instanceof Container)) {
parent = parent.getParent();
}
if (parent != null) {
parents.add((Container) parent);
}
}

Set<Widget> parentChanges = new HashSet<Widget>();
for (Container parent : parents) {
if (!parent.childComponentSizesUpdated()) {
parentChanges.add((Widget) parent);
}
}

componentSizeUpdated(parentChanges);
}

/**
* Traverses recursively ancestors until ContainerResizedListener child
* widget is found. They will delegate it futher if needed.

+ 5
- 0
src/com/itmill/toolkit/terminal/gwt/client/ui/IAccordion.java View File

@@ -299,4 +299,9 @@ public class IAccordion extends ITabsheetBase implements
}
}

public boolean childComponentSizesUpdated() {
// TODO Auto-generated method stub
return false;
}

}

+ 5
- 0
src/com/itmill/toolkit/terminal/gwt/client/ui/ICustomComponent.java View File

@@ -61,4 +61,9 @@ public class ICustomComponent extends SimplePanel implements Container {
// TODO custom component could handle its composition roots caption
}

public boolean childComponentSizesUpdated() {
// TODO Auto-generated method stub
return false;
}

}

+ 6
- 0
src/com/itmill/toolkit/terminal/gwt/client/ui/ICustomLayout.java View File

@@ -476,4 +476,10 @@ public class ICustomLayout extends ComplexPanel implements Paintable,
return false;
}
}-*/;

public boolean childComponentSizesUpdated() {
// TODO Auto-generated method stub
return false;
}

}

+ 6
- 0
src/com/itmill/toolkit/terminal/gwt/client/ui/IExpandLayout.java View File

@@ -768,4 +768,10 @@ public class IExpandLayout extends ComplexPanel implements
}
rendering = false;
}

public boolean childComponentSizesUpdated() {
// TODO Auto-generated method stub
return false;
}

}

+ 6
- 0
src/com/itmill/toolkit/terminal/gwt/client/ui/IFormLayout.java View File

@@ -301,4 +301,10 @@ public class IFormLayout extends FlexTable implements Container {
}

}

public boolean childComponentSizesUpdated() {
// TODO Auto-generated method stub
return false;
}

}

+ 10
- 0
src/com/itmill/toolkit/terminal/gwt/client/ui/IGridLayout.java View File

@@ -286,6 +286,11 @@ public class IGridLayout extends SimplePanel implements Paintable, Container,
wrapper.updateCaption(uidl);
}

public boolean childComponentSizesUpdated() {
// TODO Auto-generated method stub
return false;
}

}

private void iLayout() {
@@ -312,4 +317,9 @@ public class IGridLayout extends SimplePanel implements Paintable, Container,
Util.runDescendentsLayout(this);
}

public boolean childComponentSizesUpdated() {
// TODO Auto-generated method stub
return false;
}

}

+ 128
- 29
src/com/itmill/toolkit/terminal/gwt/client/ui/IOrderedLayout.java View File

@@ -320,6 +320,10 @@ public class IOrderedLayout extends Panel implements Container,
*/
private boolean childLayoutsHaveChanged = false;

private int renderedHeight;

private int renderedWidth;

/**
* Construct the DOM of the orderder layout.
*
@@ -535,7 +539,7 @@ public class IOrderedLayout extends Panel implements Container,
handleAlignmentsSpacingAndMargins(uidl);

// Reset sizes for the children
updateChildSizes();
updateChildSizes(-1, -1);

// Paint children
for (int i = 0; i < childsToPaint.size(); i++) {
@@ -550,6 +554,11 @@ public class IOrderedLayout extends Panel implements Container,
Util.runDescendentsLayout(this);
childLayoutsHaveChanged = false;
}

/* Store the rendered size so we later can see if it has changed */
renderedWidth = root.getOffsetWidth();
renderedHeight = root.getOffsetHeight();

}

private void updateMarginAndSpacingSizesFromCSS(UIDL uidl) {
@@ -657,7 +666,7 @@ public class IOrderedLayout extends Panel implements Container,
}

/** Recalculate and apply the space given for each child in this layout. */
private void updateChildSizes() {
private void updateChildSizes(int renderedWidth, int renderedHeight) {

int numChild = childWidgets.size();
int childHeightTotal = -1;
@@ -672,7 +681,7 @@ public class IOrderedLayout extends Panel implements Container,
if (tableMode) {

// If we know explicitly set pixel-size, use that
if (height != null && height.endsWith("px")) {
if (height.endsWith("px")) {
try {
childHeightTotal = Integer.parseInt(height.substring(0,
height.length() - 2));
@@ -686,9 +695,13 @@ public class IOrderedLayout extends Panel implements Container,
// In case of invalid number, try to measure the size;
childHeightTotal = rootOffsetMeasure("offsetHeight");
}
}
// If not, try to measure the size
else {
} else if (height.endsWith("%") && renderedHeight >= 0) {
// If we have a relative height and know how large we are we
// can
// simply use that
childWidthTotal = renderedHeight;
} else {
// If not pixels, nor percentage, try to measure the size
childHeightTotal = rootOffsetMeasure("offsetHeight");
}

@@ -718,7 +731,7 @@ public class IOrderedLayout extends Panel implements Container,

// Calculate the space for fixed contents minus marginals
// If we know explicitly set pixel-size, use that
if (width != null && width.endsWith("px")) {
if (width.endsWith("px")) {
try {
childWidthTotal = Integer.parseInt(width.substring(0, width
.length() - 2));
@@ -733,9 +746,12 @@ public class IOrderedLayout extends Panel implements Container,
// In case of invalid number, try to measure the size;
childWidthTotal = rootOffsetMeasure("offsetWidth");
}
}
// If not, try to measure the size
else {
} else if (width.endsWith("%") && renderedWidth >= 0) {
// If we have a relative width and know how large we are we can
// simply use that
childWidthTotal = renderedWidth;
} else {
// If not pixels, nor percentage, try to measure the size
childWidthTotal = rootOffsetMeasure("offsetWidth");
}

@@ -872,6 +888,8 @@ public class IOrderedLayout extends Panel implements Container,
*/
int lastForcedPixelWidth = -1;

int horizontalPadding = 0, verticalPadding = 0;

/** Widget Wrapper root element */
Element wrapperElement;

@@ -1252,31 +1270,72 @@ public class IOrderedLayout extends Panel implements Container,

final Element e = getElementWrappingWidgetAndCaption();

int paddingLeft = 0, paddingRight = 0, paddingTop = 0, paddingBottom = 0;

if (orientationMode == ORIENTATION_HORIZONTAL) {
DOM.setStyleAttribute(e, "paddingLeft", first ? (margins
.hasLeft() ? marginLeft + "px" : "0")
: (hasComponentSpacing ? hSpacing + "px" : "0"));
DOM.setStyleAttribute(e, "paddingRight", last ? (margins
.hasRight() ? marginRight + "px" : "0") : "");
DOM.setStyleAttribute(e, "paddingTop",
margins.hasTop() ? marginTop + "px" : "");
DOM.setStyleAttribute(e, "paddingBottom",
margins.hasBottom() ? marginBottom + "px" : "");
if (first) {
if (margins.hasLeft()) {
paddingLeft = marginLeft;
}
} else if (hasComponentSpacing) {
paddingLeft = hSpacing;
}

if (last) {
if (margins.hasRight()) {
paddingRight = marginRight;
}
}

if (margins.hasTop()) {
paddingTop = marginTop;
}
if (margins.hasBottom()) {
paddingBottom = marginBottom;
}

} else {
DOM.setStyleAttribute(e, "paddingLeft",
margins.hasLeft() ? marginLeft + "px" : "0");
DOM.setStyleAttribute(e, "paddingRight",
margins.hasRight() ? marginRight + "px" : "0");
DOM.setStyleAttribute(e, "paddingTop", first ? (margins
.hasTop() ? marginTop + "px" : "")
: (hasComponentSpacing ? vSpacing + "px" : "0"));
DOM.setStyleAttribute(e, "paddingBottom", last
&& margins.hasBottom() ? marginBottom + "px" : "");
if (margins.hasLeft()) {
paddingLeft = marginLeft;
}
if (margins.hasRight()) {
paddingRight = marginRight;
}

if (first) {
if (margins.hasTop()) {
paddingTop = marginTop;
}
} else if (hasComponentSpacing) {
paddingTop = vSpacing;
}
if (last && margins.hasBottom()) {
paddingBottom = marginBottom;
}

}

horizontalPadding = paddingLeft + paddingRight;
verticalPadding = paddingTop + paddingBottom;

DOM.setStyleAttribute(e, "paddingLeft", paddingLeft + "px");
DOM.setStyleAttribute(e, "paddingRight", paddingRight + "px");

DOM.setStyleAttribute(e, "paddingTop", paddingTop + "px");
DOM.setStyleAttribute(e, "paddingBottom", paddingBottom + "px");
}

public int getAllocatedHeight() {
if (lastForcedPixelHeight == -1) {
if (height == null) {
/*
* We have no height specified so return the space allocated
* by components so far
*/
return getElementWrappingClipperDiv().getOffsetHeight()
- horizontalPadding;
}

return -1;
}

@@ -1289,6 +1348,15 @@ public class IOrderedLayout extends Panel implements Container,
}

public int getAllocatedWidth() {
if (width == null) {
/*
* We have no width specified so return the space allocated by
* components so far
*/
return getElementWrappingClipperDiv().getOffsetWidth()
- horizontalPadding;
}

return lastForcedPixelWidth;
}
}
@@ -1451,7 +1519,7 @@ public class IOrderedLayout extends Panel implements Container,

/* documented at super */
public void iLayout(int availableWidth, int availableHeight) {
updateChildSizes();
updateChildSizes(availableWidth, availableHeight);
Util.runDescendentsLayout(this);
childLayoutsHaveChanged = false;
}
@@ -1475,4 +1543,35 @@ public class IOrderedLayout extends Panel implements Container,

return -1;
}

public boolean childComponentSizesUpdated() {
if (height != null && width != null) {
/*
* If the height and width has been specified for this layout the
* child components cannot make the size of the layout change
*/

return true;
}

int currentHeight = getElement().getOffsetHeight();
int currentWidth = getElement().getOffsetWidth();

if (currentHeight != renderedHeight || currentWidth != renderedWidth) {
/*
* Size has changed so we let the child components know about the
* new size.
*/
iLayout(-1, -1);
return false;
} else {
/*
* Size has not changed so we do not need to propagate the event
* further
*/
return true;
}

}

}

+ 10
- 5
src/com/itmill/toolkit/terminal/gwt/client/ui/IPopupView.java View File

@@ -171,10 +171,10 @@ public class IPopupView extends HTML implements Paintable {
}

public static native void nativeBlur(Element e) /*-{
if(e.focus) {
e.blur();
}
}-*/;
if(e.focus) {
e.blur();
}
}-*/;

private class CustomPopup extends IToolkitOverlay implements Container {

@@ -228,7 +228,7 @@ public class IPopupView extends HTML implements Paintable {
// Notify children that have used the keyboard
for (Iterator<Element> iterator = activeChildren.iterator(); iterator
.hasNext();) {
nativeBlur((Element) iterator.next());
nativeBlur(iterator.next());
}
activeChildren.clear();
remove(popupComponentWidget);
@@ -312,6 +312,11 @@ public class IPopupView extends HTML implements Paintable {
}
}

public boolean childComponentSizesUpdated() {
// TODO Auto-generated method stub
return false;
}

}// class CustomPopup

}// class IPopupView

+ 5
- 0
src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheet.java View File

@@ -478,4 +478,9 @@ public class ITabsheet extends ITabsheetBase implements
ICaption c = (ICaption) captions.get("" + i);
c.updateCaption(uidl);
}

public boolean childComponentSizesUpdated() {
// TODO Auto-generated method stub
return false;
}
}

+ 5
- 0
src/com/itmill/toolkit/terminal/gwt/client/ui/absolutegrid/ISizeableGridLayout.java View File

@@ -249,6 +249,11 @@ public class ISizeableGridLayout extends IAbsoluteGrid implements Paintable,
return marginPixels;
}

public boolean childComponentSizesUpdated() {
// TODO Auto-generated method stub
return false;
}

}

class MarginPixels {

Loading…
Cancel
Save