1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef UI_BASE_MODELS_TREE_NODE_MODEL_H_
6 #define UI_BASE_MODELS_TREE_NODE_MODEL_H_
11 #include "base/basictypes.h"
12 #include "base/compiler_specific.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/observer_list.h"
17 #include "base/strings/string16.h"
18 #include "ui/base/models/tree_model.h"
22 // TreeNodeModel and TreeNodes provide an implementation of TreeModel around
25 // TreeNodes own their children, so that deleting a node deletes all
28 // TreeNodes do NOT maintain a pointer back to the model. As such, if you
29 // are using TreeNodes with a TreeNodeModel you will need to notify the observer
30 // yourself any time you make any change directly to the TreeNodes. For example,
31 // if you directly invoke set_title on a node it does not notify the observer,
32 // you will need to do it yourself. This includes the following methods: Add,
33 // Remove and set_title. TreeNodeModel provides cover methods that mutate the
34 // TreeNodes and notify the observer. If you are using TreeNodes with a
35 // TreeNodeModel use the cover methods to save yourself the headache.
37 // The following example creates a TreeNode with two children and then
38 // creates a TreeNodeModel from it:
40 // TreeNodeWithValue<int>* root = new TreeNodeWithValue<int>();
41 // root->Add(new TreeNodeWithValue<int>(ASCIIToUTF16("child 1"), 0));
42 // root->Add(new TreeNodeWithValue<int>(ASCIIToUTF16("child 2"), 1));
43 // TreeNodeModel<TreeNodeWithValue<int> > model(root);
45 // Two variants of TreeNode are provided here:
47 // . TreeNode itself is intended for subclassing. It has one type parameter
48 // that corresponds to the type of the node. When subclassing use your class
49 // name as the type parameter, eg:
50 // class MyTreeNode : public TreeNode<MyTreeNode> .
51 // . TreeNodeWithValue is a trivial subclass of TreeNode that has one type
52 // type parameter: a value type that is associated with the node.
54 // Which you use depends upon the situation. If you want to subclass and add
55 // methods, then use TreeNode. If you don't need any extra methods and just
56 // want to associate a value with each node, then use TreeNodeWithValue.
58 // Regardless of which TreeNode you use, if you are using the nodes with a
59 // TreeView take care to notify the observer when mutating the nodes.
61 // TreeNode -------------------------------------------------------------------
63 template <class NodeType
>
64 class TreeNode
: public TreeModelNode
{
66 TreeNode() : parent_(NULL
) {}
68 explicit TreeNode(const base::string16
& title
)
69 : title_(title
), parent_(NULL
) {}
71 virtual ~TreeNode() {}
73 // Adds |node| as a child of this node, at |index|.
74 virtual void Add(NodeType
* node
, int index
) {
77 DCHECK_LE(index
, child_count());
78 // If |node| has a parent, remove it from its parent.
79 NodeType
* parent
= node
->parent_
;
82 node
->parent_
= static_cast<NodeType
*>(this);
83 children_
.insert(children_
.begin() + index
, node
);
86 // Removes |node| from this node and returns it. It's up to the caller to
88 virtual NodeType
* Remove(NodeType
* node
) {
89 typename
std::vector
<NodeType
*>::iterator i
=
90 std::find(children_
.begin(), children_
.end(), node
);
91 DCHECK(i
!= children_
.end());
93 children_
.weak_erase(i
);
97 // Removes all the children from this node. This does NOT delete the nodes.
99 for (size_t i
= 0; i
< children_
.size(); ++i
)
100 children_
[i
]->parent_
= NULL
;
101 children_
.weak_clear();
104 // Removes all existing children without deleting the nodes and adds all nodes
105 // contained in |children| into this node as children.
106 void SetChildren(const std::vector
<NodeType
*>& children
) {
108 for (size_t i
= 0; i
< children
.size(); ++i
)
109 Add(children
[i
], static_cast<int>(i
));
112 // Returns the parent node, or NULL if this is the root node.
113 const NodeType
* parent() const { return parent_
; }
114 NodeType
* parent() { return parent_
; }
116 // Returns true if this is the root node.
117 bool is_root() const { return parent_
== NULL
; }
119 // Returns the number of children.
120 int child_count() const { return static_cast<int>(children_
.size()); }
122 // Returns true if this node has no children.
123 bool empty() const { return children_
.empty(); }
125 // Returns the number of all nodes in the subtree rooted at this node,
126 // including this node.
127 int GetTotalNodeCount() const {
128 int count
= 1; // Start with one to include the node itself.
129 for (size_t i
= 0; i
< children_
.size(); ++i
)
130 count
+= children_
[i
]->GetTotalNodeCount();
134 // Returns the node at |index|.
135 const NodeType
* GetChild(int index
) const {
137 DCHECK_LT(index
, child_count());
138 return children_
[index
];
140 NodeType
* GetChild(int index
) {
141 return const_cast<NodeType
*>(
142 static_cast<const NodeType
&>(*this).GetChild(index
));
145 // Returns the index of |node|, or -1 if |node| is not a child of this.
146 int GetIndexOf(const NodeType
* node
) const {
148 typename
std::vector
<NodeType
*>::const_iterator i
=
149 std::find(children_
.begin(), children_
.end(), node
);
150 return i
!= children_
.end() ? static_cast<int>(i
- children_
.begin()) : -1;
153 // Sets the title of the node.
154 virtual void SetTitle(const base::string16
& title
) { title_
= title
; }
157 virtual const base::string16
& GetTitle() const override
{ return title_
; }
159 // Returns true if this == ancestor, or one of this nodes parents is
161 bool HasAncestor(const NodeType
* ancestor
) const {
162 if (ancestor
== this)
166 return parent_
? parent_
->HasAncestor(ancestor
) : false;
170 std::vector
<NodeType
*>& children() { return children_
.get(); }
173 // Title displayed in the tree.
174 base::string16 title_
;
176 // This node's parent.
179 // This node's children.
180 ScopedVector
<NodeType
> children_
;
182 DISALLOW_COPY_AND_ASSIGN(TreeNode
);
185 // TreeNodeWithValue ----------------------------------------------------------
187 template <class ValueType
>
188 class TreeNodeWithValue
: public TreeNode
< TreeNodeWithValue
<ValueType
> > {
190 TreeNodeWithValue() {}
192 explicit TreeNodeWithValue(const ValueType
& value
)
193 : ParentType(base::string16()), value(value
) {}
195 TreeNodeWithValue(const base::string16
& title
, const ValueType
& value
)
196 : ParentType(title
), value(value
) {}
201 typedef TreeNode
< TreeNodeWithValue
<ValueType
> > ParentType
;
203 DISALLOW_COPY_AND_ASSIGN(TreeNodeWithValue
);
206 // TreeNodeModel --------------------------------------------------------------
208 // TreeModel implementation intended to be used with TreeNodes.
209 template <class NodeType
>
210 class TreeNodeModel
: public TreeModel
{
212 // Creates a TreeNodeModel with the specified root node. The root is owned
213 // by the TreeNodeModel.
214 explicit TreeNodeModel(NodeType
* root
) : root_(root
) {}
215 virtual ~TreeNodeModel() {}
217 NodeType
* AsNode(TreeModelNode
* model_node
) {
218 return static_cast<NodeType
*>(model_node
);
221 void Add(NodeType
* parent
, NodeType
* node
, int index
) {
222 DCHECK(parent
&& node
);
223 parent
->Add(node
, index
);
224 NotifyObserverTreeNodesAdded(parent
, index
, 1);
227 NodeType
* Remove(NodeType
* parent
, NodeType
* node
) {
229 int index
= parent
->GetIndexOf(node
);
230 NodeType
* delete_node
= parent
->Remove(node
);
231 NotifyObserverTreeNodesRemoved(parent
, index
, 1);
235 void NotifyObserverTreeNodesAdded(NodeType
* parent
, int start
, int count
) {
236 FOR_EACH_OBSERVER(TreeModelObserver
,
238 TreeNodesAdded(this, parent
, start
, count
));
241 void NotifyObserverTreeNodesRemoved(NodeType
* parent
, int start
, int count
) {
242 FOR_EACH_OBSERVER(TreeModelObserver
,
244 TreeNodesRemoved(this, parent
, start
, count
));
247 void NotifyObserverTreeNodeChanged(TreeModelNode
* node
) {
248 FOR_EACH_OBSERVER(TreeModelObserver
,
250 TreeNodeChanged(this, node
));
254 virtual NodeType
* GetRoot() override
{
258 virtual int GetChildCount(TreeModelNode
* parent
) override
{
260 return AsNode(parent
)->child_count();
263 virtual NodeType
* GetChild(TreeModelNode
* parent
, int index
) override
{
265 return AsNode(parent
)->GetChild(index
);
268 virtual int GetIndexOf(TreeModelNode
* parent
, TreeModelNode
* child
) override
{
270 return AsNode(parent
)->GetIndexOf(AsNode(child
));
273 virtual TreeModelNode
* GetParent(TreeModelNode
* node
) override
{
275 return AsNode(node
)->parent();
278 virtual void AddObserver(TreeModelObserver
* observer
) override
{
279 observer_list_
.AddObserver(observer
);
282 virtual void RemoveObserver(TreeModelObserver
* observer
) override
{
283 observer_list_
.RemoveObserver(observer
);
286 virtual void SetTitle(TreeModelNode
* node
,
287 const base::string16
& title
) override
{
289 AsNode(node
)->SetTitle(title
);
290 NotifyObserverTreeNodeChanged(node
);
295 ObserverList
<TreeModelObserver
> observer_list_
;
298 scoped_ptr
<NodeType
> root_
;
300 DISALLOW_COPY_AND_ASSIGN(TreeNodeModel
);
305 #endif // UI_BASE_MODELS_TREE_NODE_MODEL_H_