Coverage Report - org.kuali.student.common.ui.client.widgets.KSLightBox
 
Classes in this File Line Coverage Branch Coverage Complexity
KSLightBox
0%
0/144
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, must reset overflow to visible to show the 'closeLink'
 195  0
         Element titlePanelContainer = mainPanel.getWidgetContainerElement(closeLinkPanel);
 196  0
         titlePanelContainer.getStyle().setOverflow(Overflow.VISIBLE);
 197  0
         scrollPanel.add(contentPanel);
 198  
 
 199  0
         installResizeHandler();
 200  
         //super.
 201  0
         closeLink.addClickHandler(new ClickHandler() {
 202  
 
 203  
             @Override
 204  
             public void onClick(ClickEvent event) {
 205  0
                 hide();
 206  0
             }
 207  
         });
 208  0
         super.setStyleName(LightBoxStyle.LIGHT_BOX.toString());
 209  
 
 210  0
     }
 211  
 
 212  
     public void setCloseLinkVisible(boolean visible) {
 213  0
         closeLink.setVisible(visible);
 214  0
     }
 215  
 
 216  
     public void removeCloseLink() {
 217  0
         closeLink.setVisible(false);
 218  0
     }
 219  
 
 220  
     public HandlerRegistration addCloseLinkClickHandler(ClickHandler clickHandler) {
 221  0
         return closeLink.addClickHandler(clickHandler);
 222  
     }
 223  
 
 224  
     /**
 225  
      * Sets the header that will be displayed at the top of the lightbox.<br/>
 226  
      * Please note: This header will not be displayed in the caption, but in the actual
 227  
      * lightbox content area.
 228  
      * @param widget The header widget.
 229  
      */
 230  
     public void setNonCaptionHeader(Widget widget) {
 231  0
         titlePanel.setWidget(widget);
 232  0
         mainPanel.setWidgetSize(titlePanel, NON_CAPTION_HEIGHT);
 233  0
         mainPanel.forceLayout();
 234  0
     }
 235  
 
 236  
     @Override
 237  
     public void setText(String text) {
 238  0
         super.setText(text);
 239  0
         getCaption().asWidget().setVisible(true);
 240  
         //Style needed to reposition the 'closeLink'
 241  0
         closeLink.addStyleName(LightBoxStyle.CLOSE_LINK_WITH_CAPTION.toString());
 242  0
     }
 243  
     
 244  
     /**
 245  
      * Removes all the buttons at the bottom of the lightbox.
 246  
      */
 247  
     public void clearButtons() {
 248  0
         buttonPanel.clear();
 249  0
     }
 250  
 
 251  
     /**
 252  
      * Adds a button to the bottom of the lightbox.
 253  
      */
 254  
     public void addButton(Widget button) {
 255  0
         button.addStyleName("ks-button-spacing");
 256  0
         buttonPanel.add(button);
 257  0
     }
 258  
 
 259  
     /**
 260  
      * Adds a {@link org.kuali.student.common.ui.client.widgets.field.layout.button.ButtonGroup} to the button panel at the bottom of the lightbox. 
 261  
      * @param group
 262  
      */
 263  
     @SuppressWarnings("rawtypes")
 264  
     public void addButtonGroup(org.kuali.student.common.ui.client.widgets.field.layout.button.ButtonGroup group) {
 265  0
         buttonPanel.add(group);
 266  0
     }
 267  
     
 268  
     /**
 269  
      * Adds a {@link org.kuali.student.common.ui.client.widgets.buttongroups.ButtonGroup} to the button panel at the bottom of the lightbox.
 270  
      * @param group
 271  
      */
 272  
     @SuppressWarnings("rawtypes")
 273  
     public void addButtonGroup(org.kuali.student.common.ui.client.widgets.buttongroups.ButtonGroup group) {
 274  0
         buttonPanel.add(group);
 275  
         
 276  0
     }
 277  
 
 278  
     public void showButtons(boolean show) {
 279  0
         buttonPanel.setVisible(show);
 280  0
         if (show) {
 281  0
             mainPanel.setWidgetSize(buttonPanel, BUTTON_HEIGHT);
 282  
         } else {
 283  0
             mainPanel.setWidgetSize(buttonPanel, 0);
 284  
         }
 285  0
         mainPanel.forceLayout();
 286  0
     }
 287  
 
 288  
     /**
 289  
      * Set the maximum width in pixels that this dialog will grow to.<br />
 290  
      * Please note: If the lightbox's size was set explicitly, this call will have no
 291  
      * effect.
 292  
      * 
 293  
      * @param width The dialog's maximum width in pixels.
 294  
      */
 295  
     public void setMaxWidth(int width) {
 296  0
         this.maxWidth = width;
 297  0
     }
 298  
 
 299  
     /**
 300  
      * Set the maximum height in pixels that this dialog will grow to.<br />
 301  
      * Please note: If the lightbox's size was set explicitly, this call will have no
 302  
      * effect.
 303  
      * 
 304  
      * @param height The dialog's maximum height in pixels.
 305  
      */
 306  
     public void setMaxHeight(int height) {
 307  0
         this.maxHeight = height;
 308  0
     }
 309  
 
 310  
     /**
 311  
      * Set the width and height of the lightbox in pixels.<br/>
 312  
      * Please note: These values will not be affected by resizing. Thus the lightbox will
 313  
      * remain the specified size, irrespective of resizing.
 314  
      * 
 315  
      * @param width The specified width in pixels.
 316  
      * @param height The specified height in pixels.
 317  
      */
 318  
     public void setSize(int width, int height) {
 319  0
         mainPanel.setSize(width + "px", width + "px");
 320  0
         this.permHeight = height;
 321  0
         this.permWidth = width;
 322  0
     }
 323  
 
 324  
     /**
 325  
      * Set the width and height of the lightbox in pixels using the {@link Size} enum.
 326  
      * 
 327  
      * @param size A predefined dialog size.
 328  
      */
 329  
     public void setSize(Size size) {
 330  0
         setSize(size.getWidth(), size.getHeight());
 331  0
     }
 332  
 
 333  
     @Override
 334  
     public void setWidget(Widget content) {
 335  0
         contentPanel.setWidget(content);
 336  0
     }
 337  
 
 338  
     @Override
 339  
     public Widget getWidget() {
 340  0
         return contentPanel.getWidget();
 341  
     }
 342  
 
 343  
     @Override
 344  
     public void hide() {
 345  0
         super.hide();
 346  0
         uninstallResizeHandler();
 347  0
     }
 348  
 
 349  
     @Override
 350  
     public void show() {
 351  0
         resizeDialog();
 352  0
         installResizeHandler();
 353  0
         super.show();
 354  0
         super.center();
 355  0
         grabFocus();
 356  0
     }
 357  
 
 358  
     private void resizeDialog() {
 359  
 
 360  0
         int width = maxWidth;
 361  0
         int height = maxHeight;
 362  
 
 363  
         //Width calculation
 364  0
         if (permWidth != -1) {
 365  0
             width = permWidth;
 366  
         } else {
 367  0
             if (Window.getClientWidth() < 850) {
 368  0
                 width = Window.getClientWidth() - 160;
 369  
             }
 370  0
             if (width > maxWidth) {
 371  0
                 width = maxWidth;
 372  
             }
 373  0
             if (width < minWidth) {
 374  0
                 width = minWidth;
 375  
             }
 376  
         }
 377  
 
 378  
         //Height calculation
 379  0
         if (permHeight != -1) {
 380  0
             height = permHeight;
 381  
         } else {
 382  0
             height = Window.getClientHeight() - 160;
 383  
 
 384  0
             if (height > maxHeight && maxHeight != 0) {
 385  0
                 height = maxHeight;
 386  
             }
 387  0
             if (height < minHeight) {
 388  0
                 height = minHeight;
 389  
             }
 390  
         }
 391  
 
 392  0
         if (width > 0 && height > 0) {
 393  0
             mainPanel.setSize(width + "px", height + "px");
 394  
         }
 395  
 
 396  0
     }
 397  
 
 398  
     private void grabFocus() {
 399  0
         Widget mainContent = contentPanel.getWidget();
 400  0
         NodeList<Element> nodeList = mainContent.getElement().getElementsByTagName("*");
 401  0
         for (int i = 0; i < nodeList.getLength(); i++) {
 402  0
             Element e = nodeList.getItem(i);
 403  0
             if (FOCUSABLE_TAGS.contains(e.getTagName().toUpperCase())) {
 404  0
                 e.focus();
 405  0
                 return;
 406  
             }
 407  
         }
 408  
 
 409  0
     }
 410  
 
 411  
     @Override
 412  
     protected void onPreviewNativeEvent(NativePreviewEvent preview) {
 413  0
         super.onPreviewNativeEvent(preview);
 414  0
         NativeEvent evt = preview.getNativeEvent();
 415  0
         if (evt.getType().equals("keydown")) {
 416  0
             switch (evt.getKeyCode()) {
 417  
                 case KeyCodes.KEY_ESCAPE:
 418  0
                     hide();
 419  
                     break;
 420  
             }
 421  
         }
 422  0
     }
 423  
 
 424  
     public void uninstallResizeHandler() {
 425  0
         if (resizeHandlerRegistrater != null) {
 426  0
             resizeHandlerRegistrater.removeHandler();
 427  0
             resizeHandlerRegistrater = null;
 428  
 
 429  
         }
 430  0
     }
 431  
 
 432  
     public void installResizeHandler() {
 433  0
         if (resizeHandlerRegistrater == null) {
 434  0
             resizeHandlerRegistrater = Window.addResizeHandler(resizeHandler);
 435  
         }
 436  0
     }
 437  
 
 438  0
     class KSDialogResizeHandler implements ResizeHandler {
 439  
         @SuppressWarnings("deprecation")
 440  
         @Override
 441  
         public void onResize(ResizeEvent event) {
 442  0
             DeferredCommand.addCommand(new Command() {
 443  
 
 444  
                 @Override
 445  
                 public void execute() {
 446  0
                     resizeDialog();
 447  0
                     int left = (Window.getClientWidth() - getOffsetWidth()) >> 1;
 448  0
                     int top = (Window.getClientHeight() - getOffsetHeight()) >> 1;
 449  0
                     setPopupPosition(Math.max(Window.getScrollLeft() + left, 0), Math.max(
 450  
                             Window.getScrollTop() + top, 0));
 451  0
                 }
 452  
             });
 453  0
         }
 454  
     }
 455  
 
 456  
     
 457  
 
 458  
 }