summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-13 18:54:20 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-13 18:54:20 +0000
commit992c625bf2d6dfaaa46cf5b45cdcd7de68e7817e (patch)
treeae6467a99cf17115e04af5bbe358a6219f9c9808 /app
parentb83fed38db16e462afa3051dcad21318c62b2357 (diff)
downloadchromium_src-992c625bf2d6dfaaa46cf5b45cdcd7de68e7817e.zip
chromium_src-992c625bf2d6dfaaa46cf5b45cdcd7de68e7817e.tar.gz
chromium_src-992c625bf2d6dfaaa46cf5b45cdcd7de68e7817e.tar.bz2
Move tree-related classes that Linux code depends on from views/ to app/
TEST=If it compiles and unit_tests pass, it's ok. Just moving files around. http://crbug.com/11066 Review URL: http://codereview.chromium.org/115185 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15982 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'app')
-rw-r--r--app/app.vcproj12
-rw-r--r--app/tree_model.h87
-rw-r--r--app/tree_node_iterator.h70
-rw-r--r--app/tree_node_iterator_unittest.cc41
-rw-r--r--app/tree_node_model.h279
5 files changed, 489 insertions, 0 deletions
diff --git a/app/app.vcproj b/app/app.vcproj
index d940bf9..64b07d87 100644
--- a/app/app.vcproj
+++ b/app/app.vcproj
@@ -262,6 +262,18 @@
>
</File>
<File
+ RelativePath=".\tree_model.h"
+ >
+ </File>
+ <File
+ RelativePath=".\tree_node_iterator.h"
+ >
+ </File>
+ <File
+ RelativePath=".\tree_node_model.h"
+ >
+ </File>
+ <File
RelativePath=".\win_util.cc"
>
</File>
diff --git a/app/tree_model.h b/app/tree_model.h
new file mode 100644
index 0000000..e7b93ee
--- /dev/null
+++ b/app/tree_model.h
@@ -0,0 +1,87 @@
+// Copyright (c) 2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef APP_TREE_MODEL_H_
+#define APP_TREE_MODEL_H_
+
+#include <string>
+
+#include "base/logging.h"
+
+class SkBitmap;
+
+class TreeModel;
+
+// TreeModelNode --------------------------------------------------------------
+
+// Type of class returned from the model.
+class TreeModelNode {
+ public:
+ // Returns the title for the node.
+ virtual std::wstring GetTitle() = 0;
+};
+
+// Observer for the TreeModel. Notified of significant events to the model.
+class TreeModelObserver {
+ public:
+ // Notification that nodes were added to the specified parent.
+ virtual void TreeNodesAdded(TreeModel* model,
+ TreeModelNode* parent,
+ int start,
+ int count) = 0;
+
+ // Notification that nodes were removed from the specified parent.
+ virtual void TreeNodesRemoved(TreeModel* model,
+ TreeModelNode* parent,
+ int start,
+ int count) = 0;
+
+ // Notification the children of |parent| have been reordered. Note, only
+ // the direct children of |parent| have been reordered, not descendants.
+ virtual void TreeNodeChildrenReordered(TreeModel* model,
+ TreeModelNode* parent) = 0;
+
+ // Notification that the contents of a node has changed.
+ virtual void TreeNodeChanged(TreeModel* model, TreeModelNode* node) = 0;
+};
+
+// TreeModel ------------------------------------------------------------------
+
+// The model for TreeView.
+class TreeModel {
+ public:
+ // Returns the root of the tree. This may or may not be shown in the tree,
+ // see SetRootShown for details.
+ virtual TreeModelNode* GetRoot() = 0;
+
+ // Returns the number of children in the specified node.
+ virtual int GetChildCount(TreeModelNode* parent) = 0;
+
+ // Returns the child node at the specified index.
+ virtual TreeModelNode* GetChild(TreeModelNode* parent, int index) = 0;
+
+ // Returns the parent of a node, or NULL if node is the root.
+ virtual TreeModelNode* GetParent(TreeModelNode* node) = 0;
+
+ // Sets the observer of the model.
+ virtual void SetObserver(TreeModelObserver* observer) = 0;
+
+ // Sets the title of the specified node.
+ // This is only invoked if the node is editable and the user edits a node.
+ virtual void SetTitle(TreeModelNode* node,
+ const std::wstring& title) {
+ NOTREACHED();
+ }
+
+ // Returns the set of icons for the nodes in the tree. You only need override
+ // this if you don't want to use the default folder icons.
+ virtual void GetIcons(std::vector<SkBitmap>* icons) {}
+
+ // Returns the index of the icon to use for |node|. Return -1 to use the
+ // default icon. The index is relative to the list of icons returned from
+ // GetIcons.
+ virtual int GetIconIndex(TreeModelNode* node) { return -1; }
+};
+
+#endif // APP_TREE_TREE_MODEL_H_
diff --git a/app/tree_node_iterator.h b/app/tree_node_iterator.h
new file mode 100644
index 0000000..7e7398c
--- /dev/null
+++ b/app/tree_node_iterator.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef APP_TREE_NODE_ITERATOR_H_
+#define APP_TREE_NODE_ITERATOR_H_
+
+#include <stack>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+
+// Iterator that iterates over the descendants of a node. The iteration does
+// not include the node itself, only the descendants. The following illustrates
+// typical usage:
+// while (iterator.has_next()) {
+// Node* node = iterator.Next();
+// // do something with node.
+// }
+template <class NodeType>
+class TreeNodeIterator {
+ public:
+ explicit TreeNodeIterator(NodeType* node) {
+ if (node->GetChildCount() > 0)
+ positions_.push(Position<NodeType>(node, 0));
+ }
+
+ // Returns true if there are more descendants.
+ bool has_next() const { return !positions_.empty(); }
+
+ // Returns the next descendant.
+ NodeType* Next() {
+ if (!has_next()) {
+ NOTREACHED();
+ return NULL;
+ }
+
+ NodeType* result = positions_.top().node->GetChild(positions_.top().index);
+
+ // Make sure we don't attempt to visit result again.
+ positions_.top().index++;
+
+ // Iterate over result's children.
+ positions_.push(Position<NodeType>(result, 0));
+
+ // Advance to next position.
+ while (!positions_.empty() && positions_.top().index >=
+ positions_.top().node->GetChildCount()) {
+ positions_.pop();
+ }
+
+ return result;
+ }
+
+ private:
+ template <class PositionNodeType>
+ struct Position {
+ Position(PositionNodeType* node, int index) : node(node), index(index) {}
+ Position() : node(NULL), index(-1) {}
+
+ PositionNodeType* node;
+ int index;
+ };
+
+ std::stack<Position<NodeType> > positions_;
+
+ DISALLOW_COPY_AND_ASSIGN(TreeNodeIterator);
+};
+
+#endif // APP_TREE_NODE_ITERATOR_H_
diff --git a/app/tree_node_iterator_unittest.cc b/app/tree_node_iterator_unittest.cc
new file mode 100644
index 0000000..c20babe
--- /dev/null
+++ b/app/tree_node_iterator_unittest.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include "app/tree_node_iterator.h"
+#include "app/tree_node_model.h"
+
+namespace {
+
+TEST(TreeNodeIteratorTest, Test) {
+ TreeNodeWithValue<int> root;
+ root.Add(0, new TreeNodeWithValue<int>(1));
+ root.Add(1, new TreeNodeWithValue<int>(2));
+ TreeNodeWithValue<int>* f3 = new TreeNodeWithValue<int>(3);
+ root.Add(2, f3);
+ TreeNodeWithValue<int>* f4 = new TreeNodeWithValue<int>(4);
+ f3->Add(0, f4);
+ f4->Add(0, new TreeNodeWithValue<int>(5));
+
+ TreeNodeIterator<TreeNodeWithValue<int> > iterator(&root);
+ ASSERT_TRUE(iterator.has_next());
+ ASSERT_EQ(root.GetChild(0), iterator.Next());
+
+ ASSERT_TRUE(iterator.has_next());
+ ASSERT_EQ(root.GetChild(1), iterator.Next());
+
+ ASSERT_TRUE(iterator.has_next());
+ ASSERT_EQ(root.GetChild(2), iterator.Next());
+
+ ASSERT_TRUE(iterator.has_next());
+ ASSERT_EQ(f4, iterator.Next());
+
+ ASSERT_TRUE(iterator.has_next());
+ ASSERT_EQ(f4->GetChild(0), iterator.Next());
+
+ ASSERT_FALSE(iterator.has_next());
+}
+
+} // namespace
diff --git a/app/tree_node_model.h b/app/tree_node_model.h
new file mode 100644
index 0000000..69d5c8d
--- /dev/null
+++ b/app/tree_node_model.h
@@ -0,0 +1,279 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef APP_TREE_NODE_MODEL_H_
+#define APP_TREE_NODE_MODEL_H_
+
+#include <algorithm>
+#include <vector>
+
+#include "app/tree_model.h"
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "base/scoped_vector.h"
+#include "base/stl_util-inl.h"
+
+// TreeNodeModel and TreeNodes provide an implementation of TreeModel around
+// TreeNodes. TreeNodes form a directed acyclic graph.
+//
+// TreeNodes own their children, so that deleting a node deletes all
+// descendants.
+//
+// TreeNodes do NOT maintain a pointer back to the model. As such, if you
+// are using TreeNodes with a TreeNodeModel you will need to notify the observer
+// yourself any time you make any change directly to the TreeNodes. For example,
+// if you directly invoke SetTitle on a node it does not notify the
+// observer, you will need to do it yourself. This includes the following
+// methods: SetTitle, Remove and Add. TreeNodeModel provides cover
+// methods that mutate the TreeNodes and notify the observer. If you are using
+// TreeNodes with a TreeNodeModel use the cover methods to save yourself the
+// headache.
+//
+// The following example creates a TreeNode with two children and then
+// creates a TreeNodeModel from it:
+//
+// TreeNodeWithValue<int> root = new TreeNodeWithValue<int>(0, L"root");
+// root.add(new TreeNodeWithValue<int>(1, L"child 1"));
+// root.add(new TreeNodeWithValue<int>(1, L"child 2"));
+// TreeNodeModel<TreeNodeWithValue<int>>* model =
+// new TreeNodeModel<TreeNodeWithValue<int>>(root);
+//
+// Two variants of TreeNode are provided here:
+//
+// . TreeNode itself is intended for subclassing. It has one type parameter
+// that corresponds to the type of the node. When subclassing use your class
+// name as the type parameter, eg:
+// class MyTreeNode : public TreeNode<MyTreeNode> .
+// . TreeNodeWithValue is a trivial subclass of TreeNode that has one type
+// type parameter: a value type that is associated with the node.
+//
+// Which you use depends upon the situation. If you want to subclass and add
+// methods, then use TreeNode. If you don't need any extra methods and just
+// want to associate a value with each node, then use TreeNodeWithValue.
+//
+// Regardless of which TreeNode you use, if you are using the nodes with a
+// TreeView take care to notify the observer when mutating the nodes.
+
+template <class NodeType>
+class TreeNodeModel;
+
+// TreeNode -------------------------------------------------------------------
+
+template <class NodeType>
+class TreeNode : public TreeModelNode {
+ public:
+ TreeNode() : parent_(NULL) { }
+
+ explicit TreeNode(const std::wstring& title)
+ : title_(title), parent_(NULL) {}
+
+ virtual ~TreeNode() {
+ }
+
+ // Adds the specified child node.
+ virtual void Add(int index, NodeType* child) {
+ DCHECK(child && index >= 0 && index <= GetChildCount());
+ // If the node has a parent, remove it from its parent.
+ NodeType* node_parent = child->GetParent();
+ if (node_parent)
+ node_parent->Remove(node_parent->IndexOfChild(child));
+ child->parent_ = static_cast<NodeType*>(this);
+ children_->insert(children_->begin() + index, child);
+ }
+
+ // Removes the node by index. This does NOT delete the specified node, it is
+ // up to the caller to delete it when done.
+ virtual NodeType* Remove(int index) {
+ DCHECK(index >= 0 && index < GetChildCount());
+ NodeType* node = GetChild(index);
+ node->parent_ = NULL;
+ children_->erase(index + children_->begin());
+ return node;
+ }
+
+ // Removes all the children from this node. This does NOT delete the nodes.
+ void RemoveAll() {
+ for (size_t i = 0; i < children_->size(); ++i)
+ children_[i]->parent_ = NULL;
+ children_->clear();
+ }
+
+ // Returns the number of children.
+ int GetChildCount() {
+ return static_cast<int>(children_->size());
+ }
+
+ // Returns a child by index.
+ NodeType* GetChild(int index) {
+ DCHECK(index >= 0 && index < GetChildCount());
+ return children_[index];
+ }
+
+ // Returns the parent.
+ NodeType* GetParent() {
+ return parent_;
+ }
+
+ // Returns the index of the specified child, or -1 if node is a not a child.
+ int IndexOfChild(const NodeType* node) {
+ DCHECK(node);
+ typename std::vector<NodeType*>::iterator i =
+ std::find(children_->begin(), children_->end(), node);
+ if (i != children_->end())
+ return static_cast<int>(i - children_->begin());
+ return -1;
+ }
+
+ // Sets the title of the node.
+ void SetTitle(const std::wstring& string) {
+ title_ = string;
+ }
+
+ // Returns the title of the node.
+ std::wstring GetTitle() {
+ return title_;
+ }
+
+ // Returns true if this is the root.
+ bool IsRoot() { return (parent_ == NULL); }
+
+ // Returns true if this == ancestor, or one of this nodes parents is
+ // ancestor.
+ bool HasAncestor(NodeType* ancestor) const {
+ if (ancestor == this)
+ return true;
+ if (!ancestor)
+ return false;
+ return parent_ ? parent_->HasAncestor(ancestor) : false;
+ }
+
+ protected:
+ std::vector<NodeType*>& children() { return children_.get(); }
+
+ private:
+ // Title displayed in the tree.
+ std::wstring title_;
+
+ NodeType* parent_;
+
+ // Children.
+ ScopedVector<NodeType> children_;
+
+ DISALLOW_COPY_AND_ASSIGN(TreeNode);
+};
+
+// TreeNodeWithValue ----------------------------------------------------------
+
+template <class ValueType>
+class TreeNodeWithValue : public TreeNode< TreeNodeWithValue<ValueType> > {
+ private:
+ typedef TreeNode< TreeNodeWithValue<ValueType> > ParentType;
+
+ public:
+ TreeNodeWithValue() { }
+
+ TreeNodeWithValue(const ValueType& value)
+ : ParentType(std::wstring()), value(value) { }
+
+ TreeNodeWithValue(const std::wstring& title, const ValueType& value)
+ : ParentType(title), value(value) { }
+
+ ValueType value;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TreeNodeWithValue);
+};
+
+// TreeNodeModel --------------------------------------------------------------
+
+// TreeModel implementation intended to be used with TreeNodes.
+template <class NodeType>
+class TreeNodeModel : public TreeModel {
+ public:
+ // Creates a TreeNodeModel with the specified root node. The root is owned
+ // by the TreeNodeModel.
+ explicit TreeNodeModel(NodeType* root)
+ : root_(root),
+ observer_(NULL) {
+ }
+
+ virtual ~TreeNodeModel() {}
+
+ virtual void SetObserver(TreeModelObserver* observer) {
+ observer_ = observer;
+ }
+
+ TreeModelObserver* GetObserver() {
+ return observer_;
+ }
+
+ // TreeModel methods, all forward to the nodes.
+ virtual NodeType* GetRoot() { return root_.get(); }
+
+ virtual int GetChildCount(TreeModelNode* parent) {
+ DCHECK(parent);
+ return AsNode(parent)->GetChildCount();
+ }
+
+ virtual NodeType* GetChild(TreeModelNode* parent, int index) {
+ DCHECK(parent);
+ return AsNode(parent)->GetChild(index);
+ }
+
+ virtual TreeModelNode* GetParent(TreeModelNode* node) {
+ DCHECK(node);
+ return AsNode(node)->GetParent();
+ }
+
+ NodeType* AsNode(TreeModelNode* model_node) {
+ return reinterpret_cast<NodeType*>(model_node);
+ }
+
+ // Sets the title of the specified node.
+ virtual void SetTitle(TreeModelNode* node,
+ const std::wstring& title) {
+ DCHECK(node);
+ AsNode(node)->SetTitle(title);
+ NotifyObserverTreeNodeChanged(node);
+ }
+
+ void Add(NodeType* parent, int index, NodeType* child) {
+ DCHECK(parent && child);
+ parent->Add(index, child);
+ NotifyObserverTreeNodesAdded(parent, index, 1);
+ }
+
+ NodeType* Remove(NodeType* parent, int index) {
+ DCHECK(parent);
+ NodeType* child = parent->Remove(index);
+ NotifyObserverTreeNodesRemoved(parent, index, 1);
+ return child;
+ }
+
+ void NotifyObserverTreeNodesAdded(NodeType* parent, int start, int count) {
+ if (observer_)
+ observer_->TreeNodesAdded(this, parent, start, count);
+ }
+
+ void NotifyObserverTreeNodesRemoved(NodeType* parent, int start, int count) {
+ if (observer_)
+ observer_->TreeNodesRemoved(this, parent, start, count);
+ }
+
+ virtual void NotifyObserverTreeNodeChanged(TreeModelNode* node) {
+ if (observer_)
+ observer_->TreeNodeChanged(this, node);
+ }
+
+ private:
+ // The root.
+ scoped_ptr<NodeType> root_;
+
+ // The observer.
+ TreeModelObserver* observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(TreeNodeModel);
+};
+
+#endif // APP_TREE_NODE_MODEL_H_