Package com.extjs.gxt.ui.client.widget

Source Code of com.extjs.gxt.ui.client.widget.ContentPanel

/*
* Ext GWT - Ext for GWT
* Copyright(c) 2007, 2008, Ext JS, LLC.
* licensing@extjs.com
*
* http://extjs.com/license
*/
package com.extjs.gxt.ui.client.widget;

import com.extjs.gxt.ui.client.Events;
import com.extjs.gxt.ui.client.Style.Direction;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.core.DomHelper;
import com.extjs.gxt.ui.client.core.El;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.FxEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.fx.FxConfig;
import com.extjs.gxt.ui.client.util.Format;
import com.extjs.gxt.ui.client.util.Markup;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ButtonBar;
import com.extjs.gxt.ui.client.widget.button.ToolButton;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Frame;

/**
* ContentPanel is a component container that has specific functionality and
* structural components that make it the perfect building block for
* application-oriented user interfaces. The Panel contains bottom and top
* toolbars, along with separate header, footer and body sections. It also
* provides built-in expandable and collapsible behavior, along with a variety
* of pre-built tool buttons that can be wired up to provide other customized
* behavior.</p>
*
* Code snippet:
*
* <pre>
ContentPanel cp = new ContentPanel();
cp.setHeading("Folder Contents");
cp.setSize(250,140);
cp.setPosition(10, 10);
cp.setCollapsible(true);
cp.setFrame(true);
cp.setBodyStyle("backgroundColor: white;");
cp.getHeader().addTool(new ToolButton("x-tool-gear"));
cp.getHeader().addTool(new ToolButton("x-tool-close"));
cp.addText(getBogusText());
cp.addButton(new Button("Ok"));
cp.setIconStyle("tree-folder-open");
RootPanel.get().add(cp);
cp.layout();
* </pre>
*
* <dl>
* <dt><b>Events:</b></dt>
*
* <dd><b>BeforeExpand</b> : ComponentEvent(component)<br>
* <div>Fires before the panel is expanded. Listeners can set the
* <code>doit</code> field to <code>false</code> to cancel the expand.</div>
* <ul>
* <li>component : this</li>
* </ul>
* </dd>
*
* <dd><b>Expand</b> : ComponentEvent(component)<br>
* <div>Fires after the panel is expanded</div>
* <ul>
* <li>component : this</li>
* </ul>
* </dd>
*
* <dd><b>BeforeCollapse</b> : ComponentEvent(component)<br>
* <div>Fires before the panel is collpased. Listeners can set the
* <code>doit</code> field <code>false</code> to cancel the collapse.</div>
* <ul>
* <li>component : this</li>
* </ul>
* </dd>
*
* <dd><b>Collapse</b> : ComponentEvent(component)<br>
* <div>Fires after the panel is collapsed.</div>
* <ul>
* <li>component : this</li>
* </ul>
* </dd>
*
* <dd><b>BeforeClose</b> : ComponentEvent(component)<br>
* <div>Fires before a content panel is closed. Listeners can set the
* <code>doit</code> field to <code>false</code> to cancel the operation.</div>
* <ul>
* <li>component : this</li>
* </ul>
* </dd>
*
* <dd><b>Close</b> : ComponentEvent(component)<br>
* <div>Fires after a content panel is closed.</div>
* <ul>
* <li>component : this</li>
* </ul>
* </dd>
* </dl>
*/
public class ContentPanel extends LayoutContainer {

  protected boolean frame;
  protected Header head;
  protected ButtonBar buttonBar;
  protected El body, bwrap;

  private String bodyStyle, bodyStyleName;
  private boolean headerVisible = true;
  private boolean collapsed, hideCollapseTool;
  private boolean footer, titleCollapse;
  private HorizontalAlignment buttonAlign = HorizontalAlignment.RIGHT;
  private boolean animCollapse = true;
  private boolean collapsible;
  private boolean bodyBorder = true;
  private Component topComponent;
  private Component bottomComponent;
  private boolean animating;
  private ToolButton collapseBtn;
  private String headerStyle, footerStyle;
  private String headerTextStyle;
  private String bwrapStyle;
  private String tbarStyle, bbarStyle;
  private String bodStyle;
  private String collapseStyle;
  private El foot, tbar, bbar;

  /**
   * Creates a new panel instance.
   */
  public ContentPanel() {
    super();
    baseStyle = "x-panel";
    buttonBar = new ButtonBar();
    head = new Header();
  }

  /**
   * Creates a new content panel.
   *
   * @param layout the panel's layout
   */
  public ContentPanel(Layout layout) {
    this();
    setLayout(layout);
  }

  /**
   * Adds a button the the panel.
   *
   * @param button the button to add
   */
  public void addButton(Button button) {
    buttonBar.add(button);
  }

  /**
   * Collapses the panel body so that it becomes hidden. Fires the
   * <i>BeforeCollapse</i> before collapsing, then the <i>Collapse</i> event
   * after collapsing.
   */
  public void collapse() {
    if (rendered) {
      if (!collapsed && !animating) {
        if (fireEvent(Events.BeforeCollapse)) {
          onCollapse();
        }
      }
    } else {
      collapsed = true;
    }
  }

  /**
   * Expands the panel body so that it becomes visible. Fires the
   * <i>BeforeExpand</i> before expanding, then the <i>Expand</i> event after
   * expanding.
   */
  public void expand() {
    if (rendered && collapsed) {
      if (fireEvent(Events.BeforeExpand)) {
        removeStyleName(collapseStyle);
        onExpand();
      }
    }
  }

  /**
   * Returns true if animation is enabled for expand / collapse.
   *
   * @return the animCollapse true for animations
   */
  public boolean getAnimCollapse() {
    return animCollapse;
  }

  /**
   * Returns the panel's body element.
   *
   * @return the body
   */
  public El getBody() {
    return body;
  }

  /**
   * Returns true if the body border is enabled.
   *
   * @return the body border state
   */
  public boolean getBodyBorder() {
    return bodyBorder;
  }

  /**
   * Returns the body style.
   *
   * @return the body style
   */
  public String getBodyStyle() {
    return bodyStyle;
  }

  /**
   * Returns the panel's bottom component.
   *
   * @return the bottom component
   */
  public Component getBottomComponent() {
    return bottomComponent;
  }

  /**
   * Returns the panel's button alignment.
   *
   * @return the button alignment
   */
  public HorizontalAlignment getButtonAlign() {
    return buttonAlign;
  }

  /**
   * Returns the panel's button bar.
   *
   * @return the button bar
   */
  public ButtonBar getButtonBar() {
    return buttonBar;
  }

  /**
   * Returns the panel's collapse button.
   *
   * @return the collapse button
   */
  public ToolButton getCollapseBtn() {
    return collapseBtn;
  }

  /**
   * Returns true if the panel is collapsible.
   *
   * @return the collapsible state
   */
  public boolean getCollapsible() {
    return collapsible;
  }

  /**
   * Provides access to internal elements.
   * <p>
   * Valid values are:
   * <ul>
   * <li>"body"</li>
   * <li>"header"</li>
   * <li>"bwrap"</li>
   * </ul>
   * </p>
   *
   * @param name the element name
   * @return the element
   */
  public Element getElement(String name) {
    if (name.equals("header")) {
      return head.getElement();
    } else if (name.equals("bwrap")) {
      return bwrap.dom;
    } else if (name.equals("body")) {
      return body.dom;
    }
    return null;
  }

  /**
   * @return the footer
   */
  public boolean getFooter() {
    return footer;
  }

  /**
   * Returns true if framing is enabled.
   *
   * @return the frame state
   */
  public boolean getFrame() {
    return frame;
  }

  /**
   * Returns the height in pixels of the framing elements of this panel
   * (including any top and bottom bars and header and footer elements, but not
   * including the body height). To retrieve the body height see
   * {@link #getInnerHeight}.
   *
   * @return the frame height
   */
  public int getFrameHeight() {
    int h = el().getFrameWidth("tb");
    h += (tbar != null ? tbar.getHeight() : 0) + (bbar != null ? bbar.getHeight() : 0);
    if (frame) {
      Element hd = el().firstChild().dom;
      Element ft = bwrap.dom.getLastChild().cast();
      h += (fly(hd).getHeight() + fly(ft).getHeight());
      Element mc = bwrap.subChild(3).dom;
      h += fly(mc).getFrameWidth("tb") + 1;
    } else {
      if (head != null) {
        h += head.getOffsetHeight();
      }
      if (foot != null) {
        h += foot.getHeight();
      }
    }
    return h;
  }

  /**
   * Returns the width in pixels of the framing elements of this panel (not
   * including the body width). To retrieve the body width see
   * {@link #getInnerWidth}.
   *
   * @return The frame width
   */
  public int getFrameWidth() {
    int w = el().getFrameWidth("lr");
    if (frame) {
      Element l = bwrap.firstChild().dom;
      w += (fly(l).getFrameWidth("l") + fly(l).firstChild().getFrameWidth("r"));
      Element mc = bwrap.subChild(3).dom;
      w += fly(mc).getFrameWidth("lr");
    }
    return w;
  }

  /**
   * Returns the panel's header.
   *
   * @return the header
   */
  public Header getHeader() {
    return head;
  }

  /**
   * Returns the panel's heading.
   *
   * @return the heading
   */
  public String getHeading() {
    return head.getText();
  }

  /**
   * Returns the panel's icon style.
   *
   * @return the icon style
   */
  public String getIconStyle() {
    return head.getIconStyle();
  }

  /**
   * Returns the height in pixels of the body element (not including the height
   * of any framing elements). For the frame height see {@link #getFrameHeight}.
   *
   * @return the inner height
   */
  public int getInnerHeight() {
    return getSize().height - getFrameHeight();
  }

  /**
   * Returns the width in pixels of the body element (not including the width of
   * any framing elements). For the frame width see {@link #getFrameWidth}.
   *
   * @return the body width
   */
  public int getInnerWidth() {
    return this.getSize().width - this.getFrameWidth();
  }

  @Override
  public El getLayoutTarget() {
    return body;
  }

  /**
   * @return the titleCollapse
   */
  public boolean getTitleCollapse() {
    return titleCollapse;
  }

  /**
   * Returns the panel's title text.
   *
   * @return the title text
   * @deprecated use {@link #getHeading()}
   */
  public String getTitleText() {
    return head.getText();
  }

  /**
   * Returns the panels top component.
   *
   * @return the top component
   */
  public Component getTopComponent() {
    return topComponent;
  }

  /**
   * Returns <code>true</code> if the panel is expanded.
   *
   * @return the expand state
   */
  public boolean isExpanded() {
    return !isCollapsed();
  }

  /**
   * Returns true if the header is visible.
   *
   * @return the header visible state
   */
  public boolean isHeaderVisible() {
    return headerVisible;
  }

  /**
   * Returns true if the collapse tool is hidden.
   *
   * @return the hide collapse tool state
   */
  public boolean isHideCollapseTool() {
    return hideCollapseTool;
  }

  @Override
  public void onComponentEvent(ComponentEvent ce) {
    super.onComponentEvent(ce);
    if (ce.type == Event.ONCLICK) {
      onClick(ce);
    }
  }

  /**
   * Sets whether exand and collapse is animating (defaults to true,
   * pre-render).
   *
   * @param animCollapse true to enable animations
   */
  public void setAnimCollapse(boolean animCollapse) {
    assertPreRender();
    this.animCollapse = animCollapse;
  }

  /**
   * True to display the borders of the panel's body element, false to hide them
   * (defaults to true, pre-render). Only applies to non-framed panels.
   *
   * @param bodyBorder true for a body border
   */
  public void setBodyBorder(boolean bodyBorder) {
    assertPreRender();
    this.bodyBorder = bodyBorder;
  }

  /**
   * Custom CSS styles to be applied to the body element in the format expected
   * by {@link El#applyStyles} (pre-render).
   *
   * @param bodyStyle the body style
   */
  public void setBodyStyle(String bodyStyle) {
    assertPreRender();
    this.bodyStyle = bodyStyle;
  }

  /**
   * A style name that is added to the panel's body element (pre-render).
   *
   * @param style the style name
   */
  public void setBodyStyleName(String style) {
    assertPreRender();
    this.bodyStyleName = style;
  }

  /**
   * Sets the panel's bottom component (pre-render). The component's natural
   * height will be used and will not be changed by the panel.
   *
   * @param bottomComponent the bottom component
   */
  public void setBottomComponent(Component bottomComponent) {
    assertPreRender();
    this.bottomComponent = bottomComponent;
  }

  /**
   * Sets the button alignment of any buttons added to this panel (defaults to
   * RIGHT, pre-render).
   *
   * @param buttonAlign the button alignment
   */
  public void setButtonAlign(HorizontalAlignment buttonAlign) {
    assertPreRender();
    this.buttonAlign = buttonAlign;
  }

  public void setButtonBar(ButtonBar buttonBar) {
    assertPreRender();
    this.buttonBar = buttonBar;
  }

  /**
   * True to make the panel collapsible and have the expand/collapse toggle
   * button automatically rendered into the header tool button area, false to
   * keep the panel statically sized with no button (defaults to false,
   * pre-render).
   *
   * @param collapsible the collapsible to set
   */
  public void setCollapsible(boolean collapsible) {
    assertPreRender();
    this.collapsible = collapsible;
  }

  /**
   * Sets the panel's expand state.
   *
   * @param expanded <code>true<code> true to expand
   */
  public void setExpanded(boolean expanded) {
    if (expanded) {
      expand();
    } else {
      collapse();
    }
  }

  /**
   * True to create the footer element explicitly, false to skip creating it
   * (pre-render). By default, when footer is not specified, if one or more
   * buttons have been added to the panel the footer will be created
   * automatically, otherwise it will not.
   *
   * @param footer the footer state
   */
  public void setFooter(boolean footer) {
    assertPreRender();
    this.footer = footer;
  }

  /**
   * True to render the panel with custom rounded borders, false to render with
   * plain 1px square borders (defaults to false, pre-render).
   *
   * @param frame true to use the frame style
   */
  public void setFrame(boolean frame) {
    assertPreRender();
    this.frame = frame;
  }

  /**
   * True to create the header element explicitly, false to skip creating it
   * (defaults to true, pre-render). By default, when header is not specified,
   * if a {@link #setHeading(String)} is set the header will be created
   * automatically, otherwise it will not. If a title is set but header is
   * explicitly set to false, the header will not be rendered.
   *
   * @param headerVisible true to show the header
   */
  public void setHeaderVisible(boolean headerVisible) {
    assertPreRender();
    this.headerVisible = headerVisible;
  }

  /**
   * Sets the title text for the panel.
   *
   * @param text the title text
   */
  public void setHeading(String text) {
    head.setText(text);
  }

  /**
   * Sets whether the collapse tool should be displayed when the panel is
   * collapsible.
   *
   * @param hideCollapseTool true if the tool is hidden
   */
  public void setHideCollapseTool(boolean hideCollapseTool) {
    this.hideCollapseTool = hideCollapseTool;
    if (rendered) {
      collapseBtn.setVisible(!hideCollapseTool);
    }
  }

  /**
   * Sets the item's icon style. The style name should match a CSS style that
   * specifies a background image using the following format:
   *
   * <pre><code> .my-icon { background: url(images/icons/my-icon.png) no-repeat
   * center left !important; } </code></pre>
   *
   * @param iconStyle the icon style
   */
  public void setIconStyle(String iconStyle) {
    head.setIconStyle(iconStyle);
  }

  /**
   * True to display an interior border on the body element of the panel, false
   * to hide it (defaults to true, pre-render). This only applies when
   * {@link #setBodyBorder(boolean)} == true.
   *
   * @param insetBorder true to display the interior border
   * @deprecated behavior not implemented
   */
  public void setInsetBorder(boolean insetBorder) {
    assertPreRender();
  }

  /**
   * True to allow expanding and collapsing the panel (when {@link #collapsible}
   * = true) by clicking anywhere in the header bar, false to allow it only by
   * clicking to tool button (defaults to false, pre-render).
   *
   * @param titleCollapse the titleCollapse to set
   */
  public void setTitleCollapse(boolean titleCollapse) {
    assertPreRender();
    this.titleCollapse = titleCollapse;
  }

  /**
   * Sets the panel's top component (pre-render).
   *
   * @param topComponent the component
   */
  public void setTopComponent(Component topComponent) {
    assertPreRender();
    this.topComponent = topComponent;
  }

  /**
   * Adds the content from the given url.
   *
   * @param url the url
   * @return the new frame instance
   */
  public Frame setUrl(String url) {
    Frame f = new Frame(url);
    fly(f.getElement()).setStyleAttribute("frameBorder", "0");
    f.setSize("100%", "100%");
    removeAll();
    add(new WidgetComponent(f));
    return f;
  }

  protected void afterCollapse() {
    addStyleName(collapseStyle);
    collapsed = true;
    animating = false;
    el().setHeight("auto");
    ComponentEvent ce = new ComponentEvent(this);
    fireEvent(Events.Collapse, ce);
  }

  protected void afterExpand() {
    collapsed = false;
    animating = false;
    ComponentEvent ce = new ComponentEvent(this);
    fireEvent(Events.Expand, ce);
  }

  @Override
  protected void afterRender() {
    super.afterRender();
  }

  protected void createStyles(String baseStyle) {
    headerStyle = baseStyle + "-header";
    headerTextStyle = baseStyle + "-header-text";
    bwrapStyle = baseStyle + "-bwrap";
    tbarStyle = baseStyle + "-tbar";
    bodStyle = baseStyle + "-body";
    bbarStyle = baseStyle + "-bbar";
    footerStyle = baseStyle + "-footer";
    collapseStyle = baseStyle + "-collapsed";
  }

  @Override
  protected void doAttachChildren() {
    super.doAttachChildren();
    if (head != null) head.onAttach();
    if (getFooter() && buttonBar != null) {
      if (buttonBar.getItemCount() > 0) {
        buttonBar.onAttach();
      }
    }
    if (topComponent != null) topComponent.onAttach();
    if (bottomComponent != null) bottomComponent.onAttach();
  }

  @Override
  protected void doDetachChildren() {
    super.doDetachChildren();
    ComponentHelper.doDetach(head);
    ComponentHelper.doDetach(buttonBar);
    ComponentHelper.doDetach(topComponent);
    ComponentHelper.doDetach(bottomComponent);
  }

  protected void initTools() {
    if (collapsible && !hideCollapseTool) {
      collapseBtn = new ToolButton("x-tool-toggle");
      collapseBtn.addListener(Events.Select, new Listener<ComponentEvent>() {
        public void handleEvent(ComponentEvent ce) {
          ce.stopEvent();
          setExpanded(!isExpanded());
        }
      });
      head.addTool(collapseBtn);
    }
  }

  protected void onClick(ComponentEvent ce) {
    if (head != null && ce.within(head.getElement()) && collapsible) {
      setExpanded(!isExpanded());
    }
  }

  protected void onCollapse() {
    if (animCollapse && !animating) {
      animating = true;
      bwrap.slideOut(Direction.UP, new FxConfig(300, new Listener<FxEvent>() {
        public void handleEvent(FxEvent fe) {
          afterCollapse();
        }
      }));
    } else {
      bwrap.setVisible(false);
      afterCollapse();
    }
  }

  protected void onExpand() {
    if (animCollapse && !animating) {
      animating = true;
      bwrap.slideIn(Direction.DOWN, new FxConfig(300, new Listener<FxEvent>() {
        public void handleEvent(FxEvent fe) {
          afterExpand();
        }
      }));
    } else {
      bwrap.setVisible(true);
      afterExpand();
    }
  }

  @Override
  protected void onRender(Element parent, int pos) {
    super.onRender(parent, pos);

    if (buttonBar.getItemCount() > 0) {
      buttonBar.setButtonAlign(buttonAlign);
      setFooter(true);
    }

    if (frame) {
      String s = Format.substitute(Markup.BBOX, baseStyle);
      DomHelper.insertHtml("afterBegin", el().dom, s);

      head.baseStyle = headerStyle;
      head.setTextStyle(headerTextStyle);
      initTools();
      head.render(el().dom);
      el().subChild(3).dom.appendChild(head.getElement());
      bwrap = el().createChild("<div class='" + bwrapStyle + "'></div>");

      Element bw = bwrap.dom;
      Element ml = DOM.getChild(el().dom, 1);
      Element bl = DOM.getChild(el().dom, 2);
      DOM.appendChild(bw, ml);
      DOM.appendChild(bw, bl);

      Element mc = fly(bw).getSubChild(3);

      if (topComponent != null) {
        tbar = fly(mc).createChild("<div class=" + tbarStyle + "></div>");
      }
      body = fly(mc).createChild("<div class=" + bodStyle + "></div>");
      if (bottomComponent != null) {
        bbar = fly(mc).createChild("<div class=" + bbarStyle + "></div>");
      }

      El e = fly(bw).lastChild().firstChild().firstChild();
      foot = e.createChild("<div class=" + footerStyle + "></div>");

      if (!headerVisible) {
        head.setVisible(false);
        body.addStyleName(bodStyle + "-noheader");
        if (tbar != null) {
          tbar.addStyleName(tbarStyle + "-noheader");
        }
      }

    } else {
      head.baseStyle = headerStyle;
      head.setTextStyle(headerTextStyle);
      initTools();
      head.render(el().dom);
      bwrap = el().createChild("<div class=" + bwrapStyle + "></div>");

      Element bw = bwrap.dom;
      if (topComponent != null) {
        tbar = fly(bw).createChild("<div class=" + tbarStyle + "></div>");
      }
      body = fly(bw).createChild("<div class=" + bodStyle + "></div>");
      if (bottomComponent != null) {
        bbar = fly(bw).createChild("<div class=" + bbarStyle + "></div>");
      }
      foot = fly(bw).createChild("<div class=" + footerStyle + "></div>");

      if (!headerVisible) {
        head.setVisible(false);
        body.addStyleName(bodStyle + "-noheader");
        if (tbar != null) {
          tbar.addStyleName(tbarStyle + "-noheader");
        }
      }
    }

    if (footer && buttonBar.getItemCount() > 0) {
      buttonBar.render(foot.dom);
    }

    if (!footer) {
      bwrap.lastChild().addStyleName("x-panel-nofooter");
    }

    if (!bodyBorder) {
      el().addStyleName(baseStyle + "-noborder");
      body.addStyleName(bodStyle + "-noborder");
      if (tbar != null) {
        tbar.addStyleName(tbarStyle + "-noborder");
      }
      if (bbar != null) {
        bbar.addStyleName(bbarStyle + "-noborder");
      }
    }

    if (bodyStyle != null) {
      body.applyStyles(bodyStyle);
    }

    if (bodyStyleName != null) {
      body.addStyleName(bodyStyleName);
    }

    if (headerVisible) {
      head.disableTextSelection(true);
    }

    if (topComponent != null) {
      topComponent.render(tbar.dom);
      topComponent.setStyleAttribute("position", "static");
    }

    if (bottomComponent != null) {
      bottomComponent.render(bbar.dom);
      bottomComponent.setStyleAttribute("position", "static");
    }

    if (titleCollapse) {
      head.setStyleAttribute("cursor", "pointer");
      el().addEventsSunk(Event.ONCLICK);
    }

    if (collapsed) {
      boolean anim = animCollapse;
      collapsed = false;
      setAnimCollapse(false);
      collapse();
      setAnimCollapse(anim);
    }
  }

  @Override
  protected void onResize(final int width, final int height) {
    super.onResize(width, height);
    if (isAutoWidth()) {
      getLayoutTarget().setWidth("auto");
    } else if (width != -1) {
      getLayoutTarget().setWidth(width - getFrameWidth(), true);
    }
    if (!collapsed) {
      if (isAutoHeight()) {
        getLayoutTarget().setHeight("auto");
      } else if (height != -1) {
        getLayoutTarget().setHeight(height - getFrameHeight(), true);
      }
    }
  }

  /**
   * Returns true if the panel is collapsed.
   *
   * @return the collapsed state
   */
  private boolean isCollapsed() {
    return collapsed;
  }

}
TOP

Related Classes of com.extjs.gxt.ui.client.widget.ContentPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.