package com.gwtmobile.ui.client.page; import java.beans.Beans; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.EventListener; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.gwtmobile.ui.client.CSS.CSS; import com.gwtmobile.ui.client.utils.Utils; import com.gwtmobile.ui.client.widgets.IsGwtMobilePanel; import com.gwtmobile.ui.client.widgets.IsGwtMobilePanel.TransitionDirection; public class Transition implements EventListener { String _transitionStyleName; Widget _from, _to; boolean _reverse; HasWidgets _parent; public enum TransitionFlavor { NONE(null), SLIDE(new Transition(CSS.T.slide())), SLIDE_UP( new Transition(CSS.T.slideup())), SLIDE_DOWN(new Transition(CSS.T.slidedown())), FADE(new Transition(CSS.T.fade())), POP(new Transition(CSS.T.pop())), FLIP(new FlipTransition()), SWAP(new SwapTransition()); private final Transition transition; private TransitionFlavor(Transition transition){ this.transition = transition; } public Transition getTransition(){ return this.transition; } }; public static Transition SLIDE = new Transition(CSS.T.slide()); public static Transition SLIDEUP = new Transition(CSS.T.slideup()); public static Transition SLIDEDOWN = new Transition(CSS.T.slidedown()); public static Transition FADE = new Transition(CSS.T.fade()); public static Transition POP = new Transition(CSS.T.pop()); public static Transition FLIP = new FlipTransition(); public static Transition SWAP = new SwapTransition(); // public static Transition CUBE = new CubeTransition(); public Transition(String transitionStyleName) { _transitionStyleName = transitionStyleName; } // No transition public static void start(final Widget from, final Widget to, final HasWidgets parent) { new Timer() { @Override public void run() { parent.remove(from); parent.add(to); if (from instanceof IsGwtMobilePanel) { ((IsGwtMobilePanel) from).onTransitionEnd(TransitionDirection.From); } if (to instanceof IsGwtMobilePanel) { ((IsGwtMobilePanel) to).onTransitionEnd(TransitionDirection.To); } } }.schedule(1); } public void start(Widget from, Widget to, HasWidgets parent, boolean reverse) { _from = from; _to = to; _parent = parent; _reverse = reverse; prepare(); if (Beans.isDesignTime()) { _from.addStyleName(CSS.T.start()); _to.addStyleName(CSS.T.start()); onTransitionEnd(); } else { start(); } } protected void prepare() { _from.addStyleName(_transitionStyleName + " " + CSS.T.out()); _to.addStyleName(_transitionStyleName + " " + CSS.T.in()); if (_reverse) { _from.addStyleName(CSS.T.reverse()); _to.addStyleName(CSS.T.reverse()); } _parent.add(_to); } protected void start() { registerTransitionEndEvent(); new Timer() { @Override public void run() { _from.addStyleName(CSS.T.start()); _to.addStyleName(CSS.T.start()); } }.schedule(20); //xxms instead of 1ms, to give iOS/Android enough time to set the starting state. } protected void removeTransitionStyles() { _from.removeStyleName(_transitionStyleName); _from.removeStyleName(CSS.T.start()); _from.removeStyleName(CSS.T.out()); _from.removeStyleName(CSS.T.reverse()); _to.removeStyleName(_transitionStyleName); _to.removeStyleName(CSS.T.in()); _to.removeStyleName(CSS.T.start()); _to.removeStyleName(CSS.T.reverse()); } @Override public void onBrowserEvent(Event e) { String type = e.getType(); if (type.equals("webkitTransitionEnd") || type.equals("webkitAnimationEnd")) { onTransitionEnd(); } } protected void onTransitionEnd() { if (_from != null && _to != null) { _parent.remove(_from); removeTransitionStyles(); if (_from instanceof IsGwtMobilePanel) { ((IsGwtMobilePanel) _from).onTransitionEnd(TransitionDirection.From); } if (_to instanceof IsGwtMobilePanel) { ((IsGwtMobilePanel) _to).onTransitionEnd(TransitionDirection.To); } _from = null; _to = null; _parent = null; } } protected void registerTransitionEndEvent() { if (!_reverse) { Utils.addEventListenerOnce(_to.getElement(), "webkitTransitionEnd", false, this); } else { Utils.addEventListenerOnce(_from.getElement(), "webkitTransitionEnd", false, this); } } //Flip private static class FlipTransition extends Transition { private int _phase = 0; FlipTransition() { super(CSS.T.flip0()); } @Override protected void registerTransitionEndEvent() { if (_phase == 0) { Utils.addEventListenerOnce(_from.getElement(), "webkitTransitionEnd", false, this); } else { Utils.addEventListenerOnce(_to.getElement(), "webkitTransitionEnd", false, this); } } @Override protected void onTransitionEnd() { removeTransitionStyles(); if (_phase == 0) { _parent.remove(_from); _parent.add(_to); _phase++; _transitionStyleName = CSS.T.flip1(); prepare(); start(); } else { if (_from instanceof IsGwtMobilePanel) { ((IsGwtMobilePanel) _from).onTransitionEnd(TransitionDirection.From); } if (_to instanceof IsGwtMobilePanel) { ((IsGwtMobilePanel) _to).onTransitionEnd(TransitionDirection.To); } _from = null; _to = null; _phase = 0; _transitionStyleName = CSS.T.flip0(); } } @Override protected void prepare() { _from.addStyleName(_transitionStyleName + " " + CSS.T.out()); _to.addStyleName(_transitionStyleName + " " + CSS.T.in()); if (_reverse) { _from.addStyleName(CSS.T.reverse()); _to.addStyleName(CSS.T.reverse()); } } } // Swap private static class SwapTransition extends Transition { private int _phase = 0; SwapTransition() { super(CSS.T.swap0()); } @Override protected void onTransitionEnd() { removeTransitionStyles(); if (_phase == 0) { _phase++; _transitionStyleName = CSS.T.swap1(); prepare(); start(); } else { _parent.remove(_from); if (_from instanceof IsGwtMobilePanel) { ((IsGwtMobilePanel) _from).onTransitionEnd(TransitionDirection.From); } if (_to instanceof IsGwtMobilePanel) { ((IsGwtMobilePanel) _to).onTransitionEnd(TransitionDirection.To); } _from = null; _to = null; _phase = 0; _transitionStyleName = CSS.T.swap0(); } } @Override protected void prepare() { _from.addStyleName(_transitionStyleName + " " + CSS.T.out()); _to.addStyleName(_transitionStyleName + " " + CSS.T.in()); if (_reverse) { _from.addStyleName(CSS.T.reverse()); _to.addStyleName(CSS.T.reverse()); } if (_phase == 0) { _parent.add(_to); } } } // Cube // private static class CubeTransition extends Transition { // // CubeTransition() { // super(CSS.T.cube()); // } // // protected void registerTransitionEndEvent() { // if (!_reverse) { // Utils.addEventListenerOnce(_to.getElement(), "webkitAnimationEnd", false, this); // } // else { // Utils.addEventListenerOnce(_from.getElement(), "webkitAnimationEnd", false, this); // } // } // } }