Package org.vaadin.alump.fancylayouts.gwt.client

Source Code of org.vaadin.alump.fancylayouts.gwt.client.GwtFancyPanel

/**
* GwtFancyPanel.java (FancyLayouts)
*
* Copyright 2012 Vaadin Ltd, Sami Viitanen <alump@vaadin.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.vaadin.alump.fancylayouts.gwt.client;

import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;

import org.vaadin.alump.fancylayouts.gwt.client.model.BrowserMode;
import org.vaadin.alump.fancylayouts.gwt.client.model.ElementStyler;
import org.vaadin.alump.fancylayouts.gwt.client.model.ElementStyler.Value;
import org.vaadin.alump.fancylayouts.gwt.client.model.FadeOutListener;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;

public class GwtFancyPanel extends SimplePanel {

    private Widget previousWidget = null;
    private Widget currentWidget = null;
    private final Set<Widget> contentWidgets = new HashSet<Widget>();

    public static final String CLASS_NAME = "fancy-panel";

    protected ElementStyler elementStyler = new ElementStyler();

    private static BrowserMode browserMode;

    protected String height = "";
    protected String width = "";

    protected ContentPanel contentPanel;

    protected Boolean scrollEnabled;

    protected FadeOutListener fadeOutListener;

    protected boolean activeTransition = false;

    private final static Logger logger = Logger.getLogger(GwtFancyPanel.class.getName());

    protected class ContentPanel extends ComplexPanel {

        public ContentPanel() {
            setElement(Document.get().createDivElement());
            setStyleName(CLASS_NAME + "-container");
            getElement().getStyle().setPosition(Position.RELATIVE);
            getElement().getStyle().setLeft(0, Unit.PX);
            getElement().getStyle().setTop(0, Unit.PX);
            getElement().getStyle().setWidth(100, Unit.PCT);
            getElement().getStyle().setHeight(100, Unit.PCT);
        }

        @Override
        public void add(Widget widget) {
            DivElement contentWrapper = Document.get().createDivElement();
            contentWrapper.setClassName(CLASS_NAME + "-cwrapper");
            contentWrapper.getStyle().setWidth(100, Unit.PCT);
            if (!GwtFancyPanel.this.isScrollable()) {
                contentWrapper.getStyle().setHeight(100, Unit.PCT);
            }
            getElement().appendChild(contentWrapper);
            add(widget,
                    (com.google.gwt.user.client.Element) Element
                            .as(contentWrapper));
            hide(widget);
        }

        @Override
        public boolean remove(Widget widget) {
            hide(widget);

            Element wrapper = getWrapper(widget);
            boolean removed = super.remove(widget);

            if (removed) {
                if (wrapper != null) {
                    getElement().removeChild(wrapper);
                }
            } else {
                logger.warning("Failed to remove child!");
            }

            return removed;
        }

        public Element getWrapper(Widget widget) {
            Element ret = null;

            if (widget != null && widget.getParent() == this
                    && widget.getElement() != null) {

                ret = widget.getElement().getParentElement();
            }

            return ret;
        }

        public void hide(Widget widget) {
            Element wrapper = getWrapper(widget);
            if (wrapper != null) {
                wrapper.getStyle().setDisplay(Display.NONE);
            }
        }

        public void show(Widget widget) {
            Element wrapper = getWrapper(widget);
            if (wrapper != null) {
                wrapper.getStyle().setDisplay(Display.BLOCK);
            }
        }

        public void hideAndShow(Widget hideWidget, Widget showWidget) {
            hide(hideWidget);
            show(showWidget);
        }
    }

    public GwtFancyPanel() {

        getElement().addClassName(CLASS_NAME);
        getElement().getStyle().setOverflow(Overflow.HIDDEN);

        contentPanel = new ContentPanel();
        super.add(contentPanel);

        if (browserMode == null) {
            browserMode = BrowserMode.resolve();
        }

        setScrollable(false);
        setFade(true);
    }

    public void setFadeOutListener(FadeOutListener listener) {
        fadeOutListener = listener;
    }

    private boolean addTransitionEndListener(Element element) {

        if (hasTransitionEndListener(element)) {
            return true;
        }

        String eventName = browserMode.getTransitionEnd();
        if (eventName != null) {
            addTransitionEndListener(eventName, element);
            return true;
        }

        return false;
    }

    private native boolean hasTransitionEndListener(Element element)
    /*-{
        return element.hasTransitionEndListener == true;
    }-*/;

    private native void addTransitionEndListener(String eventName,
            Element element)
    /*-{
         var that = this;
         element.addEventListener(eventName, function(event){
         that.@org.vaadin.alump.fancylayouts.gwt.client.GwtFancyPanel::onTransitionEnd(Ljava/lang/Object;)(element);
         },false);
         element.hasTransitionEndListener = true;
    }-*/;

    private void onTransitionEnd(Object object) {

        if (!activeTransition) {
            logger.warning("onTransitionEnd after transitions cancelled");
            return;
        }

        if (!(object instanceof Element)) {
            return;
        }

        Element element = (Element) object;

        if (previousWidget != null) {
            if (element == contentPanel.getWrapper(previousWidget)) {
                if (elementStyler.isElementStyledOut(element)) {
                    onFadeOutEnded();
                } else {
                    logger.warning("onTransitionEnd for hidden: wrong state?");
                }
            }
        } else {
            if (element == contentPanel.getWrapper(currentWidget)) {
                if (elementStyler.isElementStyledOn(element)) {
                    onFadeInEnded();
                } else {
                    logger.warning("onTransitionEnd for shown: wrong state?");
                }
            }
        }
    }

    private void onFadeOutEnded() {
        clearWrapperTransitionPosition(getContentElement(previousWidget));
        contentPanel.hideAndShow(previousWidget, currentWidget);
        previousWidget = null;

        final Widget currentWidgetWas = currentWidget;
        final Element wrapper = getContentElement(currentWidget);

        if (wrapper != null) {
            Scheduler.get().scheduleDeferred(new ScheduledCommand() {

                @Override
                public void execute() {
                    if (currentWidgetWas == currentWidget) {
                        elementStyler.styleElementOn(wrapper);
                    }
                }
            });
        } else {
            logger.warning("Failed to fade in new widget");
        }
    }

    private void onFadeInEnded() {
        clearWrapperTransitionPosition(getContentElement(currentWidget));
        activeTransition = false;
    }

    @Override
    public void add(Widget widget) {
        if (widget == null) {
            logger.warning("null widget can not be added to fancy panel");
            return;
        }

        if (contentWidgets.contains(widget)) {
            return;
        }

        contentWidgets.add(widget);
        contentPanel.add(widget);
    }

    protected void skipTransition() {
        activeTransition = false;
        clearWrapperTransitionPosition(contentPanel.getWrapper(currentWidget));
        changeContentWithoutTransition(currentWidget);
    }

    @Override
    public boolean remove(Widget widget) {

        if (widget == previousWidget) {
            if (activeTransition) {
                skipTransition();
            }
            previousWidget = null;
        } else if (widget == currentWidget) {
            currentWidget = null;
        }

        if (!contentPanel.remove(widget)) {
            return false;
        }

        contentWidgets.remove(widget);

        return true;
    }

    private void changeContentWithTransition(Widget content) {

        Element prevWrapper = getContentElement(currentWidget);
        if (prevWrapper == null) {
            logger.fine("Missing wrapper of old widget, transition skipped.");
            changeContentWithoutTransition(content);
            return;
        }

        previousWidget = currentWidget;
        currentWidget = content;

        Element nextWrapper = getContentElement(currentWidget);

        addTransitionEndListener(prevWrapper);
        addTransitionEndListener(nextWrapper);

        activeTransition = true;

        setWrapperTransitionPosition(prevWrapper);
        setWrapperTransitionPosition(nextWrapper);

        elementStyler.styleElementOut(prevWrapper);
        elementStyler.styleElementIn(nextWrapper);
    }

    protected void changeContentWithoutTransition(Widget content) {
        if (currentWidget != null) {
            contentPanel.hide(currentWidget);
        }

        currentWidget = content;
        contentPanel.show(currentWidget);
    }

    public boolean hasWidget(Widget widget) {
        return contentWidgets.contains(widget);
    }

    public void setContent(Widget content) {
        if (content == currentWidget) {
            return;
        }

        if (!contentWidgets.contains(content)) {
            logger.warning("Setting widget not found from children as current.");
            add(content);
        }

        if (browserMode.hasTransitionEndEvent() && elementStyler.hasValues()
                && previousWidget == null) {
            changeContentWithTransition(content);
        } else {
            changeContentWithoutTransition(content);
        }
    }

    protected Element getContentElement(Widget widget) {
        return contentPanel.getWrapper(widget);
    }

    public boolean isScrollable() {
        return scrollEnabled != null && scrollEnabled;
    }

    public void setScrollable(boolean scroll) {

        if (scrollEnabled != null && scrollEnabled == scroll) {
            return;
        }

        Style style = contentPanel.getElement().getStyle();

        if (scroll) {
            style.setOverflow(Overflow.AUTO);
        } else {
            style.clearOverflow();
        }

        scrollEnabled = scroll;
    }

    public void setScrollTop(int value) {
        contentPanel.getElement().setScrollTop(value);
    }

    public int getScrollTop() {
        return contentPanel.getElement().getScrollTop();
    }

    public void setScrollLeft(int value) {
        contentPanel.getElement().setScrollLeft(value);
    }

    public int getScrollLeft() {
        return contentPanel.getElement().getScrollLeft();
    }

    @Override
    public void setWidth(String width) {
        if (this.width.endsWith(width)) {
            return;
        }

        this.width = width;
        super.setWidth(width);
    }

    @Override
    public void setHeight(String height) {
        if (this.height.endsWith(height)) {
            return;
        }

        this.height = height;
        super.setHeight(height);
    }

    public void setFade(boolean enabled) {

        if (enabled == elementStyler.isValueEnabled(Value.OPACITY)) {
            return;
        }

        if (enabled) {
            contentPanel.addStyleName("fancy-fade");
        } else {
            contentPanel.removeStyleName("fancy-fade");
        }
        elementStyler.setValueEnabled(Value.OPACITY, enabled);

        if (!enabled) {
            if (!elementStyler.hasValues()) {
                activeTransition = false;
            }

            for (Widget child : contentWidgets) {
                elementStyler.removeStylingFromElement(
                        contentPanel.getWrapper(child), Value.OPACITY);
            }
        }
    }

    public void setZoom(boolean enabled) {

        if (enabled == elementStyler.isValueEnabled(Value.SCALE)) {
            return;
        }

        if (enabled) {
            contentPanel.addStyleName("fancy-zoom");
        } else {
            contentPanel.removeStyleName("fancy-zoom");
        }
        elementStyler.setValueEnabled(Value.SCALE, enabled);

        if (!enabled) {
            if (!elementStyler.hasValues()) {
                activeTransition = false;
            }

            for (Widget child : contentWidgets) {
                elementStyler.removeStylingFromElement(
                        contentPanel.getWrapper(child), Value.SCALE);
            }
        }
    }

    public void setRotate(boolean enabled, boolean horizontal) {

        if (!enabled) {
            contentPanel.removeStyleName("fancy-rotate");
            elementStyler.setValueEnabled(Value.VERTICAL_ROTATE, false);
            elementStyler.setValueEnabled(Value.HORIZONTAL_ROTATE, false);

            if (!elementStyler.hasValues()) {
                activeTransition = false;
            }

            for (Widget child : contentWidgets) {
                elementStyler.removeStylingFromElement(
                        contentPanel.getWrapper(child), Value.VERTICAL_ROTATE);
            }
        } else {
            if (horizontal) {
                elementStyler.setValueEnabled(Value.VERTICAL_ROTATE, false);
                elementStyler.setValueEnabled(Value.HORIZONTAL_ROTATE, true);
            } else {
                elementStyler.setValueEnabled(Value.HORIZONTAL_ROTATE, false);
                elementStyler.setValueEnabled(Value.VERTICAL_ROTATE, true);
            }

            contentPanel.addStyleName("fancy-rotate");
        }
    }

    /**
     * Clear hardcoded position on the screen
     *
     * @param wrapper
     */
    private void clearWrapperTransitionPosition(Element wrapper) {
        Style style = wrapper.getStyle();
        style.clearPosition();
        if (this.isScrollable()) {
            style.clearHeight();
        } else {
            style.setHeight(100, Unit.PCT);
        }
        style.clearTop();
        style.clearLeft();
        style.clearOverflow();
    }

    /**
     * Set wrapper to hard coded position on the screen
     *
     * @param wrapper
     */
    private void setWrapperTransitionPosition(Element wrapper) {
        Style style = wrapper.getStyle();

        style.setTop(0, Unit.PX);
        style.setLeft(0, Unit.PX);
        style.setHeight(100, Unit.PCT);
        style.setPosition(Position.ABSOLUTE);
        style.setOverflow(Overflow.HIDDEN);
    }
}
TOP

Related Classes of org.vaadin.alump.fancylayouts.gwt.client.GwtFancyPanel

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