Coverage Report - org.kuali.student.common.ui.client.widgets.KSLightBox
 
Classes in this File Line Coverage Branch Coverage Complexity
KSLightBox
0%
0/146
0%
0/34
1.415
KSLightBox$1
0%
0/3
N/A
1.415
KSLightBox$KSDialogResizeHandler
0%
0/3
N/A
1.415
KSLightBox$KSDialogResizeHandler$1
0%
0/6
N/A
1.415
KSLightBox$LightBoxStyle
0%
0/8
N/A
1.415
KSLightBox$LightBoxStyle$1
0%
0/2
N/A
1.415
KSLightBox$LightBoxStyle$2
0%
0/2
N/A
1.415
KSLightBox$LightBoxStyle$3
0%
0/2
N/A
1.415
KSLightBox$LightBoxStyle$4
0%
0/2
N/A
1.415
KSLightBox$LightBoxStyle$5
0%
0/2
N/A
1.415
KSLightBox$LightBoxStyle$6
0%
0/2
N/A
1.415
KSLightBox$LightBoxStyle$7
0%
0/2
N/A
1.415
KSLightBox$Size
0%
0/8
N/A
1.415
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  *
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  */
 15  
 
 16  
 package org.kuali.student.common.ui.client.widgets;
 17  
 
 18  
 import java.util.Arrays;
 19  
 import java.util.List;
 20  
 
 21  
 import com.google.gwt.dom.client.Element;
 22  
 import com.google.gwt.dom.client.NativeEvent;
 23  
 import com.google.gwt.dom.client.NodeList;
 24  
 import com.google.gwt.dom.client.Style.Overflow;
 25  
 import com.google.gwt.dom.client.Style.Unit;
 26  
 import com.google.gwt.event.dom.client.ClickEvent;
 27  
 import com.google.gwt.event.dom.client.ClickHandler;
 28  
 import com.google.gwt.event.dom.client.KeyCodes;
 29  
 import com.google.gwt.event.logical.shared.ResizeEvent;
 30  
 import com.google.gwt.event.logical.shared.ResizeHandler;
 31  
 import com.google.gwt.event.shared.HandlerRegistration;
 32  
 import com.google.gwt.user.client.Command;
 33  
 import com.google.gwt.user.client.DeferredCommand;
 34  
 import com.google.gwt.user.client.Event.NativePreviewEvent;
 35  
 import com.google.gwt.user.client.Window;
 36  
 import com.google.gwt.user.client.ui.Anchor;
 37  
 import com.google.gwt.user.client.ui.DialogBox;
 38  
 import com.google.gwt.user.client.ui.DockLayoutPanel;
 39  
 import com.google.gwt.user.client.ui.FlowPanel;
 40  
 import com.google.gwt.user.client.ui.ScrollPanel;
 41  
 import com.google.gwt.user.client.ui.SimplePanel;
 42  
 import com.google.gwt.user.client.ui.Widget;
 43  
 
 44  
 /**
 45  
  * A KSLightBox is a dialog box that lays out its contents as follows using a
 46  
  * {@link DockLayoutPanel}:<br/>
 47  
  * <br />
 48  
  * ------------------<br/>
 49  
  * HEADER (either static caption / header widget that is not part of the scrollable area)<br/>
 50  
  * ------------------<br/>
 51  
  * CONTENT (part of the scrollable area that will fill available space)<br/>
 52  
  * ------------------<br/>
 53  
  * BUTTONS (static button area that is not part of the scrollable area)<br/>
 54  
  * ------------------<br/>
 55  
  * <br/>
 56  
  * 
 57  
  * The size of the dock panel will determine the size of the lightbox. Thus only the dock
 58  
  * panel size will need to be set.<br/>
 59  
  * The size of the dock panel is usually determined dynamically when the lightbox is
 60  
  * displayed, but you can also statically set it with one of the 'setSize' methods.<br/>
 61  
  * If you however set the size statically, the lightbox won't resize.<br/>
 62  
  * If you're making use of the <b>static sizes, the non-caption header and displaying the
 63  
  * buttons</b>, don't set the height of the dialog smaller than about 155px. Otherwise
 64  
  * there's too little space left for the content and the content (even if its just one line 
 65  
  * of text) will be displayed in a scroll panel.
 66  
  * 
 67  
  */
 68  0
 public class KSLightBox extends DialogBox {
 69  
 
 70  0
     private static final List<String> FOCUSABLE_TAGS = Arrays.asList("INPUT", "SELECT", "BUTTON", "TEXTAREA");
 71  
 
 72  
     /**
 73  
      * An enum that specifies predefined width and height values (in pixels) for the
 74  
      * lightbox.
 75  
      */
 76  0
     public enum Size {
 77  0
         SMALL(400, 155), MEDIUM(550, 340), LARGE(600, 400);
 78  
 
 79  
         private int width;
 80  
 
 81  
         private int height;
 82  
 
 83  0
         Size(int width, int height) {
 84  0
             this.width = width;
 85  0
             this.height = height;
 86  0
         }
 87  
 
 88  
         public int getWidth() {
 89  0
             return width;
 90  
         }
 91  
 
 92  
         public int getHeight() {
 93  0
             return height;
 94  
         }
 95  
     }
 96  
 
 97  0
     private enum LightBoxStyle {
 98  0
         LIGHT_BOX {
 99  
             public String toString() {
 100  0
                 return "ks-lightbox";
 101  
             }
 102  
         },
 103  0
         MAIN_PANEL {
 104  
             public String toString() {
 105  0
                 return "ks-lightbox-mainPanel";
 106  
             }
 107  
         },
 108  0
         TITLE_PANEL {
 109  
             public String toString() {
 110  0
                 return "ks-lightbox-titlePanel";
 111  
             }
 112  
         },
 113  0
         SCROLL_PANEL {
 114  
             public String toString() {
 115  0
                 return "ks-lightbox-scrollPanel";
 116  
             }
 117  
         },
 118  0
         BUTTON_PANEL {
 119  
             public String toString() {
 120  0
                 return "ks-lightbox-buttonPanel";
 121  
             }
 122  
         },
 123  0
         CLOSE_LINK {
 124  
             public String toString() {
 125  0
                 return "ks-lightbox-closeLink";
 126  
             }
 127  
         },
 128  0
         CLOSE_LINK_WITH_CAPTION {
 129  
             public String toString() {
 130  0
                 return "ks-lightbox-closeLink-with-Caption";
 131  
             }
 132  
         }
 133  
     }
 134  
 
 135  
     //Resizing variables
 136  0
     private int maxWidth = 800;
 137  0
     private int maxHeight = 0;
 138  0
     private int minWidth = 400;
 139  0
     private int minHeight = 200;
 140  0
     private int permWidth = -1;
 141  0
     private int permHeight = -1;
 142  
 
 143  
     //DockLayoutPanel sizes
 144  
     private static final int BUTTON_HEIGHT = 40;//'px' units (specified in mainPanel's constructor)
 145  
     private static final int NON_CAPTION_HEIGHT = 40;//'px' units (specified in mainPanel's constructor)
 146  
 
 147  0
     private DockLayoutPanel mainPanel = new DockLayoutPanel(Unit.PX);
 148  0
     private FlowPanel closeLinkPanel = new FlowPanel();
 149  0
     private SimplePanel titlePanel = new SimplePanel();
 150  0
     private ScrollPanel scrollPanel = new ScrollPanel();
 151  0
     private SimplePanel contentPanel = new SimplePanel();
 152  0
     private FlowPanel buttonPanel = new FlowPanel();
 153  0
     private Anchor closeLink = new Anchor();
 154  
 
 155  0
     private KSDialogResizeHandler resizeHandler = new KSDialogResizeHandler();
 156  
     private HandlerRegistration resizeHandlerRegistrater;
 157  
 
 158  0
     public KSLightBox() {
 159  0
         getCaption().asWidget().setVisible(false);
 160  0
         init();
 161  0
     }
 162  
 
 163  0
     public KSLightBox(boolean addCloseLink) {
 164  0
         getCaption().asWidget().setVisible(false);
 165  0
         init();
 166  0
         closeLink.setVisible(addCloseLink);
 167  0
     }
 168  
 
 169  0
     public KSLightBox(String title) {
 170  0
         init();
 171  0
         setText(title);
 172  0
     }
 173  
 
 174  0
     public KSLightBox(String title, Size size) {
 175  0
         init();
 176  0
         setText(title);
 177  0
         setSize(size);
 178  0
     }
 179  
 
 180  
     private void init() {
 181  0
         mainPanel.setStyleName(LightBoxStyle.MAIN_PANEL.toString());
 182  0
         titlePanel.setStyleName(LightBoxStyle.TITLE_PANEL.toString());
 183  0
         closeLink.setStyleName(LightBoxStyle.CLOSE_LINK.toString());
 184  0
         scrollPanel.setStyleName(LightBoxStyle.SCROLL_PANEL.toString());
 185  0
         buttonPanel.setStyleName(LightBoxStyle.BUTTON_PANEL.toString());
 186  
 
 187  0
         setGlassEnabled(true);
 188  0
         super.setWidget(mainPanel);
 189  0
         mainPanel.addNorth(closeLinkPanel, 1);
 190  0
         mainPanel.addNorth(titlePanel, 0);
 191  0
         mainPanel.addSouth(buttonPanel, BUTTON_HEIGHT);
 192  0
         mainPanel.add(scrollPanel);
 193  0
         closeLinkPanel.add(closeLink);
 194  
         //parent element sets overflow to hidden to allow background and other css styling on the titlePanel
 195  0
         Element titlePanelContainer = mainPanel.getWidgetContainerElement(titlePanel);
 196  0
         titlePanelContainer.getStyle().setOverflow(Overflow.VISIBLE);
 197  
         //parent element sets overflow to hidden, must reset overflow to visible to show the 'closeLink'
 198  0
         Element closeLinkPanelContainer = mainPanel.getWidgetContainerElement(closeLinkPanel);
 199  0
         closeLinkPanelContainer.getStyle().setOverflow(Overflow.VISIBLE);
 200  0
         scrollPanel.add(contentPanel);
 201  
 
 202  0
         installResizeHandler();
 203  
         //super.
 204  0
         closeLink.addClickHandler(new ClickHandler() {
 205  
 
 206  
             @Override
 207  
             public void onClick(ClickEvent event) {
 208  0
                 hide();
 209  0
             }
 210  
         });
 211  0
         super.setStyleName(LightBoxStyle.LIGHT_BOX.toString());
 212  
 
 213  0
     }
 214  
 
 215  
     public void setCloseLinkVisible(boolean visible) {
 216  0
         closeLink.setVisible(visible);
 217  0
     }
 218  
 
 219  
     public void removeCloseLink() {
 220  0
         closeLink.setVisible(false);
 221  0
     }
 222  
 
 223  
     public HandlerRegistration addCloseLinkClickHandler(ClickHandler clickHandler) {
 224  0
         return closeLink.addClickHandler(clickHandler);
 225  
     }
 226  
 
 227  
     /**
 228  
      * Sets the header that will be displayed at the top of the lightbox.<br/>
 229  
      * Please note: This header will not be displayed in the caption, but in the actual
 230  
      * lightbox content area.
 231  
      * @param widget The header widget.
 232  
      */
 233  
     public void setNonCaptionHeader(Widget widget) {
 234  0
         titlePanel.setWidget(widget);
 235  0
         mainPanel.setWidgetSize(titlePanel, NON_CAPTION_HEIGHT);
 236  0
         mainPanel.forceLayout();
 237  0
     }
 238  
 
 239  
     @Override
 240  
     public void setText(String text) {
 241  0
         super.setText(text);
 242  0
         getCaption().asWidget().setVisible(true);
 243  
         //Style needed to reposition the 'closeLink'
 244  0
         closeLink.addStyleName(LightBoxStyle.CLOSE_LINK_WITH_CAPTION.toString());
 245  0
     }
 246  
     
 247  
     /**
 248  
      * Removes all the buttons at the bottom of the lightbox.
 249  
      */
 250  
     public void clearButtons() {
 251  0
         buttonPanel.clear();
 252  0
     }
 253  
 
 254  
     /**
 255  
      * Adds a button to the bottom of the lightbox.
 256  
      */
 257  
     public void addButton(Widget button) {
 258  0
         button.addStyleName("ks-button-spacing");
 259  0
         buttonPanel.add(button);
 260  0
     }
 261  
 
 262  
     /**
 263  
      * Adds a {@link org.kuali.student.common.ui.client.widgets.field.layout.button.ButtonGroup} to the button panel at the bottom of the lightbox. 
 264  
      * @param group
 265  
      */
 266  
     @SuppressWarnings("rawtypes")
 267  
     public void addButtonGroup(org.kuali.student.common.ui.client.widgets.field.layout.button.ButtonGroup group) {
 268  0
         buttonPanel.add(group);
 269  0
     }
 270  
     
 271  
     /**
 272  
      * Adds a {@link org.kuali.student.common.ui.client.widgets.buttongroups.ButtonGroup} to the button panel at the bottom of the lightbox.
 273  
      * @param group
 274  
      */
 275  
     @SuppressWarnings("rawtypes")
 276  
     public void addButtonGroup(org.kuali.student.common.ui.client.widgets.buttongroups.ButtonGroup group) {
 277  0
         buttonPanel.add(group);
 278  
         
 279  0
     }
 280  
 
 281  
     public void showButtons(boolean show) {
 282  0
         buttonPanel.setVisible(show);
 283  0
         if (show) {
 284  0
             mainPanel.setWidgetSize(buttonPanel, BUTTON_HEIGHT);
 285  
         } else {
 286  0
             mainPanel.setWidgetSize(buttonPanel, 0);
 287  
         }
 288  0
         mainPanel.forceLayout();
 289  0
     }
 290  
 
 291  
     /**
 292  
      * Set the maximum width in pixels that this dialog will grow to.<br />
 293  
      * Please note: If the lightbox's size was set explicitly, this call will have no
 294  
      * effect.
 295  
      * 
 296  
      * @param width The dialog's maximum width in pixels.
 297  
      */
 298  
     public void setMaxWidth(int width) {
 299  0
         this.maxWidth = width;
 300  0
     }
 301  
 
 302  
     /**
 303  
      * Set the maximum height in pixels that this dialog will grow to.<br />
 304  
      * Please note: If the lightbox's size was set explicitly, this call will have no
 305  
      * effect.
 306  
      * 
 307  
      * @param height The dialog's maximum height in pixels.
 308  
      */
 309  
     public void setMaxHeight(int height) {
 310  0
         this.maxHeight = height;
 311  0
     }
 312  
 
 313  
     /**
 314  
      * Set the width and height of the lightbox in pixels.<br/>
 315  
      * Please note: These values will not be affected by resizing. Thus the lightbox will
 316  
      * remain the specified size, irrespective of resizing.
 317  
      * 
 318  
      * @param width The specified width in pixels.
 319  
      * @param height The specified height in pixels.
 320  
      */
 321  
     public void setSize(int width, int height) {
 322  0
         mainPanel.setSize(width + "px", width + "px");
 323  0
         this.permHeight = height;
 324  0
         this.permWidth = width;
 325  0
     }
 326  
 
 327  
     /**
 328  
      * Set the width and height of the lightbox in pixels using the {@link Size} enum.
 329  
      * 
 330  
      * @param size A predefined dialog size.
 331  
      */
 332  
     public void setSize(Size size) {
 333  0
         setSize(size.getWidth(), size.getHeight());
 334  0
     }
 335  
 
 336  
     @Override
 337  
     public void setWidget(Widget content) {
 338  0
         contentPanel.setWidget(content);
 339  0
     }
 340  
 
 341  
     @Override
 342  
     public Widget getWidget() {
 343  0
         return contentPanel.getWidget();
 344  
     }
 345  
 
 346  
     @Override
 347  
     public void hide() {
 348  0
         super.hide();
 349  0
         uninstallResizeHandler();
 350  0
     }
 351  
 
 352  
     @Override
 353  
     public void show() {
 354  0
         resizeDialog();
 355  0
         installResizeHandler();
 356  0
         super.show();
 357  0
         super.center();
 358  0
         grabFocus();
 359  0
     }
 360  
 
 361  
     private void resizeDialog() {
 362  
 
 363  0
         int width = maxWidth;
 364  0
         int height = maxHeight;
 365  
 
 366  
         //Width calculation
 367  0
         if (permWidth != -1) {
 368  0
             width = permWidth;
 369  
         } else {
 370  0
             if (Window.getClientWidth() < 850) {
 371  0
                 width = Window.getClientWidth() - 160;
 372  
             }
 373  0
             if (width > maxWidth) {
 374  0
                 width = maxWidth;
 375  
             }
 376  0
             if (width < minWidth) {
 377  0
                 width = minWidth;
 378  
             }
 379  
         }
 380  
 
 381  
         //Height calculation
 382  0
         if (permHeight != -1) {
 383  0
             height = permHeight;
 384  
         } else {
 385  0
             height = Window.getClientHeight() - 160;
 386  
 
 387  0
             if (height > maxHeight && maxHeight != 0) {
 388  0
                 height = maxHeight;
 389  
             }
 390  0
             if (height < minHeight) {
 391  0
                 height = minHeight;
 392  
             }
 393  
         }
 394  
 
 395  0
         if (width > 0 && height > 0) {
 396  0
             mainPanel.setSize(width + "px", height + "px");
 397  
         }
 398  
 
 399  0
     }
 400  
 
 401  
     private void grabFocus() {
 402  0
         Widget mainContent = contentPanel.getWidget();
 403  0
         NodeList<Element> nodeList = mainContent.getElement().getElementsByTagName("*");
 404  0
         for (int i = 0; i < nodeList.getLength(); i++) {
 405  0
             Element e = nodeList.getItem(i);
 406  0
             if (FOCUSABLE_TAGS.contains(e.getTagName().toUpperCase())) {
 407  0
                 e.focus();
 408  0
                 return;
 409  
             }
 410  
         }
 411  
 
 412  0
     }
 413  
 
 414  
     @Override
 415  
     protected void onPreviewNativeEvent(NativePreviewEvent preview) {
 416  0
         super.onPreviewNativeEvent(preview);
 417  0
         NativeEvent evt = preview.getNativeEvent();
 418  0
         if (evt.getType().equals("keydown")) {
 419  0
             switch (evt.getKeyCode()) {
 420  
                 case KeyCodes.KEY_ESCAPE:
 421  0
                     hide();
 422  
                     break;
 423  
             }
 424  
         }
 425  0
     }
 426  
 
 427  
     public void uninstallResizeHandler() {
 428  0
         if (resizeHandlerRegistrater != null) {
 429  0
             resizeHandlerRegistrater.removeHandler();
 430  0
             resizeHandlerRegistrater = null;
 431  
 
 432  
         }
 433  0
     }
 434  
 
 435  
     public void installResizeHandler() {
 436  0
         if (resizeHandlerRegistrater == null) {
 437  0
             resizeHandlerRegistrater = Window.addResizeHandler(resizeHandler);
 438  
         }
 439  0
     }
 440  
 
 441  0
     class KSDialogResizeHandler implements ResizeHandler {
 442  
         @SuppressWarnings("deprecation")
 443  
         @Override
 444  
         public void onResize(ResizeEvent event) {
 445  0
             DeferredCommand.addCommand(new Command() {
 446  
 
 447  
                 @Override
 448  
                 public void execute() {
 449  0
                     resizeDialog();
 450  0
                     int left = (Window.getClientWidth() - getOffsetWidth()) >> 1;
 451  0
                     int top = (Window.getClientHeight() - getOffsetHeight()) >> 1;
 452  0
                     setPopupPosition(Math.max(Window.getScrollLeft() + left, 0), Math.max(
 453  
                             Window.getScrollTop() + top, 0));
 454  0
                 }
 455  
             });
 456  0
         }
 457  
     }
 458  
 
 459  
     
 460  
 
 461  
 }