All Downloads are FREE. Search and download functionalities are using the official Maven repository.

bibliothek.gui.dock.common.mode.station.CScreenDockStationHandle Maven / Gradle / Ivy

The newest version!
/*
 * 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) 2010 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
 * [email protected]
 * CH - Switzerland
 */
package bibliothek.gui.dock.common.mode.station;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import bibliothek.gui.DockController;
import bibliothek.gui.DockStation;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.ScreenDockStation;
import bibliothek.gui.dock.common.CLocation;
import bibliothek.gui.dock.common.CStation;
import bibliothek.gui.dock.common.intern.station.CScreenDockStation;
import bibliothek.gui.dock.common.location.CExternalizedLocation;
import bibliothek.gui.dock.common.location.CMaximalExternalizedLocation;
import bibliothek.gui.dock.common.mode.CExternalizedModeArea;
import bibliothek.gui.dock.common.mode.CLocationMode;
import bibliothek.gui.dock.common.mode.CLocationModeManager;
import bibliothek.gui.dock.common.mode.CMaximizedMode;
import bibliothek.gui.dock.common.mode.CMaximizedModeArea;
import bibliothek.gui.dock.facile.mode.ExternalizedMode;
import bibliothek.gui.dock.facile.mode.Location;
import bibliothek.gui.dock.facile.mode.LocationMode;
import bibliothek.gui.dock.facile.mode.LocationModeEvent;
import bibliothek.gui.dock.facile.mode.MaximizedMode;
import bibliothek.gui.dock.facile.mode.MaximizedModeArea;
import bibliothek.gui.dock.facile.mode.ModeArea;
import bibliothek.gui.dock.facile.mode.ModeAreaListener;
import bibliothek.gui.dock.layout.DockableProperty;
import bibliothek.gui.dock.station.screen.ScreenDockProperty;
import bibliothek.gui.dock.station.screen.ScreenDockStationListener;
import bibliothek.gui.dock.station.screen.ScreenDockWindow;
import bibliothek.gui.dock.support.mode.AffectedSet;
import bibliothek.gui.dock.util.DockUtilities;

/**
 * Connection between a {@link ScreenDockStation} and the {@link CExternalizedModeArea} interface.
 * @author Benjamin Sigg
 */
public class CScreenDockStationHandle {
	/** the station handled by this handle */
	private CStation station;
	
	/** Representation of this as {@link CExternalizedModeArea} */
	private External external = new External();
	
	/** Representation of this as {@link CMaximizedModeArea} */
	private Maximal maximal = new Maximal();
	
	/** the mode owning {@link #external} */
	private LocationMode externalMode;
	
	/** the mode owning {@link #maximal} */
	private CMaximizedMode maximizedMode;
	
	/** the manager handling all modes */
	private CLocationModeManager manager;
	
	/**
	 * Creates a new handle
	 * @param station the station which is handled by this handle, not null
	 * @param manager the manager handling all modes, not null
	 */
	public CScreenDockStationHandle( CStation station, CLocationModeManager manager ){
		this.station = station;
		this.manager = manager;
		
		station.getStation().addScreenDockStationListener( new ScreenDockStationListener() {
			public void windowRegistering( ScreenDockStation station, Dockable dockable, ScreenDockWindow window ) {
				// ignore
			}
			
			public void windowDeregistering( ScreenDockStation station, Dockable dockable, ScreenDockWindow window ) {
				// ignore
			}
			
			public void fullscreenChanged( ScreenDockStation station, Dockable dockable ) {
				ModeAreaListener[] listeners;
				ModeArea source;
				
				if( station.isFullscreen( dockable )){
					source = maximal;
					listeners = maximal.listeners();
				}
				else{
					source = external;
					listeners = external.listeners();
				}
				
				Set dockables = new HashSet();
				dockables.add( dockable );
				for( ModeAreaListener listener : listeners ){
					listener.internalLocationChange( source, dockables );
				}
			}
		});
	}

	/**
	 * Gets the representation of this as {@link CExternalizedModeArea}.
	 * @return the representation
	 */
	public CExternalizedModeArea getExternalizedModeArea(){
		return external;
	}
	
	/**
	 * Gets the representation of this as {@link CMaximizedModeArea}.
	 * @return the representation
	 */
	public CMaximizedModeArea getMaximizedModeArea(){
		return maximal;
	}
	
	/**
	 * Gets a {@link CLocation} describing the location of dockable on the station of this handle.
	 * @param dockable some child
	 * @return the location
	 */
	public CLocation getCLocation( Dockable dockable ){
		DockableProperty property = DockUtilities.getPropertyChain( station.getStation(), dockable );
		return expand( property );
	}

	/**
	 * Assuming dockable would be at location location if it would be a child of this station, 
	 * returns the CLocation that matches location.
	 * @param dockable some element which may or may not be a child of this station
	 * @param location the location dockable would have if it would be a child of this station
	 * @return the location or null if location.getLocation() is not valid
	 */
	public CLocation getCLocation( Dockable dockable, Location location ){
		DockableProperty property = location.getLocation();
		if( property == null )
			return null;
		
		return expand( property );
	}
	
	private CLocation expand( DockableProperty property ){
		if( property instanceof ScreenDockProperty ){
			ScreenDockProperty screen = (ScreenDockProperty)property;
			
			CLocation result;
			if( screen.isFullscreen() ){
				result = new CMaximalExternalizedLocation( screen.getX(), screen.getY(), screen.getWidth(), screen.getHeight() );
			}
			else{
				result = new CExternalizedLocation( screen.getX(), screen.getY(), screen.getWidth(), screen.getHeight() );
			}
			
			if( property.getSuccessor() != null ){
				return result.expandProperty( station.getStation().getController(), property.getSuccessor() );
			}
			else{
				return result;
			}
		}
		return null;
	}
	
	/**
	 * Represents a {@link CScreenDockStationHandle} as {@link CExternalizedModeArea}.
	 * @author Benjamin Sigg
	 */
	protected class External implements CExternalizedModeArea{
		private List listeners = new ArrayList();
		
		public DockableProperty getLocation( Dockable child ) {
			return DockUtilities.getPropertyChain( getStation(), child );
		}
		
		public boolean autoDefaultArea() {
			return true;
		}
		
		public boolean isLocationRoot(){
			return true;
		}

		public boolean setLocation( Dockable dockable, DockableProperty location, AffectedSet set ) {
			set.add( dockable );
			
			if( isChild( dockable )){
				if( location != null ){
					station.getStation().move( dockable, location );
				}
				return true;
			}
			else{
				boolean acceptable = DockUtilities.acceptable( getStation(), dockable );
				if( !acceptable ){
					return false;
				}
				
				if( location != null ){
					if( !station.getStation().drop( dockable, location )){
						location = null;
					}
				}
				if( location == null ){
					station.getStation().drop( dockable );
				}
				return true;
			}
		}

		public void addModeAreaListener( ModeAreaListener listener ) {
			listeners.add( listener );
		}

		public void removeModeAreaListener( ModeAreaListener listener ) {
			listeners.remove( listener );
		}
		
		/**
		 * Gets all the listeners that are registered at this area.
		 * @return all listeners
		 */
		public ModeAreaListener[] listeners(){
			return listeners.toArray( new ModeAreaListener[ listeners.size() ] );
		}

		public DockStation getStation() {
			return station.getStation();
		}

		public String getUniqueId() {
			return station.getUniqueId();
		}

		public boolean isChild( Dockable dockable ) {
			return dockable.getDockParent() == station.getStation() && !station.getStation().isFullscreen( dockable );
		}

		public boolean respectWorkingAreas() {
			return false;
		}

		public void setController( DockController controller ) {
			// ignore
		}
		
		public void setMode( LocationMode mode ){
			externalMode = mode;	
		}

		public CLocation getCLocation( Dockable dockable ) {
			return CScreenDockStationHandle.this.getCLocation( dockable );
		}

		public CLocation getCLocation( Dockable dockable, Location location ) {
			return CScreenDockStationHandle.this.getCLocation( dockable, location );
		}
	}
	
	/**
	 * A representation of {@link CScreenDockStationHandle} as {@link CMaximizedModeArea}.
	 * @author Benjamin Sigg
	 */
	protected class Maximal implements CMaximizedModeArea{
		private List listeners = new ArrayList();

		public Dockable[] getMaximized() {
			return station.getStation().getFullscreenChildren();
		}

		public boolean isRepresenting( DockStation station ) {
			return CScreenDockStationHandle.this.station.getStation() == station;
		}
		
		public boolean autoDefaultArea() {
			return false;
		}
		
		public boolean isLocationRoot(){
			return true;
		}

		public DockableProperty getLocation( Dockable child ){
			return DockUtilities.getPropertyChain( getStation(), child );
		}
		
		public Runnable onApply( LocationModeEvent event ) {
			if( event.isDone() )
				return null;
			
			Location location = event.getLocation();
        	Dockable dockable = event.getDockable();
			
			if( event.getMode().getUniqueIdentifier().equals( ExternalizedMode.IDENTIFIER )){
				CLocationMode last = manager.getCurrentMode( dockable );
				CLocationMode secondLast = manager.getPreviousMode( dockable );

				if( last != null && secondLast != null ){
					if( ExternalizedMode.IDENTIFIER.equals( secondLast.getUniqueIdentifier() ) &&
							MaximizedMode.IDENTIFIER.equals( last.getUniqueIdentifier() )){

						MaximizedModeArea area = maximizedMode.get( location.getRoot() );

						if( area == this ){
							dockable = maximizedMode.getMaximizingElement( dockable );
							
							area.setMaximized( dockable, false, null, event.getAffected() );
							event.done(true);
							return null;
		                }
		            }
		        }
			}
			
			return null;
		}

		public Runnable onApply( LocationModeEvent event, Dockable replacement ) {
			return null;
		}
		
		public void prepareApply( Dockable dockable, Location history, AffectedSet set ){
			// ignore
		}
		
		public LocationMode getUnmaximizedMode(){
			return externalMode;
		}

		public void setMaximized( Dockable dockable, boolean maximized, Location history, AffectedSet set ){
			ScreenDockStation station = getStation();
			DockStation parent = dockable.getDockParent();
			
			if( maximized ){
				if( parent == station ){
					station.setFullscreen( dockable, true );
				}
				else{
					Dockable child = DockUtilities.getDirectChild( station, dockable );
					if( child == null ){
						throw new IllegalArgumentException( "dockable not a child of this station" );
					}
					if( !parent.canDrag( dockable )){
						throw new IllegalArgumentException( "cannot drag dockable from its parent" );
					}
					parent.drag( dockable );
					if( !station.drop( dockable, child ) ){
						throw new IllegalStateException( "cannot drop dockable on this station" );
					}
					station.setFullscreen( dockable, true );
				}
			}
			else{
				if( parent == station ){
					station.setFullscreen( dockable, false );
				}
				else{
					Dockable child = DockUtilities.getDirectChild( station, dockable );
					ScreenDockProperty location = station.getLocation( child, dockable );
					
					if( !parent.canDrag( dockable )){
						throw new IllegalArgumentException( "cannot drag dockable from its current parent" );
					}
					location.setFullscreen( false );
					if( !station.drop( dockable, location, true )){
						throw new IllegalStateException( "could not drop dockable on this station" );
					}
				}
			}
		}

		public void addModeAreaListener( ModeAreaListener listener ) {
			listeners.add( listener );
		}

		public void removeModeAreaListener( ModeAreaListener listener ) {
			listeners.remove( listener );
		}
		
		/**
		 * Gets all the listeners that are registered at this area.
		 * @return all listeners
		 */
		public ModeAreaListener[] listeners(){
			return listeners.toArray( new ModeAreaListener[ listeners.size() ] );
		}
		
		public ScreenDockStation getStation() {
			return station.getStation();
		}

		public String getUniqueId() {
			return station.getUniqueId();
		}

		public boolean isChild( Dockable dockable ) {
			ScreenDockStation station = getStation();
			return dockable.getDockParent() == station && station.isFullscreen( dockable );
		}

		public boolean respectWorkingAreas() {
			return false;
		}

		public void setController( DockController controller ) {
			// ignore
		}
		
		public void setMode( LocationMode mode ){
			maximizedMode = (CMaximizedMode)mode;
		}

		public CLocation getCLocation( Dockable dockable ) {
			return CScreenDockStationHandle.this.getCLocation( dockable );
		}

		public CLocation getCLocation( Dockable dockable, Location location ) {
			return CScreenDockStationHandle.this.getCLocation( dockable, location );
		}
		
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy