| /******************************************************************************* |
| * Copyright (c) 2003, 2010 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.draw2d.graph; |
| |
| import java.util.Iterator; |
| |
| import org.eclipse.draw2d.geometry.Dimension; |
| import org.eclipse.draw2d.geometry.Insets; |
| |
| /** |
| * A node in a DirectedGraph. A node has 0 or more incoming and outgoing |
| * {@link Edge}s. A node is given a width and height by the client. When a |
| * layout places the node in the graph, it will determine the node's x and y |
| * location. It may also modify the node's height. |
| * |
| * A node represents both the <EM>input</EM> and the <EM>output</EM> for a |
| * layout algorithm. The following fields are used as input to a graph layout: |
| * <UL> |
| * <LI>{@link #width} - the node's width. |
| * <LI>{@link #height} - the node's height. |
| * <LI>{@link #outgoing} - the node's outgoing edges. |
| * <LI>{@link #incoming} - the node's incoming edges. |
| * <LI>padding - the amount of space to be left around the outside of the node. |
| * <LI>{@link #incomingOffset} - the default attachment point for incoming |
| * edges. |
| * <LI>{@link #outgoingOffset} - the default attachment point for outgoing |
| * edges. |
| * <LI>parent - the parent subgraph containing this node. |
| * </UL> |
| * <P> |
| * The following fields are calculated by a graph layout and comprise the |
| * <EM>output</EM>: |
| * <UL> |
| * <LI>{@link #x} - the node's x location |
| * <LI>{@link #y} - the node's y location |
| * <LI>{@link #height} - the node's height may be stretched to match the height |
| * of other nodes |
| * </UL> |
| * |
| * @author Randy Hudson |
| * @since 2.1.2 |
| */ |
| public class Node { |
| |
| Node left, right; |
| |
| Object workingData[] = new Object[3]; |
| int workingInts[] = new int[4]; |
| |
| /** |
| * Clients may use this field to mark the Node with an arbitrary data |
| * object. |
| */ |
| public Object data; |
| |
| // used by various graph visitors |
| boolean flag; |
| |
| /** |
| * The height of this node. This value should be set prior to laying out the |
| * directed graph. Depending on the layout rules, a node's height may be |
| * expanded to match the height of other nodes around it. |
| */ |
| public int height = 40; |
| |
| /** |
| * @deprecated use {@link #setRowConstraint(int)} and |
| * {@link #getRowConstraint()} |
| */ |
| public int rowOrder = -1; |
| |
| /** |
| * The edges for which this node is the target. |
| */ |
| public EdgeList incoming = new EdgeList(); |
| |
| /** |
| * The default attachment point for incoming edges. <code>-1</code> |
| * indicates that the node's horizontal center should be used. |
| */ |
| public int incomingOffset = -1; |
| |
| // A non-decreasing number given to consecutive nodes in a Rank. |
| int index; |
| |
| // Used in Compound graphs to quickly determine whether a node is inside a |
| // subgraph. |
| int nestingIndex = -1; |
| |
| /** |
| * The edges for which this node is the source. |
| */ |
| public EdgeList outgoing = new EdgeList(); |
| |
| Insets padding; |
| private Subgraph parent; |
| int rank; |
| |
| /** |
| * @deprecated for internal use only |
| */ |
| public double sortValue; |
| |
| /** |
| * The node's outgoing offset attachment point. |
| */ |
| public int outgoingOffset = -1; |
| |
| /** |
| * The node's width. The default value is 50. |
| */ |
| public int width = 50; |
| |
| /** |
| * The node's x coordinate. |
| */ |
| public int x; |
| /** |
| * The node's y coordinate. |
| */ |
| public int y; |
| |
| /** |
| * Constructs a new node. |
| */ |
| public Node() { |
| } |
| |
| /** |
| * Constructs a node with the given data object |
| * |
| * @param data |
| * an arbitrary data object |
| */ |
| public Node(Object data) { |
| this(data, null); |
| } |
| |
| /** |
| * Constructs a node inside the given subgraph. |
| * |
| * @param parent |
| * the parent subgraph |
| */ |
| public Node(Subgraph parent) { |
| this(null, parent); |
| } |
| |
| /** |
| * Constructs a node with the given data object and parent subgraph. This |
| * node is added to the set of members for the parent subgraph |
| * |
| * @param data |
| * an arbitrary data object |
| * @param parent |
| * the parent subgraph or <code>null</code> |
| */ |
| public Node(Object data, Subgraph parent) { |
| this.data = data; |
| this.parent = parent; |
| if (parent != null) |
| parent.addMember(this); |
| } |
| |
| /** |
| * Returns the incoming attachment point. This is the distance from the left |
| * edge to the default incoming attachment point for edges. Each incoming |
| * edge may have it's own attachment setting which takes priority over this |
| * default one. |
| * |
| * @return the incoming offset |
| */ |
| public int getOffsetIncoming() { |
| if (incomingOffset == -1) |
| return width / 2; |
| return incomingOffset; |
| } |
| |
| /** |
| * Returns the outgoing attachment point. This is the distance from the left |
| * edge to the default outgoing attachment point for edges. Each outgoing |
| * edge may have it's own attachment setting which takes priority over this |
| * default one. |
| * |
| * @return the outgoing offset |
| */ |
| public int getOffsetOutgoing() { |
| if (outgoingOffset == -1) |
| return width / 2; |
| return outgoingOffset; |
| } |
| |
| /** |
| * Returns the padding for this node or <code>null</code> if the default |
| * padding for the graph should be used. |
| * |
| * @return the padding or <code>null</code> |
| */ |
| public Insets getPadding() { |
| return padding; |
| } |
| |
| /** |
| * Returns the parent Subgraph or <code>null</code> if there is no parent. |
| * Subgraphs are only for use in {@link CompoundDirectedGraphLayout}. |
| * |
| * @return the parent or <code>null</code> |
| */ |
| public Subgraph getParent() { |
| return parent; |
| } |
| |
| /** |
| * For internal use only. Returns <code>true</code> if the given node is |
| * equal to this node. This method is implemented for consitency with |
| * Subgraph. |
| * |
| * @param node |
| * the node in question |
| * @return <code>true</code> if nested |
| */ |
| boolean isNested(Node node) { |
| return node == this; |
| } |
| |
| /** |
| * Sets the padding. <code>null</code> indicates that the default padding |
| * should be used. |
| * |
| * @param padding |
| * an insets or <code>null</code> |
| */ |
| public void setPadding(Insets padding) { |
| this.padding = padding; |
| } |
| |
| /** |
| * Sets the parent subgraph. This method should not be called directly. The |
| * constructor will set the parent accordingly. |
| * |
| * @param parent |
| * the parent |
| */ |
| public void setParent(Subgraph parent) { |
| this.parent = parent; |
| } |
| |
| /** |
| * Sets the row sorting constraint for this node. By default, a node's |
| * constraint is <code>-1</code>. If two nodes have different values both >= |
| * 0, the node with the smaller constraint will be placed to the left of the |
| * other node. In all other cases no relative placement is guaranteed. |
| * |
| * @param value |
| * the row constraint |
| * @since 3.2 |
| */ |
| public void setRowConstraint(int value) { |
| this.rowOrder = value; |
| } |
| |
| /** |
| * Returns the row constraint for this node. |
| * |
| * @return the row constraint |
| * @since 3.2 |
| */ |
| public int getRowConstraint() { |
| return rowOrder; |
| } |
| |
| /** |
| * Sets the size of this node to the given dimension. |
| * |
| * @param size |
| * the new size |
| * @since 3.2 |
| */ |
| public void setSize(Dimension size) { |
| width = size.width; |
| height = size.height; |
| } |
| |
| /** |
| * @see Object#toString() |
| */ |
| public String toString() { |
| return "N(" + data + ")"; //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| Iterator iteratorNeighbors() { |
| return new Iterator() { |
| int offset; |
| EdgeList list = outgoing; |
| |
| public Object next() { |
| Edge edge = list.getEdge(offset++); |
| if (offset < list.size()) |
| return edge.opposite(Node.this); |
| if (list == outgoing) { |
| list = incoming; |
| offset = 0; |
| } else |
| list = null; |
| return edge.opposite(Node.this); |
| } |
| |
| public boolean hasNext() { |
| if (list == null) |
| return false; |
| if (offset < list.size()) |
| return true; |
| if (list == outgoing) { |
| list = incoming; |
| offset = 0; |
| } |
| return offset < list.size(); |
| } |
| |
| public void remove() { |
| throw new RuntimeException("Remove not supported"); //$NON-NLS-1$ |
| } |
| }; |
| } |
| |
| /** |
| * Returns a reference to a node located left from this one |
| * |
| * @return <code>Node</code> on the left from this one |
| * @since 3.4 |
| */ |
| public Node getLeft() { |
| return left; |
| } |
| |
| /** |
| * Returns a reference to a node located right from this one |
| * |
| * @return <code>Node</code> on the right from this one |
| * @since 3.4 |
| */ |
| public Node getRight() { |
| return right; |
| } |
| |
| } |