]> source.dussan.org Git - vaadin-framework.git/commitdiff
#8324 Split split panel classes into widget and paintable
authorArtur Signell <artur@vaadin.com>
Tue, 31 Jan 2012 11:58:13 +0000 (13:58 +0200)
committerArtur Signell <artur@vaadin.com>
Tue, 31 Jan 2012 13:08:37 +0000 (15:08 +0200)
src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java [deleted file]
src/com/vaadin/terminal/gwt/client/ui/VSplitPanelHorizontal.java
src/com/vaadin/terminal/gwt/client/ui/VSplitPanelVertical.java
src/com/vaadin/terminal/gwt/client/ui/VVerticalSplitPanelPaintable.java [new file with mode: 0644]
src/com/vaadin/ui/AbstractSplitPanel.java
src/com/vaadin/ui/HorizontalSplitPanel.java
src/com/vaadin/ui/SplitPanel.java
src/com/vaadin/ui/VerticalSplitPanel.java

diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java
new file mode 100644 (file)
index 0000000..1aa9d92
--- /dev/null
@@ -0,0 +1,736 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Set;
+
+import com.google.gwt.dom.client.Node;
+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.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.Container;
+import com.vaadin.terminal.gwt.client.ContainerResizedListener;
+import com.vaadin.terminal.gwt.client.RenderInformation;
+import com.vaadin.terminal.gwt.client.RenderSpace;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VConsole;
+
+public class VAbstractSplitPanel extends ComplexPanel implements Container,
+        ContainerResizedListener {
+
+    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;
+
+    String[] componentStyleNames;
+
+    private Element draggingCurtain;
+
+    ApplicationConnection client;
+
+    private String width = "";
+
+    private String height = "";
+
+    private RenderSpace firstRenderSpace = new RenderSpace(0, 0, true);
+    private RenderSpace secondRenderSpace = new RenderSpace(0, 0, true);
+
+    RenderInformation renderInformation = new RenderInformation();
+
+    String id;
+
+    boolean immediate;
+
+    boolean rendering = false;
+
+    /* The current position of the split handle in either percentages or pixels */
+    String position;
+
+    protected Element scrolledContainer;
+
+    protected int origScrollTop;
+
+    private TouchScrollDelegate touchScrollDelegate;
+
+    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);
+
+        addDomHandler(new TouchCancelHandler() {
+            public void onTouchCancel(TouchCancelEvent event) {
+                // TODO When does this actually happen??
+                VConsole.log("TOUCH CANCEL");
+            }
+        }, TouchCancelEvent.getType());
+        addDomHandler(new TouchStartHandler() {
+            public void onTouchStart(TouchStartEvent event) {
+                Node target = event.getTouches().get(0).getTarget().cast();
+                if (splitter.isOrHasChild(target)) {
+                    onMouseDown(Event.as(event.getNativeEvent()));
+                } else {
+                    getTouchScrollDelegate().onTouchStart(event);
+                }
+            }
+
+        }, TouchStartEvent.getType());
+        addDomHandler(new TouchMoveHandler() {
+            public void onTouchMove(TouchMoveEvent event) {
+                if (resizing) {
+                    onMouseMove(Event.as(event.getNativeEvent()));
+                }
+            }
+        }, TouchMoveEvent.getType());
+        addDomHandler(new TouchEndHandler() {
+            public void onTouchEnd(TouchEndEvent event) {
+                if (resizing) {
+                    onMouseUp(Event.as(event.getNativeEvent()));
+                }
+            }
+        }, TouchEndEvent.getType());
+
+    }
+
+    private TouchScrollDelegate getTouchScrollDelegate() {
+        if (touchScrollDelegate == null) {
+            touchScrollDelegate = new TouchScrollDelegate(firstContainer,
+                    secondContainer);
+        }
+        return touchScrollDelegate;
+    }
+
+    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");
+
+        DOM.setStyleAttribute(firstContainer, "overflow", "auto");
+        DOM.setStyleAttribute(secondContainer, "overflow", "auto");
+
+    }
+
+    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%");
+        }
+
+        DOM.setElementProperty(firstContainer, "className", CLASSNAME
+                + "-first-container");
+        DOM.setElementProperty(secondContainer, "className", CLASSNAME
+                + "-second-container");
+    }
+
+    @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) {
+            pos = Float.parseFloat(pos.substring(0, pos.length() - 1))
+                    / 100
+                    * (orientation == ORIENTATION_HORIZONTAL ? getOffsetWidth()
+                            : getOffsetHeight()) + "px";
+        }
+
+        if (orientation == ORIENTATION_HORIZONTAL) {
+            if (positionReversed) {
+                DOM.setStyleAttribute(splitter, "right", pos);
+            } else {
+                DOM.setStyleAttribute(splitter, "left", pos);
+            }
+        } else {
+            if (positionReversed) {
+                DOM.setStyleAttribute(splitter, "bottom", pos);
+            } else {
+                DOM.setStyleAttribute(splitter, "top", pos);
+            }
+        }
+
+        iLayout();
+        client.runDescendentsLayout(this);
+    }
+
+    /*
+     * Calculates absolutely positioned container places/sizes (non-Javadoc)
+     * 
+     * @see com.vaadin.terminal.gwt.client.NeedsLayout#layout()
+     */
+    public void iLayout() {
+        if (!isAttached()) {
+            return;
+        }
+
+        renderInformation.updateSize(getElement());
+
+        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");
+
+            int contentHeight = renderInformation.getRenderedSize().getHeight();
+            firstRenderSpace.setHeight(contentHeight);
+            firstRenderSpace.setWidth(pixelPosition);
+            secondRenderSpace.setHeight(contentHeight);
+            secondRenderSpace.setWidth(secondContainerWidth);
+
+            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");
+
+            int contentWidth = renderInformation.getRenderedSize().getWidth();
+            firstRenderSpace.setHeight(pixelPosition);
+            firstRenderSpace.setWidth(contentWidth);
+            secondRenderSpace.setHeight(secondContainerHeight);
+            secondRenderSpace.setWidth(contentWidth);
+
+            break;
+        }
+
+        // fixes scrollbars issues on webkit based browsers
+        Util.runWebkitOverflowAutoFix(secondContainer);
+        Util.runWebkitOverflowAutoFix(firstContainer);
+
+    }
+
+    void setFirstWidget(Widget w) {
+        if (firstChild != null) {
+            firstChild.removeFromParent();
+        }
+        super.add(w, firstContainer);
+        firstChild = w;
+    }
+
+    void setSecondWidget(Widget w) {
+        if (secondChild != null) {
+            secondChild.removeFromParent();
+        }
+        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;
+            }
+            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);
+        }
+        updateSplitPositionToServer();
+    }
+
+    /**
+     * 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;
+    }
+
+    @Override
+    public void setHeight(String height) {
+        if (this.height.equals(height)) {
+            return;
+        }
+
+        this.height = height;
+        super.setHeight(height);
+
+        if (!rendering && client != null) {
+            setSplitPosition(position);
+        }
+    }
+
+    @Override
+    public void setWidth(String width) {
+        if (this.width.equals(width)) {
+            return;
+        }
+
+        this.width = width;
+        super.setWidth(width);
+
+        if (!rendering && client != null) {
+            setSplitPosition(position);
+        }
+    }
+
+    public RenderSpace getAllocatedSpace(Widget child) {
+        if (child == firstChild) {
+            return firstRenderSpace;
+        } else if (child == secondChild) {
+            return secondRenderSpace;
+        }
+
+        return null;
+    }
+
+    public boolean hasChildComponent(Widget component) {
+        return (component != null && (component == firstChild || component == secondChild));
+    }
+
+    public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
+        if (oldComponent == firstChild) {
+            setFirstWidget(newComponent);
+        } else if (oldComponent == secondChild) {
+            setSecondWidget(newComponent);
+        }
+    }
+
+    public boolean requestLayout(Set<Widget> children) {
+        // content size change might cause change to its available space
+        // (scrollbars)
+        for (Widget widget : children) {
+            client.handleComponentRelativeSize(widget);
+        }
+        if (height != null && width != null) {
+            /*
+             * If the height and width has been specified the child components
+             * cannot make the size of the layout change
+             */
+
+            return true;
+        }
+
+        if (renderInformation.updateSize(getElement())) {
+            return false;
+        } else {
+            return true;
+        }
+
+    }
+
+    /**
+     * Updates the new split position back to server.
+     */
+    private void updateSplitPositionToServer() {
+        int pos = 0;
+        if (position.indexOf("%") > 0) {
+            pos = Math.round(Float.valueOf(position.substring(0,
+                    position.length() - 1)));
+        } else {
+            pos = Integer
+                    .parseInt(position.substring(0, position.length() - 2));
+        }
+        client.updateVariable(id, "position", pos, immediate);
+    }
+
+    void setStylenames() {
+        final String splitterSuffix = (orientation == ORIENTATION_HORIZONTAL ? "-hsplitter"
+                : "-vsplitter");
+        final String firstContainerSuffix = "-first-container";
+        final String secondContainerSuffix = "-second-container";
+        String lockedSuffix = "";
+
+        String splitterStyle = CLASSNAME + splitterSuffix;
+        String firstStyle = CLASSNAME + firstContainerSuffix;
+        String secondStyle = CLASSNAME + secondContainerSuffix;
+
+        if (locked) {
+            splitterStyle = CLASSNAME + splitterSuffix + "-locked";
+            lockedSuffix = "-locked";
+        }
+        for (int i = 0; i < componentStyleNames.length; i++) {
+            splitterStyle += " " + CLASSNAME + splitterSuffix + "-"
+                    + componentStyleNames[i] + lockedSuffix;
+            firstStyle += " " + CLASSNAME + firstContainerSuffix + "-"
+                    + componentStyleNames[i];
+            secondStyle += " " + CLASSNAME + secondContainerSuffix + "-"
+                    + componentStyleNames[i];
+        }
+        DOM.setElementProperty(splitter, "className", splitterStyle);
+        DOM.setElementProperty(firstContainer, "className", firstStyle);
+        DOM.setElementProperty(secondContainer, "className", secondStyle);
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public Widget getWidgetForPaintable() {
+        return this;
+    }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java
new file mode 100644 (file)
index 0000000..1ff066d
--- /dev/null
@@ -0,0 +1,140 @@
+package com.vaadin.terminal.gwt.client.ui;\r
+\r
+import com.google.gwt.dom.client.NativeEvent;\r
+import com.google.gwt.event.dom.client.DomEvent.Type;\r
+import com.google.gwt.event.shared.EventHandler;\r
+import com.google.gwt.event.shared.HandlerRegistration;\r
+import com.google.gwt.user.client.Element;\r
+import com.google.gwt.user.client.Event;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
+import com.vaadin.terminal.gwt.client.UIDL;\r
+import com.vaadin.terminal.gwt.client.VPaintableMap;\r
+import com.vaadin.terminal.gwt.client.VPaintableWidget;\r
+\r
+public abstract class VAbstractSplitPanelPaintable extends\r
+        VAbstractPaintableWidgetContainer {\r
+\r
+    public static final String SPLITTER_CLICK_EVENT_IDENTIFIER = "sp_click";\r
+\r
+    public void updateCaption(VPaintableWidget component, UIDL uidl) {\r
+        // TODO Implement caption handling\r
+    }\r
+\r
+    ClickEventHandler clickEventHandler = new ClickEventHandler(this,\r
+            SPLITTER_CLICK_EVENT_IDENTIFIER) {\r
+\r
+        @Override\r
+        protected <H extends EventHandler> HandlerRegistration registerHandler(\r
+                H handler, Type<H> type) {\r
+            if ((Event.getEventsSunk(getWidgetForPaintable().splitter) & Event\r
+                    .getTypeInt(type.getName())) != 0) {\r
+                // If we are already sinking the event for the splitter we do\r
+                // not want to additionally sink it for the root element\r
+                return getWidgetForPaintable().addHandler(handler, type);\r
+            } else {\r
+                return getWidgetForPaintable().addDomHandler(handler, type);\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void onContextMenu(\r
+                com.google.gwt.event.dom.client.ContextMenuEvent event) {\r
+            Element target = event.getNativeEvent().getEventTarget().cast();\r
+            if (getWidgetForPaintable().splitter.isOrHasChild(target)) {\r
+                super.onContextMenu(event);\r
+            }\r
+        };\r
+\r
+        @Override\r
+        protected void fireClick(NativeEvent event) {\r
+            Element target = event.getEventTarget().cast();\r
+            if (getWidgetForPaintable().splitter.isOrHasChild(target)) {\r
+                super.fireClick(event);\r
+            }\r
+        }\r
+\r
+        @Override\r
+        protected Element getRelativeToElement() {\r
+            return null;\r
+        }\r
+\r
+    };\r
+\r
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
+        getWidgetForPaintable().client = client;\r
+        getWidgetForPaintable().id = uidl.getId();\r
+        getWidgetForPaintable().rendering = true;\r
+\r
+        getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");\r
+\r
+        if (client.updateComponent(this, uidl, true)) {\r
+            getWidgetForPaintable().rendering = false;\r
+            return;\r
+        }\r
+        getWidgetForPaintable().setEnabled(\r
+                !uidl.getBooleanAttribute("disabled"));\r
+\r
+        clickEventHandler.handleEventHandlerRegistration(client);\r
+        if (uidl.hasAttribute("style")) {\r
+            getWidgetForPaintable().componentStyleNames = uidl\r
+                    .getStringAttribute("style").split(" ");\r
+        } else {\r
+            getWidgetForPaintable().componentStyleNames = new String[0];\r
+        }\r
+\r
+        getWidgetForPaintable().setLocked(uidl.getBooleanAttribute("locked"));\r
+\r
+        getWidgetForPaintable().setPositionReversed(\r
+                uidl.getBooleanAttribute("reversed"));\r
+\r
+        getWidgetForPaintable().setStylenames();\r
+\r
+        getWidgetForPaintable().position = uidl.getStringAttribute("position");\r
+        getWidgetForPaintable().setSplitPosition(\r
+                getWidgetForPaintable().position);\r
+\r
+        final VPaintableWidget newFirstChildPaintable = client\r
+                .getPaintable(uidl.getChildUIDL(0));\r
+        final VPaintableWidget newSecondChildPaintable = client\r
+                .getPaintable(uidl.getChildUIDL(1));\r
+        Widget newFirstChild = newFirstChildPaintable.getWidgetForPaintable();\r
+        Widget newSecondChild = newSecondChildPaintable.getWidgetForPaintable();\r
+\r
+        if (getWidgetForPaintable().firstChild != newFirstChild) {\r
+            if (getWidgetForPaintable().firstChild != null) {\r
+                client.unregisterPaintable(VPaintableMap.get(client)\r
+                        .getPaintable(getWidgetForPaintable().firstChild));\r
+            }\r
+            getWidgetForPaintable().setFirstWidget(newFirstChild);\r
+        }\r
+        if (getWidgetForPaintable().secondChild != newSecondChild) {\r
+            if (getWidgetForPaintable().secondChild != null) {\r
+                client.unregisterPaintable(VPaintableMap.get(client)\r
+                        .getPaintable(getWidgetForPaintable().secondChild));\r
+            }\r
+            getWidgetForPaintable().setSecondWidget(newSecondChild);\r
+        }\r
+        newFirstChildPaintable.updateFromUIDL(uidl.getChildUIDL(0), client);\r
+        newSecondChildPaintable.updateFromUIDL(uidl.getChildUIDL(1), client);\r
+\r
+        getWidgetForPaintable().renderInformation\r
+                .updateSize(getWidgetForPaintable().getElement());\r
+\r
+        // This is needed at least for cases like #3458 to take\r
+        // appearing/disappearing scrollbars into account.\r
+        client.runDescendentsLayout(getWidgetForPaintable());\r
+\r
+        getWidgetForPaintable().rendering = false;\r
+\r
+    }\r
+\r
+    @Override\r
+    public VAbstractSplitPanel getWidgetForPaintable() {\r
+        return (VAbstractSplitPanel) super.getWidgetForPaintable();\r
+    }\r
+\r
+    @Override\r
+    protected abstract VAbstractSplitPanel createWidget();\r
+\r
+}\r
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java
new file mode 100644 (file)
index 0000000..2340ceb
--- /dev/null
@@ -0,0 +1,13 @@
+package com.vaadin.terminal.gwt.client.ui;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+\r
+public class VHorizontalSplitPanelPaintable extends\r
+        VAbstractSplitPanelPaintable {\r
+\r
+    @Override\r
+    protected VAbstractSplitPanel createWidget() {\r
+        return GWT.create(VSplitPanelHorizontal.class);\r
+    }\r
+\r
+}\r
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java
deleted file mode 100644 (file)
index 0d44609..0000000
+++ /dev/null
@@ -1,852 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Set;
-
-import com.google.gwt.dom.client.NativeEvent;
-import com.google.gwt.dom.client.Node;
-import com.google.gwt.event.dom.client.DomEvent.Type;
-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.HandlerRegistration;
-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.Container;
-import com.vaadin.terminal.gwt.client.ContainerResizedListener;
-import com.vaadin.terminal.gwt.client.RenderInformation;
-import com.vaadin.terminal.gwt.client.RenderSpace;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VConsole;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-
-public class VSplitPanel extends ComplexPanel implements Container,
-        ContainerResizedListener {
-
-    private boolean enabled = false;
-
-    public static final String CLASSNAME = "v-splitpanel";
-
-    public static final String SPLITTER_CLICK_EVENT_IDENTIFIER = "sp_click";
-
-    private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
-            SPLITTER_CLICK_EVENT_IDENTIFIER) {
-
-        @Override
-        protected <H extends EventHandler> HandlerRegistration registerHandler(
-                H handler, Type<H> type) {
-            if ((Event.getEventsSunk(splitter) & Event.getTypeInt(type
-                    .getName())) != 0) {
-                // If we are already sinking the event for the splitter we do
-                // not want to additionally sink it for the root element
-                return addHandler(handler, type);
-            } else {
-                return addDomHandler(handler, type);
-            }
-        }
-
-        @Override
-        public void onContextMenu(
-                com.google.gwt.event.dom.client.ContextMenuEvent event) {
-            Element target = event.getNativeEvent().getEventTarget().cast();
-            if (splitter.isOrHasChild(target)) {
-                super.onContextMenu(event);
-            }
-        };
-
-        @Override
-        protected void fireClick(NativeEvent event) {
-            Element target = event.getEventTarget().cast();
-            if (splitter.isOrHasChild(target)) {
-                super.fireClick(event);
-            }
-        }
-
-        @Override
-        protected Element getRelativeToElement() {
-            return null;
-        }
-
-    };
-
-    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;
-
-    private Widget firstChild;
-
-    private Widget secondChild;
-
-    private final Element wrapper = DOM.createDiv();
-
-    private final Element firstContainer = DOM.createDiv();
-
-    private final Element secondContainer = DOM.createDiv();
-
-    private 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;
-
-    private String[] componentStyleNames;
-
-    private Element draggingCurtain;
-
-    private ApplicationConnection client;
-
-    private String width = "";
-
-    private String height = "";
-
-    private RenderSpace firstRenderSpace = new RenderSpace(0, 0, true);
-    private RenderSpace secondRenderSpace = new RenderSpace(0, 0, true);
-
-    RenderInformation renderInformation = new RenderInformation();
-
-    private String id;
-
-    private boolean immediate;
-
-    private boolean rendering = false;
-
-    /* The current position of the split handle in either percentages or pixels */
-    private String position;
-
-    protected Element scrolledContainer;
-
-    protected int origScrollTop;
-
-    private TouchScrollDelegate touchScrollDelegate;
-
-    public VSplitPanel() {
-        this(ORIENTATION_HORIZONTAL);
-    }
-
-    public VSplitPanel(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);
-
-        addDomHandler(new TouchCancelHandler() {
-            public void onTouchCancel(TouchCancelEvent event) {
-                // TODO When does this actually happen??
-                VConsole.log("TOUCH CANCEL");
-            }
-        }, TouchCancelEvent.getType());
-        addDomHandler(new TouchStartHandler() {
-            public void onTouchStart(TouchStartEvent event) {
-                Node target = event.getTouches().get(0).getTarget().cast();
-                if (splitter.isOrHasChild(target)) {
-                    onMouseDown(Event.as(event.getNativeEvent()));
-                } else {
-                    getTouchScrollDelegate().onTouchStart(event);
-                }
-            }
-
-        }, TouchStartEvent.getType());
-        addDomHandler(new TouchMoveHandler() {
-            public void onTouchMove(TouchMoveEvent event) {
-                if (resizing) {
-                    onMouseMove(Event.as(event.getNativeEvent()));
-                }
-            }
-        }, TouchMoveEvent.getType());
-        addDomHandler(new TouchEndHandler() {
-            public void onTouchEnd(TouchEndEvent event) {
-                if (resizing) {
-                    onMouseUp(Event.as(event.getNativeEvent()));
-                }
-            }
-        }, TouchEndEvent.getType());
-
-    }
-
-    private TouchScrollDelegate getTouchScrollDelegate() {
-        if (touchScrollDelegate == null) {
-            touchScrollDelegate = new TouchScrollDelegate(firstContainer,
-                    secondContainer);
-        }
-        return touchScrollDelegate;
-    }
-
-    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");
-
-        DOM.setStyleAttribute(firstContainer, "overflow", "auto");
-        DOM.setStyleAttribute(secondContainer, "overflow", "auto");
-
-    }
-
-    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%");
-        }
-
-        DOM.setElementProperty(firstContainer, "className", CLASSNAME
-                + "-first-container");
-        DOM.setElementProperty(secondContainer, "className", CLASSNAME
-                + "-second-container");
-    }
-
-    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();
-
-        position = uidl.getStringAttribute("position");
-        setSplitPosition(position);
-
-        final VPaintableWidget newFirstChildPaintable = client
-                .getPaintable(uidl.getChildUIDL(0));
-        final VPaintableWidget newSecondChildPaintable = client
-                .getPaintable(uidl.getChildUIDL(1));
-        Widget newFirstChild = newFirstChildPaintable.getWidgetForPaintable();
-        Widget newSecondChild = newSecondChildPaintable.getWidgetForPaintable();
-
-        if (firstChild != newFirstChild) {
-            if (firstChild != null) {
-                client.unregisterPaintable(VPaintableMap.get(client)
-                        .getPaintable(firstChild));
-            }
-            setFirstWidget(newFirstChild);
-        }
-        if (secondChild != newSecondChild) {
-            if (secondChild != null) {
-                client.unregisterPaintable(VPaintableMap.get(client)
-                        .getPaintable(secondChild));
-            }
-            setSecondWidget(newSecondChild);
-        }
-        newFirstChildPaintable.updateFromUIDL(uidl.getChildUIDL(0), client);
-        newSecondChildPaintable.updateFromUIDL(uidl.getChildUIDL(1), client);
-
-        renderInformation.updateSize(getElement());
-
-        // This is needed at least for cases like #3458 to take
-        // appearing/disappearing scrollbars into account.
-        client.runDescendentsLayout(this);
-
-        rendering = false;
-
-    }
-
-    @Override
-    public boolean remove(Widget w) {
-        boolean removed = super.remove(w);
-        if (removed) {
-            if (firstChild == w) {
-                firstChild = null;
-            } else {
-                secondChild = null;
-            }
-        }
-        return removed;
-    }
-
-    private void setLocked(boolean newValue) {
-        if (locked != newValue) {
-            locked = newValue;
-            splitterSize = -1;
-            setStylenames();
-        }
-    }
-
-    private 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;
-        }
-    }
-
-    private void setSplitPosition(String pos) {
-        if (pos == null) {
-            return;
-        }
-
-        // Convert percentage values to pixels
-        if (pos.indexOf("%") > 0) {
-            pos = Float.parseFloat(pos.substring(0, pos.length() - 1))
-                    / 100
-                    * (orientation == ORIENTATION_HORIZONTAL ? getOffsetWidth()
-                            : getOffsetHeight()) + "px";
-        }
-
-        if (orientation == ORIENTATION_HORIZONTAL) {
-            if (positionReversed) {
-                DOM.setStyleAttribute(splitter, "right", pos);
-            } else {
-                DOM.setStyleAttribute(splitter, "left", pos);
-            }
-        } else {
-            if (positionReversed) {
-                DOM.setStyleAttribute(splitter, "bottom", pos);
-            } else {
-                DOM.setStyleAttribute(splitter, "top", pos);
-            }
-        }
-
-        iLayout();
-        client.runDescendentsLayout(this);
-    }
-
-    /*
-     * Calculates absolutely positioned container places/sizes (non-Javadoc)
-     * 
-     * @see com.vaadin.terminal.gwt.client.NeedsLayout#layout()
-     */
-    public void iLayout() {
-        if (!isAttached()) {
-            return;
-        }
-
-        renderInformation.updateSize(getElement());
-
-        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");
-
-            int contentHeight = renderInformation.getRenderedSize().getHeight();
-            firstRenderSpace.setHeight(contentHeight);
-            firstRenderSpace.setWidth(pixelPosition);
-            secondRenderSpace.setHeight(contentHeight);
-            secondRenderSpace.setWidth(secondContainerWidth);
-
-            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");
-
-            int contentWidth = renderInformation.getRenderedSize().getWidth();
-            firstRenderSpace.setHeight(pixelPosition);
-            firstRenderSpace.setWidth(contentWidth);
-            secondRenderSpace.setHeight(secondContainerHeight);
-            secondRenderSpace.setWidth(contentWidth);
-
-            break;
-        }
-
-        // fixes scrollbars issues on webkit based browsers
-        Util.runWebkitOverflowAutoFix(secondContainer);
-        Util.runWebkitOverflowAutoFix(firstContainer);
-
-    }
-
-    private void setFirstWidget(Widget w) {
-        if (firstChild != null) {
-            firstChild.removeFromParent();
-        }
-        super.add(w, firstContainer);
-        firstChild = w;
-    }
-
-    private void setSecondWidget(Widget w) {
-        if (secondChild != null) {
-            secondChild.removeFromParent();
-        }
-        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;
-            }
-            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);
-        }
-        updateSplitPositionToServer();
-    }
-
-    /**
-     * 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;
-    }
-
-    @Override
-    public void setHeight(String height) {
-        if (this.height.equals(height)) {
-            return;
-        }
-
-        this.height = height;
-        super.setHeight(height);
-
-        if (!rendering && client != null) {
-            setSplitPosition(position);
-        }
-    }
-
-    @Override
-    public void setWidth(String width) {
-        if (this.width.equals(width)) {
-            return;
-        }
-
-        this.width = width;
-        super.setWidth(width);
-
-        if (!rendering && client != null) {
-            setSplitPosition(position);
-        }
-    }
-
-    public RenderSpace getAllocatedSpace(Widget child) {
-        if (child == firstChild) {
-            return firstRenderSpace;
-        } else if (child == secondChild) {
-            return secondRenderSpace;
-        }
-
-        return null;
-    }
-
-    public boolean hasChildComponent(Widget component) {
-        return (component != null && (component == firstChild || component == secondChild));
-    }
-
-    public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
-        if (oldComponent == firstChild) {
-            setFirstWidget(newComponent);
-        } else if (oldComponent == secondChild) {
-            setSecondWidget(newComponent);
-        }
-    }
-
-    public boolean requestLayout(Set<Widget> children) {
-        // content size change might cause change to its available space
-        // (scrollbars)
-        for (Widget widget : children) {
-            client.handleComponentRelativeSize(widget);
-        }
-        if (height != null && width != null) {
-            /*
-             * If the height and width has been specified the child components
-             * cannot make the size of the layout change
-             */
-
-            return true;
-        }
-
-        if (renderInformation.updateSize(getElement())) {
-            return false;
-        } else {
-            return true;
-        }
-
-    }
-
-    public void updateCaption(VPaintableWidget component, UIDL uidl) {
-        // TODO Implement caption handling
-    }
-
-    /**
-     * Updates the new split position back to server.
-     */
-    private void updateSplitPositionToServer() {
-        int pos = 0;
-        if (position.indexOf("%") > 0) {
-            pos = Math.round(Float.valueOf(position.substring(0,
-                    position.length() - 1)));
-        } else {
-            pos = Integer
-                    .parseInt(position.substring(0, position.length() - 2));
-        }
-        client.updateVariable(id, "position", pos, immediate);
-    }
-
-    private void setStylenames() {
-        final String splitterSuffix = (orientation == ORIENTATION_HORIZONTAL ? "-hsplitter"
-                : "-vsplitter");
-        final String firstContainerSuffix = "-first-container";
-        final String secondContainerSuffix = "-second-container";
-        String lockedSuffix = "";
-
-        String splitterStyle = CLASSNAME + splitterSuffix;
-        String firstStyle = CLASSNAME + firstContainerSuffix;
-        String secondStyle = CLASSNAME + secondContainerSuffix;
-
-        if (locked) {
-            splitterStyle = CLASSNAME + splitterSuffix + "-locked";
-            lockedSuffix = "-locked";
-        }
-        for (int i = 0; i < componentStyleNames.length; i++) {
-            splitterStyle += " " + CLASSNAME + splitterSuffix + "-"
-                    + componentStyleNames[i] + lockedSuffix;
-            firstStyle += " " + CLASSNAME + firstContainerSuffix + "-"
-                    + componentStyleNames[i];
-            secondStyle += " " + CLASSNAME + secondContainerSuffix + "-"
-                    + componentStyleNames[i];
-        }
-        DOM.setElementProperty(splitter, "className", splitterStyle);
-        DOM.setElementProperty(firstContainer, "className", firstStyle);
-        DOM.setElementProperty(secondContainer, "className", secondStyle);
-    }
-
-    public void setEnabled(boolean enabled) {
-        this.enabled = enabled;
-    }
-
-    public boolean isEnabled() {
-        return enabled;
-    }
-
-    public Widget getWidgetForPaintable() {
-        return this;
-    }
-}
index ff1e2e6b7843eb86cc9cbacc2dc05251e28073e8..3902f064a5a88db864d7a1dcaadcf0ee8a989318 100644 (file)
@@ -4,9 +4,9 @@
 
 package com.vaadin.terminal.gwt.client.ui;
 
-public class VSplitPanelHorizontal extends VSplitPanel {
+public class VSplitPanelHorizontal extends VAbstractSplitPanel {
 
     public VSplitPanelHorizontal() {
-        super(VSplitPanel.ORIENTATION_HORIZONTAL);
+        super(VAbstractSplitPanel.ORIENTATION_HORIZONTAL);
     }
 }
index dcf7622e50244283f36310d793d99b9e21b5caff..e61f8cf5e5a8093991c65e7d865b2d57af0e1fb1 100644 (file)
@@ -4,9 +4,9 @@
 
 package com.vaadin.terminal.gwt.client.ui;
 
-public class VSplitPanelVertical extends VSplitPanel {
+public class VSplitPanelVertical extends VAbstractSplitPanel {
 
     public VSplitPanelVertical() {
-        super(VSplitPanel.ORIENTATION_VERTICAL);
+        super(VAbstractSplitPanel.ORIENTATION_VERTICAL);
     }
 }
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VVerticalSplitPanelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VVerticalSplitPanelPaintable.java
new file mode 100644 (file)
index 0000000..d60a318
--- /dev/null
@@ -0,0 +1,12 @@
+package com.vaadin.terminal.gwt.client.ui;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+\r
+public class VVerticalSplitPanelPaintable extends VAbstractSplitPanelPaintable {\r
+\r
+    @Override\r
+    protected VAbstractSplitPanel createWidget() {\r
+        return GWT.create(VSplitPanelVertical.class);\r
+    }\r
+\r
+}\r
index e0a2d24aaa81beae190fc88d9b8001671fda3fda..e03e73a7819081a79d5705609fc2e3b5b1778c82 100644 (file)
@@ -15,7 +15,7 @@ import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Sizeable;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.ui.VSplitPanel;
+import com.vaadin.terminal.gwt.client.ui.VAbstractSplitPanelPaintable;
 import com.vaadin.tools.ReflectTools;
 
 /**
@@ -43,7 +43,7 @@ public abstract class AbstractSplitPanel extends AbstractLayout {
 
     private boolean locked = false;
 
-    private static final String SPLITTER_CLICK_EVENT = VSplitPanel.SPLITTER_CLICK_EVENT_IDENTIFIER;
+    private static final String SPLITTER_CLICK_EVENT = VAbstractSplitPanelPaintable.SPLITTER_CLICK_EVENT_IDENTIFIER;
 
     /**
      * Modifiable and Serializable Iterator for the components, used by
index d9368635df901d75a68efa9f8baf0c06fc18d60e..d4a1e7cc0e2201672eb3066547f2385c2fc651a5 100644 (file)
@@ -3,7 +3,7 @@
  */
 package com.vaadin.ui;
 
-import com.vaadin.terminal.gwt.client.ui.VSplitPanelHorizontal;
+import com.vaadin.terminal.gwt.client.ui.VHorizontalSplitPanelPaintable;
 import com.vaadin.ui.ClientWidget.LoadStyle;
 
 /**
@@ -29,7 +29,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
  * @VERSION@
  * @since 6.5
  */
-@ClientWidget(value = VSplitPanelHorizontal.class, loadStyle = LoadStyle.EAGER)
+@ClientWidget(value = VHorizontalSplitPanelPaintable.class, loadStyle = LoadStyle.EAGER)
 public class HorizontalSplitPanel extends AbstractSplitPanel {
     public HorizontalSplitPanel() {
         super();
index bae1bf7ce02697d806e0c8240733139d344633fb..f4c5b7e66624c490409fe88c413cce0e82952d40 100644 (file)
@@ -6,7 +6,7 @@ package com.vaadin.ui;
 
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VSplitPanelHorizontal;
+import com.vaadin.terminal.gwt.client.ui.VHorizontalSplitPanelPaintable;
 import com.vaadin.ui.ClientWidget.LoadStyle;
 
 /**
@@ -23,7 +23,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
  *             {@link VerticalSplitPanel} instead.
  */
 @Deprecated
-@ClientWidget(value = VSplitPanelHorizontal.class, loadStyle = LoadStyle.EAGER)
+@ClientWidget(value = VHorizontalSplitPanelPaintable.class, loadStyle = LoadStyle.EAGER)
 public class SplitPanel extends AbstractSplitPanel {
 
     /* Predefined orientations */
index 699bd9287c23dd16841a4bae608f4a088eb401c7..46e9d681e8fa895d7b6736b081dd4347f0e34a2f 100644 (file)
@@ -3,7 +3,7 @@
  */
 package com.vaadin.ui;
 
-import com.vaadin.terminal.gwt.client.ui.VSplitPanelVertical;
+import com.vaadin.terminal.gwt.client.ui.VVerticalSplitPanelPaintable;
 import com.vaadin.ui.ClientWidget.LoadStyle;
 
 /**
@@ -23,7 +23,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
  * </pre>
  * 
  */
-@ClientWidget(value = VSplitPanelVertical.class, loadStyle = LoadStyle.EAGER)
+@ClientWidget(value = VVerticalSplitPanelPaintable.class, loadStyle = LoadStyle.EAGER)
 public class VerticalSplitPanel extends AbstractSplitPanel {
 
     public VerticalSplitPanel() {