/** * Open or close the content. This method always called immediately after the PopupPanel showing * state has changed, so we base the animation on the current state. * * @param showing true if the popup is showing, false if not */ public void setState(boolean showing, boolean isUnloading) { // Immediately complete previous open/close animation this.isUnloading = isUnloading; cancel(); // If there is a pending timer to start a show animation, then just cancel // the timer and complete the show operation. if (showTimer != null) { showTimer.cancel(); showTimer = null; onComplete(); } // Update the logical state. curPanel.showing = showing; curPanel.updateHandlers(); // Determine if we need to animate boolean animate = !isUnloading && curPanel.isAnimationEnabled; if (curPanel.animType != AnimationType.CENTER && !showing) { animate = false; } // Open the new item this.showing = showing; if (animate) { // impl.onShow takes some time to complete, so we do it before starting // the animation. If we move this to onStart, the animation will look // choppy or not run at all. if (showing) { maybeShowGlass(); // Set the position attribute, and then attach to the DOM. Otherwise, // the PopupPanel will appear to 'jump' from its static/relative // position to its absolute position (issue #1231). curPanel.getElement().getStyle().setProperty("position", "absolute"); if (curPanel.topPosition != -1) { curPanel.setPopupPosition(curPanel.leftPosition, curPanel.topPosition); } impl.setClip(curPanel.getElement(), getRectString(0, 0, 0, 0)); RootPanel.get().add(curPanel); // Wait for the popup panel and iframe to be attached before running // the animation. We use a Timer instead of a DeferredCommand so we // can cancel it if the popup is hidden synchronously. showTimer = new Timer() { @Override public void run() { showTimer = null; ResizeAnimation.this.run(ANIMATION_DURATION); } }; showTimer.schedule(1); } else { run(ANIMATION_DURATION); } } else { onInstantaneousRun(); } }