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