Package com.sencha.gxt.widget.core.client.grid

Source Code of com.sencha.gxt.widget.core.client.grid.RowExpander$RowExpanderAppearance

/**
* Sencha GXT 3.0.0 - Sencha for GWT
* Copyright(c) 2007-2012, Sencha, Inc.
* licensing@sencha.com
*
* http://www.sencha.com/products/gxt/license/
*/
package com.sencha.gxt.widget.core.client.grid;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.Cell.Context;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.Event;
import com.sencha.gxt.core.client.GXT;
import com.sencha.gxt.core.client.IdentityValueProvider;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.core.client.dom.XElement;
import com.sencha.gxt.widget.core.client.ComponentPlugin;
import com.sencha.gxt.widget.core.client.event.BeforeCollapseItemEvent;
import com.sencha.gxt.widget.core.client.event.BeforeCollapseItemEvent.BeforeCollapseItemHandler;
import com.sencha.gxt.widget.core.client.event.BeforeCollapseItemEvent.HasBeforeCollapseItemHandlers;
import com.sencha.gxt.widget.core.client.event.BeforeExpandItemEvent;
import com.sencha.gxt.widget.core.client.event.BeforeExpandItemEvent.BeforeExpandItemHandler;
import com.sencha.gxt.widget.core.client.event.BeforeExpandItemEvent.HasBeforeExpandItemHandlers;
import com.sencha.gxt.widget.core.client.event.CollapseItemEvent;
import com.sencha.gxt.widget.core.client.event.CollapseItemEvent.CollapseItemHandler;
import com.sencha.gxt.widget.core.client.event.CollapseItemEvent.HasCollapseItemHandlers;
import com.sencha.gxt.widget.core.client.event.ExpandItemEvent;
import com.sencha.gxt.widget.core.client.event.ExpandItemEvent.ExpandItemHandler;
import com.sencha.gxt.widget.core.client.event.ExpandItemEvent.HasExpandItemHandlers;
import com.sencha.gxt.widget.core.client.event.RowClickEvent;
import com.sencha.gxt.widget.core.client.event.RowClickEvent.RowClickHandler;

/**
* A <code>ColumnConfig</li> subclass and a <code>ComponentPlugin</code> that
* adds the ability for each row to be expanded, showing custom content that
* spans all the rows columns.
*
* <p />
* As with all component plugins, {@link #initPlugin(Grid)} must be called to
* initialize the row expander.
*
* @param <M> the model type
*/
public class RowExpander<M> extends ColumnConfig<M, M> implements ComponentPlugin<Grid<M>>,
    HasBeforeExpandItemHandlers<M>, HasExpandItemHandlers<M>, HasBeforeCollapseItemHandlers<M>,
    HasCollapseItemHandlers<M> {

  public interface RowExpanderAppearance<M> {
    String getRowStyles(M model, int rowIndex);

    boolean isExpanded(XElement row);

    boolean isExpandElement(XElement target);

    void onExpand(XElement row, boolean expand);

    void renderExpander(Context context, M value, SafeHtmlBuilder sb);
  }

  protected Grid<M> grid;
  protected Cell<M> contentCell;

  private SimpleEventBus eventBus;
  private final RowExpanderAppearance<M> appearance;

  /**
   * Creates a new row expander.
   *
   * @param valueProvider the value provider
   * @param contentCell the content cell
   */
  public RowExpander(IdentityValueProvider<M> valueProvider, Cell<M> contentCell) {
    this(valueProvider, contentCell, GWT.<RowExpanderAppearance<M>> create(RowExpanderAppearance.class));
  }

  /**
   * Creates a new row expander.
   *
   * @param valueProvider the value provider
   * @param contentCell the content cell
   * @param appearance the appearance
   */
  public RowExpander(IdentityValueProvider<M> valueProvider, Cell<M> contentCell,
      final RowExpanderAppearance<M> appearance) {
    super(valueProvider);

    this.contentCell = contentCell;
    this.appearance = GWT.create(RowExpanderAppearance.class);

    setHeader("");
    setColumnClassSuffix("expander");
    setWidth(20);
    setSortable(false);
    setResizable(false);
    setFixed(true);
    setMenuDisabled(true);

    setCell(new AbstractCell<M>() {
      @Override
      public void render(Context context, M value, SafeHtmlBuilder sb) {
        assert grid != null : "RowExpander grid null, must call initPlugin";
        appearance.renderExpander(context, value, sb);
      }
    });
  }

  @Override
  public HandlerRegistration addBeforeCollapseHandler(BeforeCollapseItemHandler<M> handler) {
    return ensureHandlers().addHandler(BeforeCollapseItemEvent.getType(), handler);
  }

  @Override
  public HandlerRegistration addBeforeExpandHandler(BeforeExpandItemHandler<M> handler) {
    return ensureHandlers().addHandler(BeforeExpandItemEvent.getType(), handler);
  }

  @Override
  public HandlerRegistration addCollapseHandler(CollapseItemHandler<M> handler) {
    return ensureHandlers().addHandler(CollapseItemEvent.getType(), handler);
  }

  @Override
  public HandlerRegistration addExpandHandler(ExpandItemHandler<M> handler) {
    return ensureHandlers().addHandler(ExpandItemEvent.getType(), handler);
  }

  /**
   * Collapses the given row.
   *
   * @param rowIndex the rowIndex
   */
  public void collapseRow(int rowIndex) {
    XElement row = XElement.as(grid.getView().getRow(rowIndex));
    if (row != null && isExpanded(row)) {
      collapseRow(row);
    }
  }

  /**
   * Expands the given row.
   *
   * @param rowIndex the rowIndex
   */
  public void expandRow(int rowIndex) {
    XElement row = XElement.as(grid.getView().getRow(rowIndex));
    if (row != null && !isExpanded(row)) {
      expandRow(row);
    }
  }

  /**
   * Returns the content cell.
   *
   * @return the content cell
   */
  public Cell<M> getContentCell() {
    return contentCell;
  }

  @Override
  public void initPlugin(Grid<M> component) {
    grid = component;
    grid.getView().setEnableRowBody(true);
    grid.getView().setRowBodyRowSpan(2);

    grid.addStyleName("x-expander");

    GridView<M> view = grid.getView();

    final GridViewConfig<M> config = view.getViewConfig();
    view.viewConfig = new GridViewConfig<M>() {

      @Override
      public String getColStyle(M model, ValueProvider<? super M, ?> valueProvider, int rowIndex, int colIndex) {
        return "";
      }

      @Override
      public String getRowStyle(M model, int rowIndex) {
        String s = appearance.getRowStyles(model, rowIndex);
        if (config != null) {
          return s + " " + config.getRowStyle(model, rowIndex);
        } else {
          return s;
        }
      }
    };

    grid.addRowClickHandler(new RowClickHandler() {

      @Override
      public void onRowClick(RowClickEvent event) {
        onMouseDown(event);
      }
    });
  }

  /**
   * Sets the content cell.
   *
   * @param contentCell the content cell
   */
  public void setContentCell(Cell<M> contentCell) {
    this.contentCell = contentCell;
  }

  protected boolean beforeExpand(M model, Element body, XElement row, int rowIndex) {
    BeforeExpandItemEvent<M> e = new BeforeExpandItemEvent<M>(model);
    ensureHandlers().fireEvent(e);

    if (!e.isCancelled()) {
      body.setInnerHTML(getBodyContent(model, rowIndex));
      return true;
    }
    return false;
  }

  protected void collapseRow(XElement row) {
    int idx = row.getPropertyInt("rowindex");
    M model = grid.getStore().get(idx);

    BeforeCollapseItemEvent<M> e = new BeforeCollapseItemEvent<M>(model);
    ensureHandlers().fireEvent(e);

    if (!e.isCancelled()) {
      appearance.onExpand(row, false);
      // expander row not visible in ie6 ie7 without repaint
      if (GXT.isIE6() || GXT.isIE7()) {
        grid.getElement().repaint();
      }
      ensureHandlers().fireEvent(new CollapseItemEvent<M>(model));
    }

  }

  protected void expandRow(XElement row) {
    int idx = row.getPropertyInt("rowindex");
    M model = grid.getStore().get(idx);
    Element rowBody = grid.getView().getRowBody(row);
    if (beforeExpand(model, rowBody, row, idx)) {
      appearance.onExpand(row, true);
      // expander row not visible in ie6 ie7 without repaint
      if (GXT.isIE6() || GXT.isIE7()) {
        grid.getElement().repaint();
      }
      ensureHandlers().fireEvent(new ExpandItemEvent<M>(model));
    }
  }

  protected String getBodyContent(M model, int rowIndex) {
    SafeHtmlBuilder sb = new SafeHtmlBuilder();
    contentCell.render(new Context(rowIndex, 0, grid.getStore().getKeyProvider().getKey(model)), model, sb);
    return sb.toSafeHtml().asString();
  }

  protected boolean isExpanded(XElement row) {
    return appearance.isExpanded(row);
  }

  protected void onMouseDown(RowClickEvent event) {
    Event e = event.getEvent();
    XElement target = e.getEventTarget().cast();
    if (appearance.isExpandElement(target)) {
      e.stopPropagation();
      e.preventDefault();
      XElement row = grid.getView().findRow(target).cast();
      toggleRow(row);
    }
  }

  protected void toggleRow(XElement row) {
    if (!appearance.isExpanded(row)) {
      expandRow(row);
    } else {
      collapseRow(row);
    }
    grid.getView().calculateVBar(false);
  }

  SimpleEventBus ensureHandlers() {
    return eventBus == null ? eventBus = new SimpleEventBus() : eventBus;
  }

}
TOP

Related Classes of com.sencha.gxt.widget.core.client.grid.RowExpander$RowExpanderAppearance

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.