Coverage Report - org.kuali.student.common.ui.client.widgets.search.CollapsablePanel
 
Classes in this File Line Coverage Branch Coverage Complexity
CollapsablePanel
0%
0/82
0%
0/18
1.56
CollapsablePanel$1
0%
0/5
0%
0/2
1.56
CollapsablePanel$ContentAnimation
0%
0/30
0%
0/10
1.56
CollapsablePanel$ImagePosition
0%
0/2
N/A
1.56
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the Educational Community License, Version 2.0 (the "License"); you may
 3  
  * not use this file except in compliance with the License. You may obtain a copy of the License at
 4  
  * http://www.osedu.org/licenses/ECL-2.0 Unless required by applicable law or agreed to in writing, software distributed
 5  
  * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 6  
  * implied. See the License for the specific language governing permissions and limitations under the License.
 7  
  */
 8  
 
 9  
 package org.kuali.student.common.ui.client.widgets.search;
 10  
 
 11  
 import java.util.ArrayList;
 12  
 import java.util.List;
 13  
 
 14  
 import org.kuali.student.common.ui.client.reporting.ReportExportWidget;
 15  
 import org.kuali.student.common.ui.client.theme.Theme;
 16  
 import org.kuali.student.common.ui.client.util.ExportElement;
 17  
 import org.kuali.student.common.ui.client.util.ExportUtils;
 18  
 import org.kuali.student.common.ui.client.widgets.KSButton;
 19  
 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract.ButtonStyle;
 20  
 import org.kuali.student.common.ui.client.widgets.field.layout.element.SpanPanel;
 21  
 import org.kuali.student.common.ui.client.widgets.layout.HorizontalBlockFlowPanel;
 22  
 import org.kuali.student.common.ui.client.widgets.layout.VerticalFlowPanel;
 23  
 
 24  
 import com.google.gwt.animation.client.Animation;
 25  
 import com.google.gwt.event.dom.client.ClickEvent;
 26  
 import com.google.gwt.event.dom.client.ClickHandler;
 27  
 import com.google.gwt.user.client.DOM;
 28  
 import com.google.gwt.user.client.ui.Composite;
 29  
 import com.google.gwt.user.client.ui.DisclosurePanel;
 30  
 import com.google.gwt.user.client.ui.Image;
 31  
 import com.google.gwt.user.client.ui.SimplePanel;
 32  
 import com.google.gwt.user.client.ui.Widget;
 33  
 
 34  
 public class CollapsablePanel extends Composite implements ReportExportWidget {
 35  
     protected KSButton label;
 36  0
     protected VerticalFlowPanel layout = new VerticalFlowPanel();
 37  0
     protected HorizontalBlockFlowPanel linkPanel = new HorizontalBlockFlowPanel();
 38  0
     protected SimplePanel content = new SimplePanel();
 39  0
     protected ContentAnimation animation = new ContentAnimation();
 40  
 
 41  0
     protected boolean isOpen = false;
 42  0
     protected boolean withImages = true;
 43  0
     protected ImagePosition imagePosition = ImagePosition.ALIGN_LEFT;
 44  
 
 45  0
     public enum ImagePosition {
 46  0
         ALIGN_LEFT, ALIGN_RIGHT
 47  
     }
 48  
 
 49  0
     protected Image closedImage = Theme.INSTANCE.getCommonImages().getDisclosureClosedIcon();
 50  0
     protected Image openedImage = Theme.INSTANCE.getCommonImages().getDisclosureOpenedIcon();
 51  
 
 52  0
     protected ClickHandler openCloseClickHandler = new ClickHandler() {
 53  
 
 54  
         @Override
 55  
         public void onClick(ClickEvent event) {
 56  0
             if (CollapsablePanel.this.isOpen) {
 57  0
                 CollapsablePanel.this.close();
 58  
             } else {
 59  0
                 CollapsablePanel.this.open();
 60  
             }
 61  0
         }
 62  
     };
 63  
 
 64  0
     private static class ContentAnimation extends Animation {
 65  
         /**
 66  
          * Whether the item is being opened or closed.
 67  
          */
 68  
         private boolean opening;
 69  
 
 70  
         /**
 71  
          * The {@link DisclosurePanel} being affected.
 72  
          */
 73  
         private CollapsablePanel curPanel;
 74  
 
 75  
         /**
 76  
          * Open or close the content.
 77  
          * 
 78  
          * @param panel
 79  
          *            the panel to open or close
 80  
          * @param animate
 81  
          *            true to animate, false to open instantly
 82  
          */
 83  
         public void setOpen(CollapsablePanel panel, boolean animate) {
 84  
             // Immediately complete previous open
 85  0
             cancel();
 86  
 
 87  
             // Open the new item
 88  0
             if (animate) {
 89  0
                 curPanel = panel;
 90  0
                 opening = panel.isOpen;
 91  0
                 run(1000);
 92  
             } else {
 93  0
                 panel.content.setVisible(panel.isOpen);
 94  0
                 if (panel.isOpen) {
 95  
                     // Special treatment on the visible case to ensure LazyPanel
 96  
                     // works
 97  0
                     panel.content.setVisible(true);
 98  
                 }
 99  
             }
 100  0
         }
 101  
 
 102  
         @Override
 103  
         protected void onComplete() {
 104  0
             if (!opening) {
 105  0
                 curPanel.content.setVisible(false);
 106  
             }
 107  0
             DOM.setStyleAttribute(curPanel.content.getElement(), "height", "auto");
 108  0
             DOM.setStyleAttribute(curPanel.content.getElement(), "overflow", "visible");
 109  0
             curPanel = null;
 110  0
         }
 111  
 
 112  
         @Override
 113  
         protected void onStart() {
 114  0
             super.onStart();
 115  0
             DOM.setStyleAttribute(curPanel.content.getElement(), "overflow", "hidden");
 116  0
             if (opening) {
 117  0
                 curPanel.content.setVisible(true);
 118  
                 // Special treatment on the visible case to ensure LazyPanel works
 119  0
                 curPanel.content.setVisible(true);
 120  
             }
 121  0
         }
 122  
 
 123  
         @Override
 124  
         protected void onUpdate(double progress) {
 125  0
             int scrollHeight = DOM.getElementPropertyInt(curPanel.content.getElement(), "scrollHeight");
 126  0
             int height = (int) (progress * scrollHeight);
 127  0
             if (!opening) {
 128  0
                 height = scrollHeight - height;
 129  
             }
 130  0
             height = Math.max(height, 1);
 131  
 
 132  0
             DOM.setStyleAttribute(curPanel.content.getElement(), "height", height + "px");
 133  0
             DOM.setStyleAttribute(curPanel.content.getElement(), "width", "auto");
 134  0
         }
 135  
     }
 136  
 
 137  0
     protected CollapsablePanel() {}
 138  
 
 139  0
     public CollapsablePanel(String label, Widget content, boolean isOpen) {
 140  0
         init(getButtonLabel(label), content, isOpen, true, ImagePosition.ALIGN_RIGHT);
 141  0
     }
 142  
 
 143  0
     public CollapsablePanel(String label, Widget content, boolean isOpen, boolean withImages) {
 144  0
         init(getButtonLabel(label), content, isOpen, withImages, ImagePosition.ALIGN_RIGHT);
 145  0
     }
 146  
 
 147  0
     public CollapsablePanel(String label, Widget content, boolean isOpen, boolean withImages, ImagePosition imagePosition) {
 148  0
         init(getButtonLabel(label), content, isOpen, withImages, imagePosition);
 149  0
     }
 150  
 
 151  0
     public CollapsablePanel(Widget label, Widget content, boolean isOpen, boolean withImages, ImagePosition imagePosition) {
 152  0
         init(label, content, isOpen, withImages, imagePosition);
 153  0
     }
 154  
     
 155  
     public void initialise(String label, Widget content, boolean isOpen) {
 156  0
         init(getButtonLabel(label), content, isOpen, true, ImagePosition.ALIGN_RIGHT);
 157  0
     }
 158  
 
 159  
     public void initialise(String label, Widget content, boolean isOpen, boolean withImages) {
 160  0
         init(getButtonLabel(label), content, isOpen, withImages, ImagePosition.ALIGN_RIGHT);
 161  0
     }
 162  
 
 163  
     public void initialise(String label, Widget content, boolean isOpen, boolean withImages, ImagePosition imagePosition) {
 164  0
         init(getButtonLabel(label), content, isOpen, withImages, imagePosition);
 165  0
     }
 166  
 
 167  
     public void initialise(Widget label, Widget content, boolean isOpen, boolean withImages, ImagePosition imagePosition) {
 168  0
         init(label, content, isOpen, withImages, imagePosition);
 169  0
     }
 170  
     
 171  
     protected void init(Widget label, Widget content, boolean isOpen, boolean withImages, ImagePosition imagePosition) {
 172  0
         this.isOpen = isOpen;
 173  0
         this.withImages = withImages;
 174  0
         this.imagePosition = imagePosition;
 175  0
         this.content.setWidget(content);
 176  
 
 177  0
         if (this.imagePosition == ImagePosition.ALIGN_RIGHT) {
 178  0
             linkPanel.add(label);
 179  
         }
 180  
 
 181  0
         if (this.withImages) {
 182  0
             linkPanel.add(closedImage);
 183  0
             linkPanel.add(openedImage);
 184  0
             setImageState();
 185  
         }
 186  
 
 187  0
         if (this.imagePosition == ImagePosition.ALIGN_LEFT) {
 188  0
             linkPanel.add(label);
 189  
         }
 190  
 
 191  0
         if (!isOpen) {
 192  0
             this.content.setVisible(false);
 193  
         }
 194  
 
 195  0
         closedImage.addClickHandler(openCloseClickHandler);
 196  0
         openedImage.addClickHandler(openCloseClickHandler);
 197  
 
 198  0
         layout.add(linkPanel);
 199  0
         layout.add(this.content);
 200  0
         closedImage.addStyleName("ks-image-middle-alignment");
 201  0
         openedImage.addStyleName("ks-image-middle-alignment");
 202  0
         content.addStyleName("top-padding");
 203  0
         this.initWidget(layout);
 204  0
     }
 205  
 
 206  
     protected KSButton getButtonLabel(String labelString) {
 207  0
         label = new KSButton(labelString, ButtonStyle.DEFAULT_ANCHOR);
 208  0
         label.addClickHandler(openCloseClickHandler);
 209  0
         return label;
 210  
     }
 211  
 
 212  
     /**
 213  
      * If the widget was initialized with a string label, it will return a KSButton. If the widget was initialized with a
 214  
      * label widget, it will return the label widget.
 215  
      * 
 216  
      * @return
 217  
      */
 218  
     public KSButton getLabel() {
 219  0
         return label;
 220  
     }
 221  
 
 222  
     public Widget getLabelWidget() {
 223  0
         return label;
 224  
     }
 225  
 
 226  
     public boolean isOpen() {
 227  0
         return isOpen;
 228  
     }
 229  
 
 230  
     public void open() {
 231  0
         isOpen = true;
 232  0
         if (withImages) {
 233  0
             setImageState();
 234  
         }
 235  0
         animation.setOpen(this, true);
 236  0
     }
 237  
 
 238  
     public void close() {
 239  0
         isOpen = false;
 240  0
         if (withImages) {
 241  0
             setImageState();
 242  
         }
 243  0
         animation.setOpen(this, true);
 244  0
     }
 245  
 
 246  
     /**
 247  
      * Update the image state to display opened/closed image based in isOpen() status
 248  
      */
 249  
     protected void setImageState() {
 250  0
         closedImage.setVisible(!isOpen);
 251  0
         openedImage.setVisible(isOpen);
 252  0
     }
 253  
 
 254  
     @Override
 255  
     public boolean isExportElement() {
 256  0
         return true;
 257  
     }
 258  
 
 259  
     @Override
 260  
     public List<ExportElement> getExportElementSubset(ExportElement parent) {
 261  0
         return ExportUtils.getDetailsForWidget(this.content.getWidget(), parent.getViewName(), parent.getSectionName());
 262  
     }
 263  
 
 264  
     @Override
 265  
     public String getExportFieldValue() {
 266  0
         String text = null;
 267  0
         for (int i = 0; i < this.linkPanel.getWidgetCount(); i++) {
 268  0
             Widget child = this.linkPanel.getWidget(i);
 269  0
             if (child instanceof SpanPanel) {
 270  0
                 SpanPanel header = (SpanPanel) child;
 271  0
                 text = header.getText();
 272  
             }
 273  
         }
 274  0
         return text;
 275  
     }
 276  
 
 277  
 }