Package at.bestsolution.efxclipse.runtime.panels

Source Code of at.bestsolution.efxclipse.runtime.panels.FillLayoutPane

/*******************************************************************************
* Copyright (c) 2000, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*     Tom Schindl<tom.schindl@bestsolution.at> - ported to JavaFX
*******************************************************************************/
package at.bestsolution.efxclipse.runtime.panels;

import java.util.WeakHashMap;

import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.WritableBooleanValue;
import javafx.beans.value.WritableIntegerValue;
import javafx.geometry.Bounds;
import javafx.scene.Node;

public class FillLayoutPane extends AbstractLayoutPane<FillLayoutPane.FillData> {
  /**
   * type specifies how controls will be positioned within the layout.
   *
   * The default value is HORIZONTAL.
   *
   * Possible values are:
   * <ul>
   * <li>HORIZONTAL: Position the controls horizontally from left to right</li>
   * <li>VERTICAL: Position the controls vertically from top to bottom</li>
   * </ul>
   */
  private WritableBooleanValue horizontal = new SimpleBooleanProperty(this,
      "horizontal", true);

  /**
   * marginWidth specifies the number of pixels of horizontal margin that will
   * be placed along the left and right edges of the layout.
   *
   * The default value is 0.
   *
   * @since 3.0
   */
  private WritableIntegerValue marginWidth = new SimpleIntegerProperty(this,
      "marginWidth", 0);

  /**
   * marginHeight specifies the number of pixels of vertical margin that will
   * be placed along the top and bottom edges of the layout.
   *
   * The default value is 0.
   *
   * @since 3.0
   */
  private WritableIntegerValue marginHeight = new SimpleIntegerProperty(this,
      "marginHeight", 0);

  /**
   * spacing specifies the number of pixels between the edge of one cell and
   * the edge of its neighbouring cell.
   *
   * The default value is 0.
   *
   * @since 3.0
   */
  private WritableIntegerValue spacing = new SimpleIntegerProperty(this,
      "spacing", 0);

  static class FillData {

    double defaultWidth = -1, defaultHeight = -1;
    double currentWhint, currentHhint, currentWidth = -1,
        currentHeight = -1;

    Size computeSize(Node control, double wHint, double hHint,
        boolean flushCache) {
      if (flushCache)
        flushCache();
      if (wHint == FX_DEFAULT && hHint == FX_DEFAULT) {
        if (defaultWidth == -1 || defaultHeight == -1) {
          // Size size = computeSize (wHint, hHint, flushCache);
          defaultWidth = control.prefWidth(hHint);
          defaultHeight = control.prefHeight(wHint);
        }
        return new Size(defaultWidth, defaultHeight);
      }
      if (currentWidth == -1 || currentHeight == -1
          || wHint != currentWhint || hHint != currentHhint) {
        // Point size = control.computeSize (wHint, hHint, flushCache);
        currentWhint = wHint;
        currentHhint = hHint;
        currentWidth = control.getLayoutBounds().getWidth();
        currentHeight = control.getLayoutBounds().getHeight();
      }
      return new Size(currentWidth, currentHeight);
    }

    void flushCache() {
      defaultWidth = defaultHeight = -1;
      currentWidth = currentHeight = -1;
    }
  }

  private static WeakHashMap<Node, FillData> CONSTRAINTS = new WeakHashMap<Node, FillData>();
 
  public static void setConstraint(Node n, FillData griddata) {
    CONSTRAINTS.put(n, griddata);
  }
 
  public static FillData getConstraint(Node n) {
    return CONSTRAINTS.get(n);
  }

   
  public void setHorizontal(boolean horizontal) {
    this.horizontal.set(horizontal);
  }
 
  public boolean isHorizontal() {
    return this.horizontal.get();
  }
 
  public WritableBooleanValue horizontalProperty() {
    return horizontal;
  }
 
  public void setMarginWidth(int marginWidth) {
    this.marginWidth.set(marginWidth);
  }
 
  public int getMarginWidth() {
    return this.marginWidth.get();
  }
 
  public WritableIntegerValue marginHeightProperty() {
    return marginHeight;
  }
 
  public void setMarginHeight(int marginHeight) {
    this.marginHeight.set(marginHeight);
  }
 
  public int getMarginHeight() {
    return this.marginHeight.get();
  }
 
  public WritableIntegerValue marginWidthProperty() {
    return marginWidth;
  }
 
 
  protected Size computeSize(double wHint, double hHint, boolean flushCache) {
    Node[] children = getChildren().toArray(new Node[0]);
    int count = children.length;
    double maxWidth = 0, maxHeight = 0;
    for (int i = 0; i < count; i++) {
      Node child = children[i];
      double w = wHint, h = hHint;
      if (count > 0) {
        if (horizontal.get() && wHint != FX_DEFAULT) {
          w = Math.max(0, (wHint - (count - 1) * spacing.get())
              / count);
        }
        if (!horizontal.get() && hHint != FX_DEFAULT) {
          h = Math.max(0, (hHint - (count - 1) * spacing.get())
              / count);
        }
      }
      Size size = computeChildSize(child, w, h, flushCache);
      maxWidth = Math.max(maxWidth, size.width);
      maxHeight = Math.max(maxHeight, size.height);
    }
    double width = 0, height = 0;
    if (horizontal.get()) {
      width = count * maxWidth;
      if (count != 0)
        width += (count - 1) * spacing.get();
      height = maxHeight;
    } else {
      width = maxWidth;
      height = count * maxHeight;
      if (count != 0)
        height += (count - 1) * spacing.get();
    }
    width += marginWidth.get() * 2;
    height += marginHeight.get() * 2;
    if (wHint != FX_DEFAULT)
      width = wHint;
    if (hHint != FX_DEFAULT)
      height = hHint;
    return new Size(width, height);
  }

  Size computeChildSize(Node control, double wHint, double hHint,
      boolean flushCache) {
    FillData data = getConstraint(control);
    if (data == null) {
      data = new FillData();
      setConstraint(control, data);
    }
    Size size = null;
    if (wHint == FX_DEFAULT && hHint == FX_DEFAULT) {
      size = data.computeSize(control, wHint, hHint, flushCache);
    } else {
      // TEMPORARY CODE
      int trimX, trimY;
      trimX = trimY = 0;
      //FIXME
      // if (control instanceof Scrollable) {
      // Rectangle rect = ((Scrollable) control).computeTrim(0, 0, 0, 0);
      // trimX = rect.width;
      // trimY = rect.height;
      // } else {
      // trimX = trimY = control.getBorderWidth() * 2;
      // }
      double w = wHint == FX_DEFAULT ? wHint : Math
          .max(0, wHint - trimX);
      double h = hHint == FX_DEFAULT ? hHint : Math
          .max(0, hHint - trimY);
      size = data.computeSize(control, w, h, flushCache);
    }
    return size;
  }

  @Override
  protected void layoutChildren() {
    super.layoutChildren();
   
    Bounds rect = getLayoutBounds();
    Node [] children = getChildren ().toArray(new Node[0]);
    int count = children.length;
    if (count == 0) return;
    double width = rect.getWidth() - marginWidth.get() * 2;
    double height = rect.getHeight() - marginHeight.get() * 2;
    if (horizontal.get()) {
      width -= (count - 1) * spacing.get();
      double x = rect.getMinX() + marginWidth.get(), extra = width % count;
      double y = rect.getMinY() + marginHeight.get(), cellWidth = width / count;
      for (int i=0; i<count; i++) {
        Node child = children [i];
        double childWidth = cellWidth;
        if (i == 0) {
          childWidth += extra / 2;
        } else {
          if (i == count - 1) childWidth += (extra + 1) / 2;
        }
        child.resizeRelocate(x, y, childWidth, height);
        x += childWidth + spacing.get();
      }
    } else {
      height -= (count - 1) * spacing.get();
      double x = rect.getMinX() + marginWidth.get(), cellHeight = height / count;
      double y = rect.getMinY() + marginHeight.get(), extra = height % count;
      for (int i=0; i<count; i++) {
        Node child = children [i];
        double childHeight = cellHeight;
        if (i == 0) {
          childHeight += extra / 2;
        } else {
          if (i == count - 1) childHeight += (extra + 1) / 2;
        }
        child.resizeRelocate (x, y, width, childHeight);
        y += childHeight + spacing.get();
      }
    }
  }
}
TOP

Related Classes of at.bestsolution.efxclipse.runtime.panels.FillLayoutPane

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.