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