001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.gwt.client.util;
029
030import org.opencms.util.CmsStringUtil;
031
032import com.google.gwt.dom.client.Element;
033import com.google.gwt.dom.client.Style;
034import com.google.gwt.dom.client.Style.Display;
035import com.google.gwt.dom.client.Style.Overflow;
036import com.google.gwt.dom.client.Style.Unit;
037import com.google.gwt.user.client.Command;
038
039/**
040 * Slide animation. Sliding the element into view or sliding it out.<p>
041 * Uses the in-line CSS display property, clear after completion if appropriate.<p>
042 *
043 * @since 8.0.0
044 */
045public class CmsSlideAnimation extends A_CmsAnimation {
046
047    /** The animated element. */
048    private Element m_element;
049
050    /** The element style. */
051    private Style m_elementStyle;
052
053    /** The height of the fully visible element. */
054    private int m_height;
055
056    /** Show or hide flag. */
057    private boolean m_show;
058
059    /** Flag to indicate if the animation has already started. */
060    private boolean m_started;
061
062    /**
063     * Constructor.<p>
064     *
065     * @param element the element to animate
066     * @param show <code>true</code> to show the element, <code>false</code> to hide it away
067     * @param callback the callback executed after the animation is completed
068     */
069    public CmsSlideAnimation(Element element, boolean show, Command callback) {
070
071        super(callback);
072        m_show = show;
073        m_element = element;
074        m_elementStyle = m_element.getStyle();
075    }
076
077    /**
078     * Slides the given element into view executing the callback afterwards.<p>
079     *
080     * @param element the element to slide in
081     * @param callback the callback
082     * @param duration the animation duration
083     *
084     * @return the running animation object
085     */
086    public static CmsSlideAnimation slideIn(Element element, Command callback, int duration) {
087
088        CmsSlideAnimation animation = new CmsSlideAnimation(element, true, callback);
089        animation.run(duration);
090        return animation;
091    }
092
093    /**
094     * Slides the given element out of view executing the callback afterwards.<p>
095     *
096     * @param element the element to slide out
097     * @param callback the callback
098     * @param duration the animation duration
099     *
100     * @return the running animation object
101     */
102    public static CmsSlideAnimation slideOut(Element element, Command callback, int duration) {
103
104        CmsSlideAnimation animation = new CmsSlideAnimation(element, false, callback);
105        animation.run(duration);
106        return animation;
107    }
108
109    /**
110     * @see com.google.gwt.animation.client.Animation#run(int, double)
111     */
112    @Override
113    public void run(int duration, double startTime) {
114
115        if (m_show) {
116            String heightProperty = m_elementStyle.getHeight();
117            if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(heightProperty) && heightProperty.contains("px")) {
118                m_height = CmsClientStringUtil.parseInt(heightProperty);
119            }
120            if (m_height == 0) {
121                String display = m_elementStyle.getDisplay();
122                m_elementStyle.setDisplay(Display.BLOCK);
123                m_height = m_element.getOffsetHeight();
124                m_elementStyle.setProperty("display", display);
125            }
126        } else {
127            m_height = CmsDomUtil.getCurrentStyleInt(m_element, org.opencms.gwt.client.util.CmsDomUtil.Style.height);
128        }
129        super.run(duration, startTime);
130    }
131
132    /**
133     * @see com.google.gwt.animation.client.Animation#onComplete()
134     */
135    @Override
136    protected void onComplete() {
137
138        onUpdate(1.0);
139        if (!m_show) {
140            m_elementStyle.setDisplay(Display.NONE);
141        }
142        m_elementStyle.clearHeight();
143        m_elementStyle.clearOverflow();
144        m_height = 0;
145        m_started = false;
146        if (m_callback != null) {
147            m_callback.execute();
148        }
149    }
150
151    /**
152     * @see com.google.gwt.animation.client.Animation#onUpdate(double)
153     */
154    @Override
155    protected void onUpdate(double progress) {
156
157        if (!m_started) {
158            m_started = true;
159            m_elementStyle.setOverflow(Overflow.HIDDEN);
160            m_elementStyle.setDisplay(Display.BLOCK);
161        }
162        progress = progress * progress;
163        if (m_show) {
164            m_elementStyle.setHeight(progress * m_height, Unit.PX);
165        } else {
166            m_elementStyle.setHeight((-progress + 1) * m_height, Unit.PX);
167        }
168    }
169}