View Javadoc
1   /**
2    * This file Copyright (c) 2011-2017 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.widget.controlbar;
35  
36  import info.magnolia.jcr.util.NodeTypes;
37  
38  import com.google.gwt.dom.client.Element;
39  import com.google.gwt.user.client.DOM;
40  import com.google.gwt.user.client.ui.FlowPanel;
41  import com.google.gwt.user.client.ui.Widget;
42  
43  /**
44   * Base class for horizontal bars with buttons.
45   * The instantiation of control-bars needs to happen in the following order:
46   * <pre>
47   *     <ul>
48   *         <li>
49   *             {@link #initLayout()} sets up the layout and the widgets in the necessary order: The buttons are placed
50   *             first in the DOM, followed by the status-indicator and the label.
51   *         </li>
52   *         <li>
53   *             {@link #addLabel(String, int)} or {@link #addStatusIndicator(int)} as these are depending on their div being
54   *             present in the DOM, when added. If not called the divs will remain empty and without any class-name.
55   *         </li>
56   *     </ul>
57   * </pre>
58   */
59  public abstract class AbstractBar extends SimpleBar {
60  
61  
62      private final static String EDITOR_BAR_LABEL_CLASS_NAME = "mgnlEditorBarLabel";
63      private final static String EDITOR_BAR_BUTTONS_CLASS_NAME = "mgnlEditorBarButtons";
64      private final static String EDITOR_BAR_WITH_STATUS_CLASS_NAME = "mgnlEditorBarStatusIndicator";
65  
66      private final static String MGNL_LEVEL_CLASS_NAME = "mgnlLevel-";
67  
68      protected final static String AREA_CLASS_NAME = "area";
69      protected final static String COMPONENT_CLASS_NAME = "component";
70  
71      protected final static String ICON_CLASS_NAME = "editorIcon";
72      protected final static String EDIT_CLASS_NAME = "icon-edit";
73      protected final static String ADD_CLASS_NAME = "icon-add-item";
74  
75      private final static String STATUS_INDICATOR_CLASS_NAME = "status-indicator";
76      private final static String STATUS_INACTIVATED_CLASS_NAME = "background-color-red icon-status-red";
77      private final static String STATUS_MODIFIED_CLASS_NAME = "background-color-yellow icon-status-orange";
78  
79      private final static int MAX_LEVEL = 6;
80  
81      private FlowPanel buttons;
82      private Element label;
83      private Element activationIndicator;
84  
85      /**
86       * Initializes the layout. The order of the elements matter.
87       * IIRC the FlowPanel is needed to propagate click- and touch-events, otherwise a div vould be used for the buttons
88       * as well.
89       */
90      protected void initLayout() {
91          this.buttons = new FlowPanel();
92          this.activationIndicator = DOM.createDiv();
93          this.label = DOM.createDiv();
94  
95          buttons.setStylePrimaryName(EDITOR_BAR_BUTTONS_CLASS_NAME);
96          insert(buttons, 0); // must be first element to allow overflowing (ellipsis) the label
97  
98          getElement().appendChild(activationIndicator);
99          getElement().appendChild(label);
100     }
101 
102     /**
103      * Adds the label to the control-bar. Sets the css class-names and adds the level-padding.
104      */
105     protected void addLabel(String text, int level) {
106         label.setClassName(EDITOR_BAR_LABEL_CLASS_NAME);
107         label.setInnerText(text);
108         // tooltip. Nice to have when area label is truncated because too long.
109         label.setTitle(text);
110         // replace the numerical level with 'max' if the #MAX_LEVEL has been reached
111         label.addClassName(MGNL_LEVEL_CLASS_NAME + (level > MAX_LEVEL ? "max" : String.valueOf(level)));
112     }
113 
114     /**
115      * Adds the status-indicator to the control-bar and the correlating css classes-names to the status-div as well
116      * as the control-bar itself for the left indentation.
117      */
118     protected void addStatusIndicator(int activationStatus) {
119         switch (activationStatus) {
120         case NodeTypes.Activatable.ACTIVATION_STATUS_MODIFIED:
121             activationIndicator.setClassName(STATUS_INDICATOR_CLASS_NAME);
122             activationIndicator.addClassName(STATUS_MODIFIED_CLASS_NAME);
123             addStyleName(EDITOR_BAR_WITH_STATUS_CLASS_NAME);
124             break;
125         case NodeTypes.Activatable.ACTIVATION_STATUS_NOT_ACTIVATED:
126             activationIndicator.setClassName(STATUS_INDICATOR_CLASS_NAME);
127             activationIndicator.addClassName(STATUS_INACTIVATED_CLASS_NAME);
128             addStyleName(EDITOR_BAR_WITH_STATUS_CLASS_NAME);
129             break;
130         // otherwise nothing, this is only run once, so no need to remove anything.
131         case NodeTypes.Activatable.ACTIVATION_STATUS_ACTIVATED:
132         default:
133             break;
134         }
135     }
136 
137     @Override
138     public void onAttach() {
139         super.onAttach();
140     }
141 
142     protected void addButton(final Widget button) {
143         buttons.add(button);
144     }
145 }