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;
35
36 import info.magnolia.ui.vaadin.gwt.client.jquerywrapper.AnimationSettings;
37 import info.magnolia.ui.vaadin.gwt.client.jquerywrapper.JQueryCallback;
38 import info.magnolia.ui.vaadin.gwt.client.jquerywrapper.JQueryWrapper;
39 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.VMagnoliaShell.ViewportType;
40 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.VMainLauncher.ShellAppType;
41 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.event.AppActivatedEvent;
42 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.event.ShellAppNavigationEvent;
43 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.event.ViewportCloseEvent;
44 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.event.handler.ShellNavigationHandler;
45 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.event.handler.ViewportCloseHandler;
46 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.shellmessage.VInfoMessage;
47 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.shellmessage.VShellErrorMessage;
48 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.shellmessage.VShellMessage;
49 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.shellmessage.VShellMessage.MessageType;
50 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.shellmessage.VWarningMessage;
51 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.viewport.VAppsViewport;
52 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.viewport.VAppsViewport.PreloaderCallback;
53 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.viewport.VDialogViewport;
54 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.viewport.VShellAppsViewport;
55 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.viewport.VShellViewport;
56
57 import java.util.Collection;
58 import java.util.Collections;
59 import java.util.EnumMap;
60 import java.util.Map;
61
62 import org.vaadin.artur.icepush.client.ui.VICEPush;
63
64 import com.google.gwt.core.client.Scheduler;
65 import com.google.gwt.core.client.Scheduler.ScheduledCommand;
66 import com.google.gwt.dom.client.Document;
67 import com.google.gwt.dom.client.IFrameElement;
68 import com.google.gwt.dom.client.Style.Position;
69 import com.google.gwt.dom.client.Style.Unit;
70 import com.google.gwt.event.logical.shared.ValueChangeEvent;
71 import com.google.gwt.event.logical.shared.ValueChangeHandler;
72 import com.google.gwt.user.client.History;
73 import com.google.gwt.user.client.Window;
74 import com.google.gwt.user.client.ui.RootPanel;
75 import com.google.gwt.user.client.ui.Widget;
76 import com.google.web.bindery.event.shared.EventBus;
77 import com.googlecode.mgwt.ui.client.widget.touch.TouchPanel;
78
79
80
81
82
83 public class VMagnoliaShellViewImpl extends TouchPanel implements VMagnoliaShellView, ViewportCloseHandler {
84
85 public static final String CLASSNAME = "v-magnolia-shell";
86
87 private final Map<ViewportType, VShellViewport> viewports = new EnumMap<ViewportType, VShellViewport>(ViewportType.class);
88
89 private ViewportType activeViewportType = null;
90
91 private final VMainLauncher mainAppLauncher;
92
93 private Presenter presenter;
94
95 private final EventBus eventBus;
96
97 private VShellMessage lowPriorityMessage;
98
99 private VShellMessage hiPriorityMessage;
100
101 public VMagnoliaShellViewImpl(final EventBus eventBus) {
102 super();
103 this.eventBus = eventBus;
104 this.mainAppLauncher = new VMainLauncher(eventBus);
105 setStyleName(CLASSNAME);
106 add(mainAppLauncher, getElement());
107 bindEventHandlers();
108
109
110
111 if (Window.Location.getQueryString().indexOf("tablet=true") >= 0) {
112 RootPanel.get().addStyleName("tablet");
113 }
114
115 final IFrameElement iframe = Document.get().createIFrameElement();
116 getElement().appendChild(iframe);
117 iframe.setPropertyString("width", "100%");
118 iframe.setPropertyString("height", "100%");
119 iframe.getStyle().setProperty("border", "none");
120
121 iframe.getStyle().setPosition(Position.ABSOLUTE);
122 iframe.getStyle().setLeft(0, Unit.PX);
123 iframe.getStyle().setTop(0, Unit.PX);
124 iframe.getStyle().setWidth(100, Unit.PCT);
125 iframe.getStyle().setHeight(100, Unit.PCT);
126
127 }
128
129 private void bindEventHandlers() {
130 eventBus.addHandler(ViewportCloseEvent.TYPE, this);
131 eventBus.addHandler(ShellAppNavigationEvent.TYPE, navigationHandler);
132 eventBus.addHandler(AppActivatedEvent.TYPE, navigationHandler);
133
134 History.addValueChangeHandler(new ValueChangeHandler<String>() {
135
136 @Override
137 public void onValueChange(ValueChangeEvent<String> event) {
138 presenter.handleHistoryChange(event.getValue());
139 }
140 });
141 }
142
143 protected VAppsViewport getAppViewport() {
144 return (VAppsViewport) viewports.get(ViewportType.APP_VIEWPORT);
145 }
146
147 protected VShellAppsViewport getShellAppViewport() {
148 return (VShellAppsViewport) viewports.get(ViewportType.SHELL_APP_VIEWPORT);
149 }
150
151 protected VDialogViewport getDialogViewport() {
152 return (VDialogViewport) viewports.get(ViewportType.DIALOG_VIEWPORT);
153 }
154
155 @Override
156 public void setActiveViewport(final ViewportType type) {
157 if (activeViewportType != type) {
158 final VShellViewport shellAppViewport = getShellAppViewport();
159 final VShellViewport appViewport = getAppViewport();
160
161 boolean appViewportActive = type.equals(ViewportType.APP_VIEWPORT);
162 if (appViewportActive) {
163 mainAppLauncher.deactivateControls();
164 }
165 shellAppViewport.setActive(!appViewportActive);
166 appViewport.setActive(appViewportActive);
167
168 activeViewportType = type;
169 }
170 }
171
172 @Override
173 public int getViewportHeight() {
174 int errorMessageHeight = hiPriorityMessage == null &&
175 (getWidgetIndex(hiPriorityMessage) > -1) ? hiPriorityMessage.getOffsetHeight() : 0;
176 return getOffsetHeight() - mainAppLauncher.getExpandedHeight() - errorMessageHeight;
177 }
178
179 @Override
180 public int getViewportWidth() {
181 return getOffsetWidth();
182 }
183
184 @Override
185 public boolean remove(Widget w) {
186 presenter.destroyChild(w);
187 return super.remove(w);
188 }
189
190 protected void replaceWidget(final Widget oldWidget, final Widget newWidget) {
191 if (oldWidget != newWidget) {
192 if (oldWidget != null) {
193 remove(oldWidget);
194 }
195 }
196 if (getWidgetIndex(newWidget) < 0) {
197 add(newWidget, getElement());
198 }
199 }
200
201 @Override
202 public void setPresenter(Presenter presenter) {
203 this.presenter = presenter;
204 }
205
206 @Override
207 public void setWidth(String width) {
208 Integer pxWidth = JQueryWrapper.parseInt(width);
209 boolean widthChanged = pxWidth != null && pxWidth != getOffsetWidth();
210 super.setWidth(width);
211 if (widthChanged) {
212 mainAppLauncher.updateDivet();
213 }
214 }
215
216 @Override
217 public void showMessage(MessageType type, String topic, String message, String id) {
218 final VShellMessage msg;
219 switch (type) {
220 case WARNING :
221 msg = new VWarningMessage(this, topic, message, id);
222 if (lowPriorityMessage != null && getWidgetIndex(lowPriorityMessage) != -1) {
223 lowPriorityMessage.hide();
224 }
225 lowPriorityMessage = msg;
226 break;
227 case INFO :
228 msg = new VInfoMessage(this, topic, message, id);
229 if (lowPriorityMessage != null && getWidgetIndex(lowPriorityMessage) != -1) {
230 lowPriorityMessage.hide();
231 }
232 lowPriorityMessage = msg;
233 break;
234 case ERROR :
235 msg = new VShellErrorMessage(this, topic, message, id);
236 if (hiPriorityMessage != null && getWidgetIndex(hiPriorityMessage) != -1) {
237 hiPriorityMessage.hide();
238 }
239 hiPriorityMessage = msg;
240 break;
241 default :
242 msg = null;
243 }
244 Scheduler.get().scheduleDeferred(new ScheduledCommand() {
245
246 @Override
247 public void execute() {
248 if (msg != null) {
249 add(msg, getElement());
250 }
251 }
252 });
253 }
254
255 @Override
256 public void hideAllMessages() {
257 if (hiPriorityMessage != null && getWidgetIndex(hiPriorityMessage) != -1) {
258 hiPriorityMessage.hideWithoutTransition();
259 }
260 hiPriorityMessage = null;
261
262 if (lowPriorityMessage != null && getWidgetIndex(lowPriorityMessage) != -1) {
263 lowPriorityMessage.hideWithoutTransition();
264 }
265 lowPriorityMessage = null;
266 }
267
268 @Override
269 public void updateViewport(VShellViewport viewport, ViewportType type) {
270 doUpdateViewport(viewport, type);
271 }
272
273 private final ShellNavigationHandler navigationHandler = new ShellNavigationHandler() {
274
275 @Override
276 public void onAppActivated(AppActivatedEvent event) {
277 final String fragment = activeViewportType.getFragmentPrefix()
278 + event.getAppId()
279 + ":"
280 + event.getSubAppId()
281 + ";"
282 + event.getParameter();
283 History.newItem(fragment, false);
284 }
285
286 @Override
287 public void onShellAppNavigation(final ShellAppNavigationEvent event) {
288
289 VShellAppsViewport viewport = getShellAppViewport();
290 Widget shellApp = viewport.getShellAppByType(event.getType());
291 ShellAppNavigationEvent refreshEvent = viewport.getRefreshEvent();
292
293
294 if (!event.equals(refreshEvent)) {
295 refreshEvent = null;
296 }
297 if (shellApp != null && refreshEvent == null) {
298 viewport.setRefreshEvent(event);
299
300
301 mainAppLauncher.activateControl(event.getType());
302
303 viewport.setVisibleApp(shellApp);
304
305 if (!viewport.isActive()) {
306 setActiveViewport(ViewportType.SHELL_APP_VIEWPORT);
307 }
308 } else {
309 viewport.setRefreshEvent(null);
310 getShellAppViewport().showLoadingPane();
311 presenter.loadShellApp(event.getType(), event.getToken());
312 }
313 }
314
315 };
316
317 @Override
318 public void onViewportClose(ViewportCloseEvent event) {
319 final VMagnoliaShell.ViewportType viewportType = event.getViewportType();
320 if (viewportType == ViewportType.SHELL_APP_VIEWPORT) {
321 getShellAppViewport().setClosing(true);
322 presenter.closeCurrentShellApp();
323 } else if (viewportType == ViewportType.APP_VIEWPORT) {
324 presenter.closeCurrentApp();
325 }
326 }
327
328 @Override
329 public void navigate(String appId, String subAppId, String parameter) {
330 eventBus.fireEvent(new AppActivatedEvent(activeViewportType == ViewportType.SHELL_APP_VIEWPORT, appId, subAppId, parameter));
331 }
332
333 @Override
334 public Collection<VShellViewport> getViewports() {
335 return Collections.unmodifiableCollection(viewports.values());
336 }
337
338 @Override
339 public Presenter getPresenter() {
340 return presenter;
341 }
342
343 @Override
344 public void shiftViewportsVertically(int shiftPx, boolean animated) {
345 for (final VShellViewport viewport : viewports.values()) {
346 final AnimationSettings settings = new AnimationSettings();
347 settings.setProperty("top", "+=" + shiftPx);
348 settings.setProperty("height", "+=" + -shiftPx);
349 settings.addCallback(new JQueryCallback() {
350
351 @Override
352 public void execute(JQueryWrapper query) {
353 getPresenter().updateViewportLayout(viewport);
354 }
355 });
356 JQueryWrapper.select(viewport).animate(animated ? 300 : 0, settings);
357 }
358 }
359
360 @Override
361 public void setPusher(final VICEPush pusher) {
362 if (getWidgetIndex(pusher) != -1) {
363 insert(pusher, 0);
364 }
365 }
366
367 @Override
368 public void setShellAppIndication(ShellAppType type, int indication) {
369 mainAppLauncher.setIndication(type, indication);
370 }
371
372 @Override
373 public void closeMessageEager(final String id) {
374 presenter.removeMessage(id);
375 }
376
377 @Override
378 public void navigateToMessageDetails(String id) {
379 presenter.loadShellApp(ShellAppType.PULSE, "messages/" + id);
380 }
381
382 private void doUpdateViewport(VShellViewport viewport, ViewportType shellAppViewport) {
383 final VShellViewport oldViewport = viewports.get(shellAppViewport);
384 if (oldViewport != viewport) {
385 replaceWidget(oldViewport, viewport);
386 viewport.setEventBus(eventBus);
387 viewports.put(shellAppViewport, viewport);
388 }
389 }
390
391 @Override
392 public void showAppPreloader(String prefix, PreloaderCallback preloaderCallback) {
393 setActiveViewport(ViewportType.APP_VIEWPORT);
394 getAppViewport().showAppPreloader(prefix, preloaderCallback);
395 }
396 }