/* * 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.toolbar.expand; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Insets; import java.awt.Rectangle; import bibliothek.gui.DockController; import bibliothek.gui.DockStation; import bibliothek.gui.Dockable; import bibliothek.gui.dock.ExpandableToolbarItemStrategy; import bibliothek.gui.dock.ScreenDockStation; import bibliothek.gui.dock.station.screen.ScreenDockWindow; import bibliothek.gui.dock.station.screen.magnet.MagnetizedOperation; import bibliothek.gui.dock.util.PropertyValue; /** * The {@link ExpandManager} is responsible for performing global effects that * happen after a {@link ExpandableToolbarItemStrategy} changed the * {@link ExpandedState} of a {@link Dockable}. * * @author Benjamin Sigg */ public class ExpandManager{ /** the currently active strategy */ private final PropertyValue<ExpandableToolbarItemStrategy> strategy = new PropertyValue<ExpandableToolbarItemStrategy>( ExpandableToolbarItemStrategy.STRATEGY){ @Override protected void valueChanged( ExpandableToolbarItemStrategy oldValue, ExpandableToolbarItemStrategy newValue ){ if (oldValue != null){ oldValue.removeExpandedListener(listener); } if (newValue != null){ newValue.addExpandedListener(listener); } } }; /** this listener is added to the currently active {@link #strategy} */ private final ExpandableToolbarItemStrategyListener listener = new ExpandableToolbarItemStrategyListener(){ @Override public void stretched( Dockable item ){ updateLater(item); } @Override public void shrunk( Dockable item ){ updateLater(item); } @Override public void expanded( Dockable item ){ updateLater(item); } @Override public void enablementChanged( Dockable item, ExpandedState state, boolean enabled ){ // ignore } }; public ExpandManager( DockController controller ){ strategy.setProperties(controller); } private void updateLater( final Dockable item ){ EventQueue.invokeLater(new Runnable(){ @Override public void run(){ update(item); } }); } /** * Called after the {@link ExpandedState} of <code>item</code> changed. This * method will check the position and size of <code>item</code> and if * possible change the size such that it matches the preferred size of the * <code>item</code>. * * @param item * the item whose state changed */ public void update( Dockable item ){ DockStation parent = item.getDockParent(); while (parent != null){ if (parent instanceof ScreenDockStation){ update((ScreenDockStation) parent, item); } item = parent.asDockable(); if (item == null){ parent = null; } else{ parent = item.getDockParent(); } } } /** * Called if the {@link ExpandedState} of <code>child</code> or one of its * children has changed. This method should update the size of * <code>child</code> such that it has its preferred size * * @param station * the parent of <code>child</code> * @param child * the child whose state changed */ protected void update( ScreenDockStation station, Dockable child ){ final ScreenDockWindow window = station.getWindow(child); final Insets insets = window.getDockableInsets(); final Dimension preferred = child.getComponent().getPreferredSize(); final int width = insets.left + insets.right + preferred.width; final int height = insets.top + insets.bottom + preferred.height; Rectangle bounds = window.getNormalBounds(); if (bounds == null){ bounds = window.getWindowBounds(); } bounds = new Rectangle(bounds.x, bounds.y, width, height); final MagnetizedOperation operation = station.getMagnetController() .start(window); final Rectangle validated = station.getBoundaryRestriction().check( window, bounds); if (validated != null){ bounds = validated; } bounds = operation.attract(bounds); operation.stop(); if (window.isFullscreen()){ window.setNormalBounds(bounds); } else{ window.setWindowBounds(bounds); } } }