From: Leif Åstrand Date: Thu, 9 Feb 2012 12:45:12 +0000 (+0200) Subject: Refactor to use LayoutSlot for children (#8313) X-Git-Tag: 7.0.0.alpha2~434^2~75 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e70eb29e7d0a47c0fd1b9e159731911702e7e6d0;p=vaadin-framework.git Refactor to use LayoutSlot for children (#8313) --- diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayout.java index fcfbc3fb64..088eaf46f6 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayout.java @@ -3,34 +3,21 @@ */ package com.vaadin.terminal.gwt.client.ui; -import java.util.HashMap; -import java.util.Map; - import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Document; -import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Style.Overflow; import com.google.gwt.dom.client.Style.Position; -import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.VCaption; -import com.vaadin.terminal.gwt.client.VPaintableWidget; -import com.vaadin.terminal.gwt.client.ValueMap; +import com.vaadin.terminal.gwt.client.ui.layout.VLayoutSlot; public class VMeasuringOrderedLayout extends ComplexPanel { - public static final String CLASSNAME = "v-orderedlayout"; - final boolean isVertical; - ValueMap expandRatios; - - ValueMap alignments; - - Map captions = new HashMap(); - final DivElement spacingMeasureElement; protected VMeasuringOrderedLayout(String className, boolean isVertical) { @@ -50,60 +37,159 @@ public class VMeasuringOrderedLayout extends ComplexPanel { this.isVertical = isVertical; } - static Element getWrapper(Widget widget) { - return widget.getElement().getParentElement(); - } + public void addSlot(VLayoutSlot layoutSlot) { + Widget widget = layoutSlot.getWidget(); + Element wrapperElement = layoutSlot.getWrapperElement(); - private void add(Widget widget, DivElement wrapper) { - add(widget, (com.google.gwt.user.client.Element) wrapper.cast()); - } + getElement().appendChild(wrapperElement); + add(widget, wrapperElement); - void addChildWidget(Widget widget) { - DivElement wrapper = Document.get().createDivElement(); - wrapper.getStyle().setPosition(Position.ABSOLUTE); - getElement().appendChild(wrapper); - add(widget, wrapper); - widget.getElement().getStyle() - .setProperty("MozBoxSizing", "border-box"); - widget.getElement().getStyle().setProperty("boxSizing", "border-box"); - } - - void addCaption(VCaption caption, Widget widget) { - Element wrapper = getWrapper(widget); - - // Logical attach. - getChildren().add(caption); - - // Physical attach. - DOM.insertBefore((com.google.gwt.user.client.Element) wrapper.cast(), - caption.getElement(), widget.getElement()); - - // Adopt. - adopt(caption); + widget.setLayoutData(layoutSlot); } private void togglePrefixedStyleName(String name, boolean enabled) { if (enabled) { - addStyleName(CLASSNAME + name); + addStyleDependentName(name); } else { - removeStyleName(CLASSNAME + name); + removeStyleDependentName(name); } } void updateMarginStyleNames(VMarginInfo marginInfo) { - togglePrefixedStyleName("-margin-top", marginInfo.hasTop()); - togglePrefixedStyleName("-margin-right", marginInfo.hasRight()); - togglePrefixedStyleName("-margin-bottom", marginInfo.hasBottom()); - togglePrefixedStyleName("-margin-left", marginInfo.hasLeft()); + togglePrefixedStyleName("margin-top", marginInfo.hasTop()); + togglePrefixedStyleName("margin-right", marginInfo.hasRight()); + togglePrefixedStyleName("margin-bottom", marginInfo.hasBottom()); + togglePrefixedStyleName("margin-left", marginInfo.hasLeft()); } void updateSpacingStyleName(boolean spacingEnabled) { + String styleName = getStyleName(); if (spacingEnabled) { - spacingMeasureElement.addClassName(CLASSNAME + "-spacing-on"); - spacingMeasureElement.removeClassName(CLASSNAME + "-spacing-off"); + spacingMeasureElement.addClassName(styleName + "-spacing-on"); + spacingMeasureElement.removeClassName(styleName + "-spacing-off"); } else { - spacingMeasureElement.removeClassName(CLASSNAME + "-spacing-on"); - spacingMeasureElement.addClassName(CLASSNAME + "-spacing-off"); + spacingMeasureElement.removeClassName(styleName + "-spacing-on"); + spacingMeasureElement.addClassName(styleName + "-spacing-off"); + } + } + + public void removeSlot(VLayoutSlot slot) { + VCaption caption = slot.getCaption(); + if (caption != null) { + remove(caption); + } + + remove(slot.getWidget()); + getElement().removeChild(slot.getWrapperElement()); + } + + public VLayoutSlot getSlotForChild(Widget widget) { + return (VLayoutSlot) widget.getLayoutData(); + } + + public void setCaption(Widget child, VCaption caption) { + VLayoutSlot slot = getSlotForChild(child); + + if (caption != null) { + // Logical attach. + getChildren().add(caption); + } + + // Physical attach if not null, also removes old caption + slot.setCaption(caption); + + if (caption != null) { + // Adopt. + adopt(caption); + } + } + + public int layoutPrimaryDirection(int spacingSize, int allocatedSize, + int startPadding) { + int actuallyAllocated = 0; + double totalExpand = 0; + + int childCount = 0; + for (Widget child : this) { + if (child instanceof VCaption) { + continue; + } + childCount++; + + VLayoutSlot slot = getSlotForChild(child); + totalExpand += slot.getExpandRatio(); + + if (!slot.isRelativeInDirection(isVertical)) { + actuallyAllocated += slot.getUsedSizeInDirection(isVertical); + } + } + + actuallyAllocated += spacingSize * (childCount - 1); + + if (allocatedSize == -1) { + allocatedSize = actuallyAllocated; + } + + double unallocatedSpace = Math + .max(0, allocatedSize - actuallyAllocated); + + double currentLocation = startPadding; + + for (Widget child : this) { + if (child instanceof VCaption) { + continue; + } + + VLayoutSlot slot = getSlotForChild(child); + + double childExpandRatio; + if (totalExpand == 0) { + childExpandRatio = 1d / childCount; + } else { + childExpandRatio = slot.getExpandRatio() / totalExpand; + } + + double extraPixels = unallocatedSpace * childExpandRatio; + double allocatedSpace = extraPixels; + if (!slot.isRelativeInDirection(isVertical)) { + allocatedSpace += slot.getUsedSizeInDirection(isVertical); + } + + slot.positionInDirection(currentLocation, allocatedSpace, + isVertical); + currentLocation += allocatedSpace + spacingSize; + } + + return allocatedSize; + } + + public int layoutSecondaryDirection(int allocatedSize, int startPadding) { + int maxSize = 0; + for (Widget child : this) { + if (child instanceof VCaption) { + continue; + } + + VLayoutSlot slot = getSlotForChild(child); + if (!slot.isRelativeInDirection(!isVertical)) { + maxSize = Math.max(maxSize, + slot.getUsedSizeInDirection(!isVertical)); + } } + + if (allocatedSize == -1) { + allocatedSize = maxSize; + } + + for (Widget child : this) { + if (child instanceof VCaption) { + continue; + } + + VLayoutSlot slot = getSlotForChild(child); + slot.positionInDirection(startPadding, allocatedSize, !isVertical); + } + + return allocatedSize; } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayoutPaintable.java index 0ce5c8e89f..c995e681d1 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayoutPaintable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VMeasuringOrderedLayoutPaintable.java @@ -1,12 +1,9 @@ package com.vaadin.terminal.gwt.client.ui; -import java.util.Collection; import java.util.HashSet; import java.util.Iterator; -import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style; -import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.CalculatingLayout; @@ -15,6 +12,9 @@ import com.vaadin.terminal.gwt.client.UIDL; 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; +import com.vaadin.terminal.gwt.client.ui.layout.VLayoutSlot; +import com.vaadin.terminal.gwt.client.ui.layout.VPaintableLayoutSlot; public abstract class VMeasuringOrderedLayoutPaintable extends VAbstractPaintableWidgetContainer implements CalculatingLayout { @@ -25,27 +25,21 @@ public abstract class VMeasuringOrderedLayoutPaintable extends } public void updateCaption(VPaintableWidget component, UIDL uidl) { + VMeasuringOrderedLayout layout = getWidgetForPaintable(); if (VCaption.isNeeded(uidl)) { - VCaption caption = getWidgetForPaintable().captions.get(component); + VLayoutSlot layoutSlot = layout.getSlotForChild(component + .getWidgetForPaintable()); + VCaption caption = layoutSlot.getCaption(); if (caption == null) { caption = new VCaption(component, getConnection()); Widget widget = component.getWidgetForPaintable(); - getWidgetForPaintable().addCaption(caption, widget); - getWidgetForPaintable().captions.put(component, caption); - - getMeasuredSize().registerDependency(caption.getElement()); + layout.setCaption(widget, caption); } caption.updateCaption(uidl); } else { - VCaption removedCaption = getWidgetForPaintable().captions - .remove(component); - if (removedCaption != null) { - getWidgetForPaintable().remove(removedCaption); - getMeasuredSize().deRegisterDependency( - removedCaption.getElement()); - } + layout.setCaption(component.getWidgetForPaintable(), null); } } @@ -64,86 +58,66 @@ public abstract class VMeasuringOrderedLayoutPaintable extends HashSet previousChildren = new HashSet( getChildren()); + VMeasuringOrderedLayout layout = getWidgetForPaintable(); + + ValueMap expandRatios = uidl.getMapAttribute("expandRatios"); + ValueMap alignments = uidl.getMapAttribute("alignments"); + // TODO Support reordering elements! for (final Iterator it = uidl.getChildIterator(); it.hasNext();) { final UIDL childUIDL = (UIDL) it.next(); final VPaintableWidget child = client.getPaintable(childUIDL); Widget widget = child.getWidgetForPaintable(); - if (widget.getParent() != getWidgetForPaintable()) { - getWidgetForPaintable().addChildWidget(widget); + VLayoutSlot slot = layout.getSlotForChild(widget); + + if (widget.getParent() != layout) { + slot = new VPaintableLayoutSlot(child); + layout.addSlot(slot); + } + + String pid = child.getId(); + + AlignmentInfo alignment; + if (alignments.containsKey(pid)) { + alignment = new AlignmentInfo(alignments.getInt(pid)); + } else { + alignment = AlignmentInfo.TOP_LEFT; } + slot.setAlignment(alignment); + + double expandRatio; + if (expandRatios.containsKey(pid)) { + expandRatio = expandRatios.getRawNumber(pid); + } else { + expandRatio = 0; + } + slot.setExpandRatio(expandRatio); if (!childUIDL.getBooleanAttribute("cached")) { child.updateFromUIDL(childUIDL, client); child.getMeasuredSize().setDirty(true); } - // TODO Update alignments and expand ratios previousChildren.remove(child); } 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); - } - getWidgetForPaintable().remove(widget); - // Remove the wrapper - getWidgetForPaintable().getElement().removeChild(wrapper); + layout.removeSlot(layout.getSlotForChild(widget)); VPaintableMap vPaintableMap = VPaintableMap.get(client); vPaintableMap.unregisterPaintable(child); } int bitMask = uidl.getIntAttribute("margins"); - getWidgetForPaintable() - .updateMarginStyleNames(new VMarginInfo(bitMask)); + layout.updateMarginStyleNames(new VMarginInfo(bitMask)); - getWidgetForPaintable().updateSpacingStyleName( - uidl.getBooleanAttribute("spacing")); + layout.updateSpacingStyleName(uidl.getBooleanAttribute("spacing")); - getWidgetForPaintable().expandRatios = uidl - .getMapAttribute("expandRatios"); - getWidgetForPaintable().alignments = uidl.getMapAttribute("alignments"); getMeasuredSize().setDirty(true); } - private int getCaptionWidth(VPaintableWidget child) { - VCaption caption = getWidgetForPaintable().captions.get(child); - if (caption == null) { - return 0; - } else { - return getMeasuredSize().getDependencyOuterWidth( - caption.getElement()); - } - } - - private int getCaptionHeight(VPaintableWidget child) { - VCaption caption = getWidgetForPaintable().captions.get(child); - if (caption != null) { - int captionHeight = getMeasuredSize().getDependencyOuterHeight( - caption.getElement()); - - caption.getElement().getStyle() - .setMarginTop(-captionHeight, Unit.PX); - return captionHeight; - } else { - return 0; - } - } - - private static boolean isRelativeInDirection(VPaintableWidget paintable, - boolean isVertical) { - if (isVertical) { - return paintable.isRelativeHeight(); - } else { - return paintable.isRelativeWidth(); - } - } - private int getSizeForInnerSize(int size, boolean isVertical) { MeasuredSize measuredSize = getMeasuredSize(); if (isVertical) { @@ -159,26 +133,11 @@ public abstract class VMeasuringOrderedLayoutPaintable extends return isVertical ? "height" : "width"; } - private static String getStartProperty(boolean isVertical) { - return isVertical ? "top" : "left"; - } - - private static boolean isUndefinedInDirection(VPaintableWidget paintable, - boolean isVertical) { + private boolean isUndefinedInDirection(boolean isVertical) { if (isVertical) { - return paintable.isUndefinedHeight(); + return isUndefinedHeight(); } else { - return paintable.isUndefinedWidth(); - } - } - - private static int getOuterSizeInDirection(VPaintableWidget paintable, - boolean isVertical) { - MeasuredSize measuredSize = paintable.getMeasuredSize(); - if (isVertical) { - return measuredSize.getOuterHeight(); - } else { - return measuredSize.getOuterWidth(); + return isUndefinedWidth(); } } @@ -190,147 +149,31 @@ public abstract class VMeasuringOrderedLayoutPaintable extends } } - private static int getAlignmentInDirection(AlignmentInfo alignment, - boolean isVertical) { - if (alignment == null) { - return -1; - } - if (isVertical) { - if (alignment.isTop()) { - return -1; - } else if (alignment.isBottom()) { - return 1; - } else { - return 0; - } - } else { - if (alignment.isLeft()) { - return -1; - } else if (alignment.isRight()) { - return 1; - } else { - return 0; - } - } - } - private void layoutPrimaryDirection() { - Collection children = getChildren(); - - // First pass - get total expand ratio and allocated size - int totalAllocated = 0; - double totalExpand = 0; - for (VPaintableWidget child : children) { - Widget widget = child.getWidgetForPaintable(); + VMeasuringOrderedLayout layout = getWidgetForPaintable(); + boolean isVertical = layout.isVertical; + boolean isUndefined = isUndefinedInDirection(isVertical); - totalExpand += getExpandRatio(child); + int startPadding = getStartPadding(isVertical); + int spacingSize = getSpacingInDirection(isVertical); + int allocatedSize; - int captionAllocation; - if (getWidgetForPaintable().isVertical) { - captionAllocation = getCaptionHeight(child); - getWidgetForPaintable(); - VMeasuringOrderedLayout.getWrapper(widget).getStyle() - .setPaddingTop(captionAllocation, Unit.PX); - } else { - captionAllocation = 0; - } - - if (!isRelativeInDirection(child, - getWidgetForPaintable().isVertical)) { - int childSize = getOuterSizeInDirection(child, - getWidgetForPaintable().isVertical); - if (getWidgetForPaintable().isVertical) { - childSize += captionAllocation; - } else { - childSize = Math.max(childSize, getCaptionWidth(child)); - } - totalAllocated += childSize; - } + if (isUndefined) { + allocatedSize = -1; + } else { + allocatedSize = getInnerSizeInDirection(isVertical); } - totalAllocated += getSpacingInDirection(getWidgetForPaintable().isVertical) - * (children.size() - 1); + allocatedSize = layout.layoutPrimaryDirection(spacingSize, + allocatedSize, startPadding); Style ownStyle = getWidgetForPaintable().getElement().getStyle(); - double ownSize; - if (isUndefinedInDirection(this, getWidgetForPaintable().isVertical)) { - ownSize = totalAllocated; - ownStyle.setPropertyPx( - getSizeProperty(getWidgetForPaintable().isVertical), - getSizeForInnerSize(totalAllocated, - getWidgetForPaintable().isVertical)); + if (isUndefined) { + ownStyle.setPropertyPx(getSizeProperty(isVertical), + getSizeForInnerSize(allocatedSize, isVertical)); } else { - ownSize = getInnerSizeInDirection(getWidgetForPaintable().isVertical); - ownStyle.setProperty( - getSizeProperty(getWidgetForPaintable().isVertical), - getDefinedSize(getWidgetForPaintable().isVertical)); - } - - double unallocatedSpace = Math.max(0, ownSize - totalAllocated); - - double currentLocation = getStartPadding(getWidgetForPaintable().isVertical); - for (VPaintableWidget child : children) { - Widget widget = child.getWidgetForPaintable(); - getWidgetForPaintable(); - Element wrapper = VMeasuringOrderedLayout.getWrapper(widget); - Style wrapperStyle = wrapper.getStyle(); - - double childExpandRatio; - if (totalExpand == 0) { - childExpandRatio = 1d / children.size(); - } else { - childExpandRatio = getExpandRatio(child) / totalExpand; - } - - double extraPixels = unallocatedSpace * childExpandRatio; - - boolean relative = isRelativeInDirection(child, - getWidgetForPaintable().isVertical); - - double size = getOuterSizeInDirection(child, - getWidgetForPaintable().isVertical); - int captionHeight = getCaptionHeight(child); - - if (getWidgetForPaintable().isVertical) { - size += captionHeight; - } else if (!relative) { - size = Math.max(size, getCaptionWidth(child)); - } - - double allocatedSpace = extraPixels; - if (!relative) { - allocatedSpace += size; - } - - int alignment = getAlignmentInDirection(getAlignment(child), - getWidgetForPaintable().isVertical); - - if (relative) { - double captionReservation = getWidgetForPaintable().isVertical ? captionHeight - : 0; - wrapperStyle.setProperty( - getSizeProperty(getWidgetForPaintable().isVertical), - allocatedSpace - captionReservation, Unit.PX); - } else { - wrapperStyle - .clearProperty(getSizeProperty(getWidgetForPaintable().isVertical)); - } - - double startPosition = currentLocation; - if (alignment == 0) { - // Centered - startPosition += (allocatedSpace - size) / 2; - } else if (alignment == 1) { - // Right or bottom - startPosition += allocatedSpace - size; - } - - wrapperStyle.setProperty( - getStartProperty(getWidgetForPaintable().isVertical), - startPosition, Unit.PX); - - currentLocation += allocatedSpace - + getSpacingInDirection(getWidgetForPaintable().isVertical); + ownStyle.setProperty(getSizeProperty(isVertical), + getDefinedSize(isVertical)); } } @@ -345,93 +188,33 @@ public abstract class VMeasuringOrderedLayoutPaintable extends } private void layoutSecondaryDirection() { - Collection children = getChildren(); + VMeasuringOrderedLayout layout = getWidgetForPaintable(); + boolean isVertical = layout.isVertical; + boolean isUndefined = isUndefinedInDirection(!isVertical); - int maxSize = 0; - for (VPaintableWidget child : children) { - Widget widget = child.getWidgetForPaintable(); - - int captionAllocation; - if (!getWidgetForPaintable().isVertical) { - captionAllocation = getCaptionHeight(child); - getWidgetForPaintable(); - VMeasuringOrderedLayout.getWrapper(widget).getStyle() - .setPaddingTop(captionAllocation, Unit.PX); - } else { - captionAllocation = 0; - } + int startPadding = getStartPadding(!isVertical); - if (!isRelativeInDirection(child, - !getWidgetForPaintable().isVertical)) { - int childSize = getOuterSizeInDirection(child, - !getWidgetForPaintable().isVertical) - + captionAllocation; - maxSize = Math.max(maxSize, childSize); - } + int allocatedSize; + if (isUndefined) { + allocatedSize = -1; + } else { + allocatedSize = getInnerSizeInDirection(!isVertical); } - double availableSpace; + allocatedSize = layout.layoutSecondaryDirection(allocatedSize, + startPadding); + Style ownStyle = getWidgetForPaintable().getElement().getStyle(); - if (isUndefinedInDirection(this, !getWidgetForPaintable().isVertical)) { + if (isUndefined) { ownStyle.setPropertyPx( getSizeProperty(!getWidgetForPaintable().isVertical), - getSizeForInnerSize(maxSize, + getSizeForInnerSize(allocatedSize, !getWidgetForPaintable().isVertical)); - - availableSpace = maxSize; } else { ownStyle.setProperty( getSizeProperty(!getWidgetForPaintable().isVertical), getDefinedSize(!getWidgetForPaintable().isVertical)); - availableSpace = getInnerSizeInDirection(!getWidgetForPaintable().isVertical); - } - - for (VPaintableWidget child : children) { - Widget widget = child.getWidgetForPaintable(); - getWidgetForPaintable(); - Element wrapper = VMeasuringOrderedLayout.getWrapper(widget); - Style wrapperStyle = wrapper.getStyle(); - - boolean relative = isRelativeInDirection(child, - !getWidgetForPaintable().isVertical); - - int captionHeight = getCaptionHeight(child); - - double allocatedSize = getOuterSizeInDirection(child, - !getWidgetForPaintable().isVertical); - if (!getWidgetForPaintable().isVertical) { - allocatedSize += captionHeight; - } else if (!relative) { - allocatedSize = Math.max(allocatedSize, getCaptionWidth(child)); - } - - int alignment = getAlignmentInDirection(getAlignment(child), - !getWidgetForPaintable().isVertical); - - double startPosition = getStartPadding(getWidgetForPaintable().isVertical); - if (alignment == 0) { - startPosition += (availableSpace - allocatedSize) / 2; - // Centered - } else if (alignment == 1) { - // Right or bottom - startPosition += (availableSpace - allocatedSize); - } - - wrapperStyle.setProperty( - getStartProperty(!getWidgetForPaintable().isVertical), - startPosition, Unit.PX); - - if (relative) { - double captionReservation = !getWidgetForPaintable().isVertical ? captionHeight - : 0; - wrapperStyle.setProperty( - getSizeProperty(!getWidgetForPaintable().isVertical), - availableSpace - captionReservation, Unit.PX); - } else { - wrapperStyle - .clearProperty(getSizeProperty(!getWidgetForPaintable().isVertical)); - } } } @@ -467,22 +250,4 @@ public abstract class VMeasuringOrderedLayoutPaintable extends } } - 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; - } - } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/VLayoutSlot.java b/src/com/vaadin/terminal/gwt/client/ui/layout/VLayoutSlot.java new file mode 100644 index 0000000000..9cb2a3aa63 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/layout/VLayoutSlot.java @@ -0,0 +1,199 @@ +package com.vaadin.terminal.gwt.client.ui.layout; + +import com.google.gwt.dom.client.Document; +import com.google.gwt.dom.client.Style; +import com.google.gwt.dom.client.Style.Position; +import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.terminal.gwt.client.VCaption; +import com.vaadin.terminal.gwt.client.ui.AlignmentInfo; + +public abstract class VLayoutSlot { + + private final Element wrapper = Document.get().createDivElement().cast(); + + private AlignmentInfo alignment; + private VCaption caption; + private final Widget widget; + + private double expandRatio; + + public VLayoutSlot(Widget widget) { + this.widget = widget; + + wrapper.getStyle().setPosition(Position.ABSOLUTE); + + // TODO set box sizing in CSS + Style widgetStyle = widget.getElement().getStyle(); + widgetStyle.setProperty("MozBoxSizing", "border-box"); + widgetStyle.setProperty("boxSizing", "border-box"); + } + + public VCaption getCaption() { + return caption; + } + + public void setCaption(VCaption caption) { + if (this.caption != null) { + this.caption.removeFromParent(); + } + this.caption = caption; + if (caption != null) { + // Physical attach. + DOM.insertBefore(wrapper, caption.getElement(), widget.getElement()); + caption.getElement().getStyle().setPosition(Position.ABSOLUTE); + } + } + + public AlignmentInfo getAlignment() { + return alignment; + } + + public Widget getWidget() { + return widget; + } + + public void setAlignment(AlignmentInfo alignment) { + this.alignment = alignment; + } + + public void positionHorizontally(double currentLocation, + double allocatedSpace) { + Style style = wrapper.getStyle(); + + if (isRelativeWidth()) { + style.setWidth(allocatedSpace, Unit.PX); + } else { + style.setWidth(getUsedWidth(), Unit.PX); + } + + VCaption caption = getCaption(); + Style captionStyle = caption != null ? caption.getElement().getStyle() + : null; + + AlignmentInfo alignment = getAlignment(); + if (!alignment.isLeft()) { + double usedWidth = getWidgetWidth(); + if (alignment.isHorizontalCenter()) { + currentLocation += (allocatedSpace - usedWidth) / 2d; + if (captionStyle != null) { + double captionWidth = getCaptionWidth(); + captionStyle.setLeft(usedWidth / 2 - (captionWidth / 2), + Unit.PX); + captionStyle.clearRight(); + } + } else { + currentLocation += (allocatedSpace - usedWidth); + if (captionStyle != null) { + captionStyle.clearLeft(); + captionStyle.setRight(0, Unit.PX); + } + } + } else { + if (captionStyle != null) { + captionStyle.setLeft(0, Unit.PX); + captionStyle.clearRight(); + } + } + + style.setLeft(currentLocation, Unit.PX); + } + + public void positionVertically(double currentLocation, double allocatedSpace) { + Style style = wrapper.getStyle(); + + VCaption caption = getCaption(); + double captionHeight = caption != null ? getCaptionHeight() : 0; + double contentHeight = allocatedSpace - captionHeight; + + if (isRelativeHeight()) { + style.setHeight(contentHeight, Unit.PX); + } else { + style.clearHeight(); + } + + if (caption != null) { + style.setPaddingTop(getCaptionHeight(), Unit.PX); + caption.getElement().getStyle().setTop(0, Unit.PX); + } else { + style.clearPaddingTop(); + } + + AlignmentInfo alignment = getAlignment(); + if (!alignment.isTop()) { + double actualHeight = getWidgetHeight() + captionHeight; + if (alignment.isVerticalCenter()) { + currentLocation += (allocatedSpace - actualHeight) / 2d; + } else { + currentLocation += (allocatedSpace - actualHeight); + } + } + + style.setTop(currentLocation, Unit.PX); + } + + public void positionInDirection(double currentLocation, + double allocatedSpace, boolean isVertical) { + if (isVertical) { + positionVertically(currentLocation, allocatedSpace); + } else { + positionHorizontally(currentLocation, allocatedSpace); + } + } + + public int getWidgetSizeInDirection(boolean isVertical) { + return isVertical ? getWidgetHeight() : getWidgetWidth(); + } + + public int getUsedWidth() { + int captionWidth = (caption != null ? getCaptionWidth() : 0); + return Math.max(captionWidth, getWidgetWidth()); + } + + public int getUsedHeight() { + int captionHeight = (caption != null ? getCaptionHeight() : 0); + return getWidgetHeight() + captionHeight; + } + + public int getUsedSizeInDirection(boolean isVertical) { + return isVertical ? getUsedHeight() : getUsedWidth(); + } + + protected abstract int getCaptionHeight(); + + protected abstract int getCaptionWidth(); + + public abstract int getWidgetHeight(); + + public abstract int getWidgetWidth(); + + public abstract boolean isUndefinedHeight(); + + public abstract boolean isUndefinedWidth(); + + public boolean isUndefinedInDirection(boolean isVertical) { + return isVertical ? isUndefinedHeight() : isUndefinedWidth(); + } + + public abstract boolean isRelativeHeight(); + + public abstract boolean isRelativeWidth(); + + public boolean isRelativeInDirection(boolean isVertical) { + return isVertical ? isRelativeHeight() : isRelativeWidth(); + } + + public Element getWrapperElement() { + return wrapper; + } + + public void setExpandRatio(double expandRatio) { + this.expandRatio = expandRatio; + } + + public double getExpandRatio() { + return expandRatio; + } +} \ No newline at end of file diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/VPaintableLayoutSlot.java b/src/com/vaadin/terminal/gwt/client/ui/layout/VPaintableLayoutSlot.java new file mode 100644 index 0000000000..17afab0fe8 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/layout/VPaintableLayoutSlot.java @@ -0,0 +1,79 @@ +package com.vaadin.terminal.gwt.client.ui.layout; + +import com.vaadin.terminal.gwt.client.MeasuredSize; +import com.vaadin.terminal.gwt.client.VCaption; +import com.vaadin.terminal.gwt.client.VPaintableWidget; + +public class VPaintableLayoutSlot extends VLayoutSlot { + + final VPaintableWidget paintable; + + public VPaintableLayoutSlot(VPaintableWidget paintable) { + super(paintable.getWidgetForPaintable()); + this.paintable = paintable; + } + + public VPaintableWidget getPaintable() { + return paintable; + } + + @Override + protected int getCaptionHeight() { + VCaption caption = getCaption(); + return caption != null ? getParentSize().getDependencyOuterHeight( + caption.getElement()) : 0; + } + + private MeasuredSize getParentSize() { + return paintable.getParent().getMeasuredSize(); + } + + @Override + protected int getCaptionWidth() { + VCaption caption = getCaption(); + return caption != null ? getParentSize().getDependencyOuterWidth( + caption.getElement()) : 0; + } + + @Override + public void setCaption(VCaption caption) { + VCaption oldCaption = getCaption(); + if (oldCaption != null) { + getParentSize().deRegisterDependency(oldCaption.getElement()); + } + super.setCaption(caption); + if (caption != null) { + getParentSize().registerDependency(caption.getElement()); + } + } + + @Override + public int getWidgetHeight() { + return paintable.getMeasuredSize().getOuterHeight(); + } + + @Override + public int getWidgetWidth() { + return paintable.getMeasuredSize().getOuterWidth(); + } + + @Override + public boolean isUndefinedHeight() { + return paintable.isUndefinedHeight(); + } + + @Override + public boolean isUndefinedWidth() { + return paintable.isUndefinedWidth(); + } + + @Override + public boolean isRelativeHeight() { + return paintable.isRelativeHeight(); + } + + @Override + public boolean isRelativeWidth() { + return paintable.isRelativeWidth(); + } +}