Package gwt.mosaic.client.ui

Source Code of gwt.mosaic.client.ui.Box

package gwt.mosaic.client.ui;

import gwt.mosaic.client.events.HasFillChangeHandlers;
import gwt.mosaic.client.events.HasHorizontalAlignmentChangeHandlers;
import gwt.mosaic.client.events.HasOrientationChangeHandlers;
import gwt.mosaic.client.events.HasSpacingChangeHandlers;
import gwt.mosaic.client.events.HasVerticalAlignmentChangeHandlers;
import gwt.mosaic.client.events.PropertyChangeEvent;
import gwt.mosaic.client.events.PropertyChangeHandler;
import gwt.mosaic.client.style.BoxModel;
import gwt.mosaic.shared.Bean;

import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.user.client.ui.Widget;

/**
* Container that arranges components in a line, either vertically or
* horizontally.
*/
@Bean
public class Box extends LayoutPanel implements HasOrientationChangeHandlers,
    HasHorizontalAlignmentChangeHandlers,
    HasVerticalAlignmentChangeHandlers, HasSpacingChangeHandlers,
    HasFillChangeHandlers {

  private Orientation orientation;

  // skin --------------------------------------------------------------------
  private HorizontalAlignment horizontalAlignment = HorizontalAlignment.LEFT;
  private VerticalAlignment verticalAlignment = VerticalAlignment.TOP;

  private int spacing = 4;
  private boolean fill = false;

  // -------------------------------------------------------------------------

  public Box() {
    this(Orientation.HORIZONTAL);
  }

  @Override
  public HandlerRegistration addPropertyChangeHandler(
      PropertyChangeHandler handler) {
    return addHandler(handler, PropertyChangeEvent.getType());
  }

  protected Box(Orientation orientation) {
    this.orientation = orientation;
  }

  public Orientation getOrientation() {
    return orientation;
  }

  public void setOrientation(Orientation orientation) {
    if (this.orientation != orientation) {
      this.orientation = orientation;
      PropertyChangeEvent.fire(this, "orientation");
      invalidate();
    }
  }

  public boolean isFill() {
    return fill;
  }

  public void setFill(boolean fill) {
    if (this.fill != fill) {
      this.fill = fill;
      invalidate();
    }
  }

  public int getSpacing() {
    return spacing;
  }

  public void setSpacing(int spacing) {
    if (this.spacing != spacing) {
      this.spacing = spacing;
      invalidate();
    }
  }

  public HorizontalAlignment getHorizontalAlignment() {
    return horizontalAlignment;
  }

  public void setHorizontalAlignment(HorizontalAlignment horizontalAlignment) {
    if (this.horizontalAlignment != horizontalAlignment) {
      this.horizontalAlignment = horizontalAlignment;
      invalidate();
    }
  }

  public VerticalAlignment getVerticalAlignment() {
    return verticalAlignment;
  }

  public void setVerticalAlignment(VerticalAlignment verticalAlignment) {
    if (this.verticalAlignment != verticalAlignment) {
      this.verticalAlignment = verticalAlignment;
      invalidate();
    }
  }

  @Override
  public int getPreferredWidth(int clientHeight) {

    if (clientHeight == -1) {
      // First, check if preferredWidth is cached
      if (isValid() && (preferredWidth != -1)) {
        return preferredWidth;
      }
    }

    // then check if there is a fixed preferredWidth hint stored in
    // layoutData
    LayoutData layoutData = WidgetHelper.getLayoutData(this);
    if (layoutData.getPreferredWidth() != null) {
      return WidgetHelper.getPreferredWidthImpl(this, clientHeight);
    }

    int preferredWidth = 0;

    BoxModel boxModel = WidgetHelper.getBoxModel(this);

    if (orientation == Orientation.HORIZONTAL) {
      // Include padding in constraint
      if (clientHeight != -1) {
        clientHeight = Math.max(
            clientHeight - (boxModel.getHeightContribution()), 0);
      }

      // Preferred width is the sum of the preferred widths of all widgets
      int j = 0;
      for (Widget child : getChildren()) {
        if (child.isVisible()) {
          preferredWidth += WidgetHelper.getPreferredWidth(child,
              fill ? clientHeight : -1);
          ++j;
        }
      }
     
      // Include spacing
      if (j > 1) {
        preferredWidth += spacing * (j - 1);
      }
    } else {
      // Preferred width is the maximum preferred width of all widgets
      for (Widget child : getChildren()) {
        if (child.isVisible()) {
          preferredWidth = Math.max(preferredWidth,
              WidgetHelper.getPreferredWidth(child, -1));
        }
      }
    }

    // Include left and right margin+border+padding values
    preferredWidth += boxModel.getWidthContribution();

    return (this.preferredWidth = preferredWidth);
  }

  @Override
  public int getPreferredHeight(int clientWidth) {

    if (clientWidth == -1) {
      // First, check if preferredHeight is cached
      if (isValid() && (preferredHeight != -1)) {
        return preferredHeight;
      }
    }
    // then check if there is a fixed preferredHeight hint stored in
    // layoutData
    LayoutData layoutData = WidgetHelper.getLayoutData(this);
    if (layoutData.getPreferredHeight() != null) {
      return WidgetHelper.getPreferredHeightImpl(this, clientWidth);
    }

    int preferredHeight = 0;

    BoxModel boxModel = WidgetHelper.getBoxModel(this);

    if (orientation == Orientation.HORIZONTAL) {
      // Preferred height is the maximum preferred height of all widget
      for (Widget child : getChildren()) {
        if (child.isVisible()) {
          preferredHeight = Math.max(preferredHeight,
              WidgetHelper.getPreferredHeight(child));
        }
      }
    } else {
      // Include padding in constraint
      if (clientWidth != -1) {
        clientWidth = Math
            .max(clientWidth
                - boxModel.getPaddingWidthContribution(), 0);
      }

      // Preferred height is the sum of the preferred heights of all
      // widget
      int j = 0;
      for (Widget child : getChildren()) {
        if (child.isVisible()) {
          preferredHeight += WidgetHelper.getPreferredHeight(child,
              fill ? clientWidth : -1);
          ++j;
        }
      }

      // Include spacing
      if (j > 1) {
        preferredHeight += spacing * (j - 1);
      }
    }

    // Include top and bottom margin+border+padding values
    preferredHeight += boxModel.getHeightContribution();

    return (this.preferredHeight = preferredHeight);
  }

  @Override
  public Dimensions getPreferredSize() {

    // First, check if preferred size is cached
    if (isValid() && (preferredSize != null)) {
      return preferredSize;
    }

    // then check if there is a fixed preferredWidth or preferredHeight hint
    // stored in layoutData
    LayoutData layoutData = WidgetHelper.getLayoutData(this);
    String widthHint = layoutData.getPreferredWidth();
    String heightHint = layoutData.getPreferredHeight();
    if (widthHint != null || heightHint != null) {
      return new Dimensions(getPreferredWidth(-1), getPreferredHeight(-1));
    }

    int preferredWidth = 0;
    int preferredHeight = 0;

    BoxModel boxModel = WidgetHelper.getBoxModel(this);

    switch (orientation) {
    case HORIZONTAL: {
      // Preferred width is the sum of the preferred widths of all widgets
      int j = 0;
      for (Widget child : getChildren()) {
        if (child.isVisible()) {
          Dimensions preferredSize = WidgetHelper
              .getPreferredSize(child);
          preferredWidth += preferredSize.getWidth();
          preferredHeight = Math.max(preferredSize.getHeight(),
              preferredHeight);
          ++j;
        }
      }

      // Include spacing
      if (j > 1) {
        preferredWidth += spacing * (j - 1);
      }

      break;
    }

    case VERTICAL: {
      // Preferred height is the sum of the preferred heights of all
      // widgets
      int j = 0;
      for (Widget child : getChildren()) {
        if (child.isVisible()) {
          Dimensions preferredSize = WidgetHelper
              .getPreferredSize(child);
          preferredWidth = Math.max(preferredSize.getWidth(),
              preferredWidth);
          preferredHeight += preferredSize.getHeight();
          ++j;
        }
      }

      // Include spacing
      if (j > 1) {
        preferredHeight += spacing * (j - 1);
      }

      break;
    }
    }

    // Include margin+border+padding
    preferredWidth += boxModel.getWidthContribution();
    preferredHeight += boxModel.getHeightContribution();

    return (preferredSize = new Dimensions(preferredWidth, preferredHeight));
  }

  @Override
  public int getBaseline(int width, int height) {
    int baseline = -1;
    int contentHeight = 0;

    BoxModel boxModel = WidgetHelper.getBoxModel(this);

    Insets padding = boxModel.getPadding(); // XXX

    switch (orientation) {
    case HORIZONTAL: {
      if (fill) {
        int clientHeight = Math.max(height
            - (padding.top + padding.bottom), 0);

        for (Widget child : getChildren()) {
          if (child.isVisible()) {
            int componentWidth = WidgetHelper.getPreferredWidth(
                child, clientHeight);
            baseline = Math.max(baseline, WidgetHelper.getBaseline(
                child, componentWidth, clientHeight));
          }
        }
      } else {
        contentHeight = 0;
        for (Widget child : getChildren()) {
          if (child.isVisible()) {
            contentHeight = Math.max(contentHeight,
                WidgetHelper.getPreferredHeight(child));
          }
        }

        for (Widget child : getChildren()) {
          if (child.isVisible()) {
            Dimensions size = WidgetHelper.getPreferredSize(child);

            int componentBaseline = WidgetHelper.getBaseline(child,
                size.getWidth(), size.getHeight());

            if (componentBaseline != -1) {
              switch (verticalAlignment) {
              case MIDDLE: {
                componentBaseline += (contentHeight - size
                    .getHeight()) / 2;
                break;
              }

              case BOTTOM: {
                componentBaseline += contentHeight
                    - size.getHeight();
                break;
              }
              }
            }

            baseline = Math.max(baseline, componentBaseline);
          }
        }
      }

      break;
    }

    case VERTICAL: {
      int clientWidth = Math.max(width - (padding.left + padding.right),
          0);

      for (Widget child : getChildren()) {
        if (child.isVisible()) {
          Dimensions size;
          if (fill) {
            size = new Dimensions(clientWidth,
                WidgetHelper.getPreferredHeight(child,
                    clientWidth));
          } else {
            size = WidgetHelper.getPreferredSize(child);
          }

          if (baseline == -1) {
            baseline = WidgetHelper.getBaseline(child,
                size.getWidth(), size.getHeight());
            if (baseline != -1) {
              baseline += contentHeight;
            }
          }

          contentHeight += size.getHeight() + spacing;
        }
      }

      contentHeight -= spacing;

      break;
    }
    }

    if (baseline != -1) {
      if (fill) {
        baseline += padding.top;
      } else {
        switch (verticalAlignment) {
        case TOP: {
          baseline += padding.top;
          break;
        }

        case MIDDLE: {
          baseline += (height - contentHeight) / 2;
          break;
        }

        case BOTTOM: {
          baseline += height - (contentHeight + padding.bottom);
          break;
        }
        }
      }
    }

    return baseline;
  }

  @Override
  protected void doLayout() {
    if (orientation == Orientation.HORIZONTAL) {
      doHorizontalLayout();
    } else {
      doVerticalLayout();
    }
  }

  private void doHorizontalLayout() {
    int n = getWidgetCount();

    int width = getElement().getClientWidth();
    int height = getElement().getClientHeight();

    // int preferredWidth = getPreferredWidth(fill ? height : -1);
    // width = Math.max(width, preferredWidth);

    BoxModel boxModel = WidgetHelper.getBoxModel(this);

    int totalRelativeWeight = 0;
    int totalRelativeWidth = width - boxModel.getPaddingWidthContribution();

    int[] widgetHeights = new int[n];
    int[] widgetWidths = new int[n];

    for (int i = 0; i < n; i++) {
      Widget child = getWidget(i);
      if (child.isVisible()) {
        int weight = WidgetHelper.getWeight(child);
        if (weight > 0) {
          totalRelativeWeight += weight;
        }
        if (fill) {
          int widgetHeight = Math.max(
              height - (boxModel.getPaddingHeightContribution()),
              0);
          widgetHeights[i] = widgetHeight;
          if (weight == 0) {
            widgetWidths[i] = WidgetHelper.getPreferredWidth(child,
                widgetHeight);
            totalRelativeWidth -= widgetWidths[i] + spacing;
          }
        } else {
          if (weight == 0) {
            Dimensions preferredComponentSize = WidgetHelper
                .getPreferredSize(child);
            widgetWidths[i] = preferredComponentSize.width;
            widgetHeights[i] = preferredComponentSize.height;
            totalRelativeWidth -= widgetWidths[i] + spacing;
          } else {
            widgetHeights[i] = WidgetHelper
                .getPreferredHeight(child);
          }
        }
      }
    }

    // Determine the starting x-coordinate
    int x = 0;

    if (totalRelativeWeight == 0) {
      switch (horizontalAlignment) {
      case CENTER:
        x = (width - preferredWidth) / 2;
        break;
      case RIGHT:
        x = width - preferredWidth;
        break;
      case START:
        if (LocaleInfo.getCurrentLocale().isRTL()) {
          x = width - preferredWidth;
        }
        break;
      case END:
        if (!LocaleInfo.getCurrentLocale().isRTL()) {
          x = width - preferredWidth;
        }
        break;
      }
    }

    x += boxModel.getPadding().left;

    // Lay out the widgets
    for (int i = 0; i < n; i++) {
      Widget child = getWidget(i);

      if (child.isVisible()) {
        int widgetWidth = 0;
        int widgetHeight = 0;
        int y = 0;

        int weight = WidgetHelper.getWeight(child);
        if (weight == 0) {
          widgetWidth = widgetWidths[i];
        } else {
          widgetWidth = (int) (0.5 + totalRelativeWidth
              * (double) weight / (double) totalRelativeWeight);
        }
        widgetHeight = widgetHeights[i];

        if (!fill) {
          switch (verticalAlignment) {
          case TOP:
            y = boxModel.getPadding().top;
            break;
          case MIDDLE:
            y = (height - widgetHeight) / 2;
            break;
          case BOTTOM:
            y = height - boxModel.getPadding().bottom
                - widgetHeight;
            break;
          }
        } else {
          y = boxModel.getPadding().top;
        }

        // Set the component's size and position
        WidgetHelper.setSize(child, widgetWidth, widgetHeight);
        WidgetHelper.setLocation(child, x, y);

        // Increment the x-coordinate
        x += widgetWidth + spacing;
      }
    }
  }

  private void doVerticalLayout() {
    int n = getWidgetCount();

    int width = getElement().getClientWidth();
    int height = getElement().getClientHeight();

    // int preferredHeight = getPreferredHeight(fill ? width : -1);
    // height = Math.max(height, preferredHeight);

    BoxModel boxModel = WidgetHelper.getBoxModel(this);

    int totalRelativeWeight = 0;
    int totalRelativeHeight = height
        - boxModel.getPaddingHeightContribution();

    int[] widgetHeights = new int[n];
    int[] widgetWidths = new int[n];

    for (int i = 0; i < n; i++) {
      Widget child = getWidget(i);
      if (child.isVisible()) {
        int weight = WidgetHelper.getWeight(child);
        if (weight > 0) {
          totalRelativeWeight += weight;
        }
        if (fill) {
          int widgetWidth = Math.max(
              width - boxModel.getPaddingWidthContribution(), 0);
          widgetWidths[i] = widgetWidth;
          if (weight == 0) {
            widgetHeights[i] = WidgetHelper.getPreferredHeight(
                child, widgetWidth);
            totalRelativeHeight -= widgetHeights[i] + spacing;
          }
        } else {
          if (weight == 0) {
            Dimensions preferredComponentSize = WidgetHelper
                .getPreferredSize(child);
            widgetWidths[i] = preferredComponentSize.getWidth();
            widgetHeights[i] = preferredComponentSize.getHeight();
            totalRelativeHeight -= widgetHeights[i] + spacing;
          } else {
            widgetWidths[i] = WidgetHelper.getPreferredWidth(child);
          }
        }
      }
    }

    // Determine the starting y-coordinate
    int y = 0;

    if (totalRelativeWeight == 0) {
      switch (verticalAlignment) {
      case MIDDLE:
        y = (height - preferredHeight) / 2;
        break;
      case BOTTOM:
        y = height - preferredHeight;
        break;
      }
    }

    y += boxModel.getPadding().top;

    // Lay out the widgets
    for (int i = 0; i < n; i++) {
      Widget child = getWidget(i);

      if (child.isVisible()) {
        int widgetWidth = 0;
        int widgetHeight = 0;
        int x = 0;

        int weight = WidgetHelper.getWeight(child);
        if (weight == 0) {
          widgetHeight = widgetHeights[i];
        } else {
          widgetHeight = (int) (0.5 + totalRelativeHeight
              * (double) weight / (double) totalRelativeWeight);
        }
        widgetWidth = widgetWidths[i];

        if (!fill) {
          switch (horizontalAlignment) {
          case LEFT:
            x = boxModel.getPadding().left;
            break;
          case CENTER:
            x = (width - widgetWidth) / 2;
            break;
          case RIGHT:
            x = width - boxModel.getPadding().right - widgetWidth;
            break;
          case START:
            if (LocaleInfo.getCurrentLocale().isRTL()) {
              x = width - boxModel.getPadding().right
                  - widgetWidth;
            } else {
              x = boxModel.getPadding().left;
            }
            break;
          case END:
            if (!LocaleInfo.getCurrentLocale().isRTL()) {
              x = boxModel.getPadding().left;
            } else {
              x = width - boxModel.getPadding().right
                  - widgetWidth;
              break;
            }
          }
        } else {
          x = boxModel.getPadding().left;
        }

        // Set the component's size and position
        WidgetHelper.setSize(child, widgetWidth, widgetHeight);
        WidgetHelper.setLocation(child, x, y);

        // Increment the y-coordinate
        y += widgetHeight + spacing;
      }
    }
  }

}
TOP

Related Classes of gwt.mosaic.client.ui.Box

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.