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

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

/**
* 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 com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.user.client.ui.AnimatedLayout;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.IndexedPanel;
import com.google.gwt.user.client.ui.ProvidesResize;
import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.core.client.GXT;
import com.sencha.gxt.core.client.Style.Side;
import com.sencha.gxt.core.client.dom.XElement;
import com.sencha.gxt.core.client.util.Margins;
import com.sencha.gxt.core.client.util.Rectangle;
import com.sencha.gxt.core.client.util.Size;
import com.sencha.gxt.widget.core.client.Component;

/**
* A base class for layout containers that require resize support.
*/
public abstract class ResizeContainer extends Container implements RequiresResize, ProvidesResize, HasLayout {

  protected ScheduledCommand forceLayoutCommand = new ScheduledCommand() {
    @Override
    public void execute() {
      forceLayout();
    }
  };

  protected ScheduledCommand layoutCommand = new ScheduledCommand() {
    @Override
    public void execute() {
      doLayout();
    }
  };

  protected boolean hadLayoutRunning;
  protected boolean layoutRequiredThisEventLoop = true;
  protected boolean layoutRunning;

  /**
   * By default, a container calls doLayout when resized which does not force
   * children to be laid out. To force the layout, set to true.
   */
  protected boolean forceLayoutOnResize = false;

  @Override
  public void forceLayout() {
    if (layoutRequiredThisEventLoop && isAttached() && !isLayoutRunning() && !isParentLayoutRunning()
        && parentIsOrWasLayoutRunning() && isWidgetVisible(this)) {
      layoutRequiredThisEventLoop = false;
      hadLayoutRunning = true;
      Scheduler.get().scheduleFinally(new ScheduledCommand() {
        @Override
        public void execute() {
          layoutRequiredThisEventLoop = true;
        }
      });
      onBeforeDoLayout();
      layoutRunning = true;

      doLayout();
      layoutRunning = false;
      forceLayoutOnChildren((IndexedPanel) this);
    }
  }

  @Override
  public boolean isLayoutRunning() {
    return layoutRunning;
  }

  @Override
  public boolean isOrWasLayoutRunning() {
    return hadLayoutRunning;
  }

  public void onResize() {
    if (isAttached()) {
      Size s = XElement.as(getElement().getParentElement()).getSize(true);
      setPixelSize(s.getWidth(), s.getHeight());
    }
  }

  protected void applyLayout(final Widget widget, int width, int height) {
    if (widget instanceof Component) {
      int ww = width == -1 ? Integer.MIN_VALUE : width;
      int hh = height == -1 ? Integer.MIN_VALUE : height;
      ((Component) widget).setPixelSize(ww, hh);
    } else {
      XElement.as(widget.getElement()).setSize(width, height, true);
      if (widget instanceof RequiresResize) {
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
          @Override
          public void execute() {
            ((RequiresResize) widget).onResize();
          }
        });
      }
    }
  }

  protected void applyLayout(final Widget component, Rectangle box) {
    if (component instanceof Component) {
      Component c = (Component) component;
      c.setPosition(box.getX(), box.getY());
      applyLayout(c, box.getWidth(), box.getHeight());
    } else {
      XElement.as(component.getElement()).setLeftTop(box.getX(), box.getY());
      applyLayout(component, box.getWidth(), box.getHeight());
    }
  }

  protected abstract void doLayout();

  protected void forceLayoutOnChildren(HasWidgets widgets) {
    for (Widget w : widgets) {
      if (w instanceof HasLayout) {
        ((HasLayout) w).forceLayout();
      } else if (w instanceof HasWidgets && isWidgetVisible(w)) {
        forceLayoutOnChildren((HasWidgets) w);
      } else if (w instanceof IndexedPanel && isWidgetVisible(w)) {
        forceLayoutOnChildren((IndexedPanel) w);
      }
    }
  }

  protected void forceLayoutOnChildren(IndexedPanel widgets) {
    for (int index = 0, len = widgets.getWidgetCount(); index < len; index++) {
      Widget w = widgets.getWidget(index);
      if (w instanceof HasLayout) {
        ((HasLayout) w).forceLayout();
      } else if (w instanceof HasWidgets && isWidgetVisible(w)) {
        forceLayoutOnChildren((HasWidgets) w);
      } else if (w instanceof IndexedPanel && isWidgetVisible(w)) {
        forceLayoutOnChildren((IndexedPanel) w);
      }
    }
  }

  protected int getLeftRightMargins(Widget w) {
    if (w == null) {
      return 0;
    }
    Object data = w.getLayoutData();
    if (data instanceof HasMargins) {
      Margins margins = ((HasMargins) data).getMargins();
      if (margins == null) {
        return 0;
      }
      int tot = 0;
      if (margins.getLeft() != -1) {
        tot += margins.getLeft();
      }
      if (margins.getRight() != -1) {
        tot += margins.getRight();
      }
      return tot;
    }
    return 0;
  }

  protected Widget getParentLayoutWidget() {
    return this;
  }

  protected int getSideMargins(Widget w) {
    if (GXT.isWebKit()) {
      Object data = w.getLayoutData();
      if (data != null && data instanceof MarginData) {
        MarginData m = (MarginData) data;
        Margins margins = m.getMargins();
        if (margins == null) {
          return 0;
        }
        int tot = 0;
        if (margins.getLeft() != -1) {
          tot += margins.getLeft();
        }
        if (margins.getRight() != -1) {
          tot += margins.getRight();
        }
        return tot;
      }
    } else {
      return w.getElement().<XElement> cast().getMargins(Side.LEFT, Side.RIGHT);
    }
    return 0;
  }

  protected int getTopBottomMargins(Widget w) {
    if (w == null) {
      return 0;
    }
    Object data = w.getLayoutData();
    if (data instanceof HasMargins) {
      Margins margins = ((HasMargins) data).getMargins();
      if (margins == null) {
        return 0;
      }
      int tot = 0;
      if (margins.getLeft() != -1) {
        tot += margins.getTop();
      }
      if (margins.getRight() != -1) {
        tot += margins.getBottom();
      }
      return tot;
    }

    return 0;
  }

  protected boolean isWidgetVisible(Widget w) {
    return !XElement.as(w.getElement()).isStyleAttribute("display", "none");
  }

  protected void onBeforeDoLayout() {
  }

  @Override
  protected void onLoad() {
    super.onLoad();
    if (this.getParent() instanceof AnimatedLayout) {
      Scheduler.get().scheduleDeferred(forceLayoutCommand);
    } else {
      Scheduler.get().scheduleFinally(forceLayoutCommand);
    }
  }

  @Override
  protected void onResize(int width, int height) {
    super.onResize(width, height);
    if (forceLayoutOnResize) {
      layoutRequiredThisEventLoop = true;
      Scheduler.get().scheduleFinally(forceLayoutCommand);
    } else {
      Scheduler.get().scheduleFinally(layoutCommand);
    }
  }

  private boolean isParentLayoutRunning() {
    Widget parent = getParentLayoutWidget();
    while ((parent = parent.getParent()) != null) {
      if (parent instanceof HasWidgets || parent instanceof IndexedPanel) {
        if (parent instanceof HasLayout && ((HasLayout) parent).isLayoutRunning()) {
          return true;
        }
      } else {
        return false;
      }
    }
    return false;
  }

  private boolean parentIsOrWasLayoutRunning() {
    Widget parent = getParentLayoutWidget();
    while ((parent = parent.getParent()) != null) {
      if (parent instanceof HasWidgets || parent instanceof IndexedPanel) {
        if (parent instanceof HasLayout) {
          if (((HasLayout) parent).isOrWasLayoutRunning()) {
            return true;
          } else {
            return false;
          }
        }
      } else {
        return true;
      }
    }
    return true;
  }
}
TOP

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

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.