View Javadoc

1   /**
2    * This file Copyright (c) 2013 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.framework.overlay;
35  
36  import info.magnolia.objectfactory.Classes;
37  import info.magnolia.ui.api.overlay.AlertCallback;
38  import info.magnolia.ui.api.overlay.ConfirmationCallback;
39  import info.magnolia.ui.api.overlay.MessageStyleType;
40  import info.magnolia.ui.api.overlay.NotificationCallback;
41  import info.magnolia.ui.api.overlay.OverlayCloser;
42  import info.magnolia.ui.api.overlay.OverlayLayer;
43  import info.magnolia.ui.api.view.View;
44  import info.magnolia.ui.vaadin.dialog.BaseDialog;
45  import info.magnolia.ui.vaadin.dialog.ConfirmationDialog;
46  import info.magnolia.ui.vaadin.dialog.ConfirmationDialog.ConfirmationEvent;
47  import info.magnolia.ui.vaadin.dialog.LightDialog;
48  import info.magnolia.ui.vaadin.dialog.Notification;
49  import info.magnolia.ui.vaadin.icon.CompositeIcon;
50  
51  import com.vaadin.event.LayoutEvents;
52  import com.vaadin.shared.ui.label.ContentMode;
53  import com.vaadin.ui.Button;
54  import com.vaadin.ui.Button.ClickEvent;
55  import com.vaadin.ui.Button.ClickListener;
56  import com.vaadin.ui.CssLayout;
57  import com.vaadin.ui.HorizontalLayout;
58  import com.vaadin.ui.Label;
59  import com.vaadin.ui.Layout;
60  import com.vaadin.ui.Panel;
61  import com.vaadin.ui.themes.BaseTheme;
62  
63  /**
64   * Provides implementations for most OverlayLayer methods.
65   */
66  public abstract class OverlayPresenter implements OverlayLayer {
67  
68      public static final int TIMEOUT_SECONDS_DEFAULT = 3;
69  
70      private static final String ACTION_CONFIRM = "confirm";
71  
72      /**
73       * Convenience method to open an overlay with the default strong modality level.
74       */
75      @Override
76      public OverlayCloser openOverlay(View view) {
77          return openOverlay(view, ModalityLevel.STRONG);
78      }
79  
80      /**
81       * Open alert dialog with light modality level. Close dialog on confirm.
82       */
83      @Override
84      public void openAlert(MessageStyleType type, View viewToShow, String confirmButtonText, final AlertCallback cb) {
85          BaseDialog dialog = createAlertDialog(viewToShow, confirmButtonText, type.getCssClass(), cb);
86          dialog.showCloseButton();
87  
88          final OverlayCloser overlayCloser = openOverlay(new ViewAdapter(dialog), ModalityLevel.LIGHT);
89          dialog.addDialogCloseHandler(createCloseHandler(overlayCloser));
90      }
91  
92      /**
93       * Convenience method with string content. for opening an alert.
94       */
95      @Override
96      public void openAlert(MessageStyleType type, String title, String body, String confirmButtonText, AlertCallback cb) {
97          openAlert(type, createConfirmationView(type, title, body), confirmButtonText, cb);
98      }
99  
100     private ConfirmationDialog.ConfirmationEvent.Handler createHandler(final OverlayCloser overlayCloser, final ConfirmationCallback callback) {
101         return new ConfirmationDialog.ConfirmationEvent.Handler() {
102             @Override
103             public void onConfirmation(ConfirmationEvent event) {
104                 if (event.isConfirmed()) {
105                     callback.onSuccess();
106                 } else {
107                     callback.onCancel();
108                 }
109                 overlayCloser.close();
110             }
111         };
112     }
113 
114     private ConfirmationDialog createConfirmationDialog(View contentView, String confirmButtonText, String cancelButtonText, String styleName, boolean cancelIsDefault) {
115         ConfirmationDialog dialog = new ConfirmationDialog(contentView.asVaadinComponent(), confirmButtonText, cancelButtonText, cancelIsDefault);
116         dialog.addStyleName(styleName);
117         dialog.addStyleName("confirmation");
118         return dialog;
119     }
120 
121     private BaseDialog createAlertDialog(View contentView, String confirmButtonText, String styleName, final AlertCallback cb) {
122         BaseDialog dialog = new LightDialog();
123         dialog.addStyleName(styleName);
124         dialog.addStyleName("alert");
125         dialog.setContent(contentView.asVaadinComponent());
126         HorizontalLayout footer = new HorizontalLayout();
127         Button confirmButton = new Button(confirmButtonText, new ClickListener() {
128             @Override
129             public void buttonClick(ClickEvent event) {
130                 cb.onOk();
131             }
132         });
133         confirmButton.addStyleName("default");
134         footer.addComponent(confirmButton);
135         return dialog;
136     }
137 
138     private View createConfirmationView(final MessageStyleType type, final String title, final String body) {
139         Layout layout = new CssLayout();
140 
141         Label titleLabel = new Label(title, ContentMode.HTML);
142         titleLabel.addStyleName("title");
143         layout.addComponent(titleLabel);
144 
145         Label bodyLabel = new Label(body, ContentMode.HTML);
146         bodyLabel.addStyleName("body");
147         layout.addComponent(bodyLabel);
148 
149         CompositeIcon icon = (CompositeIcon) Classes.getClassFactory().newInstance(type.getIconClass());
150         icon.setStyleName("dialog-icon");
151         layout.addComponent(icon);
152         return new ViewAdapter(layout);
153     }
154 
155     private BaseDialog.DialogCloseEvent.Handler createCloseHandler(final OverlayCloser overlayCloser) {
156         return new BaseDialog.DialogCloseEvent.Handler() {
157             @Override
158             public void onClose(BaseDialog.DialogCloseEvent event) {
159                 overlayCloser.close();
160             }
161         };
162     }
163 
164     /**
165      * Present modal confirmation dialog with light modality level. Allow any Vaadin content to be presented.
166      */
167     @Override
168     public void openConfirmation(MessageStyleType type, View contentView, String confirmButtonText, String cancelButtonText,
169                                  boolean cancelIsDefault, ConfirmationCallback callback) {
170         ConfirmationDialog dialog = createConfirmationDialog(contentView, confirmButtonText, cancelButtonText, type.getCssClass(), cancelIsDefault);
171         dialog.showCloseButton();
172 
173         Panel panel = new Panel();
174         panel.setHeight("100%");
175         panel.setWidth(null);
176         panel.setContent(dialog);
177         final OverlayCloser overlayCloser = openOverlay(new ViewAdapter(panel), ModalityLevel.LIGHT);
178         dialog.addConfirmationHandler(createHandler(overlayCloser, callback));
179         dialog.addDialogCloseHandler(createCloseHandler(overlayCloser));
180 
181     }
182 
183     /**
184      * Present modal confirmation dialog with light modality level. Allow only string content.
185      */
186     @Override
187     public void openConfirmation(MessageStyleType type, final String title, final String body, String confirmButtonText, String cancelButtonText, boolean cancelIsDefault, ConfirmationCallback cb) {
188         openConfirmation(type, createConfirmationView(type, title, body), confirmButtonText, cancelButtonText, cancelIsDefault, cb);
189     }
190 
191     /**
192      * Present notification indicator with no modality. Close after timeout expires.
193      */
194     @Override
195     public void openNotification(final MessageStyleType type, final boolean doesTimeout, final View viewToShow) {
196         final Notification notification = new Notification(type);
197         final OverlayCloser closer = openOverlay(notification, ModalityLevel.NON_MODAL);
198         notification.setContent(viewToShow.asVaadinComponent());
199         notification.addCloseButtonListener(new ClickListener() {
200             @Override
201             public void buttonClick(ClickEvent clickEvent) {
202                 closer.close();
203             }
204         });
205 
206         notification.addNotificationBodyClickListener(new LayoutEvents.LayoutClickListener() {
207             @Override
208             public void layoutClick(LayoutEvents.LayoutClickEvent layoutClickEvent) {
209                 closer.setCloseTimeout(-1);
210             }
211         });
212 
213         if (doesTimeout) {
214             closer.setCloseTimeout(TIMEOUT_SECONDS_DEFAULT);
215         }
216     }
217 
218     /**
219      * Convenience method for presenting notification indicator with string content.
220      */
221     @Override
222     public void openNotification(final MessageStyleType type, final boolean doesTimeout, final String title) {
223         openNotification(type, doesTimeout, new ViewAdapter(new Label(title, ContentMode.HTML)));
224 
225     }
226 
227     /**
228      * Convenience method for presenting notification indicator with string content.
229      */
230     @Override
231     public void openNotification(final MessageStyleType type, final boolean doesTimeout, final String title, final String linkText, final NotificationCallback cb) {
232         HorizontalLayout layout = new HorizontalLayout();
233         layout.setSpacing(true);
234         layout.addComponent(new Label(title, ContentMode.HTML));
235 
236         Button button = new Button(linkText, new ClickListener() {
237             @Override
238             public void buttonClick(ClickEvent event) {
239                 cb.onLinkClicked();
240             }
241         });
242         button.setStyleName(BaseTheme.BUTTON_LINK);
243 
244         layout.addComponent(button);
245         openNotification(type, doesTimeout, new ViewAdapter(layout));
246 
247     }
248 
249 }