diff dwtx/draw2d/graph/Node.d @ 98:95307ad235d9

Added Draw2d code, still work in progress
author Frank Benoit <benoit@tionex.de>
date Sun, 03 Aug 2008 00:52:14 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/draw2d/graph/Node.d	Sun Aug 03 00:52:14 2008 +0200
@@ -0,0 +1,332 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2008 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.draw2d.graph.Node;
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.text.convert.Format;
+
+import dwtx.draw2d.geometry.Dimension;
+import dwtx.draw2d.geometry.Insets;
+import dwtx.draw2d.graph.EdgeList;
+import dwtx.draw2d.graph.Subgraph;
+import dwtx.draw2d.graph.Edge;
+
+/**
+ * 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;
+int[] workingInts;
+
+/**
+ * Clients may use this field to mark the Node with an arbitrary data object.
+ */
+public Object data;
+
+//used by various graph visitors
+bool 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;
+
+/**
+ * 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;
+
+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 this() { }
+
+/**
+ * Constructs a node with the given data object
+ * @param data an arbitrary data object
+ */
+public this(Object data) {
+    this(data, null);
+}
+
+/**
+ * Constructs a node inside the given subgraph.
+ * @param parent the parent subgraph
+ */
+public this(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 this(Object data, Subgraph parent) {
+    this.data = data;
+    this.parent = parent;
+    incoming = new EdgeList();
+    outgoing = new EdgeList();
+    workingData = new Object[3];
+    workingInts = new int[4];
+    if (parent !is 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 is -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 is -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
+ */
+bool isNested(Node node) {
+    return node is 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 Format("N({})", data ); //$NON-NLS-1$ //$NON-NLS-2$
+}
+
+Iterator iteratorNeighbors() {
+    return new class(outgoing) Iterator {
+        int offset;
+        EdgeList list;
+        this(EdgeList a){
+            list = a;
+        }
+        public Object next() {
+            Edge edge = list.getEdge(offset++);
+            if (offset < list.size())
+                return edge.opposite(this.outer);
+            if (list is outgoing) {
+                list = incoming;
+                offset = 0;
+            } else
+                list = null;
+            return edge.opposite(this.outer);
+        }
+
+        public bool hasNext() {
+            if (list is null)
+                return false;
+            if (offset < list.size())
+                return true;
+            if (list is 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;
+}
+
+}