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

Source Code of com.extjs.gxt.ui.client.widget.layout.BorderLayout

/*
* 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.layout;

import java.util.HashMap;
import java.util.Map;

import com.extjs.gxt.ui.client.Events;
import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.core.El;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SplitBarEvent;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.util.Rectangle;
import com.extjs.gxt.ui.client.util.WidgetHelper;
import com.extjs.gxt.ui.client.widget.Container;
import com.extjs.gxt.ui.client.widget.BoxComponent;
import com.extjs.gxt.ui.client.widget.CollapsePanel;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Layout;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.SplitBar;
import com.extjs.gxt.ui.client.widget.button.ToolButton;

/**
* This is a multi-pane, application-oriented UI layout style that supports
* multiple regions, automatic split bars between regions and built-in expanding
* and collapsing of regions.
*/
public class BorderLayout extends Layout {

  protected Map<LayoutRegion, SplitBar> splitBars;

  /**
   * True to enabled state (defaults to true). When true, expand / collapse and
   * size state is persisted across user sessions.
   */
  private boolean enableState = true;
  private Listener collapseListener;
  private int minimumSize = 100;
  private BoxComponent north, south;
  private BoxComponent west, east, center;
  private boolean rendered;
  private LayoutContainer layoutContainer;

  public BorderLayout() {
    monitorResize = true;
    splitBars = new HashMap<LayoutRegion, SplitBar>();
    collapseListener = new Listener<ComponentEvent>() {
      public void handleEvent(ComponentEvent ce) {
        ToolButton btn = (ToolButton) ce.component;
        ContentPanel panel = (ContentPanel) btn.getData("panel");
        onCollapse(panel);
      }
    };
  }

  /**
   * Returns true if state is enabled.
   *
   * @return the enabled state flag
   */
  public boolean getEnableState() {
    return enableState;
  }

  /**
   * True to enabled state (defaults to true). When true, expand / collapse and
   * size state is persisted across user sessions.
   *
   * @param enableState true to enable state
   */
  public void setEnableState(boolean enableState) {
    this.enableState = enableState;
  }

  protected SplitBar createSplitBar(LayoutRegion region, BoxComponent component) {
    return new SplitBar(region, component);
  }

  @Override
  protected void onLayout(Container container, El target) {
    super.onLayout(container, target);
    layoutContainer = (LayoutContainer) container;
    if (!rendered) {
      target.makePositionable();
      target.addStyleName("x-border-layout-ct");
      int count = container.getItemCount();
      for (int i = 0; i < count; i++) {
        Component c = container.getItem(i);
        if (!c.isRendered()) {
          c.addStyleName("x-border-panel");
          c.render(target.dom, i);
        }
        if (enableState) {
          BorderLayoutData data = (BorderLayoutData) getLayoutData(c);
          Map<String, Object> st = c.getState();
          if (st.containsKey("collapsed")) {
            switchPanels((ContentPanel) c);
          } else if (st.containsKey("size") && (!(c instanceof CollapsePanel))) {
            data.setSize((Float) st.get("size"));
          }
        }
      }
      rendered = true;
    }

    Rectangle rect = target.getBounds();
    int w = rect.width;
    int h = rect.height;
    int centerW = w, centerH = h, centerY = 0, centerX = 0;

    north = getRegionWidget(LayoutRegion.NORTH);
    south = getRegionWidget(LayoutRegion.SOUTH);
    west = getRegionWidget(LayoutRegion.WEST);
    east = getRegionWidget(LayoutRegion.EAST);
    center = getRegionWidget(LayoutRegion.CENTER);

    if (north != null) {
      BorderLayoutData data = (BorderLayoutData) getLayoutData(north);
      if (north.getData("init") == null) {
        initPanel(north);
      }
      if (data.isSplit()) {
        initSplitBar(LayoutRegion.SOUTH, north, data);
      } else {
        removeSplitBar(LayoutRegion.SOUTH);
      }
      Rectangle b = new Rectangle();
      Margins m = data.getMargins();
      float s = data.getSize() < 1 ? data.getSize() * rect.height : data.getSize();
      b.height = (int) s;
      b.width = w - (m.left + m.right);
      b.x = m.left;
      b.y = m.top;
      centerY = b.height + b.y + m.bottom;
      centerH -= centerY;
      applyLayout(north, b);

    }
    if (south != null) {
      BorderLayoutData data = (BorderLayoutData) getLayoutData(south);
      if (south.getData("init") == null) {
        initPanel(south);
      }
      if (data.isSplit()) {
        initSplitBar(LayoutRegion.NORTH, south, data);
      } else {
        removeSplitBar(LayoutRegion.NORTH);
      }
      Rectangle b = south.getBounds(false);
      Margins m = data.getMargins();
      float s = data.getSize() < 1 ? data.getSize() * rect.height : data.getSize();
      b.height = (int) s;
      b.width = w - (m.left + m.right);
      b.x = m.left;
      int totalHeight = (b.height + m.top + m.bottom);
      b.y = h - totalHeight + m.top;
      centerH -= totalHeight;
      applyLayout(south, b);
    }

    if (west != null) {
      if (west.getData("init") == null) {
        initPanel(west);
      }
      BorderLayoutData data = (BorderLayoutData) getLayoutData(west);
      if (data.isSplit()) {
        initSplitBar(LayoutRegion.EAST, west, data);
      } else {
        removeSplitBar(LayoutRegion.EAST);
      }

      Rectangle box = new Rectangle();
      Margins m = data.getMargins();
      float s = data.getSize() < 1 ? data.getSize() * rect.width : data.getSize();
      box.width = (int) s;
      box.height = centerH - (m.top + m.bottom);
      box.x = m.left;
      box.y = centerY + m.top;
      int totalWidth = (box.width + m.left + m.right);
      centerX += totalWidth;
      centerW -= totalWidth;
      applyLayout(west, box);
    }
    if (east != null) {
      if (east.getData("init") == null) {
        initPanel(east);
      }
      BorderLayoutData data = (BorderLayoutData) getLayoutData(east);
      if (data.isSplit()) {
        initSplitBar(LayoutRegion.WEST, east, data);
      } else {
        removeSplitBar(LayoutRegion.WEST);
      }
      Rectangle b = east.getBounds(false);
      Margins m = data.getMargins();
      float s = data.getSize() < 1 ? data.getSize() * rect.width : data.getSize();
      b.width = (int) s;
      b.height = centerH - (m.top + m.bottom);
      int totalWidth = (b.width + m.left + m.right);
      b.x = w - totalWidth + m.left;
      b.y = centerY + m.top;
      centerW -= totalWidth;
      applyLayout(east, b);
    }
    if (center != null) {
      BorderLayoutData data = (BorderLayoutData) getLayoutData(center);
      Margins m = data.getMargins();
      Rectangle box = new Rectangle();
      box.x = centerX + m.left;
      box.y = centerY + m.top;
      box.width = centerW - (m.left + m.right);
      box.height = centerH - (m.top + m.bottom);
      applyLayout(center, box);
    }
  }

  private void applyLayout(BoxComponent component, Rectangle box) {
    component.el().makePositionable(true);
    component.el().setLeftTop(box.x, box.y);
    component.setSize(box.width, box.height);
  }

  private CollapsePanel createCollapsePanel(ContentPanel panel, BorderLayoutData data) {
    CollapsePanel cp = new CollapsePanel(panel, data) {
      protected void onExpandButton(BaseEvent be) {
        if (isExpanded()) {
          setExpanded(false);
        }
        onExpandClick(this);
      }
    };
    BorderLayoutData collapseData = new BorderLayoutData(data.getRegion());
    collapseData.setSize(24);
    collapseData.setMargins(data.getMargins());
    WidgetHelper.setLayoutData(cp, collapseData);
    cp.setData("panel", panel);
    panel.setData("collapse", cp);
    return cp;
  }

  private BoxComponent getRegionWidget(LayoutRegion region) {
    for (int i = 0; i < container.getItemCount(); i++) {
      BoxComponent w = (BoxComponent) container.getItem(i);
      if (getLayoutData(w) != null && getLayoutData(w) instanceof BorderLayoutData) {
        BorderLayoutData data = (BorderLayoutData) getLayoutData(w);
        if (data.getRegion() == region) {
          w.el().makePositionable(true);
          return w;
        }
      }
    }
    return null;
  }

  private void initPanel(BoxComponent component) {
    BorderLayoutData data = (BorderLayoutData) getLayoutData(component);
    String icon = null;
    switch (data.getRegion()) {
      case WEST:
        icon = "left";
        break;
      case EAST:
        icon = "right";
        break;
      case NORTH:
        icon = "up";
        break;
      case SOUTH:
        icon = "down";
        break;
    }
    if (data.isCollapsible() && component instanceof ContentPanel) {
      ContentPanel panel = (ContentPanel) component;
      ToolButton collapse = (ToolButton) panel.getWidget("collapseBtn");
      if (collapse == null) {
        collapse = new ToolButton("x-tool-" + icon);
        panel.getHeader().addTool(collapse);
      }
      collapse.setData("panel", panel);
      collapse.removeListener(Events.Select, collapseListener);
      collapse.addListener(Events.Select, collapseListener);
      panel.setData("collapseBtn", collapse);
      panel.setData("init", "true");
    }

  }

  private void initSplitBar(final LayoutRegion region, BoxComponent component,
      final BorderLayoutData data) {
    SplitBar bar = (SplitBar) component.getData("splitBar");
    if (bar == null || bar.getResizeWidget() != component) {
      bar = createSplitBar(region, component);
      final SplitBar fBar = bar;
      Listener splitBarListener = new Listener<ComponentEvent>() {

        public void handleEvent(ComponentEvent ce) {
          switch (ce.type) {
            case Events.DragStart:
              switch (region) {
                case WEST: {
                  int min = Math.max(minimumSize, data.getMinSize());
                  int max = east.getOffsetWidth() + center.getOffsetWidth() - minimumSize;
                  if (data.getMaxSize() > 0) {
                    max = Math.min(max, data.getMaxSize());
                  }
                  fBar.setMinSize(min);
                  fBar.setMaxSize(max);
                  break;
                }
                case EAST: {
                  int min = Math.max(minimumSize, data.getMinSize());
                  int max = west.getOffsetWidth() + center.getOffsetWidth() - minimumSize;
                  max = Math.min(data.getMaxSize(), max);
                  fBar.setMinSize(min);
                  fBar.setMaxSize(max);
                  break;
                }
                case NORTH:
                  int max = south.getOffsetHeight() + center.getOffsetHeight()
                      - minimumSize;
                  max = Math.min(max, data.getMaxSize());
                  fBar.setMaxSize(max);
                  break;
                case SOUTH:
                  // TODO
                  break;
              }
              break;
          }
        }
      };
      component.setData("splitBar", bar);

      bar.addListener(Events.DragStart, splitBarListener);
      bar.setMinSize(data.getMinSize());
      bar.setMaxSize(data.getMaxSize() == 0 ? bar.getMaxSize() : data.getMaxSize());
      bar.setAutoSize(false);
      bar.addListener(Events.Resize, new Listener<SplitBarEvent>() {
        public void handleEvent(SplitBarEvent sbe) {
          if (sbe.size < 1) {
            return;
          }
          data.setSize(sbe.size);
          Component c = sbe.splitBar.getResizeWidget();
          Map<String, Object> state = c.getState();
          state.put("size", data.getSize());
          c.saveState();
          layoutContainer();
        }
      });
      component.setData("splitBar", bar);
    }
  }

  private void onCollapse(ContentPanel panel) {
    BorderLayoutData data = (BorderLayoutData) getLayoutData(panel);
    layoutContainer.remove(panel);
    Map<String, Object> st = panel.getState();
    st.put("collapsed", true);
    panel.saveState();

    CollapsePanel cp = (CollapsePanel) panel.getData("collapse");
    if (cp == null) {
      cp = createCollapsePanel(panel, data);
    }
    layoutContainer.add(cp);
    layoutContainer.layout();
  }

  private void onExpandClick(CollapsePanel cp) {
    ContentPanel panel = cp.getContentPanel();
    Map<String, Object> st = panel.getState();
    st.remove("collapsed");
    panel.saveState();
    layoutContainer.remove(cp);
    layoutContainer.add(panel);
    layoutContainer.layout();
  }

  private void removeSplitBar(LayoutRegion region) {
    splitBars.put(region, null);
  }

  private void switchPanels(ContentPanel panel) {
    BorderLayoutData data = (BorderLayoutData) getLayoutData(panel);
    layoutContainer.remove(panel);
    CollapsePanel cp = (CollapsePanel) panel.getData("collapse");
    if (cp == null) {
      cp = createCollapsePanel(panel, data);
    }
    layoutContainer.add(cp);
    renderComponent(cp, 0, layoutContainer.getLayoutTarget());
  }

}
TOP

Related Classes of com.extjs.gxt.ui.client.widget.layout.BorderLayout

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.