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

Source Code of com.sencha.gxt.widget.core.client.container.Container

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

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

import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.AttachDetachException;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.IndexedPanel;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.WidgetCollection;
import com.sencha.gxt.core.client.dom.XElement;
import com.sencha.gxt.core.client.util.Margins;
import com.sencha.gxt.core.shared.event.GroupingHandlerRegistration;
import com.sencha.gxt.widget.core.client.Component;
import com.sencha.gxt.widget.core.client.ComponentHelper;
import com.sencha.gxt.widget.core.client.HasItemId;
import com.sencha.gxt.widget.core.client.event.AddEvent;
import com.sencha.gxt.widget.core.client.event.AddEvent.AddHandler;
import com.sencha.gxt.widget.core.client.event.BeforeAddEvent;
import com.sencha.gxt.widget.core.client.event.BeforeAddEvent.BeforeAddHandler;
import com.sencha.gxt.widget.core.client.event.BeforeRemoveEvent;
import com.sencha.gxt.widget.core.client.event.BeforeRemoveEvent.BeforeRemoveHandler;
import com.sencha.gxt.widget.core.client.event.ContainerHandler;
import com.sencha.gxt.widget.core.client.event.ContainerHandler.HasContainerHandlers;
import com.sencha.gxt.widget.core.client.event.HideEvent;
import com.sencha.gxt.widget.core.client.event.HideEvent.HasHideHandlers;
import com.sencha.gxt.widget.core.client.event.HideEvent.HideHandler;
import com.sencha.gxt.widget.core.client.event.RemoveEvent;
import com.sencha.gxt.widget.core.client.event.RemoveEvent.RemoveHandler;
import com.sencha.gxt.widget.core.client.event.ShowEvent;
import com.sencha.gxt.widget.core.client.event.ShowEvent.HasShowHandlers;
import com.sencha.gxt.widget.core.client.event.ShowEvent.ShowHandler;

/**
* Abstract base for components that can contain child widgets.
*/
public abstract class Container extends Component implements HasWidgets.ForIsWidget, IndexedPanel.ForIsWidget,
    HasContainerHandlers {

  private native static AttachDetachException.Command getAttachException() /*-{
    return @com.google.gwt.user.client.ui.AttachDetachException::attachCommand;
  }-*/;

  private native static AttachDetachException.Command getDetachException() /*-{
    return @com.google.gwt.user.client.ui.AttachDetachException::detachCommand;
  }-*/;

  private WidgetCollection children = new WidgetCollection(this);

  private Map<Widget, GroupingHandlerRegistration> widgetMap = new HashMap<Widget, GroupingHandlerRegistration>();

  /**
   * Adds a widget to this panel.
   *
   * @param child the child widget to be added
   */
  @Override
  public void add(IsWidget child) {
    this.add(asWidgetOrNull(child));
  }

  /**
   * Adds the specified widget to the container.
   * <p/>
   * If you override this method, please see {@link Panel#add(Widget)} for a
   * number of things you must take into consideration.
   *
   * @param child the child widget to be added.
   * @throws UnsupportedOperationException if the derived class has not properly
   *           overridden the method. See {@link Panel#add(Widget)} for more
   *           information.
   */
  @Override
  public void add(Widget child) {
    insert(child, getWidgetCount());
  }

  /**
   * Adds the {@link AddHandler} to the Container
   *
   * @param handler the handler
   * @return {@link HandlerRegistration}
   */
  public HandlerRegistration addAddHandler(AddHandler handler) {
    return addHandler(handler, AddEvent.getType());
  }

  /**
   * Adds the {@link BeforeAddHandler} to the Container
   *
   * @param handler the handler
   * @return {@link HandlerRegistration}
   */
  public HandlerRegistration addBeforeAddHandler(BeforeAddHandler handler) {
    return addHandler(handler, BeforeAddEvent.getType());
  }

  /**
   * Adds the {@link BeforeRemoveHandler} to the Container
   *
   * @param handler the handler
   * @return {@link HandlerRegistration}
   */
  public HandlerRegistration addBeforeRemoveHandler(BeforeRemoveHandler handler) {
    return addHandler(handler, BeforeRemoveEvent.getType());
  }

  /**
   * Adds the {@link ContainerHandler} to the Container
   *
   * @param handler the handler
   * @return {@link HandlerRegistration}
   */
  public HandlerRegistration addContainerHandler(ContainerHandler handler) {
    GroupingHandlerRegistration reg = new GroupingHandlerRegistration();
    reg.add(addHandler(handler, BeforeAddEvent.getType()));
    reg.add(addHandler(handler, BeforeRemoveEvent.getType()));
    reg.add(addHandler(handler, AddEvent.getType()));
    reg.add(addHandler(handler, RemoveEvent.getType()));
    return reg;
  }

  /**
   * Adds the {@link RemoveHandler} to the Container
   *
   * @param handler the handler
   * @return {@link HandlerRegistration}
   */
  public HandlerRegistration addRemoveHandler(RemoveHandler handler) {
    return addHandler(handler, RemoveEvent.getType());
  }

  /**
   * Clears the container's children
   *
   */
  @Override
  public void clear() {
    Iterator<Widget> it = iterator();
    while (it.hasNext()) {
      it.next();
      it.remove();
    }
  }

  @Override
  public void disable() {
    super.disable();
    Iterator<Widget> it = iterator();
    while (it.hasNext()) {
      Widget w = it.next();
      if (w instanceof Component) {
        ((Component) w).disable();
      }
    }
  }

  @Override
  public void enable() {
    super.enable();
    Iterator<Widget> it = iterator();
    while (it.hasNext()) {
      Widget w = it.next();
      if (w instanceof Component) {
        ((Component) w).enable();
      }
    }
  }

  /**
   * Returns the widget whose element, or child element, matches the given
   * element.
   *
   * @param elem the element
   * @return the matching widget or <code>null</code> if no match
   */
  public Widget findWidget(Element elem) {
    for (Widget w : this) {
      if (w.getElement().isOrHasChild(elem)) {
        return w;
      }
    }
    return null;
  }

  /**
   * Returns the child widget with the specified item id.
   *
   * @param itemId the item id
   * @return the widget or <code>null</code> if no match
   */
  public Widget getItemByItemId(String itemId) {
    if (itemId == null) {
      return null;
    }
    for (Widget w : this) {
      if (w instanceof HasItemId) {
        if (itemId.equals(((HasItemId) w).getItemId())) {
          return w;
        }
      }
    }
    return null;
  }

  @Override
  public Widget getWidget(int index) {
    return getChildren().get(index);
  }

  @Override
  public int getWidgetCount() {
    return getChildren().size();
  }

  @Override
  public int getWidgetIndex(IsWidget child) {
    return getWidgetIndex(asWidgetOrNull(child));
  }

  @Override
  public int getWidgetIndex(Widget child) {
    return getChildren().indexOf(child);
  }

  @Override
  public Iterator<Widget> iterator() {
    return getChildren().iterator();
  }

  @Override
  public boolean remove(int index) {
    return remove(getWidget(index));
  }

  @Override
  public boolean remove(IsWidget child) {
    return remove(asWidgetOrNull(child));
  }

  @Override
  public boolean remove(Widget child) {
    // Validate.
    if (child.getParent() != this) {
      return false;
    }
    if (!fireCancellableEvent(new BeforeRemoveEvent(child))) {
      return false;
    }
    // Orphan.
    try {
      orphan(child);
    } finally {
      // Physical detach.
      doPhysicalDetach(child);

      // Logical detach.
      getChildren().remove(child);
     
      widgetMap.remove(child).removeHandler();

      onRemove(child);
    }

    fireEvent(new RemoveEvent(child));
    return true;
  }
 
  protected int adjustIndex(Widget child, int beforeIndex) {
    checkIndexBoundsForInsertion(beforeIndex);

    // Check to see if this widget is already a direct child.
    if (child.getParent() == this) {
      // If the Widget's previous position was left of the desired new
      // position
      // shift the desired position left to reflect the removal
      int idx = getWidgetIndex(child);
      if (idx < beforeIndex) {
        beforeIndex--;
      }
    }

    return beforeIndex;
  }

  protected final void adopt(Widget child) {
    assert (child.getParent() == null);
    ComponentHelper.setParent(this, child);
  }

  protected void checkIndexBoundsForInsertion(int index) {
    if (index < 0 || index > getWidgetCount()) {
      throw new IndexOutOfBoundsException();
    }
  }

  @Override
  protected void doAttachChildren() {
    AttachDetachException.tryCommand(this, getAttachException());
  }

  @Override
  protected void doDetachChildren() {
    AttachDetachException.tryCommand(this, getDetachException());
  }

  protected void doPhysicalAttach(Widget child, int beforeIndex) {
    getContainerTarget().insertChild(child.getElement(), beforeIndex);
  }

  protected void doPhysicalDetach(Widget child) {
    child.getElement().removeFromParent();
  }

  protected GroupingHandlerRegistration ensureGroupingHandlerRegistration(Widget widget) {
    GroupingHandlerRegistration g = widgetMap.get(widget);
    if (g == null) {
      g = new GroupingHandlerRegistration();
      widgetMap.put(widget, g);
    }
    return g;
  }

  /**
   * Gets the list of children contained in this panel.
   *
   * @return a collection of child widgets
   */
  protected WidgetCollection getChildren() {
    return children;
  }

  protected XElement getContainerTarget() {
    return getElement();
  }

  /**
   * Insert a new child Widget into this Panel at a specified index, attaching
   * its Element to the specified container Element. The child Element will
   * either be attached to the container at the same index, or simply appended
   * to the container, depending on the value of <code>domInsert</code>.
   *
   * @param child the child Widget to be added
   * @param beforeIndex the index before which <code>child</code> will be
   *          inserted
   **/
  protected void insert(Widget child, int beforeIndex) {
    // Validate index; adjust if the widget is already a child of this
    // panel.
    beforeIndex = adjustIndex(child, beforeIndex);

    if (!fireCancellableEvent(new BeforeAddEvent(child, beforeIndex))) {
      return;
    }

    // Detach new child.
    child.removeFromParent();

    // Logical attach.
    getChildren().insert(child, beforeIndex);

    GroupingHandlerRegistration g = ensureGroupingHandlerRegistration(child);
    if (child instanceof HasShowHandlers) {
      g.add(((HasShowHandlers) child).addShowHandler(new ShowHandler() {
        @Override
        public void onShow(ShowEvent event) {
          onWidgetShow(event.getSource());
        }
      }));
    }

    if (child instanceof HasHideHandlers) {
      g.add(((HasHideHandlers) child).addHideHandler(new HideHandler() {
        @Override
        public void onHide(HideEvent event) {
          onWidgetHide(event.getSource());
        }
      }));
    }

    // Physical attach.
    doPhysicalAttach(child, beforeIndex);

    // Adopt.
    adopt(child);

    onInsert(beforeIndex, child);

    fireEvent(new AddEvent(child, beforeIndex));
  }

  protected void onInsert(int index, Widget child) {
    if (child.getLayoutData() instanceof HasMargins) {
      HasMargins m = (HasMargins) child.getLayoutData();
      Margins margins = m.getMargins();
      if (margins != null) {
        child.getElement().getStyle().setMarginTop(margins.getTop(), Unit.PX);
        child.getElement().getStyle().setMarginBottom(margins.getBottom(), Unit.PX);
        child.getElement().getStyle().setMarginLeft(margins.getLeft(), Unit.PX);
        child.getElement().getStyle().setMarginRight(margins.getRight(), Unit.PX);

      }
    }
  }

  protected void onRemove(Widget child) {
    child.getElement().getStyle().clearMarginBottom();
    child.getElement().getStyle().clearMarginTop();
    child.getElement().getStyle().clearMarginLeft();
    child.getElement().getStyle().clearMarginRight();
  }

  protected void onWidgetHide(Widget source) {

  }

  protected void onWidgetShow(Widget source) {

  }

  protected final void orphan(Widget child) {
    assert (child.getParent() == this);
    ComponentHelper.setParent(null, child);
  }
}
TOP

Related Classes of com.sencha.gxt.widget.core.client.container.Container

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.