From: Jouni Koivuviita Date: Thu, 12 Jun 2014 12:44:14 +0000 (+0300) Subject: Fix overlay animation-in/out for VNotification and PopupView X-Git-Tag: 7.3.0.beta1~2^2^2~29 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=825564cf7887383428608c4a11c9d0157b2cd08f;p=vaadin-framework.git Fix overlay animation-in/out for VNotification and PopupView - Notification delay now applied to browsers without CSS animation support - PopupView now also supports animation-in and animation-out, and also shows the “loading” widget when the popup is opened and the server response takes a little longer. The popupComponentWidget is also kept in the popup during the animation-out Change-Id: Idb26d87a8cf75cfa3e145ea670dacc1c87ce75d6 --- diff --git a/client/src/com/vaadin/client/ui/VNotification.java b/client/src/com/vaadin/client/ui/VNotification.java index 2aa8e8f879..d89dcb7634 100644 --- a/client/src/com/vaadin/client/ui/VNotification.java +++ b/client/src/com/vaadin/client/ui/VNotification.java @@ -23,6 +23,7 @@ import java.util.Iterator; import com.google.gwt.aria.client.Roles; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; @@ -32,6 +33,7 @@ import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.AnimationUtil; +import com.vaadin.client.AnimationUtil.AnimationEndListener; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.BrowserInfo; import com.vaadin.client.UIDL; @@ -268,13 +270,45 @@ public class VNotification extends VOverlay { // Run only once if (notifications.contains(this)) { DOM.removeEventPreview(this); - if (cssAnimationDelay >= 0) { - AnimationUtil.setAnimationDelay(getElement(), cssAnimationDelay - + "ms"); + + // Still animating in, wait for it to finish before touching + // the animation delay (which would restart the animation-in + // in some browsers) + if (getStyleName().contains( + VOverlay.ADDITIONAL_CLASSNAME_ANIMATE_IN)) { + AnimationUtil.addAnimationEndListener(getElement(), + new AnimationEndListener() { + @Override + public void onAnimationEnd(NativeEvent event) { + if (AnimationUtil + .getAnimationName(event) + .contains( + VOverlay.ADDITIONAL_CLASSNAME_ANIMATE_IN)) { + VNotification.this.hide(); + } + } + }); + } else { + // Use a timer in browsers without CSS animation support + // to show the notification for the duration of the delay + if (BrowserInfo.get().isIE8() || BrowserInfo.get().isIE9()) { + new Timer() { + @Override + public void run() { + VNotification.super.hide(); + } + }.schedule(cssAnimationDelay); + } else { + if (cssAnimationDelay > 0) { + AnimationUtil.setAnimationDelay(getElement(), + cssAnimationDelay + "ms"); + } + VNotification.super.hide(); + + } + fireEvent(new HideEvent(this)); + notifications.remove(this); } - super.hide(); - notifications.remove(this); - fireEvent(new HideEvent(this)); } } diff --git a/client/src/com/vaadin/client/ui/VOverlay.java b/client/src/com/vaadin/client/ui/VOverlay.java index ac4e57268a..1d653a8ff5 100644 --- a/client/src/com/vaadin/client/ui/VOverlay.java +++ b/client/src/com/vaadin/client/ui/VOverlay.java @@ -164,8 +164,8 @@ public class VOverlay extends PopupPanel implements CloseHandler { */ public static final String CLASSNAME_CONTAINER = "v-overlay-container"; - private static final String ADDITIONAL_CLASSNAME_ANIMATE_IN = "animate-in"; - private static final String ADDITIONAL_CLASSNAME_ANIMATE_OUT = "animate-out"; + public static final String ADDITIONAL_CLASSNAME_ANIMATE_IN = "animate-in"; + public static final String ADDITIONAL_CLASSNAME_ANIMATE_OUT = "animate-out"; /** * The shadow element for this overlay. @@ -433,9 +433,9 @@ public class VOverlay extends PopupPanel implements CloseHandler { public void show() { current = this; - boolean hasAnimationIn = maybeShowWithAnimation(); + maybeShowWithAnimation(); - if (isAnimationEnabled() && !hasAnimationIn) { + if (isAnimationEnabled()) { new ResizeAnimation().run(POPUP_PANEL_ANIMATION_DURATION); } else { positionOrSizeUpdated(1.0); @@ -456,6 +456,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { return false; } else { // Check if animations are used + setVisible(false); addStyleDependentName(ADDITIONAL_CLASSNAME_ANIMATE_IN); if (isShadowEnabled()) { shadow.addClassName(CLASSNAME_SHADOW + "-" @@ -467,8 +468,11 @@ public class VOverlay extends PopupPanel implements CloseHandler { if (animationName == null) { animationName = ""; } + setVisible(true); if (animationName.contains(ADDITIONAL_CLASSNAME_ANIMATE_IN)) { + // Disable GWT PopupPanel animation if used + setAnimationEnabled(false); animateInListener = AnimationUtil.addAnimationEndListener( getElement(), new AnimationEndListener() { @Override @@ -974,6 +978,7 @@ public class VOverlay extends PopupPanel implements CloseHandler { }); } else { // Check if animations are used + setVisible(false); addStyleDependentName(ADDITIONAL_CLASSNAME_ANIMATE_OUT); if (isShadowEnabled()) { shadow.addClassName(CLASSNAME_SHADOW + "-" @@ -984,8 +989,12 @@ public class VOverlay extends PopupPanel implements CloseHandler { if (animationName == null) { animationName = ""; } + setVisible(true); if (animationName.contains(ADDITIONAL_CLASSNAME_ANIMATE_OUT)) { + // Disable GWT PopupPanel closing animation if used + setAnimationEnabled(false); + AnimationUtil.addAnimationEndListener(getElement(), new AnimationEndListener() { @Override diff --git a/client/src/com/vaadin/client/ui/VPopupView.java b/client/src/com/vaadin/client/ui/VPopupView.java index adf070f453..931945e546 100644 --- a/client/src/com/vaadin/client/ui/VPopupView.java +++ b/client/src/com/vaadin/client/ui/VPopupView.java @@ -91,6 +91,9 @@ public class VPopupView extends HTML implements Iterable { addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { + preparePopup(popup); + showPopup(popup); + center(); fireEvent(new VisibilityChangeEvent(true)); } }); @@ -111,7 +114,8 @@ public class VPopupView extends HTML implements Iterable { /** For internal use only. May be removed or replaced in the future. */ public void preparePopup(final CustomPopup popup) { - popup.setVisible(false); + popup.setVisible(true); + popup.setWidget(loading); popup.show(); } @@ -128,8 +132,6 @@ public class VPopupView extends HTML implements Iterable { */ public void showPopup(final CustomPopup popup) { popup.setPopupPosition(0, 0); - - popup.setVisible(true); } /** For internal use only. May be removed or replaced in the future. */ @@ -270,9 +272,7 @@ public class VPopupView extends HTML implements Iterable { public void hide(boolean autoClosed) { VConsole.log("Hiding popupview"); syncChildren(); - if (popupComponentWidget != null && popupComponentWidget != loading) { - remove(popupComponentWidget); - } + clearPopupComponentConnector(); hasHadMouseOver = false; shortcutActionHandler = null; super.hide(autoClosed); @@ -333,15 +333,18 @@ public class VPopupView extends HTML implements Iterable { } } - @Override - public boolean remove(Widget w) { + private void clearPopupComponentConnector() { if (popupComponentConnector != null) { popupComponentConnector.removeStateChangeHandler(this); } popupComponentConnector = null; popupComponentWidget = null; captionWrapper = null; + } + @Override + public boolean remove(Widget w) { + clearPopupComponentConnector(); return super.remove(w); } diff --git a/client/src/com/vaadin/client/ui/popupview/PopupViewConnector.java b/client/src/com/vaadin/client/ui/popupview/PopupViewConnector.java index bde5f6a051..6afceb75de 100644 --- a/client/src/com/vaadin/client/ui/popupview/PopupViewConnector.java +++ b/client/src/com/vaadin/client/ui/popupview/PopupViewConnector.java @@ -26,6 +26,7 @@ import com.vaadin.client.VCaptionWrapper; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.ui.AbstractHasComponentsConnector; import com.vaadin.client.ui.PostLayoutListener; +import com.vaadin.client.ui.VOverlay; import com.vaadin.client.ui.VPopupView; import com.vaadin.shared.ui.ComponentStateUtil; import com.vaadin.shared.ui.Connect; @@ -100,27 +101,37 @@ public class PopupViewConnector extends AbstractHasComponentsConnector if (!getChildComponents().isEmpty()) { getWidget().preparePopup(getWidget().popup); getWidget().popup.setPopupConnector(getChildComponents().get(0)); - if (ComponentStateUtil.hasStyles(getState())) { - final StringBuffer styleBuf = new StringBuffer(); - final String primaryName = getWidget().popup - .getStylePrimaryName(); + + final StringBuffer styleBuf = new StringBuffer(); + final String primaryName = getWidget().popup.getStylePrimaryName(); + styleBuf.append(primaryName); + + // Add "animate-in" class back if already present + boolean isAnimatingIn = getWidget().popup.getStyleName().contains( + VOverlay.ADDITIONAL_CLASSNAME_ANIMATE_IN); + + if (isAnimatingIn) { + styleBuf.append(" "); styleBuf.append(primaryName); + styleBuf.append("-"); + styleBuf.append(VOverlay.ADDITIONAL_CLASSNAME_ANIMATE_IN); + } + + if (ComponentStateUtil.hasStyles(getState())) { for (String style : getState().styles) { styleBuf.append(" "); styleBuf.append(primaryName); styleBuf.append("-"); styleBuf.append(style); } - getWidget().popup.setStyleName(styleBuf.toString()); - } else { - getWidget().popup.setStyleName(getWidget().popup - .getStylePrimaryName()); } + + getWidget().popup.setStyleName(styleBuf.toString()); getWidget().showPopup(getWidget().popup); centerAfterLayout = true; - // The popup shouldn't be visible, try to hide it. } else { + // The popup shouldn't be visible, try to hide it. getWidget().popup.hide(); } }