/*
* 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) 2008 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.station.stack.tab;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import bibliothek.gui.DockTheme;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.station.stack.tab.layouting.TabPlacement;
/**
* This layout puts all tabs in one, or if there is not enough space, in many,
* rows. This {@link TabLayoutManager} does never create menus and ignores the
* info panel.<br>
* Please do note that this manager is no longer used by any of the default
* {@link DockTheme}s. It remains however in the framework for future uses.
* @author Benjamin Sigg
*/
public class RowLayout implements TabLayoutManager{
public Dimension getMinimumSize( TabPane pane ){
return new Dimension( 10, 10 );
}
public Dimension getPreferredSize( TabPane pane ){
return new Dimension( 10, 10 );
}
/**
* Creates a conversion for converting a layout that is
* {@link TabPlacement#TOP_OF_DOCKABLE} to the current {@link TabPane#getDockTabPlacement() orientation}.
* @param pane the pane for which the conversion is required
* @return the conversion
*/
private AxisConversion getConversion( TabPane pane ){
return new DefaultAxisConversion( pane.getAvailableArea(), pane.getDockTabPlacement() );
}
public int getIndexOfTabAt( TabPane pane, Point mouseLocation ){
int index = 0;
for( Tab tab : pane.getTabs() ){
if( tab.getBounds().contains( mouseLocation )){
return index;
}
index++;
}
return -1;
}
public void layout( TabPane pane ){
AxisConversion conversion = getConversion( pane );
TabPlacement orientation = pane.getDockTabPlacement();
Rectangle available = conversion.viewToModel( pane.getAvailableArea() );
int maxwidth = available.width;
Dockable[] dockables = pane.getDockables();
Tab[] tabs = new Tab[ dockables.length ];
for( int i = 0; i < tabs.length; i++ ){
tabs[i] = pane.putOnTab( dockables[i] );
tabs[i].setOrientation( orientation );
}
// calculate the required size for the tabs
Dimension required = conversion.viewToModel( getPreferredSize( tabs, pane ) );
// put the selection area at the bottom
if( required.height < available.height ){
pane.setSelectedBounds( conversion.modelToView( new Rectangle( 0, required.height, available.width, available.height - required.height ) ) );
}
else{
pane.setSelectedBounds( conversion.modelToView( new Rectangle( 0, 0, available.width, 0 ) ) );
}
// put the tabs at the top
int dx = 0;
int dy = 0;
int x = 0;
int y = 0;
int maxRowHeight = -1;
int rowCount = 0;
for( int i = 0; i < tabs.length; i++ ){
Dimension size = conversion.viewToModel( tabs[i].getPreferredSize() );
if( x + size.width > maxwidth && rowCount > 0 ){
rowCount = 0;
y += maxRowHeight;
x = 0;
maxRowHeight = -1;
}
// find row height
if( maxRowHeight == -1 ){
maxRowHeight = 0;
int tx = x;
for( int j = i; j < tabs.length; j++ ){
Dimension tsize = conversion.viewToModel( tabs[j].getPreferredSize() );
if( tx + tsize.width > maxwidth && rowCount > 0 ){
rowCount = 0;
break;
}
tx += tsize.width;
maxRowHeight = Math.max( maxRowHeight, tsize.height );
rowCount++;
}
}
tabs[i].setBounds( conversion.modelToView( new Rectangle( x+dx, y+dy-size.height+maxRowHeight, size.width, size.height )) );
x += size.width;
rowCount++;
}
}
private Dimension getPreferredSize( Tab[] tabs, TabPane pane ){
AxisConversion conversion = getConversion( pane );
int width;
if( pane == null )
width = Integer.MAX_VALUE;
else
width = conversion.viewToModel( pane.getAvailableArea() ).width;
int maxWidth = 0;
int currentWidth = 0;
int currentHeight = 0;
int left = 0;
int height = 0;
for( Tab tab : tabs ){
Dimension preferred = conversion.viewToModel( tab.getPreferredSize() );
if( left == 0 || currentWidth + preferred.width <= width ){
currentWidth += preferred.width;
currentHeight = Math.max( currentHeight, preferred.height );
left++;
}
else{
height += currentHeight;
maxWidth = Math.max( maxWidth, currentWidth );
left = 0;
currentWidth = preferred.width;
currentHeight = preferred.height;
left++;
}
}
height += currentHeight;
maxWidth = Math.max( maxWidth, currentWidth );
return conversion.modelToView( new Dimension( maxWidth, height ) );
}
public void install( TabPane pane ){
// nothing to do
}
public void uninstall( TabPane pane ){
// nothing to do
}
}