/* * 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.station.split; import bibliothek.gui.DockStation; import bibliothek.gui.Dockable; import bibliothek.gui.dock.SplitDockStation; import bibliothek.gui.dock.SplitDockStation.Orientation; import bibliothek.gui.dock.station.split.SplitDockPathProperty.Location; import bibliothek.gui.dock.station.support.PlaceholderMap; import bibliothek.util.Path; /** * A layout storing the contents of a {@link SplitDockStation}. * @author Benjamin Sigg */ public class SplitDockStationLayout { /** the root of the tree, can be <code>null</code> */ private Entry root; /** the id of the element that is put into fullscreen-mode */ private int fullscreen; /** whether the station showed a fullscreen action */ private boolean hasFullscreenAction; /** * Creates a new layout * @param root the root of the tree, can be <code>null</code> * @param fullscreen the id of the element which is in fullscreen-mode * @deprecated please use {@link #SplitDockStationLayout(Entry, int, boolean)} instead */ @Deprecated public SplitDockStationLayout( Entry root, int fullscreen ){ this( root, fullscreen, true ); } /** * Creates a new layout * @param root the root of the tree, can be <code>null</code> * @param fullscreen the id of the element which is in fullscreen-mode * @param hasFullscreenAction whether the {@link SplitDockStation} did show a fullscreen-action */ public SplitDockStationLayout( Entry root, int fullscreen, boolean hasFullscreenAction ){ this.root = root; this.fullscreen = fullscreen; this.hasFullscreenAction = hasFullscreenAction; } /** * Gets the root of the tree. * @return the root, can be <code>null</code> */ public Entry getRoot() { return root; } /** * Gets the id of the element which is in fullscreen-mode. * @return the id of the element, -1 means that no element is set to * fullscreen */ public int getFullscreen() { return fullscreen; } /** * Tells whether the {@link SplitDockStation} did show a fullscreen-action or not. This property * is only applied if a new {@link SplitDockStation} is created during loading. * @return whether to show an action or not */ public boolean hasFullscreenAction(){ return hasFullscreenAction; } /** * An entry in a tree, either a node or a leaf. * @author Benjamin Sigg */ public static abstract class Entry{ /** the parent element of this entry */ private Node parent; /** the unique id of this node */ private long id; /** placeholders that are associated with this entry */ private Path[] placeholders; /** placeholder information of a child {@link DockStation} */ private PlaceholderMap placeholderMap; /** * Create a new entry * @param placeholders the placeholders associated with this node or leaf * @param placeholderMap placeholder information of a child {@link DockStation} * @param id the unique id of this node or -1 */ public Entry( Path[] placeholders, PlaceholderMap placeholderMap, long id ){ this.placeholders = placeholders; this.placeholderMap = placeholderMap; this.id = id; } /** * Sets the parent of this entry. * @param parent the parent */ protected void setParent( Node parent ){ this.parent = parent; } /** * Gets the parent of this entry, is <code>null</code> for the * root entry. * @return the parent. */ public Node getParent() { return parent; } /** * Gets the unique id of this node. * @return the unique id or -1 */ public long getNodeId(){ return id; } /** * Returns <code>this</code> as leaf or <code>null</code>. * @return <code>this</code> or <code>null</code> */ public Leaf asLeaf(){ return null; } /** * Returns <code>this</code> as node or <code>null</code>. * @return <code>this</code> or <code>null</code> */ public Node asNode(){ return null; } /** * Whether this node or leaf is visible to the user. * @return <code>true</code> if this represents some graphical element or has a visible child */ public abstract boolean isVisible(); /** * Creates a new path property which describes the location of * this element. * @return the new path property */ public SplitDockPathProperty createPathProperty() { SplitDockPathProperty path = null; if( parent != null ){ path = parent.createPathProperty( this ); } else{ path = new SplitDockPathProperty(); } path.setLeafId( getNodeId() ); return path; } /** * Gets all the placeholders that are associated with this entry. * @return the placeholders */ public Path[] getPlaceholders(){ return placeholders; } /** * Gets the placeholder information of a potential child {@link DockStation}. * @return the placeholder map, can be <code>null</code> */ public PlaceholderMap getPlaceholderMap(){ return placeholderMap; } } /** * A leaf in a tree, describes one {@link Dockable}. * @author Benjamin Sigg */ public static class Leaf extends Entry{ /** the id of the element */ private int id; /** * Creates a new leaf * @param id the id of a {@link Dockable} or -1 * @param placeholders placeholders associated with this leaf * @param placeholderMap placeholder information of a child {@link DockStation} * @param nodeId the unique identifier of this node */ public Leaf( int id, Path[] placeholders, PlaceholderMap placeholderMap, long nodeId ){ super( placeholders, placeholderMap, nodeId ); this.id = id; } /** * Gets the id of a {@link Dockable}. * @return the id */ public int getId() { return id; } @Override public Leaf asLeaf() { return this; } @Override public boolean isVisible(){ return id != -1; } } /** * A node in a tree. * @author Benjamin Sigg */ public static class Node extends Entry{ /** whether the node is horizontal or vertical */ private Orientation orientation; /** the location of the divider */ private double divider; /** the top or left child */ private Entry childA; /** the bottom or right child */ private Entry childB; /** * Creates a new node. * @param orientation whether this node is horizontal or vertical * @param divider the location of the divider * @param childA the left or top child * @param childB the right or bottom child * @param placeholders placeholders associated with this node * @param placeholderMap placeholder information of a child {@link DockStation} * @param id the unique identifier of this node or -1 */ public Node( Orientation orientation, double divider, Entry childA, Entry childB, Path[] placeholders, PlaceholderMap placeholderMap, long id ){ super( placeholders, placeholderMap, id ); this.orientation = orientation; this.divider = divider; this.childA = childA; this.childB = childB; if( childA != null ) childA.setParent( this ); if( childB != null ) childB.setParent( this ); } @Override public Node asNode() { return this; } @Override public boolean isVisible(){ return childA.isVisible() && childB.isVisible(); } /** * Creates a new path pointing to <code>child</code> which must be * a child of this node. * @param child some child of this node * @return a new path for <code>child</code> */ public SplitDockPathProperty createPathProperty( Entry child ){ boolean childAvisible = childA.isVisible(); boolean childBvisible = childB.isVisible(); if( childAvisible && childBvisible ){ SplitDockPathProperty property = createPathProperty(); if( child == childA ){ if( orientation == Orientation.HORIZONTAL ){ property.add( Location.LEFT, divider, child.getNodeId() ); } else{ property.add( Location.TOP, divider, child.getNodeId() ); } } else if( child == childB ){ if( orientation == Orientation.HORIZONTAL ){ property.add( Location.RIGHT, 1-divider, child.getNodeId() ); } else{ property.add( Location.BOTTOM, 1-divider, child.getNodeId() ); } } return property; } Node parent = getParent(); if( parent != null ){ return parent.createPathProperty( this ); } else{ return new SplitDockPathProperty(); } } /** * Tells whether this node is horizontal or vertical. * @return the orientation */ public Orientation getOrientation() { return orientation; } /** * The location of the divider. * @return a value between 0 and 1 */ public double getDivider() { return divider; } /** * Gets the left or top child. * @return the left or top child */ public Entry getChildA() { return childA; } /** * Gets the right or bottom child. * @return the right or bottom child */ public Entry getChildB() { return childB; } } }