]> source.dussan.org Git - vaadin-framework.git/commitdiff
Adds tab-scrolling feature to TabSheet (clientside). Fixes #959
authorMarc Englund <marc.englund@itmill.com>
Tue, 3 Jun 2008 10:33:29 +0000 (10:33 +0000)
committerMarc Englund <marc.englund@itmill.com>
Tue, 3 Jun 2008 10:33:29 +0000 (10:33 +0000)
svn changeset:4733/svn branch:trunk

WebContent/ITMILL/themes/default/tabsheet/img/next.png [new file with mode: 0644]
WebContent/ITMILL/themes/default/tabsheet/img/prev.png [new file with mode: 0644]
WebContent/ITMILL/themes/default/tabsheet/tabsheet.css
src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheet.java

diff --git a/WebContent/ITMILL/themes/default/tabsheet/img/next.png b/WebContent/ITMILL/themes/default/tabsheet/img/next.png
new file mode 100644 (file)
index 0000000..99418be
Binary files /dev/null and b/WebContent/ITMILL/themes/default/tabsheet/img/next.png differ
diff --git a/WebContent/ITMILL/themes/default/tabsheet/img/prev.png b/WebContent/ITMILL/themes/default/tabsheet/img/prev.png
new file mode 100644 (file)
index 0000000..2916761
Binary files /dev/null and b/WebContent/ITMILL/themes/default/tabsheet/img/prev.png differ
index b7faac6171e76726a65bd0f9663069ddde776cb9..7f7e96c22f8e2e211993dc13d17018b30ebb0ea2 100644 (file)
        overflow:hidden;
 }
 
+.i-tabsheet-scroller {
+       white-space: nowrap;
+       text-align: right;
+       overflow: hidden;
+       height: 48px;
+}
+.i-tabsheet-hidetabs .i-tabsheet-scroller {
+       display: none;
+}
+.i-tabsheet-scrollerPrev,
+.i-tabsheet-scrollerNext {
+       border: none;
+       width: 12px;
+       height: 27px;
+       position: relative;
+       margin-top: -10px;
+       top: -23px;
+}
+.i-tabsheet-scrollerPrev-disabled,
+.i-tabsheet-scrollerNext-disabled {
+       border: none;
+       width: 12px;
+       height: 27px;
+       position: relative;
+       margin-top: -10px;
+       top: -23px;
+}
+
+.i-tabsheet-scrollerNext,
+.i-tabsheet-scrollerNext-disabled {
+       background: transparent url(img/next.png) no-repeat bottom left;
+       margin-right: 0px;
+}
+.i-tabsheet-scrollerPrev,
+.i-tabsheet-scrollerPrev-disabled {
+       background: transparent url(img/prev.png) no-repeat bottom left;
+       margin-right: 1px;
+}
+.i-tabsheet-scrollerPrev:hover,
+.i-tabsheet-scrollerNext:hover {
+       background-position: bottom right;
+}
+.i-tabsheet-scrollerPrev-disabled,
+.i-tabsheet-scrollerNext-disabled {
+       opacity: 0.5;
+}
+.i-tabsheet-scrollerPrev-disabled:hover,
+.i-tabsheet-scrollerNext-disabled:hover {
+       background-position: bottom left;
+       opacity: 0.5;
+}
+
 .i-tabsheet-tabs .i-caption {
        white-space: nowrap;
 }
index 83363526716f16a538819b59bb908b56ba8fb7ae..94fab77fe6ce91717061e0147ab1634876b1f52b 100644 (file)
@@ -10,6 +10,7 @@ import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.DeferredCommand;
 import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.ui.Label;
 import com.google.gwt.user.client.ui.SourcesTabEvents;
 import com.google.gwt.user.client.ui.TabBar;
@@ -27,6 +28,12 @@ public class ITabsheet extends ITabsheetBase implements
 
     public static final String CLASSNAME = "i-tabsheet";
 
+    public static final String SCROLLER_CLASSNAME = "i-tabsheet-scroller";
+    private final Element scroller; // the tab-scroller element
+    private final Element scrollerNext; // the tab-scroller next button element
+    private final Element scrollerPrev; // the tab-scroller prev button element
+    private int scrollerIndex = 0;
+
     private final TabBar tb;
     private final ITabsheetPanel tp;
     private final Element contentNode, deco;
@@ -82,10 +89,26 @@ public class ITabsheet extends ITabsheetBase implements
     public ITabsheet() {
         super(CLASSNAME);
 
+        // Tab scrolling
+        DOM.setStyleAttribute(getElement(), "overflow", "hidden");
+        scroller = DOM.createDiv();
+        DOM.setElementProperty(scroller, "className", SCROLLER_CLASSNAME);
+        scrollerPrev = DOM.createButton();
+        DOM.setElementProperty(scrollerPrev, "className", SCROLLER_CLASSNAME
+                + "Prev");
+        DOM.sinkEvents(scrollerPrev, Event.ONCLICK);
+        scrollerNext = DOM.createButton();
+        DOM.setElementProperty(scrollerNext, "className", SCROLLER_CLASSNAME
+                + "Next");
+        DOM.sinkEvents(scrollerNext, Event.ONCLICK);
+        DOM.appendChild(getElement(), scroller);
+
+        // Tabs
         tb = new TabBar();
         tp = new ITabsheetPanel();
         tp.setStyleName(CLASSNAME + "-tabsheetpanel");
         contentNode = DOM.createDiv();
+
         deco = DOM.createDiv();
 
         addStyleDependentName("loading"); // Indicate initial progress
@@ -95,7 +118,10 @@ public class ITabsheet extends ITabsheetBase implements
                         + "-content");
         DOM.setElementProperty(deco, "className", CLASSNAME + "-deco");
 
-        add(tb, getElement());
+        add(tb, scroller);
+        DOM.appendChild(scroller, scrollerPrev);
+        DOM.appendChild(scroller, scrollerNext);
+
         DOM.appendChild(getElement(), contentNode);
         add(tp, contentNode);
         DOM.appendChild(getElement(), deco);
@@ -108,6 +134,33 @@ public class ITabsheet extends ITabsheetBase implements
 
     }
 
+    public void onBrowserEvent(Event event) {
+
+        // Tab scrolling
+        if (isScrolledTabs()
+                && DOM.compare(DOM.eventGetTarget(event), scrollerPrev)) {
+            if (scrollerIndex > 0) {
+                DOM.setStyleAttribute(DOM.getChild(DOM.getFirstChild(DOM
+                        .getFirstChild(tb.getElement())), scrollerIndex),
+                        "display", "");
+                scrollerIndex--;
+                updateTabScroller();
+            }
+        } else if (isClippedTabs()
+                && DOM.compare(DOM.eventGetTarget(event), scrollerNext)) {
+            int tabs = tb.getTabCount();
+            if (scrollerIndex + 1 <= tabs) {
+                scrollerIndex++;
+                DOM.setStyleAttribute(DOM.getChild(DOM.getFirstChild(DOM
+                        .getFirstChild(tb.getElement())), scrollerIndex),
+                        "display", "none");
+                updateTabScroller();
+            }
+        } else {
+            super.onBrowserEvent(event);
+        }
+    }
+
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
         super.updateFromUIDL(uidl, client);
 
@@ -140,6 +193,7 @@ public class ITabsheet extends ITabsheetBase implements
             tb.setVisible(true);
             removeStyleName(CLASSNAME + "-hidetabs");
         }
+        updateTabScroller();
         waitingForResponse = false;
     }
 
@@ -244,6 +298,41 @@ public class ITabsheet extends ITabsheetBase implements
             DOM.setStyleAttribute(contentNode, "overflow", "");
         }
         Util.runDescendentsLayout(this);
+
+        updateTabScroller();
+    }
+
+    /**
+     * Layouts the tab-scroller elements, and applies styles.
+     */
+    private void updateTabScroller() {
+        DOM.setStyleAttribute(scroller, "width", tp.getOffsetWidth() + "px");
+
+        if (scrollerIndex > tb.getTabCount()) {
+            scrollerIndex = 0;
+        }
+        boolean scrolled = isScrolledTabs();
+        boolean clipped = isClippedTabs();
+        if (tb.isVisible() && (scrolled || clipped)) {
+            DOM.setStyleAttribute(scrollerNext, "display", "");
+            DOM.setStyleAttribute(scrollerPrev, "display", "");
+            DOM.setElementProperty(scrollerPrev, "className",
+                    SCROLLER_CLASSNAME + (scrolled ? "Prev" : "Prev-disabled"));
+            DOM.setElementProperty(scrollerNext, "className",
+                    SCROLLER_CLASSNAME + (clipped ? "Next" : "Next-disabled"));
+        } else {
+            DOM.setStyleAttribute(scrollerNext, "display", "none");
+            DOM.setStyleAttribute(scrollerPrev, "display", "none");
+        }
+
+    }
+
+    private boolean isScrolledTabs() {
+        return scrollerIndex > 0;
+    }
+
+    private boolean isClippedTabs() {
+        return tb.getOffsetWidth() > getOffsetWidth();
     }
 
     protected void clearPaintables() {