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.actionbar.widget;
35
36 import info.magnolia.ui.vaadin.gwt.client.actionbar.event.ActionTriggerEvent;
37 import info.magnolia.ui.vaadin.gwt.client.actionbar.shared.ActionbarItem;
38 import info.magnolia.ui.vaadin.gwt.client.actionbar.shared.ActionbarSection;
39
40 import java.util.Collection;
41 import java.util.LinkedHashMap;
42 import java.util.Map;
43 import java.util.logging.Logger;
44
45 import com.google.gwt.event.logical.shared.ResizeEvent;
46 import com.google.gwt.event.logical.shared.ResizeHandler;
47 import com.google.gwt.event.shared.HandlerRegistration;
48 import com.google.gwt.media.client.Audio;
49 import com.google.gwt.media.client.Video;
50 import com.google.gwt.user.client.DOM;
51 import com.google.gwt.user.client.Element;
52 import com.google.gwt.user.client.Event;
53 import com.google.gwt.user.client.Window;
54 import com.google.gwt.user.client.ui.ComplexPanel;
55 import com.google.gwt.user.client.ui.FlowPanel;
56 import com.google.gwt.user.client.ui.Image;
57 import com.google.gwt.user.client.ui.Widget;
58 import com.google.web.bindery.event.shared.EventBus;
59 import com.googlecode.mgwt.dom.client.event.touch.TouchStartEvent;
60 import com.googlecode.mgwt.dom.client.event.touch.TouchStartHandler;
61 import com.googlecode.mgwt.ui.client.widget.touch.TouchDelegate;
62
63
64
65
66 public class ActionbarWidgetViewImpl extends ComplexPanel implements ActionbarWidgetView, ActionTriggerEvent.Handler, ResizeHandler {
67
68 private static final Logger log = Logger.getLogger(ActionbarWidgetViewImpl.class.getName());
69
70 private static final int BREAK_POINT_1 = 1200;
71 private static final int BREAK_POINT_2 = 1600;
72
73 public static final String CLASSNAME = "v-actionbar";
74
75 public static final String CLASSNAME_TOGGLE = "v-actionbar-toggle";
76
77 private final Element root = DOM.createElement("section");
78
79 private final FlowPanel toggleButton = new FlowPanel();
80
81 private final Element toggleButtonIcon = DOM.createElement("span");
82
83 private final EventBus eventBus;
84
85 private final HandlerRegistration registration;
86
87 private Presenter presenter;
88
89 private int tabletRow = -1;
90
91 private int tabletColumn = 0;
92
93 private boolean isToggledOpen = false;
94
95 private final TouchDelegateient/widget/touch/TouchDelegate.html#TouchDelegate">TouchDelegate delegate = new TouchDelegate(toggleButton);
96
97 private final Map<String, ActionbarSectionWidget> sections = new LinkedHashMap<String, ActionbarSectionWidget>();
98
99 public ActionbarWidgetViewImpl(final EventBus eventBus, Presenter presenter) {
100 setElement(root);
101 addStyleName(CLASSNAME);
102
103 this.presenter = presenter;
104 this.eventBus = eventBus;
105 this.eventBus.addHandler(ActionTriggerEvent.TYPE, this);
106
107 createToggleControl();
108
109 isToggledOpen = !presenter.isDeviceTablet();
110 actualizeToggleState(isToggledOpen);
111
112 this.registration = Window.addResizeHandler(this);
113 }
114
115
116 private void createToggleControl() {
117
118 toggleButton.addStyleName(CLASSNAME_TOGGLE);
119 add(toggleButton, root);
120
121 toggleButtonIcon.addClassName("v-actionbar-toggle-icon");
122 toggleButton.getElement().appendChild(toggleButtonIcon);
123
124 DOM.sinkEvents(toggleButton.getElement(), Event.TOUCHEVENTS);
125 delegate.addTouchStartHandler(new TouchStartHandler() {
126 @Override
127 public void onTouchStart(TouchStartEvent event) {
128 isToggledOpen = !isToggledOpen;
129 presenter.setOpened(isToggledOpen);
130 }
131 });
132 }
133
134 @Override
135 protected void onDetach() {
136 super.onDetach();
137 this.registration.removeHandler();
138 }
139
140
141
142
143
144 @Override
145 public void refreshActionsPositionsTablet() {
146
147 if (!presenter.isDeviceTablet()) {
148 return;
149 }
150
151 tabletRow = -1;
152 tabletColumn = 0;
153
154 for (final ActionbarSectionWidget section : sections.values()) {
155
156
157 if (section.isVisible()) {
158
159 for (final VActionbarGroup group : section.getGroups().values()) {
160
161 tabletColumn = 0;
162 tabletRow++;
163
164 for (ActionbarItemWidget action : group.getActions()) {
165
166
167 if (group.getNumActions() > 1) {
168 if (tabletColumn == 0) {
169 action.addStyleName("flyout");
170 }
171 } else {
172 action.removeStyleName("flyout");
173 }
174 ((VActionbarItemTablet) action).setRow(tabletRow);
175 ((VActionbarItemTablet) action).setColumn(tabletColumn);
176 tabletColumn++;
177 }
178 }
179 }
180 }
181 setToggleButtonHeights(tabletRow);
182 }
183
184
185
186
187 private void actualizeToggleState(boolean isOpen) {
188 if (isOpen) {
189 toggleButtonIcon.addClassName("open");
190 } else {
191 toggleButtonIcon.removeClassName("open");
192 }
193 if (presenter.isDeviceTablet()) {
194 for (final ActionbarSectionWidget section : sections.values()) {
195 for (final VActionbarGroup group : section.getGroups().values()) {
196 group.setOpenHorizontally(isOpen);
197 }
198 }
199 }
200 }
201
202 @Override
203 public Map<String, ActionbarSectionWidget> getSections() {
204 return sections;
205 }
206
207 @Override
208 public void setPresenter(final Presenter presenter) {
209 this.presenter = presenter;
210 }
211
212 public void addSection(ActionbarSection sectionParams) {
213 ActionbarSectionWidgett/actionbar/widget/ActionbarSectionWidget.html#ActionbarSectionWidget">ActionbarSectionWidget section = new ActionbarSectionWidget(sectionParams);
214 sections.put(sectionParams.getName(), section);
215 add(section, root);
216 }
217
218 public void addAction(ActionbarItem actionParams, String sectionName) {
219 ActionbarSectionWidget section = sections.get(sectionName);
220 if (section != null) {
221 VActionbarGroup group = section.getGroups().get(actionParams.getGroupName());
222 if (group == null) {
223 tabletColumn = 0;
224 tabletRow++;
225 group = new VActionbarGroup(actionParams.getGroupName());
226 section.addGroup(group);
227 setToggleButtonHeights(tabletRow);
228 }
229
230 ActionbarItemWidget action;
231 if (presenter.isDeviceTablet()) {
232 action = new VActionbarItemTablet(actionParams, group, eventBus);
233 ((VActionbarItemTablet) action).setRow(tabletRow);
234 ((VActionbarItemTablet) action).setColumn(tabletColumn);
235 tabletColumn++;
236 } else {
237 action = new ActionbarItemWidget(actionParams, group, eventBus);
238 }
239 group.addAction(action);
240 }
241 }
242
243
244
245
246 private void setToggleButtonHeights(int tabletRow) {
247
248 toggleButton.setStyleName(CLASSNAME_TOGGLE + " row-" + (tabletRow + 1));
249 }
250
251 @Override
252 public void onActionTriggered(ActionTriggerEvent event) {
253 ActionbarItemWidget action = event.getSource();
254 ActionbarSectionWidget/../../info/magnolia/ui/vaadin/gwt/client/actionbar/widget/ActionbarSectionWidget.html#ActionbarSectionWidget">ActionbarSectionWidget section = (ActionbarSectionWidget) action.getParent().getParent();
255 presenter.triggerAction(section.getName() + ":" + action.getName());
256 }
257
258 @Override
259 public void setSections(Collection<ActionbarSection> newSections) {
260 for (final ActionbarSectionWidget section : this.sections.values()) {
261 remove(section);
262 }
263 sections.clear();
264 for (final ActionbarSection section : newSections) {
265 addSection(section);
266 for (final String actionName : section.getActionOrder()) {
267 ActionbarItem action = section.getActions().get(actionName);
268 if (action.getIconFontId() == null) {
269 action.setResourceUrl(presenter.getIconResourceURL(action.getName()));
270 }
271 addAction(action, section.getName());
272 }
273 }
274 updateLayout();
275 refreshActionsPositionsTablet();
276 }
277
278 @Override
279 public void setVisibleSections(Collection<ActionbarSection> visibleSections) {
280 for (final ActionbarSectionWidget section : sections.values()) {
281 section.setVisible(visibleSections.contains(section.getData()));
282 }
283 updateLayout();
284 refreshActionsPositionsTablet();
285 }
286
287 @Override
288 public void setDisabledActions(Collection<ActionbarItem> disabledActions) {
289 for (final ActionbarSectionWidget section : sections.values()) {
290 for (final VActionbarGroup group : section.getGroups().values()) {
291 for (final ActionbarItemWidget action : group.getActions()) {
292 action.setEnabled(!disabledActions.contains(action.getData()));
293 }
294 }
295 }
296 }
297
298 @Override
299 public boolean isOpen() {
300 return isToggledOpen;
301 }
302
303 @Override
304 public void setOpen(boolean isOpen) {
305 actualizeToggleState(isToggledOpen);
306 if (isToggledOpen != isOpen) {
307 presenter.forceLayout();
308 updateLayout();
309 }
310 }
311
312 @Override
313 public void setSectionPreview(String sectionName, String previewUrl) {
314 ActionbarSectionWidget sectionWidget = sections.get(sectionName);
315 if (sectionWidget != null) {
316 sectionWidget.addStyleName("preview");
317
318 if (previewUrl != null) {
319 Widget widget;
320 Video video = Video.createIfSupported();
321 if (video != null && !"".equals(video.canPlayType("video/" + previewUrl.substring(previewUrl.lastIndexOf(".") + 1)))) {
322 video.addSource(previewUrl);
323 video.setControls(true);
324 widget = video;
325 } else {
326 Audio audio = Audio.createIfSupported();
327 if (audio != null && !"".equals(audio.canPlayType("audio/" + previewUrl.substring(previewUrl.lastIndexOf(".") + 1)))) {
328 audio.addSource(previewUrl);
329 audio.setControls(true);
330 widget = audio;
331 } else {
332 widget = new Image(previewUrl);
333 }
334 }
335 sectionWidget.setPreview(widget);
336 }
337 }
338 }
339
340 @Override
341 public void updateLayout() {
342 int windowWidth = Window.getClientWidth();
343
344
345 final int MARGIN_TOP = windowWidth < BREAK_POINT_1 ? 55 : (windowWidth >= BREAK_POINT_2 ? 125 : 100) ;
346 final int MARGIN_BOTTOM = 20;
347
348 int availableHeight = getOffsetHeight();
349 if (sections.containsKey("preview") && sections.get("preview").isVisible() && isToggledOpen) {
350 availableHeight -= 215 - MARGIN_BOTTOM;
351 }
352
353 int actualHeight = 0;
354 for (ActionbarSectionWidget section : sections.values()) {
355 if (!section.getName().equals("preview") && section.isVisible()) {
356 section.getElement().getStyle().clearProperty("maxHeight");
357 actualHeight += section.getOffsetHeight() + MARGIN_TOP + MARGIN_BOTTOM;
358 }
359 }
360 log.fine("actualHeight/availableHeight: " + actualHeight + "/" + availableHeight);
361
362
363 int i = getWidgetCount() - 1;
364 int minimumHeight = 75;
365 while (actualHeight > availableHeight && i >= 0) {
366 log.fine("rewinding widget list, current height diff: " + (actualHeight - availableHeight) + " (i=" + i + ")");
367 Widget widget = getWidget(i);
368 if (widget instanceof ActionbarSectionWidget && widget.isVisible()) {
369 String sectionName = ((ActionbarSectionWidget) widget).getName();
370 if (!sectionName.equals("preview")) {
371 int currentHeight = widget.getOffsetHeight() + MARGIN_TOP;
372 if (currentHeight > minimumHeight) {
373 int newHeight = (actualHeight - availableHeight > currentHeight - minimumHeight) ? minimumHeight : currentHeight + availableHeight - actualHeight;
374 log.fine(sectionName + " currentHeight => newHeight: " + currentHeight + "=>" + (newHeight - MARGIN_TOP));
375 widget.getElement().getStyle().setPropertyPx("maxHeight", newHeight - MARGIN_TOP);
376 actualHeight -= (currentHeight - newHeight);
377 }
378 }
379 }
380 i--;
381 }
382 }
383
384 @Override
385 public void onResize(ResizeEvent event) {
386 updateLayout();
387 }
388 }