Package org.gwtoolbox.widget.client.panel.tab

Source Code of org.gwtoolbox.widget.client.panel.tab.SimpleTabBar$LargestTabScrollStrategy

package org.gwtoolbox.widget.client.panel.tab;

import com.google.gwt.animation.client.Animation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.*;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.event.logical.shared.*;
import com.google.gwt.event.shared.HandlerRegistration;
import org.gwtoolbox.commons.collections.client.EmptyIterator;
import org.gwtoolbox.commons.ui.client.event.EventUtils;
import org.gwtoolbox.commons.ui.client.event.Handler;
import org.gwtoolbox.commons.ui.client.event.HoverHandler;

import static org.gwtoolbox.commons.ui.client.event.EventUtils.addOnClickHandler;
import static org.gwtoolbox.commons.ui.client.event.EventUtils.addContextMenuListener;

import org.gwtoolbox.commons.ui.client.event.ContextMenuHandler;
import org.gwtoolbox.widget.client.menu.MenuBuilder;
import org.gwtoolbox.widget.client.panel.LayoutPanel;
import org.gwtoolbox.widget.client.panel.LayoutUtils;
import static org.gwtoolbox.widget.client.panel.LayoutUtils.*;
import org.gwtoolbox.widget.client.menu.MenuPopup;
import org.gwtoolbox.widget.client.panel.layout.tab.TabSpec;
import org.gwtoolbox.widget.client.popup.Popup;

import java.util.*;

/**
* @author Uri Boness
* @deprecated use {@link org.gwtoolbox.widget.client.panel.layout.tab.TabLayout instead}
*/
@Deprecated
public class SimpleTabBar extends LayoutPanel implements HasSelectionHandlers<SimpleTabBar.Tab>, HasCloseHandlers<SimpleTabBar.Tab> {

    private final static Iterator<Widget> ITERATOR = new EmptyIterator<Widget>();

    private final static int SCROLL_BUTTON_WIDTH = 18;
    private final static int TAB_HORIZONTAL_MARGIN = 2;
    private final static int SCROLL_JUMP = 100;

    private Impl impl = GWT.create(Impl.class);

    private Element container;
    private Element leftScrollButton;
    private Element tabsViewportElement;
    private Element tabsElement;
    private Element rightScrollButton;

    private List<Tab> tabs = new ArrayList<Tab>();
    private Map<String, Tab> tabById = new HashMap<String, Tab>();

    private Tab selectedTab;

    private ScrollStrategy scrollStrategy = new StaticScrollStrategy(SCROLL_JUMP);

    public SimpleTabBar() {
        impl.init(this);

        Element main = preventBoxStyles(DOM.createDiv());
        setElement(main);

        container = DOM.createDiv();
        addRelativePositoning(container);
        DOM.setStyleAttribute(container, "height", impl.getContainerHeight());
        DOM.setStyleAttribute(container, "borderBottomWidth", "1px");
        DOM.setStyleAttribute(container, "borderBottomStyle", "solid");
        DOM.setStyleAttribute(container, "overflow", "hidden");
        DOM.setStyleAttribute(container, "margin", "0");
        DOM.setStyleAttribute(container, "padding", "0 0 2px 0");
        DOM.setStyleAttribute(container, "position", "relative");
        DOM.setStyleAttribute(container, "left", "0");
        DOM.setStyleAttribute(container, "top", "0");
        container.setClassName("SimpleTabBar");
        main.appendChild(container);

        leftScrollButton = DOM.createDiv();
        setClassname(leftScrollButton, "tabs-left-scroll-button");
        DOM.appendChild(container, leftScrollButton);
        setVisible(leftScrollButton, false);
        DOM.setStyleAttribute(leftScrollButton, "position", "absolute");
        DOM.setStyleAttribute(leftScrollButton, "left", "0");
        DOM.setStyleAttribute(leftScrollButton, "top", "0");
        DOM.setStyleAttribute(leftScrollButton, "width", "18px");
        DOM.setStyleAttribute(leftScrollButton, "height", "23px");
        DOM.setStyleAttribute(leftScrollButton, "borderBottomWidth", "1px");
        DOM.setStyleAttribute(leftScrollButton, "borderBottomStyle", "solid");
        DOM.setStyleAttribute(leftScrollButton, "cursor", "pointer");
        addOnClickHandler(leftScrollButton, new Handler<Event>() {
            public void handle(Event event) {
                scrollLeft();
            }
        });


        rightScrollButton = DOM.createDiv();
        setClassname(rightScrollButton, "tabs-right-scroll-button");
        DOM.appendChild(container, rightScrollButton);
        setVisible(rightScrollButton, false);
        DOM.setStyleAttribute(rightScrollButton, "position", "absolute");
        DOM.setStyleAttribute(rightScrollButton, "top", "0");
        DOM.setStyleAttribute(rightScrollButton, "width", "18px");
        DOM.setStyleAttribute(rightScrollButton, "height", "23px");
        DOM.setStyleAttribute(rightScrollButton, "borderBottomWidth", "1px");
        DOM.setStyleAttribute(rightScrollButton, "borderBottomStyle", "solid");
        DOM.setStyleAttribute(rightScrollButton, "cursor", "pointer");
        addOnClickHandler(rightScrollButton, new Handler<Event>() {
            public void handle(Event event) {
                scrollRight();
            }
        });

        tabsViewportElement = DOM.createDiv();
        tabsViewportElement.setClassName("tabs-viewport");
        DOM.setStyleAttribute(tabsViewportElement, "position", "absolute");
        DOM.setStyleAttribute(tabsViewportElement, "left", "0px");
        DOM.setStyleAttribute(tabsViewportElement, "height", impl.getTabsViewportHeight());
        DOM.setStyleAttribute(tabsViewportElement, "overflow", "hidden");
        DOM.setStyleAttribute(tabsViewportElement, "padding", "2px 0 0 0");
        DOM.appendChild(container, tabsViewportElement);

        tabsElement = DOM.createElement("ul");
        tabsElement.setClassName("tabs");
        DOM.appendChild(tabsViewportElement, tabsElement);
        DOM.setStyleAttribute(tabsElement, "display", "block");
        DOM.setStyleAttribute(tabsElement, "position", "relative");
        DOM.setStyleAttribute(tabsElement, "width", "4000px");
        DOM.setStyleAttribute(tabsElement, "height", "20px");
        DOM.setStyleAttribute(tabsElement, "borderBottomWidth", "1px");
        DOM.setStyleAttribute(tabsElement, "borderBottomStyle", "solid");
        DOM.setStyleAttribute(tabsElement, "listStyleImage", "none");
        DOM.setStyleAttribute(tabsElement, "listStylePosition", "outside");
        DOM.setStyleAttribute(tabsElement, "listStyleType", "none");
        DOM.setStyleAttribute(tabsElement, "margin", "0");
        DOM.setStyleAttribute(tabsElement, "padding", "1px 0 0 0");
    }

    public void add(Widget widget) {
        throw new UnsupportedOperationException("SimpleTabBar does not contain widgets");
    }

    public boolean remove(Widget child) {
        throw new UnsupportedOperationException("SimpleTabBar does not contain widgets");
    }

    public void add(String text) {
        add(text, false);
    }

    public void add(String id, String text) {
        add(id, text, false);
    }

    public void add(String text, boolean closable) {
        add(text, text, closable);
    }

    public void add(String id, String text, boolean closable) {
        TabSpec spec = new TabSpec(id).setText(text).setClosable(closable);
        addTab(spec);
    }

    public int getTabIndex(String id) {
        Tab tab = tabById.get(id);
        return tabs.indexOf(tab);
    }

    public String getTabId(int index) {
        Tab tab = tabs.get(index);
        return tab.id;
    }

    public void addTab(TabSpec tabSpec) {
        insertTab(tabSpec, -1);
    }

    public void insertTab(TabSpec tabSpec, int index) {
        assert tabSpec.getText() != null;

        // creating the containing parent
        final Element li = DOM.createElement("li");
        setClassname(li, "tab");

        Element closeButtonElement = null;
        if (tabSpec.isClosable()) {
            closeButtonElement = DOM.createDiv();
            closeButtonElement.setClassName("tab-close-button");
            closeButtonElement.setInnerHTML("&nbsp;");
            DOM.appendChild(li, closeButtonElement);
        }

        Element leftDiv = DOM.createDiv();
        leftDiv.setClassName("tab-left");
        DOM.appendChild(li, leftDiv);

        Element rightDiv = DOM.createDiv();
        rightDiv.setClassName("tab-right");
        DOM.appendChild(leftDiv, rightDiv);

        Element centerSpan = DOM.createSpan();
        centerSpan.setClassName("tab-center");
        Integer width = tabSpec.getWidth();
        if (width == null) {
            width = impl.getTextWidth(tabSpec.getText(), "tab-text-measurement");
        }
        DOM.setStyleAttribute(centerSpan, "width", width + "px");
        DOM.appendChild(rightDiv, centerSpan);

        Element textSpan = DOM.createSpan();
        textSpan.setClassName("tab-text");
        textSpan.setInnerText(tabSpec.getText());
        DOM.appendChild(centerSpan, textSpan);

        final Tab tab = new Tab(tabSpec, li, textSpan, closeButtonElement);
        if (index > -1) {
            tabs.add(index, tab);
            tab.setIndex(index);
        } else {
            tabs.add(tab);
            tab.setIndex(tabs.size() - 1);
        }
        tabById.put(tabSpec.getId(), tab);

        // Physical attach new.
        DOM.appendChild(tabsElement, li);

        if (isAttached()) {
            impl.layout();
        }
    }

    public HandlerRegistration addSelectionHandler(SelectionHandler<Tab> tabSelectionHandler) {
        return addHandler(tabSelectionHandler, SelectionEvent.getType());
    }

    public HandlerRegistration addCloseHandler(CloseHandler<Tab> tabCloseHandler) {
        return addHandler(tabCloseHandler, CloseEvent.getType());
    }

    public Tab getSelectedTab() {
        return selectedTab;
    }

    public int getSelectedTabIndex() {
        return tabs.indexOf(selectedTab);
    }

    public void selectTab(String id) {
        Tab tab = tabById.get(id);
        tab.select();
    }

    public int getTabCount() {
        return tabs.size();
    }

    public void setTabEnabled(String id, boolean enabled) {
        tabById.get(id).setEnabled(enabled);
    }

    public boolean isTabEnabled(String id) {
        return tabById.get(id).isEnabled();
    }

    public Tab remove(String id) {
        Tab tab = tabById.remove(id);
        if (tab == null) {
            return null;
        }
        tabs.indexOf(tab);
        tabs.remove(tab);
        if (selectedTab != null && selectedTab == tab) {
            selectedTab.unselect();
        }
        DOM.removeChild(tabsElement, tab.tabElement);
        impl.layout();
        return tab;
    }

    public void clear() {
        for (Tab tab : tabs.toArray(new Tab[tabs.size()])) {
            remove(tab.id);
        }
    }

    public Iterator<Widget> iterator() {
        return ITERATOR;
    }

    public void layout() {
        impl.layout();
    }

    @Override
    protected void onLoad() {
        impl.onAttach();
    }

    @Override
    protected void onUnload() {
        impl.onDetach();
    }

    public void setScrollJump(int jump) {
        scrollStrategy = new StaticScrollStrategy(jump);
    }

    public void setScrollJumpToSmallestTab() {
        scrollStrategy = new SmallestTabScrollStrategy();
        if (isAttached()) {
            scrollStrategy.update(this);
        }
    }

    public void setScrollJumpToLargestTab() {
        scrollStrategy = new LargestTabScrollStrategy();
        if (isAttached()) {
            scrollStrategy.update(this);
        }
    }


    //================================================ Helper Methods ==================================================

    private void scrollLeft() {
        int left = tabsElement.getOffsetLeft();
        int targetLeft = 0;
        if (left <= - scrollStrategy.getScrollJump()) {
            targetLeft = left + scrollStrategy.getScrollJump();
        }
        new SlideLeftAnimation(left, targetLeft, tabsElement).start();
    }

    private void scrollRight() {
        Element lastTabElement = tabs.get(tabs.size() - 1).tabElement;
        int lastTabRight = lastTabElement.getAbsoluteLeft() + LayoutUtils.getOffsetWidth(lastTabElement);
        int tabsElementRight = tabsViewportElement.getAbsoluteLeft() + LayoutUtils.getOffsetWidth(tabsViewportElement);
        int delta = lastTabRight - tabsElementRight;
        int left = tabsElement.getOffsetLeft();
        int targetLeft;
        if (delta < scrollStrategy.getScrollJump()) {
            targetLeft = tabsElement.getOffsetLeft() - delta - TAB_HORIZONTAL_MARGIN;
        } else {
            targetLeft = tabsElement.getOffsetLeft() - scrollStrategy.getScrollJump();
        }

        new SlideLeftAnimation(left, targetLeft, tabsElement).start();
    }

    //================================================= Inner Classes ==================================================

    private class SlideLeftAnimation extends Animation {

        private int from;
        private int to;
        private Element element;

        private final int delta;

        private SlideLeftAnimation(int from, int to, Element element) {
            this.from = from;
            this.to = to;
            this.element = element;
            delta = to - from;
        }

        protected void onUpdate(double progress) {
            if (progress == 1.0) {
                setLeft(element, to + "px");
                return;
            }
            int interval = (int) (progress * delta);
            setLeft(element, from + interval + "px");
        }

        public void start() {
            run(300);
        }
    }

    private static class Impl {

        protected SimpleTabBar bar;

        public void init(SimpleTabBar panel) {
            this.bar = panel;
        }

        public String getContainerHeight() {
            return "25px";
        }

        public String getTabsViewportHeight() {
            return "22px";
        }

        public void onAttach() {
            layout();
            DeferredCommand.addCommand(new Command() {
                public void execute() {
                    layout();
                }
            });
        }

        public void onDetach() {
        }

        public void layout() {

            bar.setVisible(true);

            int containerHeight = LayoutUtils.getOffsetHeight(bar.container);
            if (containerHeight == 0) {
                return;
            }

            if (bar.tabs.isEmpty()) {
                setLeft(bar.tabsViewportElement, "0px");
                LayoutUtils.setWidth(bar.tabsViewportElement, "100%");
                setVisible(bar.leftScrollButton, false);
                setVisible(bar.rightScrollButton, false);
                return;
            }

            setLeft(bar.tabsElement, "0px");

            Element lastTabElement = bar.tabs.get(bar.tabs.size() - 1).tabElement;
            int lastTabLeft = lastTabElement.getAbsoluteLeft() - bar.tabsElement.getAbsoluteLeft();
            int tabsWidth = lastTabLeft + LayoutUtils.getOffsetWidth(lastTabElement);

            int containerWidth = LayoutUtils.getOffsetWidth(bar.container);

            if (tabsWidth > containerWidth) {
                setLeft(bar.tabsViewportElement, SCROLL_BUTTON_WIDTH + "px");
                LayoutUtils.setWidth(bar.tabsViewportElement, (containerWidth - 2 * SCROLL_BUTTON_WIDTH) + "px");
                setVisible(bar.leftScrollButton, true);
                setLeft(bar.rightScrollButton, (containerWidth - SCROLL_BUTTON_WIDTH) + "px");
                setVisible(bar.rightScrollButton, true);
            } else {
                setLeft(bar.tabsViewportElement, "0px");
                LayoutUtils.setWidth(bar.tabsViewportElement, "100%");
                setVisible(bar.leftScrollButton, false);
                setVisible(bar.rightScrollButton, false);
            }

            bar.scrollStrategy.update(bar);

            bar.notifyLayout();

        }

        public int getTextWidth(String text, String className) {
            return LayoutUtils.getTextWidth(text, className);
        }


    }

    private static class ImplIE6 extends Impl {

        @Override
        public String getContainerHeight() {
            return "27px";
        }

        @Override
        public String getTabsViewportHeight() {
            return "23px";
        }

        public void onAttach() {
            addResizeListener(bar.container);
            layout();
        }

        public void onDetach() {
            DOM.setElementProperty(bar.container, "onresize", null);
        }

        private native void addResizeListener(Element container) /*-{
            var self = this;
            container.onresize = function() {
                self.@org.gwtoolbox.widget.client.panel.tab.SimpleTabBar$ImplIE6::layout()();
            };
        }-*/;

        @Override
        public int getTextWidth(String text, String className) {
            int width = super.getTextWidth(text, className);
            width += 26; //adding the padding;
            return width;
        }
    }


    public class Tab {

        private String id;
        private String text;
        private int index;
        private Element tabElement;
        private Element textElement;
        private Element closeButtonElement;
        private boolean enabled = true;

        private Tab(TabSpec tabSpec, Element tabElement, Element textElement, final Element closeButtonElement) {
            this.id = tabSpec.getId();
            this.text = tabSpec.getText();
            this.tabElement = tabElement;
            this.textElement = textElement;
            this.closeButtonElement = closeButtonElement;
            addOnClickHandler(tabElement, new Handler<Event>() {
                public void handle(Event event) {
                    handleOnClick();
                }
            });
            EventUtils.addMouseHoverHandler(tabElement, new HoverHandler() {
                public void onMouseOver(Event event) {
                    handleMouseOver();
                }

                public void onMouseOut(Event event) {
                    handleMouseOut();
                }
            });
            if (closeButtonElement != null) {
                addOnClickHandler(closeButtonElement, new Handler<Event>() {
                    public void handle(Event event) {
                        handleOnClose();
                    }
                });
                EventUtils.addMouseHoverHandler(closeButtonElement, new HoverHandler() {
                    public void onMouseOver(Event event) {
                        setStyleName(closeButtonElement, "tab-close-button-hover", true);
                    }

                    public void onMouseOut(Event event) {
                        setStyleName(closeButtonElement, "tab-close-button-hover", false);
                    }
                });
            }
            final MenuBuilder menuBuilder = tabSpec.getMenuBuilder();
            if (menuBuilder != null) {
                addContextMenuListener(tabElement, new ContextMenuHandler() {
                    public void onContextMenu(final com.google.gwt.dom.client.Element element, final int x, final int y) {
                        final MenuPopup menu = new MenuPopup(true);
                        menuBuilder.build(menu.getMenu());
                        menu.setPopupPositionAndShow(new Popup.PositionCallback() {
                        public void setPosition(int offsetWidth, int offsetHeight) {
                            menu.setPopupPosition(element.getAbsoluteLeft() + x, element.getAbsoluteTop() + y);
                        }
                    });
                    }
                });
            }
//            addContextMenuListener(tabElement, new ContextMenuHandler() {
//                public void onContextMenu(final com.google.gwt.dom.client.Element element, final int x, final int y) {
//                    final MenuPopup menu = new MenuPopup(true);
//                    if (!isSelected()) {
//                        menu.addItem("Select", new Command() {
//                            public void execute() {
//                                select();
//                            }
//                        }).setEnabled(enabled);
//                    }
//                    if (closeButtonElement != null) {
//                        menu.addItem("Close", new Command() {
//                            public void execute() {
//                                handleOnClose();
//                            }
//                        }).setEnabled(enabled);
//                    }
//                    menu.addItem("Close Others", new Command() {
//                        public void execute() {
//                            handleCloseAll();
//                        }
//                    }).setEnabled(enabled);
//                    menu.setPopupPositionAndShow(new Popup.PositionCallback() {
//                        public void setPosition(int offsetWidth, int offsetHeight) {
//                            menu.setPopupPosition(element.getAbsoluteLeft() + x, element.getAbsoluteTop() + y);
//                        }
//                    });
//                }
//            });
        }

        public boolean isEnabled() {
            return enabled;
        }

        public boolean isSelected() {
            return this == selectedTab;
        }

        public String getId() {
            return id;
        }

        public String getText() {
            return text;
        }

        public int getIndex() {
            return index;
        }

        private void setIndex(int index) {
            this.index = index;
        }

        private void setEnabled(boolean enabled) {
            this.enabled = enabled;
            if (isSelected() && !enabled) {
                unselect();
            }
            markEnabled(enabled);
        }

        private void handleMouseOver() {
            if (!isSelected() && enabled) {
                setStyleName(textElement, "tab-text-hover", true);
            }
        }

        private void handleMouseOut() {
            if (!isSelected() && enabled) {
                setStyleName(textElement, "tab-text-hover", false);
            }
        }

        private void handleOnClick() {
            if (enabled) {
                select();
            }
        }

        private void handleOnClose() {
            if (enabled) {
                Tab tab = remove(id);
                CloseEvent.fire(SimpleTabBar.this, tab);
            }
        }

        private void handleCloseAll() {
            for (Tab tab : tabs) {
                if (tab != this && tab.isClosable()) {
                    tab.handleOnClose();
                }
            }
        }

        public boolean isClosable() {
            return closeButtonElement != null;
        }

        public void select() {
            if (selectedTab != null) {
                selectedTab.markSelected(false);
            }
            selectedTab = this;
            selectedTab.markSelected(true);
            SelectionEvent.fire(SimpleTabBar.this, this);
        }

        public void unselect() {
            markSelected(false);
            selectedTab = null;
            SelectionEvent.fire(SimpleTabBar.this, null);
        }

        private void markSelected(boolean selected) {
            if (selected) {
                setClassname(tabElement, "tab-selected");
            } else {
                setClassname(tabElement, "tab");
            }
        }

        private void markEnabled(boolean enabled) {
            if (!enabled) {
                setClassname(tabElement, "tab-disabled");
            } else {
                if (isSelected()) {
                    setClassname(tabElement, "tab-selected");
                } else {
                    setClassname(tabElement, "tab");
                }
            }
        }
    }

    private interface ScrollStrategy {

        int getScrollJump();

        void update(SimpleTabBar tabBar);
    }


    private class StaticScrollStrategy implements ScrollStrategy {

        private final int jump;

        private StaticScrollStrategy(int jump) {
            this.jump = jump;
        }

        public int getScrollJump() {
            return jump;
        }

        public void update(SimpleTabBar tabBar) {
        }
    }

    private class SmallestTabScrollStrategy implements ScrollStrategy {

        private int jump;

        private SmallestTabScrollStrategy() {
            update(SimpleTabBar.this);
        }

        public int getScrollJump() {
            return jump;
        }

        public void update(SimpleTabBar tabBar) {
            int width = 4000;
            for (Tab tab : tabBar.tabs) {
                int offsetWidth = tab.tabElement.getOffsetWidth();
                if (width > offsetWidth) {
                    width = offsetWidth;
                }
            }
            this.jump = width;
        }
    }

    private class LargestTabScrollStrategy implements ScrollStrategy {

        private int jump;

        private LargestTabScrollStrategy() {
            update(SimpleTabBar.this);
        }

        public int getScrollJump() {
            return jump;
        }

        public void update(SimpleTabBar tabBar) {
            int width = 0;
            for (Tab tab : tabBar.tabs) {
                int offsetWidth = tab.tabElement.getOffsetWidth();
                if (width < offsetWidth) {
                    width = offsetWidth;
                }
            }
            this.jump = width;
        }
    }
}
TOP

Related Classes of org.gwtoolbox.widget.client.panel.tab.SimpleTabBar$LargestTabScrollStrategy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.