Package at.bestsolution.efxclipse.runtime.panels

Source Code of at.bestsolution.efxclipse.runtime.panels.SashLayoutPane$MUIElement

/*******************************************************************************
* Copyright (c) 2000, 2010 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.ArrayList;
import java.util.List;

import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.WritableIntegerValue;
import javafx.event.EventHandler;
import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;

public class SashLayoutPane extends Pane {
  class SashRect {
    Bounds rect;
    MGenericTile container;
    MUIElement left;
    MUIElement right;

    public SashRect(Bounds rect, MGenericTile container,
        MUIElement left, MUIElement right) {
      this.container = container;
      this.rect = rect;
      this.left = left;
      this.right = right;
    }
  }
 
  public abstract static class MUIElement {
    Double weight;
    Object widget;
    boolean visible = true;
   
    public boolean isVisible() {
      return visible;
    }
   
    public void setWeight(Double weight) {
      this.weight = weight;
    }
  }
 
  public static class MGenericTile extends MUIElement {
    boolean horizontal;
    List<MUIElement> children = new ArrayList<MUIElement>();
   
    public MGenericTile() {
     
    }
   
    public void setHorizontal(boolean horizontal) {
      this.horizontal = horizontal;
    }
   
    public void add(MUIElement element) {
      children.add(element);
    }
  }
 
  public static class MUIControl extends MUIElement {
    public MUIControl() {
     
    }
  }
 
  private WritableIntegerValue minSashPercent = new SimpleIntegerProperty(this, "minSashPercent", 10);
 
  private WritableIntegerValue marginLeft = new SimpleIntegerProperty(this, "marginLeft", 0);
  private WritableIntegerValue marginRight = new SimpleIntegerProperty(this, "marginRight", 0);
  private WritableIntegerValue marginTop = new SimpleIntegerProperty(this, "marginTop", 0);
  private WritableIntegerValue marginBottom = new SimpleIntegerProperty(this, "marginBottom", 0);
  private WritableIntegerValue sashWidth = new SimpleIntegerProperty(this, "sashWidth", 4);
 
  private MGenericTile root;
  private List<SashRect> sashes = new ArrayList<SashRect>();
  private boolean draggingSashes = false;
  List<SashRect> sashesToDrag;
 
  public SashLayoutPane() {
    this.root = new MGenericTile();
    this.root.widget = this;
   
    onMouseMovedProperty().set(new EventHandler<MouseEvent>() {

      @Override
      public void handle(MouseEvent event) {
        if (!draggingSashes) {
          // Set the cursor feedback
          List<SashRect> sashList = getSashRects(event.getX(), event.getY());
          if (sashList.size() == 0) {
            setCursor(Cursor.DEFAULT);
          } else if (sashList.size() == 1) {
            if (sashList.get(0).container.horizontal) {
              setCursor(Cursor.W_RESIZE);
            } else {
              setCursor(Cursor.S_RESIZE);
            }
          } else {
            setCursor(Cursor.CROSSHAIR);
          }
        }
      }
    });
   
    onMouseDraggedProperty().set(new EventHandler<MouseEvent>() {

      @Override
      public void handle(MouseEvent event) {
        if (draggingSashes) {
          adjustWeights(sashesToDrag, event.getX(), event.getY());
          requestLayout();
        }
      }
    });
   
    onMouseReleasedProperty().set(new EventHandler<MouseEvent>() {

      @Override
      public void handle(MouseEvent event) {
        draggingSashes = false;
      }
    });
   
    onMousePressedProperty().set(new EventHandler<MouseEvent>() {

      @Override
      public void handle(MouseEvent event) {
        sashesToDrag = getSashRects(event.getX(), event.getY());
        if (sashesToDrag.size() > 0) {
          draggingSashes = true;
        }
      }
    });
   
//    onMouseMovedProperty().addListener(new ChangeListener<EventHandler<MouseEvent>>() {
//
//      @Override
//      public void changed(
//          ObservableValue<? extends EventHandler<MouseEvent>> observable,
//          EventHandler<MouseEvent> oldValue,
//          EventHandler<MouseEvent> newValue) {
//        newValue.
//      }
//    });
   
//    host.addMouseListener(new MouseListener() {
//      public void mouseUp(MouseEvent e) {
//        host.setCapture(false);
//        draggingSashes = false;
//      }
//
//      public void mouseDown(MouseEvent e) {
//        if (e.button != 1)
//          return;
//
//        sashesToDrag = getSashRects(e.x, e.y);
//        if (sashesToDrag.size() > 0) {
//          draggingSashes = true;
//          host.setCapture(true);
//        }
//      }
//
//      public void mouseDoubleClick(MouseEvent e) {
//      }
//    });
   
  }
 
  public void setMarginLeft(int marginLeft) {
    this.marginLeft.set(marginLeft);
  }
 
  public int getMarginLeft() {
    return this.marginLeft.get();
  }
 
  public void setMarginRight(int marginRight) {
    this.marginRight.set(marginRight);
  }
 
  public int getMarginRight() {
    return this.marginRight.get();
  }
 
  public void setMarginTop(int marginTop) {
    this.marginTop.set(marginTop);
  }
 
  public int getMarginTop() {
    return this.marginTop.get();
  }
 
  public void setMarginBottom(int marginBottom) {
    this.marginBottom.set(marginBottom);
  }
 
  public int getMarginBottom() {
    return this.marginBottom.get();
  }
 
  public void setSashWidth(int sashWidth) {
    this.sashWidth.set(sashWidth);
  }
 
  public int getSashWidth() {
    return this.sashWidth.get();
  }
 
  protected List<SashRect> getSashRects(double x, double y) {
    List<SashRect> srs = new ArrayList<SashRect>();
    boolean inSash = false;
    for (SashRect sr : sashes) {
      if (sr.rect.contains(x, y))
        inSash = true;
    }
    if (!inSash)
      return srs;

    BoundingBox target = new BoundingBox(x - 5, y - 5, 10, 10);
    for (SashRect sr : sashes) {
      if (sr.rect.intersects(target))
        srs.add(sr);
    }
    return srs;
  }
 
  protected void adjustWeights(List<SashRect> sashes, double curX, double curY) {
    for (SashRect sr : sashes) {
      double totalWeight = getWeight(sr.left) + getWeight(sr.right);
      double minSashValue = (((totalWeight / 100.0) * minSashPercent.get()) + 0.5);
     
      Bounds leftRect = getRectangle(sr.left);
      Bounds rightRect = getRectangle(sr.right);
      if (leftRect == null || rightRect == null)
        continue;

      double leftWeight;
      double rightWeight;

      if (sr.container.horizontal) {
        double left = leftRect.getMinX();
        double right = rightRect.getMinX() + rightRect.getWidth();
        double pct = (curX - left) / (right - left);
        leftWeight = ((totalWeight * pct) + 0.5);
        if (leftWeight < minSashValue)
          leftWeight = minSashValue;
        if (leftWeight > (totalWeight - minSashValue))
          leftWeight = totalWeight - minSashValue;
        rightWeight = totalWeight - leftWeight;
      } else {
        double top = leftRect.getMinY();
        double bottom = rightRect.getMinY() + rightRect.getHeight();
        double pct = (curY - top) / (bottom - top);
        leftWeight = (int)((totalWeight * pct) + 0.5);
       
        if (leftWeight < minSashValue)
          leftWeight = minSashValue;
       
        if (leftWeight > (totalWeight - minSashValue))
          leftWeight = totalWeight - minSashValue;
       
        rightWeight = totalWeight - leftWeight;
      }

      setWeight(sr.left, leftWeight);
      setWeight(sr.right, rightWeight);
     
    }
  }
 
  private void setWeight(MUIElement element, double weight) {
    element.weight = weight;
  }
 
  public void setConstraint(Node node, MUIControl data) {
    data.widget = node;
  }
 
  public MGenericTile getRoot() {
    return root;
  }
 
  @Override
  protected void layoutChildren() {
    if (root == null)
      return;

    Bounds bounds = getLayoutBounds();
    bounds = new BoundingBox(bounds.getMinX() + marginLeft.get(),
        bounds.getMinY() + marginTop.get(),
        bounds.getWidth() - (marginLeft.get() + marginRight.get()),
        bounds.getHeight() - (marginTop.get() + marginBottom.get()));

    sashes.clear();
    tileSubNodes(bounds, root);
  }
 
  private Bounds getRectangle(MUIElement element) {
    if (element instanceof MGenericTile)
      return (Bounds) element.widget;
    else if (element.widget instanceof Node)
      return ((Node) (element.widget)).getBoundsInParent();
    return null;
  }
 
  private void setRectangle(MUIElement node, Bounds bounds) {
    if (node.widget instanceof Node) {
      Node ctrl = (Node) node.widget;
      ctrl.resizeRelocate(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), bounds.getHeight());
    } else if (node instanceof MGenericTile) {
      Bounds newRect = new BoundingBox(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(),
          bounds.getHeight());
      node.widget = newRect;
    }
  }
 
  private List<MUIElement> getVisibleChildren(MGenericTile sashContainer) {
    List<MUIElement> visKids = new ArrayList<MUIElement>();
    for (MUIElement child : sashContainer.children) {
      if (child.isVisible())
        visKids.add(child);
    }
    return visKids;
  }
 
  private double totalWeight(MGenericTile node) {
    double total = 0;
    for (MUIElement subNode : node.children) {
      if (subNode.isVisible())
        total += getWeight(subNode);
    }
    return total;
  }
 
  private void tileSubNodes(Bounds bounds, MUIElement node) {
    if (node != root)
      setRectangle(node, bounds);

    if (!(node instanceof MGenericTile))
      return;

    MGenericTile sashContainer = (MGenericTile) node;
    List<MUIElement> visibleChildren = getVisibleChildren(sashContainer);
    int childCount = visibleChildren.size();

    // How many pixels do we have?
    double availableWidth = sashContainer.horizontal ? bounds.getWidth()
        : bounds.getHeight();

    // Subtract off the room for the sashes
    availableWidth -= ((childCount - 1) * sashWidth.get());

    // Get the total of the weights
    double totalWeight = totalWeight(sashContainer);
    double tilePos = sashContainer.horizontal ? bounds.getMinX() : bounds.getMinY();

    MUIElement prev = null;
    for (MUIElement subNode : visibleChildren) {
      // Add a 'sash' between this node and the 'prev'
      if (prev != null) {
        Bounds sashRect = sashContainer.horizontal ? new BoundingBox(
            tilePos, bounds.getMinY(), sashWidth.get(), bounds.getHeight())
            : new BoundingBox(bounds.getMinX(), tilePos, bounds.getWidth(),
                sashWidth.get());
        sashes.add(new SashRect(sashRect, sashContainer, prev, subNode));
        tilePos += sashWidth.get();
      }

      // Calc the new size as a %'age of the total
      double ratio = getWeight(subNode) / totalWeight;
      double newSize = availableWidth * ratio;
     
      Bounds subBounds = sashContainer.horizontal ? new BoundingBox(
          tilePos, bounds.getMinY(), newSize, bounds.getHeight()) : new BoundingBox(
          bounds.getMinX(), tilePos, bounds.getWidth(), newSize);
         
         
      tilePos += newSize;

      tileSubNodes(subBounds, subNode);
      prev = subNode;
    }
  }
 
  private static double getWeight(MUIElement element) {
    Double info = element.weight;
    if (info == null ) {
      element.weight = Double.valueOf(100);
      info = element.weight;
    }

    return info;
  }
}
TOP

Related Classes of at.bestsolution.efxclipse.runtime.panels.SashLayoutPane$MUIElement

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.