/* * Bibliothek - DockingFrames * Library built on Java/Swing, allows the user to "drag and drop" * panels containing any Swing-Component the developer likes to add. * * Copyright (C) 2007 Benjamin Sigg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Benjamin Sigg * benjamin_sigg@gmx.ch * CH - Switzerland */ package bibliothek.gui.dock.facile.station.split; import bibliothek.gui.dock.SplitDockStation.Orientation; import bibliothek.gui.dock.station.split.Node; /** * Represents a {@link Node}. * @author Benjamin Sigg */ public class ResizeNode<T> extends ResizeElement<T>{ /** the node that is represented by this node-element */ private Node node; /** size of the divider before the resize */ private double dividerSize; /** the two children of this node */ @SuppressWarnings("unchecked") private ResizeElement<T>[] children = new ResizeElement[2]; /** * Creates a new node-element. * @param layout the layout that uses this node * @param parent the parent of this node * @param node the node that is represented by this node-element */ public ResizeNode( LockedResizeLayoutManager<T> layout, ResizeElement<T> parent, Node node ){ super( parent, layout ); this.node = node; children[0] = layout.toElement( this, node.getLeft() ); children[1] = layout.toElement( this, node.getRight() ); } /** * Gets the node that is represented by this element * @return the node */ public Node getNode() { return node; } /** * Gets the left or top child of this node * @return the left or top child */ public ResizeElement<T> getLeft() { return children[0]; } /** * Gets the right or bottom child of this node * @return the left or bottom child */ public ResizeElement<T> getRight() { return children[1]; } @Override protected ResizeElement<T>[] getChildren() { return children; } @Override public void prepareResize() { super.prepareResize(); if( node.getOrientation() == Orientation.HORIZONTAL ) dividerSize = getDividerWidth(); else dividerSize = getDividerHeight(); } /** * Gets the space that a divider needs in the width. * @return the width of a divider */ public double getDividerWidth(){ return node.getStation().getDividerSize() / node.getRoot().getWidthFactor(); } /** * Gets the space that a divider needs in the height. * @return the height of a divider */ public double getDividerHeight(){ return node.getStation().getDividerSize() / node.getRoot().getHeightFactor(); } /** * Gets the space the divider needs right now. * @return the space the divider occupies now */ public double getNewDividerSize(){ if( node.getOrientation() == Orientation.HORIZONTAL ) return getDividerWidth(); else return getDividerHeight(); } /** * Gets the space the divider needed before the resize. * @return the old size needed by the divider */ public double getOldDividerSize(){ return dividerSize; } @Override protected ResizeRequest createRequest() { ResizeRequest alpha = getLeft().getRequest(); ResizeRequest beta = getRight().getRequest(); boolean horizontal = node.getOrientation() == Orientation.HORIZONTAL; if( horizontal ){ return getLayout().getConflictResolver().requestHorizontal( alpha, beta, this ); } else{ return getLayout().getConflictResolver().requestVertical( alpha, beta, this ); } } @Override public void adapt( double deltaWidth, double deltaHeight ) { ResizeRequest alpha = getLeft().getRequest(); ResizeRequest beta = getRight().getRequest(); boolean horizontal = node.getOrientation() == Orientation.HORIZONTAL; if( horizontal ){ if( alpha != null && alpha.getFractionWidth() == -1 ) alpha = null; if( beta != null && beta.getFractionWidth() == -1 ) beta = null; } else{ if( alpha != null && alpha.getFractionHeight() == -1 ) alpha = null; if( beta != null && beta.getFractionHeight() == -1 ) beta = null; } if( alpha == null && beta == null ){ if( horizontal ){ getLeft().adapt( deltaWidth * node.getDivider(), deltaHeight ); getRight().adapt( deltaWidth * (1-node.getDivider()), deltaHeight ); } else{ getLeft().adapt( deltaWidth, deltaHeight * node.getDivider()); getRight().adapt( deltaHeight, deltaHeight * (1-node.getDivider())); } } else if( horizontal ){ double divider = node.getDivider(); double width = node.getWidth(); double dividerWidth = getDividerWidth(); double leftBefore = width * divider - dividerWidth / 2.0; double rightBefore = width * (1-divider) - dividerWidth / 2.0; double delta; width += deltaWidth; if( beta == null ){ // alpha != null double request = alpha.getDeltaWidth() / alpha.getFractionWidth(); request -= deltaWidth * divider; delta = width <= 0.0 ? 0.0 : request / width; } else if( alpha == null ){ // beta != null double request = beta.getDeltaWidth() / beta.getFractionWidth(); request -= deltaWidth * (1-divider); delta = width <= 0.0 ? 0.0 : -request / width; } else{ double requestLeft = alpha.getDeltaWidth() / alpha.getFractionWidth(); double requestRight = beta.getDeltaWidth() / beta.getFractionWidth(); requestLeft -= deltaWidth * divider; requestRight -= deltaWidth * (1-divider); double deltaLeft = width <= 0.0 ? 0.0 : requestLeft / width; double deltaRight = width <= 0.0 ? 0.0 : -requestRight / width; delta = getLayout().getConflictResolver().resolveHorizontal( this, alpha, deltaLeft, beta, deltaRight ); } divider += delta; divider = Math.min( 1.0, Math.max( 0.0, divider ) ); node.setDivider( divider ); double leftAfter = width * divider - dividerWidth / 2.0; double rightAfter = width * (1-divider) - dividerWidth / 2.0; getLeft().adapt( leftAfter - leftBefore, deltaHeight ); getRight().adapt( rightAfter - rightBefore, deltaHeight ); } else{ // vertical double divider = node.getDivider(); double height = node.getHeight(); double dividerHeight = getDividerHeight(); double topBefore = height * divider - dividerHeight / 2.0; double bottomBefore = height * (1-divider) - dividerHeight / 2.0; double delta; height += deltaHeight; if( beta == null ){ // alpha != null double request = alpha.getDeltaHeight() / alpha.getFractionHeight(); request -= deltaHeight * divider; delta = height <= 0.0 ? 0.0 : request / height; } else if( alpha == null ){ // beta != null double request = beta.getDeltaHeight() / beta.getFractionHeight(); request -= deltaHeight * (1-divider); delta = height <= 0.0 ? 0.0 : -request / height; } else{ double requestTop = alpha.getDeltaHeight() / alpha.getFractionHeight(); double requestBottom = beta.getDeltaHeight() / beta.getFractionHeight(); requestTop -= deltaHeight * divider; requestBottom -= deltaHeight * (1-divider); double deltaTop = height <= 0.0 ? 0.0 : requestTop / height; double deltaBottom = height <= 0.0 ? 0.0 : -requestBottom / height; delta = getLayout().getConflictResolver().resolveVertical( this, alpha, deltaTop, beta, deltaBottom ); } divider += delta; divider = Math.min( 1.0, Math.max( 0.0, divider ) ); node.setDivider( divider ); double topAfter = height * divider - dividerHeight / 2.0; double bottomAfter = height * (1-divider) - dividerHeight / 2.0; getLeft().adapt( deltaWidth, topAfter - topBefore ); getRight().adapt( deltaWidth, bottomAfter - bottomBefore ); } } }