You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by tv...@apache.org on 2009/10/05 17:59:56 UTC
svn commit: r821885 - in
/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk: TreeView.java
content/TreeViewNodeEditor.java content/TreeViewNodeRenderer.java
skin/terra/TerraTreeViewSkin.java
Author: tvolkert
Date: Mon Oct 5 15:59:55 2009
New Revision: 821885
URL: http://svn.apache.org/viewvc?rev=821885&view=rev
Log:
PIVOT-305 :: Added path to TreeView.NodeRenderer interface
Modified:
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TreeView.java
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeViewNodeEditor.java
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeViewNodeRenderer.java
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraTreeViewSkin.java
Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TreeView.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TreeView.java?rev=821885&r1=821884&r2=821885&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TreeView.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TreeView.java Mon Oct 5 15:59:55 2009
@@ -89,9 +89,37 @@
* Tree view node renderer interface.
*/
public interface NodeRenderer extends Renderer {
- public void render(Object node, TreeView treeView, boolean expanded,
- boolean selected, NodeCheckState checkState, boolean highlighted,
- boolean disabled);
+ /**
+ * Prepares the renderer for layout or paint.
+ *
+ * @param node
+ * The node value to render, or <tt>null</tt> if called to calculate
+ * preferred height for skins that assume a fixed renderer height.
+ *
+ * @param path
+ * The path to the node being rendered, or <tt>null</tt> if
+ * <tt>node</tt> is <tt>null</tt>.
+ *
+ * @param treeView
+ * The tree view that contains the node.
+ *
+ * @param expanded
+ * <tt>true</tt> if the node is expanded; <tt>false</tt> otherwise.
+ *
+ * @param selected
+ * <tt>true</tt> if the node is selected; <tt>false</tt> otherwise.
+ *
+ * @param checkState
+ * The node's {@linkplain NodeCheckState check state}.
+ *
+ * @param highlighted
+ * <tt>true</tt> if the node is highlighted; <tt>false</tt> otherwise.
+ *
+ * @param disabled
+ * <tt>true</tt> if the node is disabled; <tt>false</tt> otherwise.
+ */
+ public void render(Object node, Path path, TreeView treeView, boolean expanded,
+ boolean selected, NodeCheckState checkState, boolean highlighted, boolean disabled);
}
/**
Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeViewNodeEditor.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeViewNodeEditor.java?rev=821885&r1=821884&r2=821885&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeViewNodeEditor.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeViewNodeEditor.java Mon Oct 5 15:59:55 2009
@@ -255,7 +255,7 @@
// Render the node data
TreeViewNodeRenderer nodeRenderer = (TreeViewNodeRenderer)treeView.getNodeRenderer();
- nodeRenderer.render(nodeData, treeView, false, false,
+ nodeRenderer.render(nodeData, path, treeView, false, false,
TreeView.NodeCheckState.UNCHECKED, false, false);
nodeRenderer.setSize(nodeBounds.width, nodeBounds.height);
Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeViewNodeRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeViewNodeRenderer.java?rev=821885&r1=821884&r2=821885&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeViewNodeRenderer.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/content/TreeViewNodeRenderer.java Mon Oct 5 15:59:55 2009
@@ -19,6 +19,7 @@
import java.awt.Color;
import java.awt.Font;
+import org.apache.pivot.collections.Sequence.Tree.Path;
import org.apache.pivot.wtk.Bounds;
import org.apache.pivot.wtk.BoxPane;
import org.apache.pivot.wtk.HorizontalAlignment;
@@ -28,7 +29,6 @@
import org.apache.pivot.wtk.VerticalAlignment;
import org.apache.pivot.wtk.media.Image;
-
/**
* Default tree node renderer, which knows how to render instances of
* {@link TreeNode} and {@link Image}. Anything else will be rendered as a
@@ -65,7 +65,7 @@
}
@Override
- public void render(Object node, TreeView treeView, boolean expanded,
+ public void render(Object node, Path path, TreeView treeView, boolean expanded,
boolean selected, TreeView.NodeCheckState checkState,
boolean highlighted, boolean disabled) {
if (node != null) {
Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraTreeViewSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraTreeViewSkin.java?rev=821885&r1=821884&r2=821885&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraTreeViewSkin.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraTreeViewSkin.java Mon Oct 5 15:59:55 2009
@@ -23,6 +23,8 @@
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.geom.GeneralPath;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
import org.apache.pivot.collections.ArrayList;
import org.apache.pivot.collections.List;
@@ -46,7 +48,6 @@
import org.apache.pivot.wtk.TreeViewSelectionListener;
import org.apache.pivot.wtk.skin.ComponentSkin;
-
/**
* Tree view skin.
*/
@@ -68,6 +69,107 @@
}
/**
+ * Iterates through the visible nodes. For callers who wish to know the
+ * path of each visible node, using this iterator will be much more
+ * efficient than manually iterating over the visible nodes and calling
+ * <tt>getPath()</tt> on each node.
+ */
+ protected final class VisibleNodeIterator implements Iterator<NodeInfo> {
+ private int index;
+ private int end;
+
+ private Path path = null;
+ private NodeInfo previous = null;
+
+ public VisibleNodeIterator() {
+ this(0, visibleNodes.getLength() - 1);
+ }
+
+ /**
+ * Creates a new visible node iterator that will iterate over a portion
+ * of the visible nodes list (useful during painting).
+ *
+ * @param start
+ * The start index, inclusive
+ *
+ * @param end
+ * The end index, inclusive
+ */
+ public VisibleNodeIterator(int start, int end) {
+ if (start < 0
+ || end >= visibleNodes.getLength()
+ || start > end) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ this.index = start;
+ this.end = end;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean hasNext() {
+ return (index <= end);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NodeInfo next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ NodeInfo next = visibleNodes.get(index++);
+
+ if (path == null) {
+ // First iteration
+ path = next.getPath();
+ } else if (next.parent == previous) {
+ // Child of previous visible node
+ path.add(0);
+ } else {
+ int n = path.getLength();
+ while (next.parent != previous.parent) {
+ path.remove(--n, 1);
+ previous = previous.parent;
+ }
+
+ int tail = path.get(n - 1);
+ path.update(n - 1, tail + 1);
+ }
+
+ previous = next;
+
+ return next;
+ }
+
+ /**
+ * This operation is not supported by this iterator.
+ *
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Gets the path of the node last returned by a call to {@link #next()}.
+ *
+ * @return
+ * The path to the node, or <tt>null</tt> if <tt>next()</tt> has not
+ * yet been called.
+ */
+ public Path getPath() {
+ return path;
+ }
+ }
+
+ /**
* An internal data structure that keeps track of skin-related metadata
* for a tree node. The justification for the existence of this class lies
* in the <tt>visibleNodes</tt> data structure, which is a flat list of
@@ -83,15 +185,15 @@
*/
protected static class NodeInfo {
// Core metadata
- protected final TreeView treeView;
- protected final BranchInfo parent;
- protected final Object data;
- protected final int depth;
+ final TreeView treeView;
+ final BranchInfo parent;
+ final Object data;
+ final int depth;
// Cached fields. Note that this is maintained as a bitmask in favor of
// separate properties because it allows us to easily clear any cached
// field for all nodes in one common method. See #clearField(byte)
- protected byte fields = 0;
+ byte fields = 0;
public static final byte HIGHLIGHTED_MASK = 1 << 0;
public static final byte SELECTED_MASK = 1 << 1;
@@ -104,7 +206,7 @@
| CHECK_STATE_MIXED_MASK;
@SuppressWarnings("unchecked")
- public NodeInfo(TreeView treeView, BranchInfo parent, Object data) {
+ private NodeInfo(TreeView treeView, BranchInfo parent, Object data) {
this.treeView = treeView;
this.parent = parent;
this.data = data;
@@ -128,7 +230,7 @@
}
@SuppressWarnings("unchecked")
- public static NodeInfo createNew(TreeView treeView, BranchInfo parent, Object data) {
+ private static NodeInfo newInstance(TreeView treeView, BranchInfo parent, Object data) {
NodeInfo nodeInfo = null;
if (data instanceof List<?>) {
@@ -249,13 +351,13 @@
* An internal data structure that keeps track of skin-related metadata
* for a tree branch.
*/
- protected static class BranchInfo extends NodeInfo {
+ protected static final class BranchInfo extends NodeInfo {
// Core skin metadata
- protected List<NodeInfo> children = null;
+ private List<NodeInfo> children = null;
public static final byte EXPANDED_MASK = 1 << 6;
- public BranchInfo(TreeView treeView, BranchInfo parent, List<Object> data) {
+ private BranchInfo(TreeView treeView, BranchInfo parent, List<Object> data) {
super(treeView, parent, data);
}
@@ -277,7 +379,7 @@
for (int i = 0; i < count; i++) {
Object nodeData = data.get(i);
- NodeInfo childNodeInfo = NodeInfo.createNew(treeView, this, nodeData);
+ NodeInfo childNodeInfo = NodeInfo.newInstance(treeView, this, nodeData);
children.add(childNodeInfo);
}
}
@@ -382,13 +484,14 @@
int preferredWidth = 0;
- for (int i = 0, n = visibleNodes.getLength(); i < n; i++) {
- NodeInfo nodeInfo = visibleNodes.get(i);
+ VisibleNodeIterator visibleNodeIterator = new VisibleNodeIterator();
+ while (visibleNodeIterator.hasNext()) {
+ NodeInfo nodeInfo = visibleNodeIterator.next();
int nodeWidth = (nodeInfo.depth - 1) * (indent + spacing);
- nodeRenderer.render(nodeInfo.data, treeView, false, false,
- TreeView.NodeCheckState.UNCHECKED, false, false);
+ nodeRenderer.render(nodeInfo.data, visibleNodeIterator.getPath(), treeView,
+ false, false, TreeView.NodeCheckState.UNCHECKED, false, false);
nodeWidth += nodeRenderer.getPreferredWidth(-1);
preferredWidth = Math.max(preferredWidth, nodeWidth);
@@ -455,8 +558,9 @@
int nodeY = nodeStart * (nodeHeight + VERTICAL_SPACING);
- for (int i = nodeStart; i <= nodeEnd; i++) {
- NodeInfo nodeInfo = visibleNodes.get(i);
+ VisibleNodeIterator visibleNodeIterator = new VisibleNodeIterator(nodeStart, nodeEnd);
+ while (visibleNodeIterator.hasNext()) {
+ NodeInfo nodeInfo = visibleNodeIterator.next();
boolean expanded = false;
boolean highlighted = nodeInfo.isHighlighted();
@@ -568,8 +672,8 @@
// Paint the node data
Graphics2D rendererGraphics = (Graphics2D)graphics.create(nodeX, nodeY,
nodeWidth, nodeHeight);
- nodeRenderer.render(nodeInfo.data, treeView, expanded, selected,
- checkState, highlighted, disabled);
+ nodeRenderer.render(nodeInfo.data, visibleNodeIterator.getPath(), treeView,
+ expanded, selected, checkState, highlighted, disabled);
nodeRenderer.setSize(nodeWidth, nodeHeight);
nodeRenderer.paint(rendererGraphics);
rendererGraphics.dispose();
@@ -1034,7 +1138,7 @@
protected int getNodeHeight() {
TreeView treeView = (TreeView)getComponent();
TreeView.NodeRenderer nodeRenderer = treeView.getNodeRenderer();
- nodeRenderer.render(null, treeView, false, false,
+ nodeRenderer.render(null, null, treeView, false, false,
TreeView.NodeCheckState.UNCHECKED, false, false);
int nodeHeight = nodeRenderer.getPreferredHeight(-1);
@@ -1049,7 +1153,7 @@
* Gets the metadata associated with the node found at the specified
* y-coordinate, or <tt>null</tt> if there is no node at that location.
*/
- protected NodeInfo getNodeInfoAt(int y) {
+ protected final NodeInfo getNodeInfoAt(int y) {
NodeInfo nodeInfo = null;
int nodeHeight = getNodeHeight();
@@ -1068,7 +1172,7 @@
* The path must be valid. The empty path is supported and represents the
* root node info.
*/
- protected NodeInfo getNodeInfoAt(Path path) {
+ protected final NodeInfo getNodeInfoAt(Path path) {
assert(path != null) : "Path is null";
NodeInfo result = null;
@@ -1100,7 +1204,7 @@
* Gets the bounding box defined by the specified node, or <tt>null</tt>
* if the node is not currently visible.
*/
- protected Bounds getNodeBounds(NodeInfo nodeInfo) {
+ protected final Bounds getNodeBounds(NodeInfo nodeInfo) {
Bounds bounds = null;
int index = visibleNodes.indexOf(nodeInfo);
@@ -1892,7 +1996,7 @@
// Update our internal branch info
if (branchInfo.children != null) {
- NodeInfo nodeInfo = NodeInfo.createNew(treeView, branchInfo, branchData.get(index));
+ NodeInfo nodeInfo = NodeInfo.newInstance(treeView, branchInfo, branchData.get(index));
branchInfo.children.insert(nodeInfo, index);
}
@@ -1931,7 +2035,7 @@
removeVisibleNodes(branchInfo, index, 1);
// Update our internal branch info
- nodeInfo = NodeInfo.createNew(treeView, branchInfo, nodeData);
+ nodeInfo = NodeInfo.newInstance(treeView, branchInfo, nodeData);
branchInfo.children.update(index, nodeInfo);
// Add the new node to the visible nodes list