]> source.dussan.org Git - vaadin-framework.git/commitdiff
Merge commit '8b064'
authorJohannes Dahlström <johannesd@vaadin.com>
Mon, 11 Jun 2012 11:08:31 +0000 (14:08 +0300)
committerJohannes Dahlström <johannesd@vaadin.com>
Mon, 11 Jun 2012 11:08:31 +0000 (14:08 +0300)
Conflicts:
src/com/vaadin/terminal/gwt/client/ui/panel/VPanel.java
src/com/vaadin/terminal/gwt/client/ui/splitpanel/VAbstractSplitPanel.java

1  2 
src/com/vaadin/terminal/gwt/client/ui/panel/VPanel.java
src/com/vaadin/terminal/gwt/client/ui/splitpanel/VAbstractSplitPanel.java

index c6c46f1be9cc89028fba00d56e8ff31c377f6baa,0000000000000000000000000000000000000000..16637450dd1c2d1e4fc49b559f5d1af85a8c6a4c
mode 100644,000000..100644
--- /dev/null
@@@ -1,179 -1,0 +1,183 @@@
-         TouchScrollDelegate.enableTouchScrolling(this, contentNode);
 +/*
 +@VaadinApache2LicenseForJavaFiles@
 + */
 +
 +package com.vaadin.terminal.gwt.client.ui.panel;
 +
 +import com.google.gwt.dom.client.DivElement;
 +import com.google.gwt.dom.client.Document;
 +import com.google.gwt.user.client.DOM;
 +import com.google.gwt.user.client.Element;
 +import com.google.gwt.user.client.Event;
 +import com.google.gwt.user.client.ui.SimplePanel;
 +import com.vaadin.terminal.gwt.client.ApplicationConnection;
 +import com.vaadin.terminal.gwt.client.Focusable;
 +import com.vaadin.terminal.gwt.client.ui.Icon;
 +import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler;
 +import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
 +import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate;
++import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate.TouchScrollHandler;
 +
 +public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner,
 +        Focusable {
 +
 +    public static final String CLASSNAME = "v-panel";
 +
 +    ApplicationConnection client;
 +
 +    String id;
 +
 +    final Element captionNode = DOM.createDiv();
 +
 +    private final Element captionText = DOM.createSpan();
 +
 +    private Icon icon;
 +
 +    final Element bottomDecoration = DOM.createDiv();
 +
 +    final Element contentNode = DOM.createDiv();
 +
 +    private Element errorIndicatorElement;
 +
 +    ShortcutActionHandler shortcutHandler;
 +
 +    int scrollTop;
 +
 +    int scrollLeft;
 +
++    private final TouchScrollHandler touchScrollHandler;
++
 +    public VPanel() {
 +        super();
 +        DivElement captionWrap = Document.get().createDivElement();
 +        captionWrap.appendChild(captionNode);
 +        captionNode.appendChild(captionText);
 +
 +        captionWrap.setClassName(CLASSNAME + "-captionwrap");
 +        captionNode.setClassName(CLASSNAME + "-caption");
 +        contentNode.setClassName(CLASSNAME + "-content");
 +        bottomDecoration.setClassName(CLASSNAME + "-deco");
 +
 +        getElement().appendChild(captionWrap);
 +
 +        /*
 +         * Make contentNode focusable only by using the setFocus() method. This
 +         * behaviour can be changed by invoking setTabIndex() in the serverside
 +         * implementation
 +         */
 +        contentNode.setTabIndex(-1);
 +
 +        getElement().appendChild(contentNode);
 +
 +        getElement().appendChild(bottomDecoration);
 +        setStyleName(CLASSNAME);
 +        DOM.sinkEvents(getElement(), Event.ONKEYDOWN);
 +        DOM.sinkEvents(contentNode, Event.ONSCROLL | Event.TOUCHEVENTS);
 +
 +        contentNode.getStyle().setProperty("position", "relative");
 +        getElement().getStyle().setProperty("overflow", "hidden");
 +
++        touchScrollHandler = TouchScrollDelegate.enableTouchScrolling(this,
++                contentNode);
 +    }
 +
 +    /**
 +     * Sets the keyboard focus on the Panel
 +     * 
 +     * @param focus
 +     *            Should the panel have focus or not.
 +     */
 +    public void setFocus(boolean focus) {
 +        if (focus) {
 +            getContainerElement().focus();
 +        } else {
 +            getContainerElement().blur();
 +        }
 +    }
 +
 +    /*
 +     * (non-Javadoc)
 +     * 
 +     * @see com.vaadin.terminal.gwt.client.Focusable#focus()
 +     */
 +    @Override
 +    public void focus() {
 +        setFocus(true);
 +
 +    }
 +
 +    @Override
 +    protected Element getContainerElement() {
 +        return contentNode;
 +    }
 +
 +    void setCaption(String text) {
 +        DOM.setInnerHTML(captionText, text);
 +    }
 +
 +    void setErrorIndicatorVisible(boolean showError) {
 +        if (showError) {
 +            if (errorIndicatorElement == null) {
 +                errorIndicatorElement = DOM.createSpan();
 +                DOM.setElementProperty(errorIndicatorElement, "className",
 +                        "v-errorindicator");
 +                DOM.sinkEvents(errorIndicatorElement, Event.MOUSEEVENTS);
 +                sinkEvents(Event.MOUSEEVENTS);
 +            }
 +            DOM.insertBefore(captionNode, errorIndicatorElement, captionText);
 +        } else if (errorIndicatorElement != null) {
 +            DOM.removeChild(captionNode, errorIndicatorElement);
 +            errorIndicatorElement = null;
 +        }
 +    }
 +
 +    void setIconUri(String iconUri, ApplicationConnection client) {
 +        if (iconUri == null) {
 +            if (icon != null) {
 +                DOM.removeChild(captionNode, icon.getElement());
 +                icon = null;
 +            }
 +        } else {
 +            if (icon == null) {
 +                icon = new Icon(client);
 +                DOM.insertChild(captionNode, icon.getElement(), 0);
 +            }
 +            icon.setUri(iconUri);
 +        }
 +    }
 +
 +    @Override
 +    public void onBrowserEvent(Event event) {
 +        super.onBrowserEvent(event);
 +
 +        final Element target = DOM.eventGetTarget(event);
 +        final int type = DOM.eventGetType(event);
 +        if (type == Event.ONKEYDOWN && shortcutHandler != null) {
 +            shortcutHandler.handleKeyboardEvent(event);
 +            return;
 +        }
 +        if (type == Event.ONSCROLL) {
 +            int newscrollTop = DOM.getElementPropertyInt(contentNode,
 +                    "scrollTop");
 +            int newscrollLeft = DOM.getElementPropertyInt(contentNode,
 +                    "scrollLeft");
 +            if (client != null
 +                    && (newscrollLeft != scrollLeft || newscrollTop != scrollTop)) {
 +                scrollLeft = newscrollLeft;
 +                scrollTop = newscrollTop;
 +                client.updateVariable(id, "scrollTop", scrollTop, false);
 +                client.updateVariable(id, "scrollLeft", scrollLeft, false);
 +            }
 +        } else if (captionNode.isOrHasChild(target)) {
 +            if (client != null) {
 +                client.handleTooltipEvent(event, this);
 +            }
 +        }
 +    }
 +
 +    @Override
 +    public ShortcutActionHandler getShortcutActionHandler() {
 +        return shortcutHandler;
 +    }
 +
 +}
index 21816e0b34750d3cd30e09967aebcae37af24657,0000000000000000000000000000000000000000..f4b08db46895419e81c6b776049f10559eed7899
mode 100644,000000..100644
--- /dev/null
@@@ -1,676 -1,0 +1,754 @@@
-         TouchScrollDelegate.enableTouchScrolling(this, firstContainer,
-                 secondContainer);
 +/*
 +@VaadinApache2LicenseForJavaFiles@
 + */
 +
 +package com.vaadin.terminal.gwt.client.ui.splitpanel;
 +
 +import java.util.List;
 +
 +import com.google.gwt.dom.client.Node;
 +import com.google.gwt.dom.client.Style;
 +import com.google.gwt.event.dom.client.TouchCancelEvent;
 +import com.google.gwt.event.dom.client.TouchCancelHandler;
 +import com.google.gwt.event.dom.client.TouchEndEvent;
 +import com.google.gwt.event.dom.client.TouchEndHandler;
 +import com.google.gwt.event.dom.client.TouchMoveEvent;
 +import com.google.gwt.event.dom.client.TouchMoveHandler;
 +import com.google.gwt.event.dom.client.TouchStartEvent;
 +import com.google.gwt.event.dom.client.TouchStartHandler;
 +import com.google.gwt.event.shared.EventHandler;
 +import com.google.gwt.event.shared.GwtEvent;
 +import com.google.gwt.user.client.DOM;
 +import com.google.gwt.user.client.Element;
 +import com.google.gwt.user.client.Event;
 +import com.google.gwt.user.client.ui.ComplexPanel;
 +import com.google.gwt.user.client.ui.Widget;
 +import com.vaadin.terminal.gwt.client.ApplicationConnection;
 +import com.vaadin.terminal.gwt.client.BrowserInfo;
 +import com.vaadin.terminal.gwt.client.ComponentConnector;
 +import com.vaadin.terminal.gwt.client.ConnectorMap;
 +import com.vaadin.terminal.gwt.client.LayoutManager;
 +import com.vaadin.terminal.gwt.client.Util;
 +import com.vaadin.terminal.gwt.client.VConsole;
++<<<<<<< HEAD
 +import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate;
 +import com.vaadin.terminal.gwt.client.ui.VOverlay;
 +import com.vaadin.terminal.gwt.client.ui.splitpanel.VAbstractSplitPanel.SplitterMoveHandler.SplitterMoveEvent;
++=======
++import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate.TouchScrollHandler;
++>>>>>>> 8b064
 +
 +public class VAbstractSplitPanel extends ComplexPanel {
 +
 +    private boolean enabled = false;
 +
 +    public static final String CLASSNAME = "v-splitpanel";
 +
 +    public static final int ORIENTATION_HORIZONTAL = 0;
 +
 +    public static final int ORIENTATION_VERTICAL = 1;
 +
 +    private static final int MIN_SIZE = 30;
 +
 +    private int orientation = ORIENTATION_HORIZONTAL;
 +
 +    Widget firstChild;
 +
 +    Widget secondChild;
 +
 +    private final Element wrapper = DOM.createDiv();
 +
 +    private final Element firstContainer = DOM.createDiv();
 +
 +    private final Element secondContainer = DOM.createDiv();
 +
 +    final Element splitter = DOM.createDiv();
 +
 +    private boolean resizing;
 +
 +    private boolean resized = false;
 +
 +    private int origX;
 +
 +    private int origY;
 +
 +    private int origMouseX;
 +
 +    private int origMouseY;
 +
 +    private boolean locked = false;
 +
 +    private boolean positionReversed = false;
 +
 +    List<String> componentStyleNames;
 +
 +    private Element draggingCurtain;
 +
 +    ApplicationConnection client;
 +
 +    boolean immediate;
 +
 +    /* The current position of the split handle in either percentages or pixels */
 +    String position;
 +
++    private final TouchScrollHandler touchScrollHandler;
++
 +    protected Element scrolledContainer;
 +
 +    protected int origScrollTop;
 +
 +    public VAbstractSplitPanel() {
 +        this(ORIENTATION_HORIZONTAL);
 +    }
 +
 +    public VAbstractSplitPanel(int orientation) {
 +        setElement(DOM.createDiv());
 +        switch (orientation) {
 +        case ORIENTATION_HORIZONTAL:
 +            setStyleName(CLASSNAME + "-horizontal");
 +            break;
 +        case ORIENTATION_VERTICAL:
 +        default:
 +            setStyleName(CLASSNAME + "-vertical");
 +            break;
 +        }
 +        // size below will be overridden in update from uidl, initial size
 +        // needed to keep IE alive
 +        setWidth(MIN_SIZE + "px");
 +        setHeight(MIN_SIZE + "px");
 +        constructDom();
 +        setOrientation(orientation);
 +        sinkEvents(Event.MOUSEEVENTS);
 +
-         splitter.addClassName(splitterClass);
-         firstContainer.addClassName(firstContainerClass);
-         secondContainer.addClassName(secondContainerClass);
++        touchScrollHandler = TouchScrollDelegate.enableTouchScrolling(this,
++                firstContainer, secondContainer);
 +
 +        addDomHandler(new TouchCancelHandler() {
 +            @Override
 +            public void onTouchCancel(TouchCancelEvent event) {
 +                // TODO When does this actually happen??
 +                VConsole.log("TOUCH CANCEL");
 +            }
 +        }, TouchCancelEvent.getType());
 +        addDomHandler(new TouchStartHandler() {
 +            @Override
 +            public void onTouchStart(TouchStartEvent event) {
 +                Node target = event.getTouches().get(0).getTarget().cast();
 +                if (splitter.isOrHasChild(target)) {
 +                    onMouseDown(Event.as(event.getNativeEvent()));
 +                }
 +            }
 +        }, TouchStartEvent.getType());
 +        addDomHandler(new TouchMoveHandler() {
 +            @Override
 +            public void onTouchMove(TouchMoveEvent event) {
 +                if (resizing) {
 +                    onMouseMove(Event.as(event.getNativeEvent()));
 +                }
 +            }
 +        }, TouchMoveEvent.getType());
 +        addDomHandler(new TouchEndHandler() {
 +            @Override
 +            public void onTouchEnd(TouchEndEvent event) {
 +                if (resizing) {
 +                    onMouseUp(Event.as(event.getNativeEvent()));
 +                }
 +            }
 +        }, TouchEndEvent.getType());
 +
 +    }
 +
 +    protected void constructDom() {
 +        DOM.appendChild(splitter, DOM.createDiv()); // for styling
 +        DOM.appendChild(getElement(), wrapper);
 +        DOM.setStyleAttribute(wrapper, "position", "relative");
 +        DOM.setStyleAttribute(wrapper, "width", "100%");
 +        DOM.setStyleAttribute(wrapper, "height", "100%");
 +
 +        DOM.appendChild(wrapper, secondContainer);
 +        DOM.appendChild(wrapper, firstContainer);
 +        DOM.appendChild(wrapper, splitter);
 +
 +        DOM.setStyleAttribute(splitter, "position", "absolute");
 +        DOM.setStyleAttribute(secondContainer, "position", "absolute");
 +
 +        setStylenames();
 +    }
 +
 +    private void setOrientation(int orientation) {
 +        this.orientation = orientation;
 +        if (orientation == ORIENTATION_HORIZONTAL) {
 +            DOM.setStyleAttribute(splitter, "height", "100%");
 +            DOM.setStyleAttribute(splitter, "top", "0");
 +            DOM.setStyleAttribute(firstContainer, "height", "100%");
 +            DOM.setStyleAttribute(secondContainer, "height", "100%");
 +        } else {
 +            DOM.setStyleAttribute(splitter, "width", "100%");
 +            DOM.setStyleAttribute(splitter, "left", "0");
 +            DOM.setStyleAttribute(firstContainer, "width", "100%");
 +            DOM.setStyleAttribute(secondContainer, "width", "100%");
 +        }
 +    }
 +
++<<<<<<< HEAD
++=======
++    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
++        this.client = client;
++        id = uidl.getId();
++        rendering = true;
++
++        immediate = uidl.hasAttribute("immediate");
++
++        if (client.updateComponent(this, uidl, true)) {
++            rendering = false;
++            return;
++        }
++        setEnabled(!uidl.getBooleanAttribute("disabled"));
++
++        clickEventHandler.handleEventHandlerRegistration(client);
++        if (uidl.hasAttribute("style")) {
++            componentStyleNames = uidl.getStringAttribute("style").split(" ");
++        } else {
++            componentStyleNames = new String[0];
++        }
++
++        setLocked(uidl.getBooleanAttribute("locked"));
++
++        setPositionReversed(uidl.getBooleanAttribute("reversed"));
++
++        setStylenames();
++
++        // Ensure panels are still scrollable
++        touchScrollHandler.setElements(firstContainer, secondContainer);
++
++        position = uidl.getStringAttribute("position");
++        setSplitPosition(position);
++
++        final Paintable newFirstChild = client.getPaintable(uidl
++                .getChildUIDL(0));
++        final Paintable newSecondChild = client.getPaintable(uidl
++                .getChildUIDL(1));
++        if (firstChild != newFirstChild) {
++            if (firstChild != null) {
++                client.unregisterPaintable((Paintable) firstChild);
++            }
++            setFirstWidget((Widget) newFirstChild);
++        }
++        if (secondChild != newSecondChild) {
++            if (secondChild != null) {
++                client.unregisterPaintable((Paintable) secondChild);
++            }
++            setSecondWidget((Widget) newSecondChild);
++        }
++        newFirstChild.updateFromUIDL(uidl.getChildUIDL(0), client);
++        newSecondChild.updateFromUIDL(uidl.getChildUIDL(1), client);
++
++        renderInformation.updateSize(getElement());
++
++        if (BrowserInfo.get().isIE7()) {
++            // Part III of IE7 hack
++            Scheduler.get().scheduleDeferred(new Command() {
++                public void execute() {
++                    iLayout();
++                }
++            });
++        }
++
++        // This is needed at least for cases like #3458 to take
++        // appearing/disappearing scrollbars into account.
++        client.runDescendentsLayout(this);
++
++        rendering = false;
++    }
++
++>>>>>>> 8b064
 +    @Override
 +    public boolean remove(Widget w) {
 +        boolean removed = super.remove(w);
 +        if (removed) {
 +            if (firstChild == w) {
 +                firstChild = null;
 +            } else {
 +                secondChild = null;
 +            }
 +        }
 +        return removed;
 +    }
 +
 +    void setLocked(boolean newValue) {
 +        if (locked != newValue) {
 +            locked = newValue;
 +            splitterSize = -1;
 +            setStylenames();
 +        }
 +    }
 +
 +    void setPositionReversed(boolean reversed) {
 +        if (positionReversed != reversed) {
 +            if (orientation == ORIENTATION_HORIZONTAL) {
 +                DOM.setStyleAttribute(splitter, "right", "");
 +                DOM.setStyleAttribute(splitter, "left", "");
 +            } else if (orientation == ORIENTATION_VERTICAL) {
 +                DOM.setStyleAttribute(splitter, "top", "");
 +                DOM.setStyleAttribute(splitter, "bottom", "");
 +            }
 +
 +            positionReversed = reversed;
 +        }
 +    }
 +
 +    void setSplitPosition(String pos) {
 +        if (pos == null) {
 +            return;
 +        }
 +
 +        // Convert percentage values to pixels
 +        if (pos.indexOf("%") > 0) {
 +            int size = orientation == ORIENTATION_HORIZONTAL ? getOffsetWidth()
 +                    : getOffsetHeight();
 +            float percentage = Float.parseFloat(pos.substring(0,
 +                    pos.length() - 1));
 +            pos = percentage / 100 * size + "px";
 +        }
 +
 +        String attributeName;
 +        if (orientation == ORIENTATION_HORIZONTAL) {
 +            if (positionReversed) {
 +                attributeName = "right";
 +            } else {
 +                attributeName = "left";
 +            }
 +        } else {
 +            if (positionReversed) {
 +                attributeName = "bottom";
 +            } else {
 +                attributeName = "top";
 +            }
 +        }
 +
 +        Style style = splitter.getStyle();
 +        if (!pos.equals(style.getProperty(attributeName))) {
 +            style.setProperty(attributeName, pos);
 +            updateSizes();
 +        }
 +    }
 +
 +    void updateSizes() {
 +        if (!isAttached()) {
 +            return;
 +        }
 +
 +        int wholeSize;
 +        int pixelPosition;
 +
 +        switch (orientation) {
 +        case ORIENTATION_HORIZONTAL:
 +            wholeSize = DOM.getElementPropertyInt(wrapper, "clientWidth");
 +            pixelPosition = DOM.getElementPropertyInt(splitter, "offsetLeft");
 +
 +            // reposition splitter in case it is out of box
 +            if ((pixelPosition > 0 && pixelPosition + getSplitterSize() > wholeSize)
 +                    || (positionReversed && pixelPosition < 0)) {
 +                pixelPosition = wholeSize - getSplitterSize();
 +                if (pixelPosition < 0) {
 +                    pixelPosition = 0;
 +                }
 +                setSplitPosition(pixelPosition + "px");
 +                return;
 +            }
 +
 +            DOM.setStyleAttribute(firstContainer, "width", pixelPosition + "px");
 +            int secondContainerWidth = (wholeSize - pixelPosition - getSplitterSize());
 +            if (secondContainerWidth < 0) {
 +                secondContainerWidth = 0;
 +            }
 +            DOM.setStyleAttribute(secondContainer, "width",
 +                    secondContainerWidth + "px");
 +            DOM.setStyleAttribute(secondContainer, "left",
 +                    (pixelPosition + getSplitterSize()) + "px");
 +
 +            LayoutManager layoutManager = LayoutManager.get(client);
 +            ConnectorMap connectorMap = ConnectorMap.get(client);
 +            if (firstChild != null) {
 +                ComponentConnector connector = connectorMap
 +                        .getConnector(firstChild);
 +                if (connector.isRelativeWidth()) {
 +                    layoutManager.reportWidthAssignedToRelative(connector,
 +                            pixelPosition);
 +                } else {
 +                    layoutManager.setNeedsMeasure(connector);
 +                }
 +            }
 +            if (secondChild != null) {
 +                ComponentConnector connector = connectorMap
 +                        .getConnector(secondChild);
 +                if (connector.isRelativeWidth()) {
 +                    layoutManager.reportWidthAssignedToRelative(connector,
 +                            secondContainerWidth);
 +                } else {
 +                    layoutManager.setNeedsMeasure(connector);
 +                }
 +            }
 +            break;
 +        case ORIENTATION_VERTICAL:
 +            wholeSize = DOM.getElementPropertyInt(wrapper, "clientHeight");
 +            pixelPosition = DOM.getElementPropertyInt(splitter, "offsetTop");
 +
 +            // reposition splitter in case it is out of box
 +            if ((pixelPosition > 0 && pixelPosition + getSplitterSize() > wholeSize)
 +                    || (positionReversed && pixelPosition < 0)) {
 +                pixelPosition = wholeSize - getSplitterSize();
 +                if (pixelPosition < 0) {
 +                    pixelPosition = 0;
 +                }
 +                setSplitPosition(pixelPosition + "px");
 +                return;
 +            }
 +
 +            DOM.setStyleAttribute(firstContainer, "height", pixelPosition
 +                    + "px");
 +            int secondContainerHeight = (wholeSize - pixelPosition - getSplitterSize());
 +            if (secondContainerHeight < 0) {
 +                secondContainerHeight = 0;
 +            }
 +            DOM.setStyleAttribute(secondContainer, "height",
 +                    secondContainerHeight + "px");
 +            DOM.setStyleAttribute(secondContainer, "top",
 +                    (pixelPosition + getSplitterSize()) + "px");
 +
 +            layoutManager = LayoutManager.get(client);
 +            connectorMap = ConnectorMap.get(client);
 +            if (firstChild != null) {
 +                ComponentConnector connector = connectorMap
 +                        .getConnector(firstChild);
 +                if (connector.isRelativeHeight()) {
 +                    layoutManager.reportHeightAssignedToRelative(connector,
 +                            pixelPosition);
 +                } else {
 +                    layoutManager.setNeedsMeasure(connector);
 +                }
 +            }
 +            if (secondChild != null) {
 +                ComponentConnector connector = connectorMap
 +                        .getConnector(secondChild);
 +                if (connector.isRelativeHeight()) {
 +                    layoutManager.reportHeightAssignedToRelative(connector,
 +                            secondContainerHeight);
 +                } else {
 +                    layoutManager.setNeedsMeasure(connector);
 +                }
 +            }
 +            break;
 +        }
 +    }
 +
 +    void setFirstWidget(Widget w) {
 +        if (firstChild != null) {
 +            firstChild.removeFromParent();
 +        }
 +        if (w != null) {
 +            super.add(w, firstContainer);
 +        }
 +        firstChild = w;
 +    }
 +
 +    void setSecondWidget(Widget w) {
 +        if (secondChild != null) {
 +            secondChild.removeFromParent();
 +        }
 +        if (w != null) {
 +            super.add(w, secondContainer);
 +        }
 +        secondChild = w;
 +    }
 +
 +    @Override
 +    public void onBrowserEvent(Event event) {
 +        switch (DOM.eventGetType(event)) {
 +        case Event.ONMOUSEMOVE:
 +            // case Event.ONTOUCHMOVE:
 +            if (resizing) {
 +                onMouseMove(event);
 +            }
 +            break;
 +        case Event.ONMOUSEDOWN:
 +            // case Event.ONTOUCHSTART:
 +            onMouseDown(event);
 +            break;
 +        case Event.ONMOUSEOUT:
 +            // Dragging curtain interferes with click events if added in
 +            // mousedown so we add it only when needed i.e., if the mouse moves
 +            // outside the splitter.
 +            if (resizing) {
 +                showDraggingCurtain();
 +            }
 +            break;
 +        case Event.ONMOUSEUP:
 +            // case Event.ONTOUCHEND:
 +            if (resizing) {
 +                onMouseUp(event);
 +            }
 +            break;
 +        case Event.ONCLICK:
 +            resizing = false;
 +            break;
 +        }
 +        // Only fire click event listeners if the splitter isn't moved
 +        if (Util.isTouchEvent(event) || !resized) {
 +            super.onBrowserEvent(event);
 +        } else if (DOM.eventGetType(event) == Event.ONMOUSEUP) {
 +            // Reset the resized flag after a mouseup has occured so the next
 +            // mousedown/mouseup can be interpreted as a click.
 +            resized = false;
 +        }
 +    }
 +
 +    public void onMouseDown(Event event) {
 +        if (locked || !isEnabled()) {
 +            return;
 +        }
 +        final Element trg = event.getEventTarget().cast();
 +        if (trg == splitter || trg == DOM.getChild(splitter, 0)) {
 +            resizing = true;
 +            DOM.setCapture(getElement());
 +            origX = DOM.getElementPropertyInt(splitter, "offsetLeft");
 +            origY = DOM.getElementPropertyInt(splitter, "offsetTop");
 +            origMouseX = Util.getTouchOrMouseClientX(event);
 +            origMouseY = Util.getTouchOrMouseClientY(event);
 +            event.stopPropagation();
 +            event.preventDefault();
 +        }
 +    }
 +
 +    public void onMouseMove(Event event) {
 +        switch (orientation) {
 +        case ORIENTATION_HORIZONTAL:
 +            final int x = Util.getTouchOrMouseClientX(event);
 +            onHorizontalMouseMove(x);
 +            break;
 +        case ORIENTATION_VERTICAL:
 +        default:
 +            final int y = Util.getTouchOrMouseClientY(event);
 +            onVerticalMouseMove(y);
 +            break;
 +        }
 +
 +    }
 +
 +    private void onHorizontalMouseMove(int x) {
 +        int newX = origX + x - origMouseX;
 +        if (newX < 0) {
 +            newX = 0;
 +        }
 +        if (newX + getSplitterSize() > getOffsetWidth()) {
 +            newX = getOffsetWidth() - getSplitterSize();
 +        }
 +
 +        if (position.indexOf("%") > 0) {
 +            float pos = newX;
 +            // 100% needs special handling
 +            if (newX + getSplitterSize() >= getOffsetWidth()) {
 +                pos = getOffsetWidth();
 +            }
 +            // Reversed position
 +            if (positionReversed) {
 +                pos = getOffsetWidth() - pos - getSplitterSize();
 +            }
 +            position = (pos / getOffsetWidth() * 100) + "%";
 +        } else {
 +            // Reversed position
 +            if (positionReversed) {
 +                position = (getOffsetWidth() - newX - getSplitterSize()) + "px";
 +            } else {
 +                position = newX + "px";
 +            }
 +        }
 +
 +        if (origX != newX) {
 +            resized = true;
 +        }
 +
 +        // Reversed position
 +        if (positionReversed) {
 +            newX = getOffsetWidth() - newX - getSplitterSize();
 +        }
 +
 +        setSplitPosition(newX + "px");
 +    }
 +
 +    private void onVerticalMouseMove(int y) {
 +        int newY = origY + y - origMouseY;
 +        if (newY < 0) {
 +            newY = 0;
 +        }
 +
 +        if (newY + getSplitterSize() > getOffsetHeight()) {
 +            newY = getOffsetHeight() - getSplitterSize();
 +        }
 +
 +        if (position.indexOf("%") > 0) {
 +            float pos = newY;
 +            // 100% needs special handling
 +            if (newY + getSplitterSize() >= getOffsetHeight()) {
 +                pos = getOffsetHeight();
 +            }
 +            // Reversed position
 +            if (positionReversed) {
 +                pos = getOffsetHeight() - pos - getSplitterSize();
 +            }
 +            position = pos / getOffsetHeight() * 100 + "%";
 +        } else {
 +            // Reversed position
 +            if (positionReversed) {
 +                position = (getOffsetHeight() - newY - getSplitterSize())
 +                        + "px";
 +            } else {
 +                position = newY + "px";
 +            }
 +        }
 +
 +        if (origY != newY) {
 +            resized = true;
 +        }
 +
 +        // Reversed position
 +        if (positionReversed) {
 +            newY = getOffsetHeight() - newY - getSplitterSize();
 +        }
 +
 +        setSplitPosition(newY + "px");
 +    }
 +
 +    public void onMouseUp(Event event) {
 +        DOM.releaseCapture(getElement());
 +        hideDraggingCurtain();
 +        resizing = false;
 +        if (!Util.isTouchEvent(event)) {
 +            onMouseMove(event);
 +        }
 +        fireEvent(new SplitterMoveEvent(this));
 +    }
 +
 +    public interface SplitterMoveHandler extends EventHandler {
 +        public void splitterMoved(SplitterMoveEvent event);
 +
 +        public static class SplitterMoveEvent extends
 +                GwtEvent<SplitterMoveHandler> {
 +
 +            public static final Type<SplitterMoveHandler> TYPE = new Type<SplitterMoveHandler>();
 +
 +            private Widget splitPanel;
 +
 +            public SplitterMoveEvent(Widget splitPanel) {
 +                this.splitPanel = splitPanel;
 +            }
 +
 +            @Override
 +            public com.google.gwt.event.shared.GwtEvent.Type<SplitterMoveHandler> getAssociatedType() {
 +                return TYPE;
 +            }
 +
 +            @Override
 +            protected void dispatch(SplitterMoveHandler handler) {
 +                handler.splitterMoved(this);
 +            }
 +
 +        }
 +    }
 +
 +    String getSplitterPosition() {
 +        return position;
 +    }
 +
 +    /**
 +     * Used in FF to avoid losing mouse capture when pointer is moved on an
 +     * iframe.
 +     */
 +    private void showDraggingCurtain() {
 +        if (!isDraggingCurtainRequired()) {
 +            return;
 +        }
 +        if (draggingCurtain == null) {
 +            draggingCurtain = DOM.createDiv();
 +            DOM.setStyleAttribute(draggingCurtain, "position", "absolute");
 +            DOM.setStyleAttribute(draggingCurtain, "top", "0px");
 +            DOM.setStyleAttribute(draggingCurtain, "left", "0px");
 +            DOM.setStyleAttribute(draggingCurtain, "width", "100%");
 +            DOM.setStyleAttribute(draggingCurtain, "height", "100%");
 +            DOM.setStyleAttribute(draggingCurtain, "zIndex", ""
 +                    + VOverlay.Z_INDEX);
 +
 +            DOM.appendChild(wrapper, draggingCurtain);
 +        }
 +    }
 +
 +    /**
 +     * A dragging curtain is required in Gecko and Webkit.
 +     * 
 +     * @return true if the browser requires a dragging curtain
 +     */
 +    private boolean isDraggingCurtainRequired() {
 +        return (BrowserInfo.get().isGecko() || BrowserInfo.get().isWebkit());
 +    }
 +
 +    /**
 +     * Hides dragging curtain
 +     */
 +    private void hideDraggingCurtain() {
 +        if (draggingCurtain != null) {
 +            DOM.removeChild(wrapper, draggingCurtain);
 +            draggingCurtain = null;
 +        }
 +    }
 +
 +    private int splitterSize = -1;
 +
 +    private int getSplitterSize() {
 +        if (splitterSize < 0) {
 +            if (isAttached()) {
 +                switch (orientation) {
 +                case ORIENTATION_HORIZONTAL:
 +                    splitterSize = DOM.getElementPropertyInt(splitter,
 +                            "offsetWidth");
 +                    break;
 +
 +                default:
 +                    splitterSize = DOM.getElementPropertyInt(splitter,
 +                            "offsetHeight");
 +                    break;
 +                }
 +            }
 +        }
 +        return splitterSize;
 +    }
 +
 +    private void setStylenames() {
 +        final String splitterClass = CLASSNAME
 +                + (orientation == ORIENTATION_HORIZONTAL ? "-hsplitter"
 +                        : "-vsplitter");
 +        final String firstContainerClass = CLASSNAME + "-first-container";
 +        final String secondContainerClass = CLASSNAME + "-second-container";
 +        final String lockedSuffix = locked ? "-locked" : "";
 +
++        splitter.setClassName(splitterClass + lockedSuffix);
++        firstContainer.setClassName(firstContainerClass);
++        secondContainer.setClassName(secondContainerClass);
 +
 +        for (String styleName : componentStyleNames) {
 +            splitter.addClassName(splitterClass + "-" + styleName
 +                    + lockedSuffix);
 +            firstContainer.addClassName(firstContainerClass + "-" + styleName);
 +            secondContainer
 +                    .addClassName(secondContainerClass + "-" + styleName);
 +        }
 +    }
 +
 +    public void setEnabled(boolean enabled) {
 +        this.enabled = enabled;
 +    }
 +
 +    public boolean isEnabled() {
 +        return enabled;
 +    }
 +
 +}