View Javadoc
1   /**
2    * This file Copyright (c) 2012-2018 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.ui.vaadin.gwt.client.applauncher.widget;
35  
36  import info.magnolia.ui.vaadin.gwt.client.applauncher.event.AppActivationEvent;
37  import info.magnolia.ui.vaadin.gwt.client.applauncher.shared.AppGroup;
38  import info.magnolia.ui.vaadin.gwt.client.applauncher.shared.AppTile;
39  
40  import java.util.HashMap;
41  import java.util.Map;
42  import java.util.Map.Entry;
43  import java.util.function.Function;
44  
45  import com.google.gwt.dom.client.Style;
46  import com.google.gwt.dom.client.Style.Unit;
47  import com.google.gwt.event.dom.client.ScrollEvent;
48  import com.google.gwt.event.dom.client.ScrollHandler;
49  import com.google.gwt.user.client.ui.FlowPanel;
50  import com.google.gwt.user.client.ui.ScrollPanel;
51  import com.google.web.bindery.event.shared.EventBus;
52  import com.vaadin.client.ComputedStyle;
53  import com.vaadin.client.ui.Icon;
54  import com.vaadin.client.ui.layout.ElementResizeEvent;
55  import com.vaadin.client.ui.layout.ElementResizeListener;
56  
57  /**
58   * Implementation of AppLauncher view.
59   */
60  public class AppLauncherViewImpl extends FlowPanel implements AppLauncherView, AppActivationEvent.Handler {
61  
62      private static final double TEMPORARY_PERMANENT_SECTIONS_OFFSET = 170.0;
63  
64      private static final String PERMANENT_APP_GROUP_BORDER = "permanent-app-group-border";
65  
66      private static final String PERMANENT_APP_GROUP_BORDER_BOTTOM = PERMANENT_APP_GROUP_BORDER + "-bottom";
67  
68      private static final String PERMANENT_APP_GROUP_BORDER_TOP = PERMANENT_APP_GROUP_BORDER + "-top";
69  
70      public static final String PERMANENT_APP_SCROLL_PANEL = "permanent-app-scroll-panel";
71  
72      private final Map<String, VAppTileGroup> groups = new HashMap<String, VAppTileGroup>();
73  
74      private final VTemporaryAppGroupBar temporarySectionsBar = new VTemporaryAppGroupBar();
75  
76      private final EventBus eventBus;
77  
78      private final Function<String, Icon> iconResolver;
79  
80      private Presenter presenter;
81  
82      private ScrollPanel permanentAppScrollPanel = new ScrollPanel();;
83  
84      private FlowPanel permanentAppContainer = new FlowPanel();;
85  
86      private ComputedStyle permanentAppScrollPanelStyle = new ComputedStyle(permanentAppScrollPanel.getElement());
87  
88      public AppLauncherViewImpl(final EventBus eventBus, Function<String, Icon> iconResolver) {
89          super();
90          this.eventBus = eventBus;
91          this.iconResolver = iconResolver;
92          add(temporarySectionsBar);
93          this.eventBus.addHandler(AppActivationEvent.TYPE, this);
94  
95          permanentAppScrollPanel.getElement().getStyle().setOverflowX(Style.Overflow.HIDDEN);
96          permanentAppScrollPanel.addStyleName(PERMANENT_APP_SCROLL_PANEL);
97  
98          permanentAppScrollPanel.add(permanentAppContainer);
99          permanentAppScrollPanel.addScrollHandler(new ScrollHandler() {
100             @Override
101             public void onScroll(ScrollEvent event) {
102                 updatePermanentAppGroupBorder();
103             }
104         });
105         add(permanentAppScrollPanel);
106     }
107 
108     @Override
109     public void addAppGroup(AppGroup group) {
110         if (group.isPermanent()) {
111             addPermanentAppGroup(group);
112         } else {
113             addTemporaryAppGroup(group);
114         }
115     }
116 
117     public void addTemporaryAppGroup(AppGroup groupParams) {
118         final VTemporaryAppTileGroup group = new VTemporaryAppTileGroup(groupParams.getBackgroundColor());
119         group.setClientGroup(groupParams.isClientGroup());
120         groups.put(groupParams.getName(), group);
121         temporarySectionsBar.addGroup(groupParams.getCaption(), group);
122         add(group);
123 
124         presenter.registerElementResizeListener(group.getElement(), new ElementResizeListener() {
125             @Override
126             public void onElementResize(ElementResizeEvent e) {
127                 final VTemporaryAppTileGroup currentOpenGroup = temporarySectionsBar.getCurrentOpenGroup();
128                 if (currentOpenGroup == null || group == currentOpenGroup) {
129                     permanentAppScrollPanel.getElement().getStyle().setBottom(TEMPORARY_PERMANENT_SECTIONS_OFFSET + group.getOffsetHeight(), Unit.PX);
130                     updatePermanentAppGroupBorder();
131                 }
132             }
133         });
134     }
135 
136     public void addPermanentAppGroup(AppGroup groupParams) {
137         final VPermanentAppTileGroup group = new VPermanentAppTileGroup(groupParams.getCaption(), groupParams.getBackgroundColor());
138         group.setClientGroup(groupParams.isClientGroup());
139         groups.put(groupParams.getName(), group);
140         permanentAppContainer.add(group);
141 
142         presenter.registerElementResizeListener(permanentAppScrollPanel.getElement(), new ElementResizeListener() {
143             @Override
144             public void onElementResize(ElementResizeEvent e) {
145                 updatePermanentAppGroupBorder();
146             }
147         });
148     }
149 
150     private void updatePermanentAppGroupBorder() {
151         permanentAppScrollPanel.removeStyleName(PERMANENT_APP_GROUP_BORDER_BOTTOM);
152         permanentAppScrollPanel.removeStyleName(PERMANENT_APP_GROUP_BORDER_TOP);
153         int maxScrollPosition = getPermanentAppGroupMaxScrollTop();
154         if (maxScrollPosition > 0) {
155             int verticalScrollPosition = permanentAppScrollPanel.getVerticalScrollPosition();
156             if (verticalScrollPosition > 0) {
157                 permanentAppScrollPanel.addStyleName(PERMANENT_APP_GROUP_BORDER_TOP);
158             }
159 
160             if (verticalScrollPosition < maxScrollPosition) {
161                 permanentAppScrollPanel.addStyleName(PERMANENT_APP_GROUP_BORDER_BOTTOM);
162             }
163 
164         }
165     }
166 
167     private int getPermanentAppGroupMaxScrollTop() {
168         return permanentAppScrollPanel.getMaximumVerticalScrollPosition() - permanentAppScrollPanelStyle.getBorder()[0] - permanentAppScrollPanelStyle.getBorder()[2];
169     }
170 
171     @Override
172     public void onAppActivated(AppActivationEvent event) {
173         presenter.activateApp(event.getAppName());
174     }
175 
176     @Override
177     public void setPresenter(Presenter presenter) {
178         this.presenter = presenter;
179     }
180 
181     @Override
182     public void setAppActive(String appName, boolean isActive) {
183         for (Entry<String, VAppTileGroup> entry : groups.entrySet()) {
184             if (entry.getValue().hasApp(appName)) {
185                 AppTileWidget tile = entry.getValue().getAppTile(appName);
186                 tile.setActiveState(isActive);
187             }
188         }
189     }
190 
191     @Override
192     public void addAppTile(AppTile tileData, AppGroup groupData) {
193         AppTileWidget tile = new AppTileWidget(eventBus, tileData, iconResolver);
194         VAppTileGroup group = groups.get(groupData.getName());
195         if (group != null) {
196             group.addAppTile(tile);
197         }
198     }
199 
200     @Override
201     public void clear() {
202         temporarySectionsBar.clear();
203         for (final VAppTileGroup group : groups.values()) {
204             remove(group);
205         }
206         groups.clear();
207     }
208 }