Coverage Report - org.kuali.student.common.ui.client.widgets.search.CollapsablePanel
 
Classes in this File Line Coverage Branch Coverage Complexity
CollapsablePanel
0%
0/74
0%
0/18
1.667
CollapsablePanel$1
0%
0/5
0%
0/2
1.667
CollapsablePanel$ContentAnimation
0%
0/30
0%
0/10
1.667
CollapsablePanel$ImagePosition
0%
0/2
N/A
1.667
 
 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
     private 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  
     protected void init(Widget label, Widget content, boolean isOpen, boolean withImages, ImagePosition imagePosition) {
 156  0
         this.isOpen = isOpen;
 157  0
         this.withImages = withImages;
 158  0
         this.imagePosition = imagePosition;
 159  0
         this.content.setWidget(content);
 160  
 
 161  0
         if (this.imagePosition == ImagePosition.ALIGN_RIGHT) {
 162  0
             linkPanel.add(label);
 163  
         }
 164  
 
 165  0
         if (this.withImages) {
 166  0
             linkPanel.add(closedImage);
 167  0
             linkPanel.add(openedImage);
 168  0
             setImageState();
 169  
         }
 170  
 
 171  0
         if (this.imagePosition == ImagePosition.ALIGN_LEFT) {
 172  0
             linkPanel.add(label);
 173  
         }
 174  
 
 175  0
         if (!isOpen) {
 176  0
             this.content.setVisible(false);
 177  
         }
 178  
 
 179  0
         closedImage.addClickHandler(openCloseClickHandler);
 180  0
         openedImage.addClickHandler(openCloseClickHandler);
 181  
 
 182  0
         layout.add(linkPanel);
 183  0
         layout.add(this.content);
 184  0
         closedImage.addStyleName("ks-image-middle-alignment");
 185  0
         openedImage.addStyleName("ks-image-middle-alignment");
 186  0
         content.addStyleName("top-padding");
 187  0
         this.initWidget(layout);
 188  0
     }
 189  
 
 190  
     protected KSButton getButtonLabel(String labelString) {
 191  0
         label = new KSButton(labelString, ButtonStyle.DEFAULT_ANCHOR);
 192  0
         label.addClickHandler(openCloseClickHandler);
 193  0
         return label;
 194  
     }
 195  
 
 196  
     /**
 197  
      * If the widget was initialized with a string label, it will return a KSButton. If the widget was initialized with a
 198  
      * label widget, it will return the label widget.
 199  
      * 
 200  
      * @return
 201  
      */
 202  
     public KSButton getLabel() {
 203  0
         return label;
 204  
     }
 205  
 
 206  
     public Widget getLabelWidget() {
 207  0
         return label;
 208  
     }
 209  
 
 210  
     public boolean isOpen() {
 211  0
         return isOpen;
 212  
     }
 213  
 
 214  
     public void open() {
 215  0
         isOpen = true;
 216  0
         if (withImages) {
 217  0
             setImageState();
 218  
         }
 219  0
         animation.setOpen(this, true);
 220  0
     }
 221  
 
 222  
     public void close() {
 223  0
         isOpen = false;
 224  0
         if (withImages) {
 225  0
             setImageState();
 226  
         }
 227  0
         animation.setOpen(this, true);
 228  0
     }
 229  
 
 230  
     /**
 231  
      * Update the image state to display opened/closed image based in isOpen() status
 232  
      */
 233  
     protected void setImageState() {
 234  0
         closedImage.setVisible(!isOpen);
 235  0
         openedImage.setVisible(isOpen);
 236  0
     }
 237  
 
 238  
     @Override
 239  
     public boolean isExportElement() {
 240  0
         return true;
 241  
     }
 242  
 
 243  
     @Override
 244  
     public List<ExportElement> getExportElementSubset(ExportElement parent) {
 245  0
         return ExportUtils.getDetailsForWidget(this.content.getWidget(), parent.getViewName(), parent.getSectionName());
 246  
     }
 247  
 
 248  
     @Override
 249  
     public String getExportFieldValue() {
 250  0
         String text = null;
 251  0
         for (int i = 0; i < this.linkPanel.getWidgetCount(); i++) {
 252  0
             Widget child = this.linkPanel.getWidget(i);
 253  0
             if (child instanceof SpanPanel) {
 254  0
                 SpanPanel header = (SpanPanel) child;
 255  0
                 text = header.getText();
 256  
             }
 257  
         }
 258  0
         return text;
 259  
     }
 260  
 
 261  
 }