/* * 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) 2012 Herve Guillaume, 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 * * Herve Guillaume * rvguillaume@hotmail.com * FR - France * * Benjamin Sigg * benjamin_sigg@gmx.ch * CH - Switzerland */ package bibliothek.gui.dock.station.toolbar; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.LayoutManager2; import javax.swing.JComponent; import bibliothek.gui.DockController; import bibliothek.gui.Orientation; import bibliothek.gui.Position; import bibliothek.gui.dock.ToolbarContainerDockStation; import bibliothek.gui.dock.station.span.Span; import bibliothek.gui.dock.station.span.SpanFactory; import bibliothek.gui.dock.station.support.ListSpanStrategy; import bibliothek.gui.dock.themes.ThemeManager; /** * The {@link LayoutManager2} used by a {@link ToolbarContainerDockStation}, this {@link LayoutManager2} * uses the current {@link SpanFactory} to add gaps between {@link Component}s if necessary. * @author Benjamin Sigg */ public class ToolbarContainerLayoutManager implements LayoutManager2{ private JComponent parent; private ToolbarContainerDockStation station; private ListSpanStrategy spans; /** * Creates a new layout manager * @param parent the panel using this layout manager * @param station the station showing <code>panel</code> */ public ToolbarContainerLayoutManager( JComponent parent, ToolbarContainerDockStation station ){ this.parent = parent; this.station = station; spans = createSpans(); } /** * Sets the {@link DockController} in whose realm this layout manager is used. * @param controller the controller, can be <code>null</code> */ public void setController( DockController controller ){ spans.setController( controller ); } /** * Tells this layout manager which {@link Span}s have to mutate. * @param info information about the item that is currently dropped */ public void setDrawing( ToolbarContainerDropInfo info ){ if( info == null ){ spans.untease(); } else{ int index = info.getIndex(); Position position = info.getSideDockableBeneathMouse(); if( position == Position.SOUTH || position == Position.EAST ){ index++; } spans.tease( index ); if( station.getOrientation() == Orientation.HORIZONTAL ){ spans.size( index, info.getItem().getComponent().getWidth() ); } else{ spans.size( index, info.getItem().getComponent().getHeight() ); } } } private ListSpanStrategy createSpans(){ return new ListSpanStrategy( ThemeManager.SPAN_FACTORY + ".toolbar.container", station ){ @Override protected void spanResized(){ parent.revalidate(); } @Override protected boolean isHorizontal(){ return station.getOrientation() == Orientation.HORIZONTAL; } @Override protected int getNumberOfDockables(){ return station.getDockableCount(); } }; } @Override public void addLayoutComponent( String name, Component comp ){ spans.reset(); } @Override public void removeLayoutComponent( Component comp ){ spans.reset(); } @Override public Dimension maximumLayoutSize( Container target ){ return preferredLayoutSize( target ); } @Override public Dimension preferredLayoutSize( Container parent ){ if( station.getOrientation() == Orientation.VERTICAL ){ int width = spans.getTeasing(); int height = 0; for( int i = 0, n = parent.getComponentCount(); i<n; i++ ){ Dimension size = parent.getComponent( i ).getPreferredSize(); width = Math.max( size.width, width ); height += size.height; height += spans.getGap( i ); } height += spans.getGap( parent.getComponentCount() ); return new Dimension( width, height ); } else{ int width = 0; int height = spans.getTeasing(); for( int i = 0, n = parent.getComponentCount(); i<n; i++ ){ Dimension size = parent.getComponent( i ).getPreferredSize(); height = Math.max( size.height, height ); width += size.width; width += spans.getGap( i ); } width += spans.getGap( parent.getComponentCount() ); return new Dimension( width, height ); } } @Override public void layoutContainer( Container parent ){ Dimension preferred = preferredLayoutSize( parent ); int gaps = 0; for( int i = 0, n = parent.getComponentCount(); i <= n; i++ ){ gaps += spans.getGap( i ); } if( station.getOrientation() == Orientation.HORIZONTAL ){ if( preferred.width > gaps ){ float factor = parent.getWidth() / (float)(preferred.width - gaps); if( factor > 1 ){ factor = 1; } else if( factor < 0 ){ factor = 0; } int x = 0; int height = parent.getHeight(); for( int i = 0, n = parent.getComponentCount(); i<n; i++ ){ x += spans.getGap( i ); Component child = parent.getComponent( i ); Dimension size = child.getPreferredSize(); int width = (int)(size.width * factor); child.setBounds( x, 0, width, Math.min( height, size.height ) ); x += width; } } } else{ if( preferred.height > gaps ){ float factor = parent.getHeight() / (float)(preferred.height - gaps); if( factor > 1 ){ factor = 1; } else if( factor < 0 ){ factor = 0; } int y = 0; int width = parent.getWidth(); for( int i = 0, n = parent.getComponentCount(); i<n; i++ ){ y += spans.getGap( i ); Component child = parent.getComponent( i ); Dimension size = child.getPreferredSize(); int height = (int)(size.height * factor); child.setBounds( 0, y, Math.min( width, size.width ), height ); y += height; } } } } @Override public Dimension minimumLayoutSize( Container parent ){ return preferredLayoutSize( parent ); } @Override public void addLayoutComponent( Component comp, Object constraints ){ spans.reset(); } @Override public float getLayoutAlignmentX( Container target ){ return 0.5f; } @Override public float getLayoutAlignmentY( Container target ){ return 0.5f; } @Override public void invalidateLayout( Container target ){ // ignore } }