bibliothek.gui.dock.station.screen.magnet
Class StickMagnetGraph

java.lang.Object
  extended by bibliothek.gui.dock.station.screen.magnet.StickMagnetGraph

public class StickMagnetGraph
extends Object

The StickMagnetGraph is a helper class for a MagnetStrategy. The StickMagnetGraph is a directed graph without cycles telling which moved ScreenDockWindow affects which other ScreenDockWindow, the graph is created depending on the stickiness of two windows.

Author:
Benjamin Sigg

Nested Class Summary
protected  class StickMagnetGraph.DefaultEdge
          Default implementation of StickMagnetGraph.Edge.
protected  class StickMagnetGraph.DefaultNode
          The default implementation of StickMagnetGraph.Node
static interface StickMagnetGraph.Edge
          Represents an edge between two StickMagnetGraph.Nodes of a graph.
static interface StickMagnetGraph.Node
          Represents one node of the graph.
static interface StickMagnetGraph.Visitor
          A StickMagnetGraph.Visitor can be used to visit all the nodes of the graph.
 
Constructor Summary
StickMagnetGraph(MagnetController controller, MagnetRequest request)
           
 
Method Summary
protected  void buildConstraints()
          Makes an initial guess telling which node has to be resized by how much.
 boolean depends(ScreenDockWindow window, MagnetRequest.Side side)
          Tells whether the side side of window will be moved if the root window is moved at side.
protected  void executeConstraints()
          Reshapes all nodes except the root node according to StickMagnetGraph.Node.getConstraints().
protected  void expand(int index, StickMagnetGraph.DefaultNode[] nodes, ScreenDockWindow[] windows)
          Builds the entire stickiness graph using a breath first search algorithm.
 MagnetController getController()
          Gets information about all known ScreenDockWindows.
protected  StickMagnetGraph.DefaultEdge[] getEdgesByDistance()
          Gets all edges of this graph ordered by the distance of their target node to the root node.
 MagnetRequest getRequest()
          Gets information about the moved ScreenDockWindow.
 StickMagnetGraph.Node getRoot()
          Gets the root node of the graph.
protected  void hardPush(MagnetRequest.Side side)
          Starting at the root node, this method follows all StickMagnetGraph.Edges going into direction side and sets the hard flag on side and on MagnetRequest.Side.opposite() on all StickMagnetGraph.Node.getConstraints()s it encounters.
 void moveAndResizeNeighbors()
          Compares the initial location and side of the root ScreenDockWindow with its current shape and reshapes all neighbors such that with the resulting boundaries the same graph as this would be created.
 void moveNeighbors()
          Compares the initial location of the root ScreenDockWindow with its current location and moves all neighbors by the same amount.
protected  MagnetRequest.Side relation(ScreenDockWindow moved, ScreenDockWindow fixed)
          Gets the relation of moved to fixed.
protected  void resizeRipple(StickMagnetGraph.Node node, MagnetRequest.Side topleft)
          Starting from the resized node node this method distributes resizing over a chain of nodes.
 String toString()
           
 void unmark()
          Calls StickMagnetGraph.Node.unmark() on all nodes of this graph
protected  void validateConstraints()
          Tries to ensure that the modifications described in StickMagnetGraph.Node.getConstraints() can be achieved.
protected  void validateHardConstraints()
          Ensures that if one side of an StickMagnetGraph.Edge is hard, then the other side is hard as well.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

StickMagnetGraph

public StickMagnetGraph(MagnetController controller,
                        MagnetRequest request)
Method Detail

getRoot

public StickMagnetGraph.Node getRoot()
Gets the root node of the graph. The root node has no ingoing edges and its window is the same object as MagnetRequest.getWindow(). The root node is created the first time this method is called, it is then cached.

Returns:
the root node, never null

getController

public MagnetController getController()
Gets information about all known ScreenDockWindows.

Returns:
the information, not null

getRequest

public MagnetRequest getRequest()
Gets information about the moved ScreenDockWindow.

Returns:
the information, not null

toString

public String toString()
Overrides:
toString in class Object

unmark

public void unmark()
Calls StickMagnetGraph.Node.unmark() on all nodes of this graph


expand

protected void expand(int index,
                      StickMagnetGraph.DefaultNode[] nodes,
                      ScreenDockWindow[] windows)
Builds the entire stickiness graph using a breath first search algorithm.

Parameters:
index - the node whose neighbors have to be found by this method
nodes - an array containing all nodes that may be created. An entry of null at index a indicates that the ScreenDockWindow in windows at index a is not yet part of the graph
windows - all the windows of the ScreenDockStation

relation

protected MagnetRequest.Side relation(ScreenDockWindow moved,
                                      ScreenDockWindow fixed)
Gets the relation of moved to fixed. The relation is null if the two windows to not stick together.

Parameters:
moved - the window that was moved
fixed - the window that was not moved
Returns:
if fixed depends on moved: the side at which fixed stays, null if fixed does not depend on moved

moveNeighbors

public void moveNeighbors()
Compares the initial location of the root ScreenDockWindow with its current location and moves all neighbors by the same amount. This method does not change the size of any window.


moveAndResizeNeighbors

public void moveAndResizeNeighbors()
Compares the initial location and side of the root ScreenDockWindow with its current shape and reshapes all neighbors such that with the resulting boundaries the same graph as this would be created. In general this method preferres to change only the position of ScreenDockWindows, the method is however free to change the size as well if it looks like a good choice.


getEdgesByDistance

protected StickMagnetGraph.DefaultEdge[] getEdgesByDistance()
Gets all edges of this graph ordered by the distance of their target node to the root node.

Returns:
the edges

buildConstraints

protected void buildConstraints()
Makes an initial guess telling which node has to be resized by how much. This means that the constraints of the nodes are set.


hardPush

protected void hardPush(MagnetRequest.Side side)
Starting at the root node, this method follows all StickMagnetGraph.Edges going into direction side and sets the hard flag on side and on MagnetRequest.Side.opposite() on all StickMagnetGraph.Node.getConstraints()s it encounters.

Parameters:
side - the direction to travel

validateHardConstraints

protected void validateHardConstraints()
Ensures that if one side of an StickMagnetGraph.Edge is hard, then the other side is hard as well.


validateConstraints

protected void validateConstraints()
Tries to ensure that the modifications described in StickMagnetGraph.Node.getConstraints() can be achieved. For example a constraint resulting in a negative width or height of a ScreenDockWindow can never be achieved.
The default implementation tries to smooth out resizes by distributing the changes to many windows. Note that truelly invalid boundaries will be catched and processed by the BoundaryRestriction, which cannot be influenced by the StickMagnetGraph.
Implementations should also pay attention to StickMagnetGraphConstraint.isHard(MagnetRequest.Side) and not modify hard sides.
Note that while the root window has a StickMagnetGraphConstraint, that constraint is actually ignored.


resizeRipple

protected void resizeRipple(StickMagnetGraph.Node node,
                            MagnetRequest.Side topleft)
Starting from the resized node node this method distributes resizing over a chain of nodes. All the affected sides are set to hard to prevent further modifications. Resizing stops at any hard side.

Parameters:
node - the node that was resized
topleft - the direction into which the resize operation should ripple, the operation will also ripple in the opposite direction

executeConstraints

protected void executeConstraints()
Reshapes all nodes except the root node according to StickMagnetGraph.Node.getConstraints().


depends

public boolean depends(ScreenDockWindow window,
                       MagnetRequest.Side side)
Tells whether the side side of window will be moved if the root window is moved at side. This means that there is a path from the root window at side to window at side going only in directions side and MagnetRequest.Side.opposite().

Parameters:
window - the window to check
side - the side that might be affected
Returns:
true if side is affected by the root window