123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573 |
- /*
- * Copyright 2000-2013 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
- package com.vaadin.client.ui;
-
- import com.google.gwt.dom.client.DivElement;
- import com.google.gwt.dom.client.Document;
- import com.google.gwt.dom.client.Style;
- 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.ComplexPanel;
- import com.google.gwt.user.client.ui.SimplePanel;
- import com.google.gwt.user.client.ui.Widget;
- import com.vaadin.client.StyleConstants;
- import com.vaadin.client.VCaption;
-
- public class VAbsoluteLayout extends ComplexPanel {
-
- /** Tag name for widget creation */
- public static final String TAGNAME = "absolutelayout";
-
- /** Class name, prefix in styling */
- public static final String CLASSNAME = "v-absolutelayout";
-
- private DivElement marginElement;
-
- protected final Element canvas = DOM.createDiv();
-
- /**
- * Default constructor
- */
- public VAbsoluteLayout() {
- setElement(Document.get().createDivElement());
- marginElement = Document.get().createDivElement();
- canvas.getStyle().setProperty("position", "relative");
- canvas.getStyle().setProperty("overflow", "hidden");
- marginElement.appendChild(canvas);
- getElement().appendChild(marginElement);
- setStyleName(CLASSNAME);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.user.client.ui.Panel#add(com.google.gwt.user.client.ui
- * .Widget)
- */
- @Override
- public void add(Widget child) {
- AbsoluteWrapper wrapper = new AbsoluteWrapper(child);
- wrapper.updateStyleNames();
- super.add(wrapper, canvas);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.user.client.ui.ComplexPanel#remove(com.google.gwt.user
- * .client.ui.Widget)
- */
- @Override
- public boolean remove(Widget w) {
- AbsoluteWrapper wrapper = getChildWrapper(w);
- if (wrapper != null) {
- wrapper.destroy();
- return super.remove(wrapper);
- }
- return super.remove(w);
- }
-
- /**
- * Does this layout contain a widget
- *
- * @param widget
- * The widget to check
- * @return Returns true if the widget is in this layout, false if not
- */
- public boolean contains(Widget widget) {
- return getChildWrapper(widget) != null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.google.gwt.user.client.ui.ComplexPanel#getWidget(int)
- */
- @Override
- public Widget getWidget(int index) {
- for (int i = 0, j = 0; i < super.getWidgetCount(); i++) {
- Widget w = super.getWidget(i);
- if (w instanceof AbsoluteWrapper) {
- if (j == index) {
- return w;
- } else {
- j++;
- }
- }
- }
- return null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.google.gwt.user.client.ui.ComplexPanel#getWidgetCount()
- */
- @Override
- public int getWidgetCount() {
- int counter = 0;
- for (int i = 0; i < super.getWidgetCount(); i++) {
- if (super.getWidget(i) instanceof AbsoluteWrapper) {
- counter++;
- }
- }
- return counter;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.user.client.ui.ComplexPanel#getWidgetIndex(com.google.
- * gwt.user.client.ui.Widget)
- */
- @Override
- public int getWidgetIndex(Widget child) {
- for (int i = 0, j = 0; i < super.getWidgetCount(); i++) {
- Widget w = super.getWidget(i);
- if (w instanceof AbsoluteWrapper) {
- if (child == w) {
- return j;
- } else {
- j++;
- }
- }
- }
- return -1;
- }
-
- /**
- * Sets a caption for a contained widget
- *
- * @param child
- * The child widget to set the caption for
- * @param caption
- * The caption of the widget
- */
- public void setWidgetCaption(Widget child, VCaption caption) {
- AbsoluteWrapper wrapper = getChildWrapper(child);
- if (wrapper != null) {
- if (caption != null) {
- if (!getChildren().contains(caption)) {
- super.add(caption, canvas);
- }
- wrapper.setCaption(caption);
- caption.updateCaption();
- wrapper.updateCaptionPosition();
- } else if (wrapper.getCaption() != null) {
- wrapper.setCaption(null);
- }
- }
- }
-
- /**
- * Set the position of the widget in the layout. The position is a CSS
- * property string using properties such as top,left,right,top
- *
- * @param child
- * The child widget to set the position for
- * @param position
- * The position string
- */
- public void setWidgetPosition(Widget child, String position) {
- AbsoluteWrapper wrapper = getChildWrapper(child);
- if (wrapper != null) {
- wrapper.setPosition(position);
- }
- }
-
- /**
- * Get the caption for a widget
- *
- * @param child
- * The child widget to get the caption of
- */
- public VCaption getWidgetCaption(Widget child) {
- AbsoluteWrapper wrapper = getChildWrapper(child);
- if (wrapper != null) {
- return wrapper.getCaption();
- }
- return null;
- }
-
- /**
- * Get the pixel width of an slot in the layout
- *
- * @param child
- * The widget in the layout.
- * @return Returns the size in pixels, or 0 if child is not in the layout
- */
- public int getWidgetSlotWidth(Widget child) {
- AbsoluteWrapper wrapper = getChildWrapper(child);
- if (wrapper != null) {
- return wrapper.getOffsetWidth();
- }
- return 0;
- }
-
- /**
- * Get the pixel height of an slot in the layout
- *
- * @param child
- * The widget in the layout
- * @return Returns the size in pixels, or 0 if the child is not in the
- * layout
- */
- public int getWidgetSlotHeight(Widget child) {
- AbsoluteWrapper wrapper = getChildWrapper(child);
- if (wrapper != null) {
- return wrapper.getOffsetHeight();
- }
- return 0;
- }
-
- /**
- * Get the wrapper for a widget
- *
- * @param child
- * The child to get the wrapper for
- * @return
- */
- protected AbsoluteWrapper getChildWrapper(Widget child) {
- for (Widget w : getChildren()) {
- if (w instanceof AbsoluteWrapper) {
- AbsoluteWrapper wrapper = (AbsoluteWrapper) w;
- if (wrapper.getWidget() == child) {
- return wrapper;
- }
- }
- }
- return null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.user.client.ui.UIObject#setStylePrimaryName(java.lang.
- * String)
- */
- @Override
- public void setStylePrimaryName(String style) {
- updateStylenames(style);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.user.client.ui.UIObject#setStyleName(java.lang.String)
- */
- @Override
- public void setStyleName(String style) {
- super.setStyleName(style);
- updateStylenames(style);
- addStyleName(StyleConstants.UI_LAYOUT);
- }
-
- /**
- * Updates all style names contained in the layout
- *
- * @param primaryStyleName
- * The style name to use as primary
- */
- protected void updateStylenames(String primaryStyleName) {
- super.setStylePrimaryName(primaryStyleName);
- canvas.setClassName(getStylePrimaryName() + "-canvas");
- canvas.setClassName(getStylePrimaryName() + "-margin");
- for (Widget w : getChildren()) {
- if (w instanceof AbsoluteWrapper) {
- AbsoluteWrapper wrapper = (AbsoluteWrapper) w;
- wrapper.updateStyleNames();
- }
- }
- }
-
- /**
- * Performs a vertical layout of the layout. Should be called when a widget
- * is added or removed
- */
- public void layoutVertically() {
- for (Widget widget : getChildren()) {
- if (widget instanceof AbsoluteWrapper) {
- AbsoluteWrapper wrapper = (AbsoluteWrapper) widget;
-
- /*
- * Cleanup old wrappers which have been left empty by other
- * inner layouts moving the widget from the wrapper into their
- * own hierarchy. This usually happens when a call to
- * setWidget(widget) is done in an inner layout which
- * automatically detaches the widget from the parent, in this
- * case the wrapper, and re-attaches it somewhere else. This has
- * to be done in the layout phase since the order of the
- * hierarchy events are not defined.
- */
- if (wrapper.getWidget() == null) {
- wrapper.destroy();
- super.remove(wrapper);
- continue;
- }
-
- Style wrapperStyle = wrapper.getElement().getStyle();
- Style widgetStyle = wrapper.getWidget().getElement().getStyle();
-
- // Ensure previous heights do not affect the measures
- wrapperStyle.clearHeight();
-
- if (widgetStyle.getHeight() != null
- && widgetStyle.getHeight().endsWith("%")) {
- int h;
- if (wrapper.top != null && wrapper.bottom != null) {
- h = wrapper.getOffsetHeight();
- } else if (wrapper.bottom != null) {
- // top not defined, available space 0... bottom of
- // wrapper
- h = wrapper.getElement().getOffsetTop()
- + wrapper.getOffsetHeight();
- } else {
- // top defined or both undefined, available space ==
- // canvas - top
- h = canvas.getOffsetHeight()
- - wrapper.getElement().getOffsetTop();
- }
- wrapperStyle.setHeight(h, Unit.PX);
- }
-
- wrapper.updateCaptionPosition();
- }
- }
- }
-
- /**
- * Performs an horizontal layout. Should be called when a widget is add or
- * removed
- */
- public void layoutHorizontally() {
- for (Widget widget : getChildren()) {
- if (widget instanceof AbsoluteWrapper) {
- AbsoluteWrapper wrapper = (AbsoluteWrapper) widget;
-
- /*
- * Cleanup old wrappers which have been left empty by other
- * inner layouts moving the widget from the wrapper into their
- * own hierarchy. This usually happens when a call to
- * setWidget(widget) is done in an inner layout which
- * automatically detaches the widget from the parent, in this
- * case the wrapper, and re-attaches it somewhere else. This has
- * to be done in the layout phase since the order of the
- * hierarchy events are not defined.
- */
- if (wrapper.getWidget() == null) {
- wrapper.destroy();
- super.remove(wrapper);
- continue;
- }
-
- Style wrapperStyle = wrapper.getElement().getStyle();
- Style widgetStyle = wrapper.getWidget().getElement().getStyle();
-
- // Ensure previous heights do not affect the measures
- wrapperStyle.clearWidth();
-
- if (widgetStyle.getWidth() != null
- && widgetStyle.getWidth().endsWith("%")) {
- int w;
- if (wrapper.left != null && wrapper.right != null) {
- w = wrapper.getOffsetWidth();
- } else if (wrapper.right != null) {
- // left == null
- // available width == right edge == offsetleft + width
- w = wrapper.getOffsetWidth()
- + wrapper.getElement().getOffsetLeft();
- } else {
- // left != null && right == null || left == null &&
- // right == null
- // available width == canvas width - offset left
- w = canvas.getOffsetWidth()
- - wrapper.getElement().getOffsetLeft();
- }
- wrapperStyle.setWidth(w, Unit.PX);
- }
-
- wrapper.updateCaptionPosition();
- }
- }
- }
-
- /**
- * Sets style names for the wrapper wrapping the widget in the layout. The
- * style names will be prefixed with v-absolutelayout-wrapper.
- *
- * @param widget
- * The widget which wrapper we want to add the stylenames to
- * @param stylenames
- * The style names that should be added to the wrapper
- */
- public void setWidgetWrapperStyleNames(Widget widget, String... stylenames) {
- AbsoluteWrapper wrapper = getChildWrapper(widget);
- if (wrapper == null) {
- throw new IllegalArgumentException(
- "No wrapper for widget found, has the widget been added to the layout?");
- }
- wrapper.setWrapperStyleNames(stylenames);
- }
-
- /**
- * Internal wrapper for wrapping widgets in the Absolute layout
- */
- protected class AbsoluteWrapper extends SimplePanel {
- private String css;
- private String left;
- private String top;
- private String right;
- private String bottom;
- private String zIndex;
-
- private VCaption caption;
- private String[] extraStyleNames;
-
- /**
- * Constructor
- *
- * @param child
- * The child to wrap
- */
- public AbsoluteWrapper(Widget child) {
- setWidget(child);
- }
-
- /**
- * Get the caption of the wrapper
- */
- public VCaption getCaption() {
- return caption;
- }
-
- /**
- * Set the caption for the wrapper
- *
- * @param caption
- * The caption for the wrapper
- */
- public void setCaption(VCaption caption) {
- if (caption != null) {
- this.caption = caption;
- } else if (this.caption != null) {
- this.caption.removeFromParent();
- this.caption = caption;
- }
- }
-
- /**
- * Removes the wrapper caption and itself from the layout
- */
- public void destroy() {
- if (caption != null) {
- caption.removeFromParent();
- }
- removeFromParent();
- }
-
- /**
- * Set the position for the wrapper in the layout
- *
- * @param position
- * The position string
- */
- public void setPosition(String position) {
- if (css == null || !css.equals(position)) {
- css = position;
- top = right = bottom = left = zIndex = null;
- if (!css.equals("")) {
- String[] properties = css.split(";");
- for (int i = 0; i < properties.length; i++) {
- String[] keyValue = properties[i].split(":");
- if (keyValue[0].equals("left")) {
- left = keyValue[1];
- } else if (keyValue[0].equals("top")) {
- top = keyValue[1];
- } else if (keyValue[0].equals("right")) {
- right = keyValue[1];
- } else if (keyValue[0].equals("bottom")) {
- bottom = keyValue[1];
- } else if (keyValue[0].equals("z-index")) {
- zIndex = keyValue[1];
- }
- }
- }
- // ensure ne values
- Style style = getElement().getStyle();
- /*
- * IE8 dies when nulling zIndex, even in IE7 mode. All other css
- * properties (and even in older IE's) accept null values just
- * fine. Assign empty string instead of null.
- */
- if (zIndex != null) {
- style.setProperty("zIndex", zIndex);
- } else {
- style.setProperty("zIndex", "");
- }
- style.setProperty("top", top);
- style.setProperty("left", left);
- style.setProperty("right", right);
- style.setProperty("bottom", bottom);
-
- }
- updateCaptionPosition();
- }
-
- /**
- * Updates the caption position by using element offset left and top
- */
- private void updateCaptionPosition() {
- if (caption != null) {
- Style style = caption.getElement().getStyle();
- style.setProperty("position", "absolute");
- style.setPropertyPx("left", getElement().getOffsetLeft());
- style.setPropertyPx("top", getElement().getOffsetTop()
- - caption.getHeight());
- }
- }
-
- /**
- * Sets the style names of the wrapper. Will be prefixed with the
- * v-absolutelayout-wrapper prefix
- *
- * @param stylenames
- * The wrapper style names
- */
- public void setWrapperStyleNames(String... stylenames) {
- extraStyleNames = stylenames;
- updateStyleNames();
- }
-
- /**
- * Updates the style names using the primary style name as prefix
- */
- protected void updateStyleNames() {
- setStyleName(VAbsoluteLayout.this.getStylePrimaryName()
- + "-wrapper");
- if (extraStyleNames != null) {
- for (String stylename : extraStyleNames) {
- addStyleDependentName(stylename);
- }
- }
- }
- }
- }
|