package com.vaadin.terminal.gwt.client;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
import com.google.gwt.core.client.JsArrayString;
-import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.Widget;
public class MeasureManager {
- public static final class MeasuredSize {
- private int width = -1;
- private int height = -1;
-
- private int[] paddings = new int[4];
- private int[] borders = new int[4];
- private int[] margins = new int[4];
-
- private final VPaintableWidget paintable;
-
- private boolean isDirty = true;
-
- private final Map<Element, int[]> dependencySizes = new HashMap<Element, int[]>();
-
- public MeasuredSize(VPaintableWidget paintable) {
- this.paintable = paintable;
- }
-
- public int getOuterHeight() {
- return height;
- }
-
- public int getOuterWidth() {
- return width;
- }
-
- private static int sumWidths(int[] sizes) {
- return sizes[1] + sizes[3];
- }
-
- private static int sumHeights(int[] sizes) {
- return sizes[0] + sizes[2];
- }
-
- public int getInnerHeight() {
- return height - sumHeights(margins) - sumHeights(borders)
- - sumHeights(paddings);
- }
-
- public int getInnerWidth() {
- return width - sumWidths(margins) - sumWidths(borders)
- - sumWidths(paddings);
- }
-
- public void setOuterHeight(int height) {
- if (this.height != height) {
- isDirty = true;
- this.height = height;
- }
- }
-
- public void setOuterWidth(int width) {
- if (this.width != width) {
- isDirty = true;
- this.width = width;
- }
- }
-
- public boolean isDirty() {
- return isDirty;
- }
-
- public void setDirty(boolean isDirty) {
- this.isDirty = isDirty;
- }
-
- public void registerDependency(Element element) {
- if (!dependencySizes.containsKey(element)) {
- dependencySizes.put(element, new int[] { -1, -1 });
- isDirty = true;
- }
- }
-
- public void deRegisterDependency(Element element) {
- dependencySizes.remove(element);
- }
-
- public int getDependencyOuterWidth(Element e) {
- return getDependencySize(e, 0);
- }
-
- public int getDependencyOuterHeight(Element e) {
- return getDependencySize(e, 1);
- }
-
- private int getDependencySize(Element e, int index) {
- int[] sizes = dependencySizes.get(e);
- if (sizes == null) {
- return -1;
- } else {
- return sizes[index];
- }
- }
-
- public int getBorderHeight() {
- return sumHeights(borders);
- }
-
- public int getBorderWidth() {
- return sumWidths(borders);
- }
-
- public int getPaddingHeight() {
- return sumHeights(paddings);
- }
-
- public int getPaddingWidth() {
- return sumWidths(paddings);
- }
-
- public int getMarginHeight() {
- return sumHeights(margins);
- }
-
- public int getMarginWidth() {
- return sumWidths(margins);
- }
-
- public int getMarginTop() {
- return margins[0];
- }
-
- public int getMarginRight() {
- return margins[1];
- }
-
- public int getMarginBottom() {
- return margins[2];
- }
-
- public int getMarginLeft() {
- return margins[3];
- }
-
- public int getBorderTop() {
- return margins[0];
- }
-
- public int getBorderRight() {
- return margins[1];
- }
-
- public int getBorderBottom() {
- return margins[2];
- }
-
- public int getBorderLeft() {
- return margins[3];
- }
-
- public int getPaddingTop() {
- return paddings[0];
- }
-
- public int getPaddingRight() {
- return paddings[1];
- }
-
- public int getPaddingBottom() {
- return paddings[2];
- }
-
- public int getPaddingLeft() {
- return paddings[3];
- }
-
- private void measure() {
- boolean changed = isDirty;
-
- Widget widget = paintable.getWidgetForPaintable();
- ComputedStyle computedStyle = new ComputedStyle(widget.getElement());
-
- int[] paddings = computedStyle.getPadding();
- if (!changed && !Arrays.equals(this.paddings, paddings)) {
- changed = true;
- this.paddings = paddings;
- }
-
- int[] margins = computedStyle.getMargin();
- if (!changed && !Arrays.equals(this.margins, margins)) {
- changed = true;
- this.margins = margins;
- }
-
- int[] borders = computedStyle.getBorder();
- if (!changed && !Arrays.equals(this.borders, borders)) {
- changed = true;
- this.borders = borders;
- }
-
- int offsetHeight = widget.getOffsetHeight();
- int marginHeight = sumHeights(margins);
- setOuterHeight(offsetHeight + marginHeight);
-
- int offsetWidth = widget.getOffsetWidth();
- int marginWidth = sumWidths(margins);
- setOuterWidth(offsetWidth + marginWidth);
-
- // int i = 0;
- for (Entry<Element, int[]> entry : dependencySizes.entrySet()) {
- Element element = entry.getKey();
- // int[] elementMargin = new ComputedStyle(element).getMargin();
- int[] sizes = entry.getValue();
-
- int elementWidth = element.getOffsetWidth();
- // elementWidth += elementMargin[1] + elementMargin[3];
- if (elementWidth != sizes[0]) {
- // System.out.println(paintable.getId() + " dependency " + i
- // + " width changed from " + sizes[0] + " to "
- // + elementWidth);
- sizes[0] = elementWidth;
- changed = true;
- }
-
- int elementHeight = element.getOffsetHeight();
- // Causes infinite loops as a negative margin based on the
- // measured height is currently used for captions
- // elementHeight += elementMargin[0] + elementMargin[1];
- if (elementHeight != sizes[1]) {
- // System.out.println(paintable.getId() + " dependency " + i
- // + " height changed from " + sizes[1] + " to "
- // + elementHeight);
- sizes[1] = elementHeight;
- changed = true;
- }
- // i++;
- }
-
- if (changed) {
- setDirty(true);
- }
- }
- }
-
public void doLayout(ApplicationConnection client) {
VPaintableMap paintableMap = client.getPaintableMap();
VPaintableWidget[] paintableWidgets = paintableMap
long passStart = System.currentTimeMillis();
passes++;
long measureStart = System.currentTimeMillis();
- FastStringSet changedSet = findChangedWidgets(paintableWidgets,
- paintableMap);
+ FastStringSet changedSet = findChangedWidgets(paintableWidgets);
JsArrayString changed = changedSet.dump();
long measureEnd = System.currentTimeMillis();
.getPaintable(changed.get(i));
VPaintableWidget parentPaintable = paintable.getParent();
if (parentPaintable instanceof CalculatingLayout) {
- affectedContainers
- .add(paintableMap.getPid(parentPaintable));
+ affectedContainers.add(parentPaintable.getId());
}
}
VConsole.log("Total layout time: " + (end - start) + "ms");
}
- private FastStringSet findChangedWidgets(
- VPaintableWidget[] paintableWidgets, VPaintableMap paintableMap) {
+ private FastStringSet findChangedWidgets(VPaintableWidget[] paintableWidgets) {
FastStringSet changed = FastStringSet.create();
for (VPaintableWidget paintableWidget : paintableWidgets) {
- MeasureManager.MeasuredSize measuredSize = paintableWidget
- .getMeasuredSize();
+ MeasuredSize measuredSize = paintableWidget.getMeasuredSize();
measuredSize.measure();
if (measuredSize.isDirty()) {
- changed.add(paintableMap.getPid(paintableWidget));
+ changed.add(paintableWidget.getId());
measuredSize.setDirty(false);
}
}
--- /dev/null
+package com.vaadin.terminal.gwt.client;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.user.client.ui.Widget;
+
+public final class MeasuredSize {
+ private int width = -1;
+ private int height = -1;
+
+ private int[] paddings = new int[4];
+ private int[] borders = new int[4];
+ private int[] margins = new int[4];
+
+ private final VPaintableWidget paintable;
+
+ private boolean isDirty = true;
+
+ private final Map<Element, int[]> dependencySizes = new HashMap<Element, int[]>();
+
+ public MeasuredSize(VPaintableWidget paintable) {
+ this.paintable = paintable;
+ }
+
+ public int getOuterHeight() {
+ return height;
+ }
+
+ public int getOuterWidth() {
+ return width;
+ }
+
+ private static int sumWidths(int[] sizes) {
+ return sizes[1] + sizes[3];
+ }
+
+ private static int sumHeights(int[] sizes) {
+ return sizes[0] + sizes[2];
+ }
+
+ public int getInnerHeight() {
+ return height - sumHeights(margins) - sumHeights(borders)
+ - sumHeights(paddings);
+ }
+
+ public int getInnerWidth() {
+ return width - sumWidths(margins) - sumWidths(borders)
+ - sumWidths(paddings);
+ }
+
+ public void setOuterHeight(int height) {
+ if (this.height != height) {
+ isDirty = true;
+ this.height = height;
+ }
+ }
+
+ public void setOuterWidth(int width) {
+ if (this.width != width) {
+ isDirty = true;
+ this.width = width;
+ }
+ }
+
+ public boolean isDirty() {
+ return isDirty;
+ }
+
+ public void setDirty(boolean isDirty) {
+ this.isDirty = isDirty;
+ }
+
+ public void registerDependency(Element element) {
+ if (!dependencySizes.containsKey(element)) {
+ dependencySizes.put(element, new int[] { -1, -1 });
+ isDirty = true;
+ }
+ }
+
+ public void deRegisterDependency(Element element) {
+ dependencySizes.remove(element);
+ }
+
+ public int getDependencyOuterWidth(Element e) {
+ return getDependencySize(e, 0);
+ }
+
+ public int getDependencyOuterHeight(Element e) {
+ return getDependencySize(e, 1);
+ }
+
+ private int getDependencySize(Element e, int index) {
+ int[] sizes = dependencySizes.get(e);
+ if (sizes == null) {
+ return -1;
+ } else {
+ return sizes[index];
+ }
+ }
+
+ public int getBorderHeight() {
+ return sumHeights(borders);
+ }
+
+ public int getBorderWidth() {
+ return sumWidths(borders);
+ }
+
+ public int getPaddingHeight() {
+ return sumHeights(paddings);
+ }
+
+ public int getPaddingWidth() {
+ return sumWidths(paddings);
+ }
+
+ public int getMarginHeight() {
+ return sumHeights(margins);
+ }
+
+ public int getMarginWidth() {
+ return sumWidths(margins);
+ }
+
+ public int getMarginTop() {
+ return margins[0];
+ }
+
+ public int getMarginRight() {
+ return margins[1];
+ }
+
+ public int getMarginBottom() {
+ return margins[2];
+ }
+
+ public int getMarginLeft() {
+ return margins[3];
+ }
+
+ public int getBorderTop() {
+ return margins[0];
+ }
+
+ public int getBorderRight() {
+ return margins[1];
+ }
+
+ public int getBorderBottom() {
+ return margins[2];
+ }
+
+ public int getBorderLeft() {
+ return margins[3];
+ }
+
+ public int getPaddingTop() {
+ return paddings[0];
+ }
+
+ public int getPaddingRight() {
+ return paddings[1];
+ }
+
+ public int getPaddingBottom() {
+ return paddings[2];
+ }
+
+ public int getPaddingLeft() {
+ return paddings[3];
+ }
+
+ void measure() {
+ boolean changed = isDirty;
+
+ Widget widget = paintable.getWidgetForPaintable();
+ ComputedStyle computedStyle = new ComputedStyle(widget.getElement());
+
+ int[] paddings = computedStyle.getPadding();
+ if (!changed && !Arrays.equals(this.paddings, paddings)) {
+ changed = true;
+ this.paddings = paddings;
+ }
+
+ int[] margins = computedStyle.getMargin();
+ if (!changed && !Arrays.equals(this.margins, margins)) {
+ changed = true;
+ this.margins = margins;
+ }
+
+ int[] borders = computedStyle.getBorder();
+ if (!changed && !Arrays.equals(this.borders, borders)) {
+ changed = true;
+ this.borders = borders;
+ }
+
+ int offsetHeight = widget.getOffsetHeight();
+ int marginHeight = sumHeights(margins);
+ setOuterHeight(offsetHeight + marginHeight);
+
+ int offsetWidth = widget.getOffsetWidth();
+ int marginWidth = sumWidths(margins);
+ setOuterWidth(offsetWidth + marginWidth);
+
+ // int i = 0;
+ for (Entry<Element, int[]> entry : dependencySizes.entrySet()) {
+ Element element = entry.getKey();
+ // int[] elementMargin = new ComputedStyle(element).getMargin();
+ int[] sizes = entry.getValue();
+
+ int elementWidth = element.getOffsetWidth();
+ // elementWidth += elementMargin[1] + elementMargin[3];
+ if (elementWidth != sizes[0]) {
+ // System.out.println(paintable.getId() + " dependency " + i
+ // + " width changed from " + sizes[0] + " to "
+ // + elementWidth);
+ sizes[0] = elementWidth;
+ changed = true;
+ }
+
+ int elementHeight = element.getOffsetHeight();
+ // Causes infinite loops as a negative margin based on the
+ // measured height is currently used for captions
+ // elementHeight += elementMargin[0] + elementMargin[1];
+ if (elementHeight != sizes[1]) {
+ // System.out.println(paintable.getId() + " dependency " + i
+ // + " height changed from " + sizes[1] + " to "
+ // + elementHeight);
+ sizes[1] = elementHeight;
+ changed = true;
+ }
+ // i++;
+ }
+
+ if (changed) {
+ setDirty(true);
+ }
+ }
+}
\ No newline at end of file
package com.vaadin.terminal.gwt.client;
import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.MeasureManager.MeasuredSize;
/**
* An interface used by client-side widgets or paintable parts to receive
import com.google.gwt.user.client.ui.Focusable;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.MeasureManager;
-import com.vaadin.terminal.gwt.client.MeasureManager.MeasuredSize;
+import com.vaadin.terminal.gwt.client.MeasuredSize;
import com.vaadin.terminal.gwt.client.TooltipInfo;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VPaintableMap;
.getStringAttribute("height") : "";
// Dirty if either dimension changed between relative and non-relative
- MeasureManager.MeasuredSize measuredSize = getMeasuredSize();
+ MeasuredSize measuredSize = getMeasuredSize();
if (!measuredSize.isDirty()
&& (w.endsWith("%") != definedWidth.endsWith("%") || h
.endsWith("%") != definedHeight.endsWith("%"))) {
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.VCaption;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ValueMap;
final boolean isVertical;
- ApplicationConnection client;
-
- String id;
-
ValueMap expandRatios;
ValueMap alignments;
add(widget, (com.google.gwt.user.client.Element) wrapper.cast());
}
- AlignmentInfo getAlignment(VPaintableWidget child) {
- String pid = VPaintableMap.get(client).getPid(child);
- if (alignments.containsKey(pid)) {
- return new AlignmentInfo(alignments.getInt(pid));
- } else {
- return AlignmentInfo.TOP_LEFT;
- }
- }
-
- double getExpandRatio(VPaintableWidget child) {
- String pid = VPaintableMap.get(client).getPid(child);
- if (expandRatios.containsKey(pid)) {
- return expandRatios.getRawNumber(pid);
- } else {
- return 0;
- }
- }
-
void addChildWidget(Widget widget) {
DivElement wrapper = Document.get().createDivElement();
wrapper.getStyle().setPosition(Position.ABSOLUTE);
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.CalculatingLayout;
-import com.vaadin.terminal.gwt.client.MeasureManager;
-import com.vaadin.terminal.gwt.client.MeasureManager.MeasuredSize;
+import com.vaadin.terminal.gwt.client.MeasuredSize;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VCaption;
import com.vaadin.terminal.gwt.client.VPaintableMap;
if (VCaption.isNeeded(uidl)) {
VCaption caption = getWidgetForPaintable().captions.get(component);
if (caption == null) {
- caption = new VCaption(component,
- getWidgetForPaintable().client);
+ caption = new VCaption(component, getConnection());
Widget widget = component.getWidgetForPaintable();
@Override
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().id = uidl.getId();
-
super.updateFromUIDL(uidl, client);
if (!isRealUpdate(uidl)) {
return;
}
- HashSet<Widget> previousChildren = new HashSet<Widget>();
- for (Widget child : getWidgetForPaintable()) {
- if (!(child instanceof VCaption)) {
- previousChildren.add(child);
- }
- }
+ HashSet<VPaintableWidget> previousChildren = new HashSet<VPaintableWidget>(
+ getChildren());
+
// TODO Support reordering elements!
for (final Iterator<Object> it = uidl.getChildIterator(); it.hasNext();) {
final UIDL childUIDL = (UIDL) it.next();
}
// TODO Update alignments and expand ratios
- previousChildren.remove(widget);
+ previousChildren.remove(child);
}
- for (Widget widget : previousChildren) {
- Element wrapper = getWidgetForPaintable().getWrapper(widget);
+ for (VPaintableWidget child : previousChildren) {
+ Widget widget = child.getWidgetForPaintable();
+ Element wrapper = VMeasuringOrderedLayout.getWrapper(widget);
VCaption caption = getWidgetForPaintable().captions.remove(widget);
if (caption != null) {
getWidgetForPaintable().remove(caption);
// Remove the wrapper
getWidgetForPaintable().getElement().removeChild(wrapper);
- client.unregisterPaintable(VPaintableMap.get(client).getPaintable(
- widget));
+ VPaintableMap vPaintableMap = VPaintableMap.get(client);
+ vPaintableMap.unregisterPaintable(child);
}
int bitMask = uidl.getIntAttribute("margins");
private static int getOuterSizeInDirection(VPaintableWidget paintable,
boolean isVertical) {
- MeasureManager.MeasuredSize measuredSize = paintable.getMeasuredSize();
+ MeasuredSize measuredSize = paintable.getMeasuredSize();
if (isVertical) {
return measuredSize.getOuterHeight();
} else {
for (VPaintableWidget child : children) {
Widget widget = child.getWidgetForPaintable();
- totalExpand += getWidgetForPaintable().getExpandRatio(child);
+ totalExpand += getExpandRatio(child);
int captionAllocation;
if (getWidgetForPaintable().isVertical) {
captionAllocation = getCaptionHeight(child);
- getWidgetForPaintable().getWrapper(widget).getStyle()
+ getWidgetForPaintable();
+ VMeasuringOrderedLayout.getWrapper(widget).getStyle()
.setPaddingTop(captionAllocation, Unit.PX);
} else {
captionAllocation = 0;
double currentLocation = getStartPadding(getWidgetForPaintable().isVertical);
for (VPaintableWidget child : children) {
Widget widget = child.getWidgetForPaintable();
- Element wrapper = getWidgetForPaintable().getWrapper(widget);
+ getWidgetForPaintable();
+ Element wrapper = VMeasuringOrderedLayout.getWrapper(widget);
Style wrapperStyle = wrapper.getStyle();
double childExpandRatio;
if (totalExpand == 0) {
childExpandRatio = 1d / children.size();
} else {
- childExpandRatio = getWidgetForPaintable()
- .getExpandRatio(child) / totalExpand;
+ childExpandRatio = getExpandRatio(child) / totalExpand;
}
double extraPixels = unallocatedSpace * childExpandRatio;
allocatedSpace += size;
}
- int alignment = getAlignmentInDirection(getWidgetForPaintable()
- .getAlignment(child), getWidgetForPaintable().isVertical);
+ int alignment = getAlignmentInDirection(getAlignment(child),
+ getWidgetForPaintable().isVertical);
if (relative) {
double captionReservation = getWidgetForPaintable().isVertical ? captionHeight
int captionAllocation;
if (!getWidgetForPaintable().isVertical) {
captionAllocation = getCaptionHeight(child);
- getWidgetForPaintable().getWrapper(widget).getStyle()
+ getWidgetForPaintable();
+ VMeasuringOrderedLayout.getWrapper(widget).getStyle()
.setPaddingTop(captionAllocation, Unit.PX);
} else {
captionAllocation = 0;
for (VPaintableWidget child : children) {
Widget widget = child.getWidgetForPaintable();
- Element wrapper = getWidgetForPaintable().getWrapper(widget);
+ getWidgetForPaintable();
+ Element wrapper = VMeasuringOrderedLayout.getWrapper(widget);
Style wrapperStyle = wrapper.getStyle();
boolean relative = isRelativeInDirection(child,
allocatedSize = Math.max(allocatedSize, getCaptionWidth(child));
}
- int alignment = getAlignmentInDirection(getWidgetForPaintable()
- .getAlignment(child), !getWidgetForPaintable().isVertical);
+ int alignment = getAlignmentInDirection(getAlignment(child),
+ !getWidgetForPaintable().isVertical);
double startPosition = getStartPadding(getWidgetForPaintable().isVertical);
if (alignment == 0) {
layoutSecondaryDirection();
}
}
+
+ AlignmentInfo getAlignment(VPaintableWidget child) {
+ String pid = child.getId();
+ if (getWidgetForPaintable().alignments.containsKey(pid)) {
+ return new AlignmentInfo(
+ getWidgetForPaintable().alignments.getInt(pid));
+ } else {
+ return AlignmentInfo.TOP_LEFT;
+ }
+ }
+
+ double getExpandRatio(VPaintableWidget child) {
+ String pid = child.getId();
+ if (getWidgetForPaintable().expandRatios.containsKey(pid)) {
+ return getWidgetForPaintable().expandRatios.getRawNumber(pid);
+ } else {
+ return 0;
+ }
+ }
}