View Javadoc

1   /**
2    * This file Copyright (c) 2012-2014 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.AppTile;
38  
39  import com.google.gwt.dom.client.Style;
40  import com.google.gwt.event.dom.client.MouseOutEvent;
41  import com.google.gwt.event.dom.client.MouseOutHandler;
42  import com.google.gwt.event.dom.client.MouseOverEvent;
43  import com.google.gwt.event.dom.client.MouseOverHandler;
44  import com.google.gwt.user.client.DOM;
45  import com.google.gwt.user.client.Element;
46  import com.google.gwt.user.client.Event;
47  import com.google.gwt.user.client.ui.Widget;
48  import com.google.web.bindery.event.shared.EventBus;
49  import com.googlecode.mgwt.dom.client.event.touch.TouchEndEvent;
50  import com.googlecode.mgwt.dom.client.event.touch.TouchEndHandler;
51  import com.googlecode.mgwt.dom.client.event.touch.TouchStartEvent;
52  import com.googlecode.mgwt.dom.client.event.touch.TouchStartHandler;
53  import com.googlecode.mgwt.ui.client.widget.touch.TouchDelegate;
54  
55  /**
56   * The tile of one single app in AppLauncher.
57   */
58  public class AppTileWidget extends Widget {
59  
60      private final Element icon = DOM.createDiv();
61  
62      private final Element label = DOM.createDiv();
63  
64      private final Element root = DOM.createDiv();
65  
66      private final Element runningIndicator = DOM.createDiv();
67  
68      private final Element iconContent = DOM.createSpan();
69  
70      private final AppTile appTile;
71  
72      private final EventBus eventBus;
73  
74      private boolean isActive = false;
75  
76      private TouchDelegate touchDelegate = new TouchDelegate(this);
77  
78      public AppTileWidget(EventBus eventBus, AppTile appTile) {
79          super();
80          this.appTile = appTile;
81          this.eventBus = eventBus;
82          constructDOM();
83          bindHandlers();
84          updateIcon();
85          updateCaption();
86      }
87  
88      private void constructDOM() {
89          setElement(root);
90          root.appendChild(icon);
91          root.appendChild(label);
92          root.appendChild(runningIndicator);
93          addStyleName("item");
94          icon.addClassName("icon");
95          icon.appendChild(iconContent);
96  
97          label.addClassName("label");
98          DOM.sinkEvents(getElement(), Event.MOUSEEVENTS);
99      }
100 
101     private void bindHandlers() {
102         /**
103          * Note that we have to add a explict hover class and not use the :hover
104          * pseudo-selector. This is because we need an active state for when in
105          * click that overrules the hover colors, And we cannot use an :active
106          * pseudoselector either because the colors are assigned by code, not
107          * stylesheet. But FYI, hover states are not useful for touch devices,
108          * just for desktop now.
109          */
110         addDomHandler(new MouseOverHandler() {
111             @Override
112             public void onMouseOver(MouseOverEvent event) {
113                 getElement().addClassName("hover");
114             }
115         }, MouseOverEvent.getType());
116 
117         addDomHandler(new MouseOutHandler() {
118             @Override
119             public void onMouseOut(MouseOutEvent event) {
120                 getElement().removeClassName("hover");
121                 updateColors();
122             }
123         }, MouseOutEvent.getType());
124 
125         touchDelegate.addTouchStartHandler(new TouchStartHandler() {
126             @Override
127             public void onTouchStart(TouchStartEvent event) {
128                 getElement().removeClassName("hover");
129                 setColorsClick();
130             }
131         });
132 
133         touchDelegate.addTouchEndHandler(new TouchEndHandler() {
134             @Override
135             public void onTouchEnd(TouchEndEvent event) {
136                 getElement().removeClassName("hover");
137                 setActiveState(true);
138                 eventBus.fireEvent(new AppActivationEvent(appTile.getName()));
139             }
140         });
141     }
142 
143     public void setActiveState(boolean isActive) {
144         this.isActive = isActive;
145         updateColors();
146     }
147 
148     /**
149      * ** COLORING. ********
150      */
151 
152     public void updateColors() {
153         if (isActive()) {
154             setColorsOn();
155         } else {
156             setColorsOff();
157         }
158     }
159 
160     /**
161      * Set the tile colors for the Off state, not active, not clicked.
162      */
163     private void setColorsOff() {
164         final Style style = getElement().getStyle();
165         style.setProperty("backgroundColor", "");
166         style.setProperty("color", "");
167     }
168 
169     /**
170      * Set the tile colors for the click state, whether active or not.
171      */
172     private void setColorsClick() {
173         boolean isTileWhite = !getParent().isClientGroup();
174         setColors(isTileWhite);
175     }
176 
177     /**
178      * Set the tile colors for the state: active, but not in a click or touch.
179      */
180     private void setColorsOn() {
181         boolean isTileWhite = getParent().isClientGroup();
182         setColors(isTileWhite);
183     }
184 
185     /**
186      * Set colors with the group coloring.
187      */
188     private void setColors(boolean isTileWhite) {
189         final Style style = getElement().getStyle();
190         if (isTileWhite) {
191             style.setColor(getParent().getColor());
192             style.setBackgroundColor("white");
193         } else {
194             style.setBackgroundColor(getParent().getColor());
195             style.setColor("white");
196         }
197     }
198 
199     public String getName() {
200         return appTile.getName();
201     }
202 
203     public String getCaption() {
204         return appTile.getCaption();
205     }
206 
207     public boolean isActive() {
208         return isActive;
209     }
210 
211     @Override
212     public VAppTileGroup getParent() {
213         return (VAppTileGroup) super.getParent();
214     }
215 
216     public void updateCaption() {
217         if (appTile != null) {
218             label.setInnerText(appTile.getCaption());
219         }
220     }
221 
222     public void updateIcon() {
223         iconContent.addClassName(appTile.getIcon());
224     }
225 }