Coverage Report - org.kuali.student.common.ui.client.widgets.search.CollapsablePanel
 
Classes in this File Line Coverage Branch Coverage Complexity
CollapsablePanel
0%
0/66
0%
0/14
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
 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.search;
 17  
 
 18  
 import org.kuali.student.common.ui.client.theme.Theme;
 19  
 import org.kuali.student.common.ui.client.widgets.KSButton;
 20  
 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract.ButtonStyle;
 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 {
 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  0
         }
 139  
         
 140  0
         public CollapsablePanel(String label, Widget content, boolean isOpen) {
 141  0
                 init(getButtonLabel(label), content, isOpen, true, ImagePosition.ALIGN_RIGHT);
 142  0
         }
 143  
 
 144  0
         public CollapsablePanel(String label, Widget content, boolean isOpen, boolean withImages) {
 145  0
                 init(getButtonLabel(label), content, isOpen, withImages, ImagePosition.ALIGN_RIGHT);
 146  0
         }
 147  
 
 148  0
         public CollapsablePanel(String label, Widget content, boolean isOpen, boolean withImages, ImagePosition imagePosition) {
 149  0
                 init(getButtonLabel(label), content, isOpen, withImages, imagePosition);
 150  0
         }
 151  
 
 152  0
         public CollapsablePanel(Widget label, Widget content, boolean isOpen, boolean withImages, ImagePosition imagePosition) {
 153  0
                 init(label, content, isOpen, withImages, imagePosition);
 154  0
         }
 155  
 
 156  
         protected void init(Widget label, Widget content, boolean isOpen, boolean withImages, ImagePosition imagePosition) {
 157  0
                 this.isOpen = isOpen;
 158  0
                 this.withImages = withImages;
 159  0
                 this.imagePosition = imagePosition;                
 160  0
                 this.content.setWidget(content);
 161  
 
 162  0
                 if (this.imagePosition == ImagePosition.ALIGN_RIGHT){
 163  0
                         linkPanel.add(label);
 164  
                 }
 165  
                 
 166  0
                 if (this.withImages){
 167  0
                         linkPanel.add(closedImage);
 168  0
                         linkPanel.add(openedImage);
 169  0
                         setImageState();
 170  
                 }
 171  
 
 172  0
                 if (this.imagePosition == ImagePosition.ALIGN_LEFT){
 173  0
                         linkPanel.add(label);
 174  
                 }
 175  
 
 176  0
                 if (!isOpen) {
 177  0
                         this.content.setVisible(false);
 178  
                 }
 179  
 
 180  0
                 closedImage.addClickHandler(openCloseClickHandler);
 181  0
                 openedImage.addClickHandler(openCloseClickHandler);
 182  
 
 183  0
                 layout.add(linkPanel);
 184  0
                 layout.add(this.content);
 185  0
                 closedImage.addStyleName("ks-image-middle-alignment");
 186  0
                 openedImage.addStyleName("ks-image-middle-alignment");
 187  0
                 content.addStyleName("top-padding");
 188  0
                 this.initWidget(layout);
 189  0
         }
 190  
 
 191  
         protected KSButton getButtonLabel(String labelString){
 192  0
                 label = new KSButton(labelString, ButtonStyle.DEFAULT_ANCHOR);                                
 193  0
                 label.addClickHandler(openCloseClickHandler);                
 194  0
                 return label;
 195  
         }
 196  
         
 197  
         /**
 198  
          * If the widget was initialized with a string label, it will return a KSButton.
 199  
          * If the widget was initialized with a label widget, it will return the label widget.
 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  
 }