--- /dev/null
- import com.google.gwt.user.client.Event;
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui.tabsheet;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
- private TouchScrollHandler touchScrollHandler;
+import com.google.gwt.user.client.ui.ComplexPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate;
+import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate.TouchScrollHandler;
+
+/**
+ * A panel that displays all of its child widgets in a 'deck', where only one
+ * can be visible at a time. It is used by
+ * {@link com.vaadin.terminal.gwt.client.ui.tabsheet.VTabsheet}.
+ *
+ * This class has the same basic functionality as the GWT DeckPanel
+ * {@link com.google.gwt.user.client.ui.DeckPanel}, with the exception that it
+ * doesn't manipulate the child widgets' width and height attributes.
+ */
+public class VTabsheetPanel extends ComplexPanel {
+
+ private Widget visibleWidget;
+
- sinkEvents(Event.TOUCHEVENTS);
-
++ private final TouchScrollHandler touchScrollHandler;
+
+ /**
+ * Creates an empty tabsheet panel.
+ */
+ public VTabsheetPanel() {
+ setElement(DOM.createDiv());
+ touchScrollHandler = TouchScrollDelegate.enableTouchScrolling(this);
+ }
+
+ /**
+ * Adds the specified widget to the deck.
+ *
+ * @param w
+ * the widget to be added
+ */
+ @Override
+ public void add(Widget w) {
+ Element el = createContainerElement();
+ DOM.appendChild(getElement(), el);
+ super.add(w, el);
+ }
+
+ private Element createContainerElement() {
+ Element el = DOM.createDiv();
+ DOM.setStyleAttribute(el, "position", "absolute");
+ hide(el);
++ touchScrollHandler.addElement(el);
+ return el;
+ }
+
+ /**
+ * Gets the index of the currently-visible widget.
+ *
+ * @return the visible widget's index
+ */
+ public int getVisibleWidget() {
+ return getWidgetIndex(visibleWidget);
+ }
+
+ /**
+ * Inserts a widget before the specified index.
+ *
+ * @param w
+ * the widget to be inserted
+ * @param beforeIndex
+ * the index before which it will be inserted
+ * @throws IndexOutOfBoundsException
+ * if <code>beforeIndex</code> is out of range
+ */
+ public void insert(Widget w, int beforeIndex) {
+ Element el = createContainerElement();
+ DOM.insertChild(getElement(), el, beforeIndex);
+ super.insert(w, el, beforeIndex, false);
+ }
+
+ @Override
+ public boolean remove(Widget w) {
+ Element child = w.getElement();
+ Element parent = null;
+ if (child != null) {
+ parent = DOM.getParent(child);
+ }
+ final boolean removed = super.remove(w);
+ if (removed) {
+ if (visibleWidget == w) {
+ visibleWidget = null;
+ }
+ if (parent != null) {
+ DOM.removeChild(getElement(), parent);
+ }
++ touchScrollHandler.removeElement(parent);
+ }
+ return removed;
+ }
+
+ /**
+ * Shows the widget at the specified index. This causes the currently-
+ * visible widget to be hidden.
+ *
+ * @param index
+ * the index of the widget to be shown
+ */
+ public void showWidget(int index) {
+ checkIndexBoundsForAccess(index);
+ Widget newVisible = getWidget(index);
+ if (visibleWidget != newVisible) {
+ if (visibleWidget != null) {
+ hide(DOM.getParent(visibleWidget.getElement()));
+ }
+ visibleWidget = newVisible;
+ touchScrollHandler.setElements(visibleWidget.getElement()
+ .getParentElement());
+ }
+ // Always ensure the selected tab is visible. If server prevents a tab
+ // change we might end up here with visibleWidget == newVisible but its
+ // parent is still hidden.
+ unHide(DOM.getParent(visibleWidget.getElement()));
+ }
+
+ private void hide(Element e) {
+ DOM.setStyleAttribute(e, "visibility", "hidden");
+ DOM.setStyleAttribute(e, "top", "-100000px");
+ DOM.setStyleAttribute(e, "left", "-100000px");
+ }
+
+ private void unHide(Element e) {
+ DOM.setStyleAttribute(e, "top", "0px");
+ DOM.setStyleAttribute(e, "left", "0px");
+ DOM.setStyleAttribute(e, "visibility", "");
+ }
+
+ public void fixVisibleTabSize(int width, int height, int minWidth) {
+ if (visibleWidget == null) {
+ return;
+ }
+
+ boolean dynamicHeight = false;
+
+ if (height < 0) {
+ height = visibleWidget.getOffsetHeight();
+ dynamicHeight = true;
+ }
+ if (width < 0) {
+ width = visibleWidget.getOffsetWidth();
+ }
+ if (width < minWidth) {
+ width = minWidth;
+ }
+
+ Element wrapperDiv = (Element) visibleWidget.getElement()
+ .getParentElement();
+
+ // width first
+ getElement().getStyle().setPropertyPx("width", width);
+ wrapperDiv.getStyle().setPropertyPx("width", width);
+
+ if (dynamicHeight) {
+ // height of widget might have changed due wrapping
+ height = visibleWidget.getOffsetHeight();
+ }
+ // v-tabsheet-tabsheetpanel height
+ getElement().getStyle().setPropertyPx("height", height);
+
+ // widget wrapper height
+ if (dynamicHeight) {
+ wrapperDiv.getStyle().clearHeight();
+ } else {
+ // widget wrapper height
+ wrapperDiv.getStyle().setPropertyPx("height", height);
+ }
+ }
+
+ public void replaceComponent(Widget oldComponent, Widget newComponent) {
+ boolean isVisible = (visibleWidget == oldComponent);
+ int widgetIndex = getWidgetIndex(oldComponent);
+ remove(oldComponent);
+ insert(newComponent, widgetIndex);
+ if (isVisible) {
+ showWidget(widgetIndex);
+ }
+ }
+}