1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.vaadin.gwt.client.magnoliashell.viewport;
35
36 import info.magnolia.ui.vaadin.gwt.client.jquerywrapper.JQueryCallback;
37 import info.magnolia.ui.vaadin.gwt.client.jquerywrapper.JQueryWrapper;
38 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.ShellState;
39 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.viewport.animation.FadeAnimation;
40 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.viewport.animation.ZoomAnimation;
41 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.viewport.widget.AppsViewportWidget;
42
43 import java.util.logging.Logger;
44
45 import com.google.gwt.dom.client.Style;
46 import com.google.gwt.dom.client.Style.Visibility;
47 import com.google.gwt.user.client.Command;
48 import com.google.gwt.user.client.Element;
49 import com.google.gwt.user.client.ui.Widget;
50 import com.vaadin.client.ApplicationConnection;
51 import com.vaadin.client.Util;
52
53
54
55
56
57 public class AppsTransitionDelegate implements TransitionDelegate {
58
59 private static final Logger log = Logger.getLogger(AppsTransitionDelegate.class.getName());
60
61 private static final double CURTAIN_ALPHA = 0.9;
62
63 private static final int CURTAIN_FADE_IN_DURATION = 500;
64
65 private static final int CURTAIN_FADE_OUT_DURATION = 800;
66
67 private static final int CURTAIN_FADE_OUT_DELAY = 200;
68
69 private static final int ZOOM_DURATION = 500;
70
71 private final AppsViewportWidget viewport;
72
73
74
75
76
77 private Object lock = new Object();
78
79
80
81
82
83 private boolean isResponseProcessingInProgress = false;
84
85 private ZoomAnimationt/magnoliashell/viewport/animation/ZoomAnimation.html#ZoomAnimation">ZoomAnimation zoomOutAnimation = new ZoomAnimation(false) {
86 @Override
87 protected void onComplete() {
88 super.onComplete();
89 viewport.removeChildNoTransition(Util.<Widget>findWidget(getElement(), null));
90 }
91 };
92
93 private ZoomAnimationnt/magnoliashell/viewport/animation/ZoomAnimation.html#ZoomAnimation">ZoomAnimation zoomInAnimation = new ZoomAnimation(true) {
94 @Override
95 protected void onStart() {
96 super.onStart();
97 setCurtainAttached(false);
98 Util.findConnectorFor(viewport).getConnection().getMessageHandler().suspendReponseHandling(lock);
99 }
100
101 @Override
102 protected void onComplete() {
103 super.onComplete();
104 ShellState.get().setAppStarted();
105 log.warning("Switching to 'APP STARTED' state after zoom-in animation");
106 Util.findConnectorFor(viewport).getConnection().getMessageHandler().resumeResponseHandling(lock);
107 }
108 };
109
110 private FadeAnimationliashell/viewport/animation/FadeAnimation.html#FadeAnimation">FadeAnimation curtainFadeOutAnimation = new FadeAnimation(0, true);
111 private FadeAnimationoliashell/viewport/animation/FadeAnimation.html#FadeAnimation">FadeAnimation curtainFadeInAnimation = new FadeAnimation(CURTAIN_ALPHA, true) {
112 @Override
113 protected void onStart() {
114 super.onStart();
115 getJQueryWrapper().get(0).getStyle().setOpacity(0d);
116 }
117 };
118
119 private Command pendingAppZoomCommand = null;
120
121 final ApplicationConnection.CommunicationHandler communicationHandler = new ApplicationConnection.CommunicationHandler() {
122
123 @Override
124 public void onRequestStarting(ApplicationConnection.RequestStartingEvent e) {}
125
126 @Override
127 public void onResponseHandlingStarted(ApplicationConnection.ResponseHandlingStartedEvent e) {
128 isResponseProcessingInProgress = true;
129 }
130
131 @Override
132 public void onResponseHandlingEnded(ApplicationConnection.ResponseHandlingEndedEvent e) {
133 isResponseProcessingInProgress = false;
134 if (pendingAppZoomCommand != null) {
135 pendingAppZoomCommand.execute();
136 pendingAppZoomCommand = null;
137 }
138 }
139 };
140
141 public AppsTransitionDelegate(final AppsViewportWidget viewportWidget) {
142 this.viewport = viewportWidget;
143 curtainFadeOutAnimation.addCallback(new JQueryCallback() {
144 @Override
145 public void execute(JQueryWrapper jq) {
146 setCurtainAttached(false);
147 }
148 });
149
150 Util.findConnectorFor(viewportWidget).getConnection().addHandler(ApplicationConnection.ResponseHandlingStartedEvent.TYPE, communicationHandler);
151 Util.findConnectorFor(viewportWidget).getConnection().addHandler(ApplicationConnection.ResponseHandlingEndedEvent.TYPE, communicationHandler);
152 }
153
154
155
156
157
158 @Override
159 public void setVisibleChild(final Widget app) {
160 if (ShellState.get().isAppStarting() && isWidgetVisibilityHidden(app)) {
161 viewport.showChildNoTransition(app);
162 pendingAppZoomCommand = new Command() {
163 @Override
164 public void execute() {
165 Util.findConnectorFor(viewport).getLayoutManager().layoutNow();
166 zoomInAnimation.run(ZOOM_DURATION, app.getElement());
167 }
168 };
169
170 if (!isResponseProcessingInProgress) {
171 pendingAppZoomCommand.execute();
172 this.pendingAppZoomCommand = null;
173 }
174
175
176 } else {
177 viewport.showChildNoTransition(app);
178 ShellState.get().setAppStarted();
179 log.warning("Switching to 'APP STARTED' state without app transition");
180 }
181 }
182
183 public void setCurtainVisible(boolean visible) {
184 final Element curtain = viewport.getCurtain();
185 if (visible) {
186 setCurtainAttached(true);
187 curtainFadeOutAnimation.cancel();
188 curtainFadeInAnimation.run(CURTAIN_FADE_IN_DURATION, curtain);
189 } else {
190 curtainFadeInAnimation.cancel();
191 curtainFadeOutAnimation.run(CURTAIN_FADE_OUT_DURATION + CURTAIN_FADE_OUT_DELAY, curtain);
192 }
193 }
194
195 public void removeWidget(Widget w) {
196 zoomOutAnimation.run(ZOOM_DURATION, w.getElement());
197 }
198
199 private boolean isWidgetVisibilityHidden(final Widget app) {
200 return Visibility.HIDDEN.getCssName().equals(app.getElement().getStyle().getVisibility()) ||
201 Style.Display.NONE.getCssName().equals(app.getElement().getStyle().getDisplay());
202 }
203
204 public void setCurtainAttached(boolean visible) {
205 Element viewportElement = viewport.getElement();
206 Element curtain = viewport.getCurtain();
207 if (visible) {
208 viewportElement.appendChild(curtain);
209 } else if (viewportElement.isOrHasChild(curtain)) {
210 viewportElement.removeChild(curtain);
211 }
212 }
213
214 @Override
215 public boolean inProgress() {
216 return zoomInAnimation.isRunning() || zoomOutAnimation.isRunning();
217 }
218
219 @Override
220 public void setActive(boolean active) {
221 viewport.setVisible(active);
222 }
223 }