summaryrefslogtreecommitdiffstats
path: root/chrome/views/controls/tree
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/views/controls/tree')
-rw-r--r--chrome/views/controls/tree/tree_model.h91
-rw-r--r--chrome/views/controls/tree/tree_node_iterator.h74
-rw-r--r--chrome/views/controls/tree/tree_node_iterator_unittest.cc41
-rw-r--r--chrome/views/controls/tree/tree_node_model.h283
-rw-r--r--chrome/views/controls/tree/tree_view.cc745
-rw-r--r--chrome/views/controls/tree/tree_view.h305
6 files changed, 0 insertions, 1539 deletions
diff --git a/chrome/views/controls/tree/tree_model.h b/chrome/views/controls/tree/tree_model.h
deleted file mode 100644
index 8c54b75..0000000
--- a/chrome/views/controls/tree/tree_model.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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 CHROME_VIEWS_CONTROLS_TREE_TREE_MODEL_H_
-#define CHROME_VIEWS_CONTROLS_TREE_TREE_MODEL_H_
-
-#include <string>
-
-#include "base/logging.h"
-
-class SkBitmap;
-
-namespace views {
-
-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; }
-};
-
-} // namespace views
-
-#endif // CHROME_VIEWS_CONTROLS_TREE_TREE_MODEL_H_
diff --git a/chrome/views/controls/tree/tree_node_iterator.h b/chrome/views/controls/tree/tree_node_iterator.h
deleted file mode 100644
index fa28b3e..0000000
--- a/chrome/views/controls/tree/tree_node_iterator.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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 CHROME_VIEWS_CONTROLS_TREE_TREE_NODE_ITERATOR_H_
-#define CHROME_VIEWS_CONTROLS_TREE_TREE_NODE_ITERATOR_H_
-
-#include <stack>
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-
-namespace views {
-
-// 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);
-};
-
-} // namespace views
-
-#endif // CHROME_VIEWS_CONTROLS_TREE_TREE_NODE_ITERATOR_H_
diff --git a/chrome/views/controls/tree/tree_node_iterator_unittest.cc b/chrome/views/controls/tree/tree_node_iterator_unittest.cc
deleted file mode 100644
index 3aec1af..0000000
--- a/chrome/views/controls/tree/tree_node_iterator_unittest.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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 "chrome/views/controls/tree/tree_node_iterator.h"
-#include "chrome/views/controls/tree/tree_node_model.h"
-
-typedef testing::Test TreeNodeIteratorTest;
-
-using views::TreeNodeWithValue;
-
-TEST_F(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));
-
- views::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());
-}
diff --git a/chrome/views/controls/tree/tree_node_model.h b/chrome/views/controls/tree/tree_node_model.h
deleted file mode 100644
index 14e5748..0000000
--- a/chrome/views/controls/tree/tree_node_model.h
+++ /dev/null
@@ -1,283 +0,0 @@
-// 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 CHROME_VIEWS_CONTROLS_TREE_TREE_NODE_MODEL_H_
-#define CHROME_VIEWS_CONTROLS_TREE_TREE_NODE_MODEL_H_
-
-#include <algorithm>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/scoped_ptr.h"
-#include "base/scoped_vector.h"
-#include "base/stl_util-inl.h"
-#include "chrome/views/controls/tree/tree_model.h"
-
-namespace views {
-
-// 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);
-};
-
-} // namespace views
-
-#endif // CHROME_VIEWS_CONTROLS_TREE_TREE_NODE_MODEL_H_
diff --git a/chrome/views/controls/tree/tree_view.cc b/chrome/views/controls/tree/tree_view.cc
deleted file mode 100644
index 1bf668c..0000000
--- a/chrome/views/controls/tree/tree_view.cc
+++ /dev/null
@@ -1,745 +0,0 @@
-// 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 "chrome/views/controls/tree/tree_view.h"
-
-#include <shellapi.h>
-
-#include "app/gfx/chrome_canvas.h"
-#include "app/gfx/icon_util.h"
-#include "app/l10n_util.h"
-#include "app/l10n_util_win.h"
-#include "app/resource_bundle.h"
-#include "base/stl_util-inl.h"
-#include "base/win_util.h"
-#include "chrome/views/focus/focus_manager.h"
-#include "chrome/views/widget/widget.h"
-#include "grit/theme_resources.h"
-
-namespace views {
-
-TreeView::TreeView()
- : tree_view_(NULL),
- model_(NULL),
- editable_(true),
- next_id_(0),
- controller_(NULL),
- editing_node_(NULL),
- root_shown_(true),
- process_enter_(false),
- show_context_menu_only_when_node_selected_(true),
- select_on_right_mouse_down_(true),
- wrapper_(this),
- original_handler_(NULL),
- drag_enabled_(false),
- has_custom_icons_(false),
- image_list_(NULL) {
-}
-
-TreeView::~TreeView() {
- if (model_)
- model_->SetObserver(NULL);
- // Both param_to_details_map_ and node_to_details_map_ have the same value,
- // as such only need to delete from one.
- STLDeleteContainerPairSecondPointers(id_to_details_map_.begin(),
- id_to_details_map_.end());
- if (image_list_)
- ImageList_Destroy(image_list_);
-}
-
-void TreeView::SetModel(TreeModel* model) {
- if (model == model_)
- return;
- if(model_ && tree_view_)
- DeleteRootItems();
- if (model_)
- model_->SetObserver(NULL);
- model_ = model;
- if (tree_view_ && model_) {
- CreateRootItems();
- model_->SetObserver(this);
- HIMAGELIST last_image_list = image_list_;
- image_list_ = CreateImageList();
- TreeView_SetImageList(tree_view_, image_list_, TVSIL_NORMAL);
- if (last_image_list)
- ImageList_Destroy(last_image_list);
- }
-}
-
-// Sets whether the user can edit the nodes. The default is true.
-void TreeView::SetEditable(bool editable) {
- if (editable == editable_)
- return;
- editable_ = editable;
- if (!tree_view_)
- return;
- LONG_PTR style = GetWindowLongPtr(tree_view_, GWL_STYLE);
- style &= ~TVS_EDITLABELS;
- SetWindowLongPtr(tree_view_, GWL_STYLE, style);
-}
-
-void TreeView::StartEditing(TreeModelNode* node) {
- DCHECK(node && tree_view_);
- // Cancel the current edit.
- CancelEdit();
- // Make sure all ancestors are expanded.
- if (model_->GetParent(node))
- Expand(model_->GetParent(node));
- const NodeDetails* details = GetNodeDetails(node);
- // Tree needs focus for editing to work.
- SetFocus(tree_view_);
- // Select the node, else if the user commits the edit the selection reverts.
- SetSelectedNode(node);
- TreeView_EditLabel(tree_view_, details->tree_item);
-}
-
-void TreeView::CancelEdit() {
- DCHECK(tree_view_);
- TreeView_EndEditLabelNow(tree_view_, TRUE);
-}
-
-void TreeView::CommitEdit() {
- DCHECK(tree_view_);
- TreeView_EndEditLabelNow(tree_view_, FALSE);
-}
-
-TreeModelNode* TreeView::GetEditingNode() {
- // I couldn't find a way to dynamically query for this, so it is cached.
- return editing_node_;
-}
-
-void TreeView::SetSelectedNode(TreeModelNode* node) {
- DCHECK(tree_view_);
- if (!node) {
- TreeView_SelectItem(tree_view_, NULL);
- return;
- }
- if (node != model_->GetRoot())
- Expand(model_->GetParent(node));
- if (!root_shown_ && node == model_->GetRoot()) {
- // If the root isn't shown, we can't select it, clear out the selection
- // instead.
- TreeView_SelectItem(tree_view_, NULL);
- } else {
- // Select the node and make sure it is visible.
- TreeView_SelectItem(tree_view_, GetNodeDetails(node)->tree_item);
- }
-}
-
-TreeModelNode* TreeView::GetSelectedNode() {
- if (!tree_view_)
- return NULL;
- HTREEITEM selected_item = TreeView_GetSelection(tree_view_);
- if (!selected_item)
- return NULL;
- NodeDetails* details = GetNodeDetailsByTreeItem(selected_item);
- DCHECK(details);
- return details->node;
-}
-
-void TreeView::Expand(TreeModelNode* node) {
- DCHECK(model_ && node);
- if (!root_shown_ && model_->GetRoot() == node) {
- // Can only expand the root if it is showing.
- return;
- }
- TreeModelNode* parent = model_->GetParent(node);
- if (parent) {
- // Make sure all the parents are expanded.
- Expand(parent);
- }
- // And expand this item.
- TreeView_Expand(tree_view_, GetNodeDetails(node)->tree_item, TVE_EXPAND);
-}
-
-void TreeView::ExpandAll() {
- DCHECK(model_);
- ExpandAll(model_->GetRoot());
-}
-
-void TreeView::ExpandAll(TreeModelNode* node) {
- DCHECK(node);
- // Expand the node.
- if (node != model_->GetRoot() || root_shown_)
- TreeView_Expand(tree_view_, GetNodeDetails(node)->tree_item, TVE_EXPAND);
- // And recursively expand all the children.
- for (int i = model_->GetChildCount(node) - 1; i >= 0; --i) {
- TreeModelNode* child = model_->GetChild(node, i);
- ExpandAll(child);
- }
-}
-
-bool TreeView::IsExpanded(TreeModelNode* node) {
- TreeModelNode* parent = model_->GetParent(node);
- if (!parent)
- return true;
- if (!IsExpanded(parent))
- return false;
- NodeDetails* details = GetNodeDetails(node);
- return (TreeView_GetItemState(tree_view_, details->tree_item, TVIS_EXPANDED) &
- TVIS_EXPANDED) != 0;
-}
-
-void TreeView::SetRootShown(bool root_shown) {
- if (root_shown_ == root_shown)
- return;
- root_shown_ = root_shown;
- if (!model_)
- return;
- // Repopulate the tree.
- DeleteRootItems();
- CreateRootItems();
-}
-
-void TreeView::TreeNodesAdded(TreeModel* model,
- TreeModelNode* parent,
- int start,
- int count) {
- DCHECK(parent && start >= 0 && count > 0);
- if (node_to_details_map_.find(parent) == node_to_details_map_.end()) {
- // User hasn't navigated to this entry yet. Ignore the change.
- return;
- }
- HTREEITEM parent_tree_item = NULL;
- if (root_shown_ || parent != model_->GetRoot()) {
- const NodeDetails* details = GetNodeDetails(parent);
- if (!details->loaded_children) {
- if (count == model_->GetChildCount(parent)) {
- // Reset the treeviews child count. This triggers the treeview to call
- // us back.
- TV_ITEM tv_item = {0};
- tv_item.mask = TVIF_CHILDREN;
- tv_item.cChildren = count;
- tv_item.hItem = details->tree_item;
- TreeView_SetItem(tree_view_, &tv_item);
- }
-
- // Ignore the change, we haven't actually created entries in the tree
- // for the children.
- return;
- }
- parent_tree_item = details->tree_item;
- }
-
- // The user has expanded this node, add the items to it.
- for (int i = 0; i < count; ++i) {
- if (i == 0 && start == 0) {
- CreateItem(parent_tree_item, TVI_FIRST, model_->GetChild(parent, 0));
- } else {
- TreeModelNode* previous_sibling = model_->GetChild(parent, i + start - 1);
- CreateItem(parent_tree_item,
- GetNodeDetails(previous_sibling)->tree_item,
- model_->GetChild(parent, i + start));
- }
- }
-}
-
-void TreeView::TreeNodesRemoved(TreeModel* model,
- TreeModelNode* parent,
- int start,
- int count) {
- DCHECK(parent && start >= 0 && count > 0);
- HTREEITEM parent_tree_item = GetTreeItemForNodeDuringMutation(parent);
- if (!parent_tree_item)
- return;
-
- // Find the last item. Windows doesn't offer a convenient way to get the
- // TREEITEM at a particular index, so we iterate.
- HTREEITEM tree_item = TreeView_GetChild(tree_view_, parent_tree_item);
- for (int i = 0; i < (start + count - 1); ++i) {
- tree_item = TreeView_GetNextSibling(tree_view_, tree_item);
- }
- // NOTE: the direction doesn't matter here. I've made it backwards to
- // reinforce we're deleting from the end forward.
- for (int i = count - 1; i >= 0; --i) {
- HTREEITEM previous = (start + i) > 0 ?
- TreeView_GetPrevSibling(tree_view_, tree_item) : NULL;
- RecursivelyDelete(GetNodeDetailsByTreeItem(tree_item));
- tree_item = previous;
- }
-}
-
-namespace {
-
-// Callback function used to compare two items. The first two args are the
-// LPARAMs of the HTREEITEMs being compared. The last arg maps from LPARAM
-// to order. This is invoked from TreeNodeChildrenReordered.
-int CALLBACK CompareTreeItems(LPARAM item1_lparam,
- LPARAM item2_lparam,
- LPARAM map_as_lparam) {
- std::map<int, int>& mapping =
- *reinterpret_cast<std::map<int, int>*>(map_as_lparam);
- return mapping[static_cast<int>(item1_lparam)] -
- mapping[static_cast<int>(item2_lparam)];
-}
-
-} // namespace
-
-void TreeView::TreeNodeChildrenReordered(TreeModel* model,
- TreeModelNode* parent) {
- DCHECK(parent);
- if (model_->GetChildCount(parent) <= 1)
- return;
-
- TVSORTCB sort_details;
- sort_details.hParent = GetTreeItemForNodeDuringMutation(parent);
- if (!sort_details.hParent)
- return;
-
- std::map<int, int> lparam_to_order_map;
- for (int i = 0; i < model_->GetChildCount(parent); ++i) {
- TreeModelNode* node = model_->GetChild(parent, i);
- lparam_to_order_map[GetNodeDetails(node)->id] = i;
- }
-
- sort_details.lpfnCompare = &CompareTreeItems;
- sort_details.lParam = reinterpret_cast<LPARAM>(&lparam_to_order_map);
- TreeView_SortChildrenCB(tree_view_, &sort_details, 0);
-}
-
-void TreeView::TreeNodeChanged(TreeModel* model, TreeModelNode* node) {
- if (node_to_details_map_.find(node) == node_to_details_map_.end()) {
- // User hasn't navigated to this entry yet. Ignore the change.
- return;
- }
- const NodeDetails* details = GetNodeDetails(node);
- TV_ITEM tv_item = {0};
- tv_item.mask = TVIF_TEXT;
- tv_item.hItem = details->tree_item;
- tv_item.pszText = LPSTR_TEXTCALLBACK;
- TreeView_SetItem(tree_view_, &tv_item);
-}
-
-gfx::Point TreeView::GetKeyboardContextMenuLocation() {
- int y = height() / 2;
- if (GetSelectedNode()) {
- RECT bounds;
- RECT client_rect;
- if (TreeView_GetItemRect(tree_view_,
- GetNodeDetails(GetSelectedNode())->tree_item,
- &bounds, TRUE) &&
- GetClientRect(tree_view_, &client_rect) &&
- bounds.bottom >= 0 && bounds.bottom < client_rect.bottom) {
- y = bounds.bottom;
- }
- }
- gfx::Point screen_loc(0, y);
- if (UILayoutIsRightToLeft())
- screen_loc.set_x(width());
- ConvertPointToScreen(this, &screen_loc);
- return screen_loc;
-}
-
-HWND TreeView::CreateNativeControl(HWND parent_container) {
- int style = WS_CHILD | TVS_HASBUTTONS | TVS_HASLINES | TVS_SHOWSELALWAYS;
- if (!drag_enabled_)
- style |= TVS_DISABLEDRAGDROP;
- if (editable_)
- style |= TVS_EDITLABELS;
- tree_view_ = ::CreateWindowEx(WS_EX_CLIENTEDGE | GetAdditionalExStyle(),
- WC_TREEVIEW,
- L"",
- style,
- 0, 0, width(), height(),
- parent_container, NULL, NULL, NULL);
- SetWindowLongPtr(tree_view_, GWLP_USERDATA,
- reinterpret_cast<LONG_PTR>(&wrapper_));
- original_handler_ = win_util::SetWindowProc(tree_view_,
- &TreeWndProc);
- l10n_util::AdjustUIFontForWindow(tree_view_);
-
- if (model_) {
- CreateRootItems();
- model_->SetObserver(this);
- image_list_ = CreateImageList();
- TreeView_SetImageList(tree_view_, image_list_, TVSIL_NORMAL);
- }
-
- // Bug 964884: detach the IME attached to this window.
- // We should attach IMEs only when we need to input CJK strings.
- ::ImmAssociateContextEx(tree_view_, NULL, 0);
- return tree_view_;
-}
-
-LRESULT TreeView::OnNotify(int w_param, LPNMHDR l_param) {
- switch (l_param->code) {
- case TVN_GETDISPINFO: {
- // Windows is requesting more information about an item.
- // WARNING: At the time this is called the tree_item of the NodeDetails
- // in the maps is NULL.
- DCHECK(model_);
- NMTVDISPINFO* info = reinterpret_cast<NMTVDISPINFO*>(l_param);
- const NodeDetails* details =
- GetNodeDetailsByID(static_cast<int>(info->item.lParam));
- if (info->item.mask & TVIF_CHILDREN)
- info->item.cChildren = model_->GetChildCount(details->node);
- if (info->item.mask & TVIF_TEXT) {
- std::wstring text = details->node->GetTitle();
- DCHECK(info->item.cchTextMax);
-
- // Adjust the string direction if such adjustment is required.
- std::wstring localized_text;
- if (l10n_util::AdjustStringForLocaleDirection(text, &localized_text))
- text.swap(localized_text);
-
- wcsncpy_s(info->item.pszText, info->item.cchTextMax, text.c_str(),
- _TRUNCATE);
- }
- // Instructs windows to cache the values for this node.
- info->item.mask |= TVIF_DI_SETITEM;
- // Return value ignored.
- return 0;
- }
-
- case TVN_ITEMEXPANDING: {
- // Notification that a node is expanding. If we haven't populated the
- // tree view with the contents of the model, we do it here.
- DCHECK(model_);
- NMTREEVIEW* info = reinterpret_cast<NMTREEVIEW*>(l_param);
- NodeDetails* details =
- GetNodeDetailsByID(static_cast<int>(info->itemNew.lParam));
- if (!details->loaded_children) {
- details->loaded_children = true;
- for (int i = 0; i < model_->GetChildCount(details->node); ++i)
- CreateItem(details->tree_item, TVI_LAST,
- model_->GetChild(details->node, i));
- }
- // Return FALSE to allow the item to be expanded.
- return FALSE;
- }
-
- case TVN_SELCHANGED:
- if (controller_)
- controller_->OnTreeViewSelectionChanged(this);
- break;
-
- case TVN_BEGINLABELEDIT: {
- NMTVDISPINFO* info = reinterpret_cast<NMTVDISPINFO*>(l_param);
- NodeDetails* details =
- GetNodeDetailsByID(static_cast<int>(info->item.lParam));
- // Return FALSE to allow editing.
- if (!controller_ || controller_->CanEdit(this, details->node)) {
- editing_node_ = details->node;
- return FALSE;
- }
- return TRUE;
- }
-
- case TVN_ENDLABELEDIT: {
- NMTVDISPINFO* info = reinterpret_cast<NMTVDISPINFO*>(l_param);
- if (info->item.pszText) {
- // User accepted edit.
- NodeDetails* details =
- GetNodeDetailsByID(static_cast<int>(info->item.lParam));
- model_->SetTitle(details->node, info->item.pszText);
- editing_node_ = NULL;
- // Return FALSE so that the tree item doesn't change its text (if the
- // model changed the value, it should have sent out notification which
- // will have updated the value).
- return FALSE;
- }
- editing_node_ = NULL;
- // Return value ignored.
- return 0;
- }
-
- case TVN_KEYDOWN:
- if (controller_) {
- NMTVKEYDOWN* key_down_message =
- reinterpret_cast<NMTVKEYDOWN*>(l_param);
- controller_->OnTreeViewKeyDown(key_down_message->wVKey);
- }
- break;
-
- default:
- break;
- }
- return 0;
-}
-
-bool TreeView::OnKeyDown(int virtual_key_code) {
- if (virtual_key_code == VK_F2) {
- if (!GetEditingNode()) {
- TreeModelNode* selected_node = GetSelectedNode();
- if (selected_node)
- StartEditing(selected_node);
- }
- return true;
- } else if (virtual_key_code == VK_RETURN && !process_enter_) {
- Widget* widget = GetWidget();
- DCHECK(widget);
- FocusManager* fm = FocusManager::GetFocusManager(widget->GetNativeView());
- DCHECK(fm);
- Accelerator accelerator(Accelerator(static_cast<int>(virtual_key_code),
- win_util::IsShiftPressed(),
- win_util::IsCtrlPressed(),
- win_util::IsAltPressed()));
- fm->ProcessAccelerator(accelerator);
- return true;
- }
- return false;
-}
-
-void TreeView::OnContextMenu(const CPoint& location) {
- if (!GetContextMenuController())
- return;
-
- if (location.x == -1 && location.y == -1) {
- // Let NativeControl's implementation handle keyboard gesture.
- NativeControl::OnContextMenu(location);
- return;
- }
-
- if (show_context_menu_only_when_node_selected_) {
- if (!GetSelectedNode())
- return;
-
- // Make sure the mouse is over the selected node.
- TVHITTESTINFO hit_info;
- gfx::Point local_loc(location);
- ConvertPointToView(NULL, this, &local_loc);
- hit_info.pt.x = local_loc.x();
- hit_info.pt.y = local_loc.y();
- HTREEITEM hit_item = TreeView_HitTest(tree_view_, &hit_info);
- if (!hit_item ||
- GetNodeDetails(GetSelectedNode())->tree_item != hit_item ||
- (hit_info.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT |
- TVHT_ONITEMINDENT)) == 0) {
- return;
- }
- }
- ShowContextMenu(location.x, location.y, true);
-}
-
-TreeModelNode* TreeView::GetNodeForTreeItem(HTREEITEM tree_item) {
- NodeDetails* details = GetNodeDetailsByTreeItem(tree_item);
- return details ? details->node : NULL;
-}
-
-HTREEITEM TreeView::GetTreeItemForNode(TreeModelNode* node) {
- NodeDetails* details = GetNodeDetails(node);
- return details ? details->tree_item : NULL;
-}
-
-void TreeView::DeleteRootItems() {
- HTREEITEM root = TreeView_GetRoot(tree_view_);
- if (root) {
- if (root_shown_) {
- RecursivelyDelete(GetNodeDetailsByTreeItem(root));
- } else {
- do {
- RecursivelyDelete(GetNodeDetailsByTreeItem(root));
- } while ((root = TreeView_GetRoot(tree_view_)));
- }
- }
-}
-
-void TreeView::CreateRootItems() {
- DCHECK(model_);
- TreeModelNode* root = model_->GetRoot();
- if (root_shown_) {
- CreateItem(NULL, TVI_LAST, root);
- } else {
- for (int i = 0; i < model_->GetChildCount(root); ++i)
- CreateItem(NULL, TVI_LAST, model_->GetChild(root, i));
- }
-}
-
-void TreeView::CreateItem(HTREEITEM parent_item,
- HTREEITEM after,
- TreeModelNode* node) {
- DCHECK(node);
- TVINSERTSTRUCT insert_struct = {0};
- insert_struct.hParent = parent_item;
- insert_struct.hInsertAfter = after;
- insert_struct.itemex.mask = TVIF_PARAM | TVIF_CHILDREN | TVIF_TEXT |
- TVIF_SELECTEDIMAGE | TVIF_IMAGE;
- // Call us back for the text.
- insert_struct.itemex.pszText = LPSTR_TEXTCALLBACK;
- // And the number of children.
- insert_struct.itemex.cChildren = I_CHILDRENCALLBACK;
- // Set the index of the icons to use. These are relative to the imagelist
- // created in CreateImageList.
- int icon_index = model_->GetIconIndex(node);
- if (icon_index == -1) {
- insert_struct.itemex.iImage = 0;
- insert_struct.itemex.iSelectedImage = 1;
- } else {
- // The first two images are the default ones.
- insert_struct.itemex.iImage = icon_index + 2;
- insert_struct.itemex.iSelectedImage = icon_index + 2;
- }
- int node_id = next_id_++;
- insert_struct.itemex.lParam = node_id;
-
- // Invoking TreeView_InsertItem triggers OnNotify to be called. As such,
- // we set the map entries before adding the item.
- NodeDetails* node_details = new NodeDetails(node_id, node);
-
- node_to_details_map_[node] = node_details;
- id_to_details_map_[node_id] = node_details;
-
- node_details->tree_item = TreeView_InsertItem(tree_view_, &insert_struct);
-}
-
-void TreeView::RecursivelyDelete(NodeDetails* node) {
- DCHECK(node);
- HTREEITEM item = node->tree_item;
- DCHECK(item);
-
- // Recurse through children.
- for (HTREEITEM child = TreeView_GetChild(tree_view_, item);
- child ; child = TreeView_GetNextSibling(tree_view_, child)) {
- RecursivelyDelete(GetNodeDetailsByTreeItem(child));
- }
-
- TreeView_DeleteItem(tree_view_, item);
-
- // finally, it is safe to delete the data for this node.
- id_to_details_map_.erase(node->id);
- node_to_details_map_.erase(node->node);
- delete node;
-}
-
-TreeView::NodeDetails* TreeView::GetNodeDetailsByTreeItem(HTREEITEM tree_item) {
- DCHECK(tree_view_ && tree_item);
- TV_ITEM tv_item = {0};
- tv_item.hItem = tree_item;
- tv_item.mask = TVIF_PARAM;
- if (TreeView_GetItem(tree_view_, &tv_item))
- return GetNodeDetailsByID(static_cast<int>(tv_item.lParam));
- return NULL;
-}
-
-HIMAGELIST TreeView::CreateImageList() {
- std::vector<SkBitmap> model_images;
- model_->GetIcons(&model_images);
-
- bool rtl = UILayoutIsRightToLeft();
- // Creates the default image list used for trees.
- SkBitmap* closed_icon =
- ResourceBundle::GetSharedInstance().GetBitmapNamed(
- (rtl ? IDR_FOLDER_CLOSED_RTL : IDR_FOLDER_CLOSED));
- SkBitmap* opened_icon =
- ResourceBundle::GetSharedInstance().GetBitmapNamed(
- (rtl ? IDR_FOLDER_OPEN_RTL : IDR_FOLDER_OPEN));
- int width = closed_icon->width();
- int height = closed_icon->height();
- DCHECK(opened_icon->width() == width && opened_icon->height() == height);
- HIMAGELIST image_list =
- ImageList_Create(width, height, ILC_COLOR32, model_images.size() + 2,
- model_images.size() + 2);
- if (image_list) {
- // NOTE: the order the images are added in effects the selected
- // image index when adding items to the tree. If you change the
- // order you'll undoubtedly need to update itemex.iSelectedImage
- // when the item is added.
- HICON h_closed_icon = IconUtil::CreateHICONFromSkBitmap(*closed_icon);
- HICON h_opened_icon = IconUtil::CreateHICONFromSkBitmap(*opened_icon);
- ImageList_AddIcon(image_list, h_closed_icon);
- ImageList_AddIcon(image_list, h_opened_icon);
- DestroyIcon(h_closed_icon);
- DestroyIcon(h_opened_icon);
- for (size_t i = 0; i < model_images.size(); ++i) {
- HICON model_icon = IconUtil::CreateHICONFromSkBitmap(model_images[i]);
- ImageList_AddIcon(image_list, model_icon);
- DestroyIcon(model_icon);
- }
- }
- return image_list;
-}
-
-HTREEITEM TreeView::GetTreeItemForNodeDuringMutation(TreeModelNode* node) {
- if (node_to_details_map_.find(node) == node_to_details_map_.end()) {
- // User hasn't navigated to this entry yet. Ignore the change.
- return NULL;
- }
- if (!root_shown_ || node != model_->GetRoot()) {
- const NodeDetails* details = GetNodeDetails(node);
- if (!details->loaded_children)
- return NULL;
- return details->tree_item;
- }
- return TreeView_GetRoot(tree_view_);
-}
-
-LRESULT CALLBACK TreeView::TreeWndProc(HWND window,
- UINT message,
- WPARAM w_param,
- LPARAM l_param) {
- TreeViewWrapper* wrapper = reinterpret_cast<TreeViewWrapper*>(
- GetWindowLongPtr(window, GWLP_USERDATA));
- DCHECK(wrapper);
- TreeView* tree = wrapper->tree_view;
-
- // We handle the messages WM_ERASEBKGND and WM_PAINT such that we paint into
- // a DIB first and then perform a BitBlt from the DIB into the underlying
- // window's DC. This double buffering code prevents the tree view from
- // flickering during resize.
- switch (message) {
- case WM_ERASEBKGND:
- return 1;
-
- case WM_PAINT: {
- ChromeCanvasPaint canvas(window);
- if (canvas.isEmpty())
- return 0;
-
- HDC dc = canvas.beginPlatformPaint();
- if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) {
- // ChromeCanvas ends up configuring the DC with a mode of GM_ADVANCED.
- // For some reason a graphics mode of ADVANCED triggers all the text
- // to be mirrored when RTL. Set the mode back to COMPATIBLE and
- // explicitly set the layout. Additionally SetWorldTransform and
- // COMPATIBLE don't play nicely together. We need to use
- // SetViewportOrgEx when using a mode of COMPATIBLE.
- //
- // Reset the transform to the identify transform. Even though
- // SetWorldTransform and COMPATIBLE don't play nicely, bits of the
- // transform still carry over when we set the mode.
- XFORM xform = {0};
- xform.eM11 = xform.eM22 = 1;
- SetWorldTransform(dc, &xform);
-
- // Set the mode and layout.
- SetGraphicsMode(dc, GM_COMPATIBLE);
- SetLayout(dc, LAYOUT_RTL);
-
- // Transform the viewport such that the origin of the dc is that of
- // the dirty region. This way when we invoke WM_PRINTCLIENT tree-view
- // draws the dirty region at the origin of the DC so that when we
- // copy the bits everything lines up nicely. Without this we end up
- // copying the upper-left corner to the redraw region.
- SetViewportOrgEx(dc, -canvas.paintStruct().rcPaint.left,
- -canvas.paintStruct().rcPaint.top, NULL);
- }
- SendMessage(window, WM_PRINTCLIENT, reinterpret_cast<WPARAM>(dc), 0);
- if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) {
- // Reset the origin of the dc back to 0. This way when we copy the bits
- // over we copy the right bits.
- SetViewportOrgEx(dc, 0, 0, NULL);
- }
- canvas.endPlatformPaint();
- return 0;
- }
-
- case WM_RBUTTONDOWN:
- if (tree->select_on_right_mouse_down_) {
- TVHITTESTINFO hit_info;
- hit_info.pt.x = GET_X_LPARAM(l_param);
- hit_info.pt.y = GET_Y_LPARAM(l_param);
- HTREEITEM hit_item = TreeView_HitTest(window, &hit_info);
- if (hit_item && (hit_info.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT |
- TVHT_ONITEMINDENT)) != 0)
- TreeView_SelectItem(tree->tree_view_, hit_item);
- }
- // Fall through and let the default handler process as well.
- break;
- }
- WNDPROC handler = tree->original_handler_;
- DCHECK(handler);
- return CallWindowProc(handler, window, message, w_param, l_param);
-}
-
-} // namespace views
diff --git a/chrome/views/controls/tree/tree_view.h b/chrome/views/controls/tree/tree_view.h
deleted file mode 100644
index ca6f784..0000000
--- a/chrome/views/controls/tree/tree_view.h
+++ /dev/null
@@ -1,305 +0,0 @@
-// 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 CHROME_VIEWS_CONTROLS_TREE_TREE_VIEW_H_
-#define CHROME_VIEWS_CONTROLS_TREE_TREE_VIEW_H_
-
-#include <map>
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "chrome/views/controls/native_control.h"
-#include "chrome/views/controls/tree/tree_model.h"
-
-namespace views {
-
-class TreeView;
-
-// TreeViewController ---------------------------------------------------------
-
-// Controller for the treeview.
-class TreeViewController {
- public:
- // Notification that the selection of the tree view has changed. Use
- // GetSelectedNode to find the current selection.
- virtual void OnTreeViewSelectionChanged(TreeView* tree_view) = 0;
-
- // Returns true if the node can be edited. This is only used if the
- // TreeView is editable.
- virtual bool CanEdit(TreeView* tree_view, TreeModelNode* node) {
- return true;
- }
-
- // Invoked when a key is pressed on the tree view.
- virtual void OnTreeViewKeyDown(unsigned short virtual_keycode) {}
-};
-
-// TreeView -------------------------------------------------------------------
-
-// TreeView displays hierarchical data as returned from a TreeModel. The user
-// can expand, collapse and edit the items. A Controller may be attached to
-// receive notification of selection changes and restrict editing.
-class TreeView : public NativeControl, TreeModelObserver {
- public:
- TreeView();
- virtual ~TreeView();
-
- // Is dragging enabled? The default is false.
- void set_drag_enabled(bool drag_enabled) { drag_enabled_ = drag_enabled; }
- bool drag_enabled() const { return drag_enabled_; }
-
- // Sets the model. TreeView does not take ownership of the model.
- void SetModel(TreeModel* model);
- TreeModel* model() const { return model_; }
-
- // Sets whether the user can edit the nodes. The default is true. If true,
- // the Controller is queried to determine if a particular node can be edited.
- void SetEditable(bool editable);
-
- // Edits the specified node. This cancels the current edit and expands
- // all parents of node.
- void StartEditing(TreeModelNode* node);
-
- // Cancels the current edit. Does nothing if not editing.
- void CancelEdit();
-
- // Commits the current edit. Does nothing if not editing.
- void CommitEdit();
-
- // If the user is editing a node, it is returned. If the user is not
- // editing a node, NULL is returned.
- TreeModelNode* GetEditingNode();
-
- // Selects the specified node. This expands all the parents of node.
- void SetSelectedNode(TreeModelNode* node);
-
- // Returns the selected node, or NULL if nothing is selected.
- TreeModelNode* GetSelectedNode();
-
- // Make sure node and all its parents are expanded.
- void Expand(TreeModelNode* node);
-
- // Convenience to expand ALL nodes in the tree.
- void ExpandAll();
-
- // Invoked from ExpandAll(). Expands the supplied node and recursively
- // invokes itself with all children.
- void ExpandAll(TreeModelNode* node);
-
- // Returns true if the specified node is expanded.
- bool IsExpanded(TreeModelNode* node);
-
- // Sets whether the root is shown. If true, the root node of the tree is
- // shown, if false only the children of the root are shown. The default is
- // true.
- void SetRootShown(bool root_visible);
-
- // TreeModelObserver methods. Don't call these directly, instead your model
- // should notify the observer TreeView adds to it.
- virtual void TreeNodesAdded(TreeModel* model,
- TreeModelNode* parent,
- int start,
- int count);
- virtual void TreeNodesRemoved(TreeModel* model,
- TreeModelNode* parent,
- int start,
- int count);
- virtual void TreeNodeChildrenReordered(TreeModel* model,
- TreeModelNode* parent);
- virtual void TreeNodeChanged(TreeModel* model, TreeModelNode* node);
-
- // Sets the controller, which may be null. TreeView does not take ownership
- // of the controller.
- void SetController(TreeViewController* controller) {
- controller_ = controller;
- }
-
- // Sets whether enter is processed when not editing. If true, enter will
- // expand/collapse the node. If false, enter is passed to the focus manager
- // so that an enter accelerator can be enabled. The default is false.
- //
- // NOTE: Changing this has no effect after the hwnd has been created.
- void SetProcessesEnter(bool process_enter) {
- process_enter_ = process_enter;
- }
- bool GetProcessedEnter() { return process_enter_; }
-
- // Sets when the ContextMenuController is notified. If true, the
- // ContextMenuController is only notified when a node is selected and the
- // mouse is over a node. The default is true.
- void SetShowContextMenuOnlyWhenNodeSelected(bool value) {
- show_context_menu_only_when_node_selected_ = value;
- }
- bool GetShowContextMenuOnlyWhenNodeSelected() {
- return show_context_menu_only_when_node_selected_;
- }
-
- // If true, a right click selects the node under the mouse. The default
- // is true.
- void SetSelectOnRightMouseDown(bool value) {
- select_on_right_mouse_down_ = value;
- }
- bool GetSelectOnRightMouseDown() { return select_on_right_mouse_down_; }
-
- protected:
- // Overriden to return a location based on the selected node.
- virtual gfx::Point GetKeyboardContextMenuLocation();
-
- // Creates and configures the tree_view.
- virtual HWND CreateNativeControl(HWND parent_container);
-
- // Invoked when the native control sends a WM_NOTIFY message to its parent.
- // Handles a variety of potential TreeView messages.
- virtual LRESULT OnNotify(int w_param, LPNMHDR l_param);
-
- // Yes, we want to be notified of key down for two reasons. To circumvent
- // VK_ENTER from toggling the expaned state when processes_enter_ is false,
- // and to have F2 start editting.
- virtual bool NotifyOnKeyDown() const { return true; }
- virtual bool OnKeyDown(int virtual_key_code);
-
- virtual void OnContextMenu(const CPoint& location);
-
- // Returns the TreeModelNode for |tree_item|.
- TreeModelNode* GetNodeForTreeItem(HTREEITEM tree_item);
-
- // Returns the tree item for |node|.
- HTREEITEM GetTreeItemForNode(TreeModelNode* node);
-
- private:
- // See notes in TableView::TableViewWrapper for why this is needed.
- struct TreeViewWrapper {
- explicit TreeViewWrapper(TreeView* view) : tree_view(view) { }
- TreeView* tree_view;
- };
-
- // Internally used to track the state of nodes. NodeDetails are lazily created
- // as the user expands nodes.
- struct NodeDetails {
- NodeDetails(int id, TreeModelNode* node)
- : id(id), node(node), tree_item(NULL), loaded_children(false) {}
-
- // Unique identifier for the node. This corresponds to the lParam of
- // the tree item.
- const int id;
-
- // The node from the model.
- TreeModelNode* node;
-
- // From the native TreeView.
- //
- // This should be treated as const, but can't due to timing in creating the
- // entry.
- HTREEITEM tree_item;
-
- // Whether the children have been loaded.
- bool loaded_children;
- };
-
- // Deletes the root items from the treeview. This is used when the model
- // changes.
- void DeleteRootItems();
-
- // Creates the root items in the treeview from the model. This is used when
- // the model changes.
- void CreateRootItems();
-
- // Creates and adds an item to the treeview. parent_item identifies the
- // parent and is null for root items. after dictates where among the
- // children of parent_item the item is to be created. node is the node from
- // the model.
- void CreateItem(HTREEITEM parent_item, HTREEITEM after, TreeModelNode* node);
-
- // Removes entries from the map for item. This method will also
- // remove the items from the TreeView because the process of
- // deleting an item will send an TVN_GETDISPINFO message, consulting
- // our internal map data.
- void RecursivelyDelete(NodeDetails* node);
-
- // Returns the NodeDetails by node from the model.
- NodeDetails* GetNodeDetails(TreeModelNode* node) {
- DCHECK(node &&
- node_to_details_map_.find(node) != node_to_details_map_.end());
- return node_to_details_map_[node];
- }
-
- // Returns the NodeDetails by identifier (lparam of the HTREEITEM).
- NodeDetails* GetNodeDetailsByID(int id) {
- DCHECK(id_to_details_map_.find(id) != id_to_details_map_.end());
- return id_to_details_map_[id];
- }
-
- // Returns the NodeDetails by HTREEITEM.
- NodeDetails* GetNodeDetailsByTreeItem(HTREEITEM tree_item);
-
- // Creates the image list to use for the tree.
- HIMAGELIST CreateImageList();
-
- // Returns the HTREEITEM for |node|. This is intended to be called when a
- // model mutation event occur with |node| as the parent. This returns null
- // if the user has never expanded |node| or all of its parents.
- HTREEITEM GetTreeItemForNodeDuringMutation(TreeModelNode* node);
-
- // The window function installed on the treeview.
- static LRESULT CALLBACK TreeWndProc(HWND window,
- UINT message,
- WPARAM w_param,
- LPARAM l_param);
-
- // Handle to the tree window.
- HWND tree_view_;
-
- // The model, may be null.
- TreeModel* model_;
-
- // Maps from id to NodeDetails.
- std::map<int,NodeDetails*> id_to_details_map_;
-
- // Maps from model entry to NodeDetails.
- std::map<TreeModelNode*,NodeDetails*> node_to_details_map_;
-
- // Whether the user can edit the items.
- bool editable_;
-
- // Next id to create. Any time an item is added this is incremented by one.
- int next_id_;
-
- // The controller.
- TreeViewController* controller_;
-
- // Node being edited. If null, not editing.
- TreeModelNode* editing_node_;
-
- // Whether or not the root is shown in the tree.
- bool root_shown_;
-
- // Whether enter should be processed by the tree when not editing.
- bool process_enter_;
-
- // Whether we notify context menu controller only when mouse is over node
- // and node is selected.
- bool show_context_menu_only_when_node_selected_;
-
- // Whether the selection is changed on right mouse down.
- bool select_on_right_mouse_down_;
-
- // A wrapper around 'this', used for subclassing the TreeView control.
- TreeViewWrapper wrapper_;
-
- // Original handler installed on the TreeView.
- WNDPROC original_handler_;
-
- bool drag_enabled_;
-
- // Did the model return a non-empty set of icons from GetIcons?
- bool has_custom_icons_;
-
- HIMAGELIST image_list_;
-
- DISALLOW_COPY_AND_ASSIGN(TreeView);
-};
-
-} // namespace views
-
-#endif // CHROME_VIEWS_CONTROLS_TREE_TREE_VIEW_H_