| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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. | |
| 4 | |
| 5 #ifndef VIEWS_CONTROLS_TREE_TREE_VIEW_H_ | |
| 6 #define VIEWS_CONTROLS_TREE_TREE_VIEW_H_ | |
| 7 #pragma once | |
| 8 | |
| 9 #include <windows.h> | |
| 10 #include <commctrl.h> | |
| 11 | |
| 12 #include <map> | |
| 13 | |
| 14 #include "base/basictypes.h" | |
| 15 #include "base/compiler_specific.h" | |
| 16 #include "ui/base/keycodes/keyboard_codes.h" | |
| 17 #include "ui/base/models/tree_model.h" | |
| 18 #include "views/controls/native_control.h" | |
| 19 | |
| 20 namespace views { | |
| 21 | |
| 22 class TreeView; | |
| 23 | |
| 24 // TreeViewController --------------------------------------------------------- | |
| 25 | |
| 26 // Controller for the treeview. | |
| 27 class TreeViewController { | |
| 28 public: | |
| 29 // Notification that the selection of the tree view has changed. Use | |
| 30 // GetSelectedNode to find the current selection. | |
| 31 virtual void OnTreeViewSelectionChanged(TreeView* tree_view) = 0; | |
| 32 | |
| 33 // Returns true if the node can be edited. This is only used if the | |
| 34 // TreeView is editable. | |
| 35 virtual bool CanEdit(TreeView* tree_view, ui::TreeModelNode* node) { | |
| 36 return true; | |
| 37 } | |
| 38 | |
| 39 // Invoked when a key is pressed on the tree view. | |
| 40 virtual void OnTreeViewKeyDown(ui::KeyboardCode keycode) {} | |
| 41 }; | |
| 42 | |
| 43 // TreeView ------------------------------------------------------------------- | |
| 44 | |
| 45 // TreeView displays hierarchical data as returned from a TreeModel. The user | |
| 46 // can expand, collapse and edit the items. A Controller may be attached to | |
| 47 // receive notification of selection changes and restrict editing. | |
| 48 class VIEWS_EXPORT TreeView : public NativeControl, ui::TreeModelObserver { | |
| 49 public: | |
| 50 TreeView(); | |
| 51 virtual ~TreeView(); | |
| 52 | |
| 53 // Is dragging enabled? The default is false. | |
| 54 void set_drag_enabled(bool drag_enabled) { drag_enabled_ = drag_enabled; } | |
| 55 bool drag_enabled() const { return drag_enabled_; } | |
| 56 | |
| 57 // Sets the model. TreeView does not take ownership of the model. | |
| 58 void SetModel(ui::TreeModel* model); | |
| 59 ui::TreeModel* model() const { return model_; } | |
| 60 | |
| 61 // Sets whether to automatically expand children when a parent node is | |
| 62 // expanded. The default is false. If true, when a node in the tree is | |
| 63 // expanded for the first time, its children are also automatically expanded. | |
| 64 // If a node is subsequently collapsed and expanded again, the children | |
| 65 // will not be automatically expanded. | |
| 66 void set_auto_expand_children(bool auto_expand_children) { | |
| 67 auto_expand_children_ = auto_expand_children; | |
| 68 } | |
| 69 | |
| 70 // Sets whether the user can edit the nodes. The default is true. If true, | |
| 71 // the Controller is queried to determine if a particular node can be edited. | |
| 72 void SetEditable(bool editable); | |
| 73 | |
| 74 // Sets whether lines are drawn from the root node to child nodes (and | |
| 75 // whether plus boxes show up next to the root node.) The default is false. | |
| 76 // If root_shown_ is false, the children of the root act as the roots in the | |
| 77 // native control, and so this setting takes effect for them. | |
| 78 void set_lines_at_root(bool lines_at_root) { | |
| 79 lines_at_root_ = lines_at_root; | |
| 80 } | |
| 81 | |
| 82 // Overridden from View: | |
| 83 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; | |
| 84 | |
| 85 // Edits the specified node. This cancels the current edit and expands | |
| 86 // all parents of node. | |
| 87 void StartEditing(ui::TreeModelNode* node); | |
| 88 | |
| 89 // Cancels the current edit. Does nothing if not editing. | |
| 90 void CancelEdit(); | |
| 91 | |
| 92 // Commits the current edit. Does nothing if not editing. | |
| 93 void CommitEdit(); | |
| 94 | |
| 95 // If the user is editing a node, it is returned. If the user is not | |
| 96 // editing a node, NULL is returned. | |
| 97 ui::TreeModelNode* GetEditingNode(); | |
| 98 | |
| 99 // Selects the specified node. This expands all the parents of node. | |
| 100 void SetSelectedNode(ui::TreeModelNode* node); | |
| 101 | |
| 102 // Returns the selected node, or NULL if nothing is selected. | |
| 103 ui::TreeModelNode* GetSelectedNode(); | |
| 104 | |
| 105 // Make sure node and all its parents are expanded. | |
| 106 void Expand(ui::TreeModelNode* node); | |
| 107 | |
| 108 // Invoked from ExpandAll(). Expands the supplied node and recursively | |
| 109 // invokes itself with all children. | |
| 110 void ExpandAll(ui::TreeModelNode* node); | |
| 111 | |
| 112 // Returns true if the specified node is expanded. | |
| 113 bool IsExpanded(ui::TreeModelNode* node); | |
| 114 | |
| 115 // Sets whether the root is shown. If true, the root node of the tree is | |
| 116 // shown, if false only the children of the root are shown. The default is | |
| 117 // true. | |
| 118 void SetRootShown(bool root_visible); | |
| 119 | |
| 120 // Begin TreeModelObserver implementation. | |
| 121 // These methods shouldn't be called directly. The model is responsible for | |
| 122 // firing them. | |
| 123 virtual void TreeNodesAdded(ui::TreeModel* model, | |
| 124 ui::TreeModelNode* parent, | |
| 125 int start, | |
| 126 int count) OVERRIDE; | |
| 127 virtual void TreeNodesRemoved(ui::TreeModel* model, | |
| 128 ui::TreeModelNode* parent, | |
| 129 int start, | |
| 130 int count) OVERRIDE; | |
| 131 virtual void TreeNodeChanged(ui::TreeModel* model, | |
| 132 ui::TreeModelNode* node) OVERRIDE; | |
| 133 // End TreeModelObserver implementation. | |
| 134 | |
| 135 // Sets the controller, which may be null. TreeView does not take ownership | |
| 136 // of the controller. | |
| 137 void SetController(TreeViewController* controller) { | |
| 138 controller_ = controller; | |
| 139 } | |
| 140 | |
| 141 // Sets whether enter is processed when not editing. If true, enter will | |
| 142 // expand/collapse the node. If false, enter is passed to the focus manager | |
| 143 // so that an enter accelerator can be enabled. The default is false. | |
| 144 // | |
| 145 // NOTE: Changing this has no effect after the hwnd has been created. | |
| 146 void SetProcessesEnter(bool process_enter) { | |
| 147 process_enter_ = process_enter; | |
| 148 } | |
| 149 bool GetProcessedEnter() { return process_enter_; } | |
| 150 | |
| 151 // Sets when the ContextMenuController is notified. If true, the | |
| 152 // ContextMenuController is only notified when a node is selected and the | |
| 153 // mouse is over a node. The default is true. | |
| 154 void SetShowContextMenuOnlyWhenNodeSelected(bool value) { | |
| 155 show_context_menu_only_when_node_selected_ = value; | |
| 156 } | |
| 157 bool GetShowContextMenuOnlyWhenNodeSelected() { | |
| 158 return show_context_menu_only_when_node_selected_; | |
| 159 } | |
| 160 | |
| 161 // If true, a right click selects the node under the mouse. The default | |
| 162 // is true. | |
| 163 void SetSelectOnRightMouseDown(bool value) { | |
| 164 select_on_right_mouse_down_ = value; | |
| 165 } | |
| 166 bool GetSelectOnRightMouseDown() { return select_on_right_mouse_down_; } | |
| 167 | |
| 168 protected: | |
| 169 // Overriden to return a location based on the selected node. | |
| 170 virtual gfx::Point GetKeyboardContextMenuLocation(); | |
| 171 | |
| 172 // Creates and configures the tree_view. | |
| 173 virtual HWND CreateNativeControl(HWND parent_container); | |
| 174 | |
| 175 // Invoked when the native control sends a WM_NOTIFY message to its parent. | |
| 176 // Handles a variety of potential TreeView messages. | |
| 177 virtual LRESULT OnNotify(int w_param, LPNMHDR l_param); | |
| 178 | |
| 179 // Invoked when the native control send a WM_DESTROY message to its parent. | |
| 180 virtual void OnDestroy(); | |
| 181 | |
| 182 // We pay attention to key down for two reasons: to circumvent VK_ENTER from | |
| 183 // toggling the expaned state when processes_enter_ is false, and to have F2 | |
| 184 // start editting. | |
| 185 virtual bool OnKeyDown(ui::KeyboardCode virtual_key_code); | |
| 186 | |
| 187 virtual void OnContextMenu(const POINT& location); | |
| 188 | |
| 189 // Returns the TreeModelNode for |tree_item|. | |
| 190 ui::TreeModelNode* GetNodeForTreeItem(HTREEITEM tree_item); | |
| 191 | |
| 192 // Returns the tree item for |node|. | |
| 193 HTREEITEM GetTreeItemForNode(ui::TreeModelNode* node); | |
| 194 | |
| 195 private: | |
| 196 // See notes in TableView::TableViewWrapper for why this is needed. | |
| 197 struct TreeViewWrapper { | |
| 198 explicit TreeViewWrapper(TreeView* view) : tree_view(view) { } | |
| 199 TreeView* tree_view; | |
| 200 }; | |
| 201 | |
| 202 // Internally used to track the state of nodes. NodeDetails are lazily created | |
| 203 // as the user expands nodes. | |
| 204 struct NodeDetails { | |
| 205 NodeDetails(int id, ui::TreeModelNode* node) | |
| 206 : id(id), node(node), tree_item(NULL), loaded_children(false) {} | |
| 207 | |
| 208 // Unique identifier for the node. This corresponds to the lParam of | |
| 209 // the tree item. | |
| 210 const int id; | |
| 211 | |
| 212 // The node from the model. | |
| 213 ui::TreeModelNode* node; | |
| 214 | |
| 215 // From the native TreeView. | |
| 216 // | |
| 217 // This should be treated as const, but can't due to timing in creating the | |
| 218 // entry. | |
| 219 HTREEITEM tree_item; | |
| 220 | |
| 221 // Whether the children have been loaded. | |
| 222 bool loaded_children; | |
| 223 }; | |
| 224 | |
| 225 // Cleanup all resources used by treeview. | |
| 226 void Cleanup(); | |
| 227 | |
| 228 // Make sure the tree view is observing the tree model. | |
| 229 void AddObserverToModel(); | |
| 230 | |
| 231 // Make sure the tree view is no longer observing the tree model. | |
| 232 void RemoveObserverFromModel(); | |
| 233 | |
| 234 // Deletes the root items from the treeview. This is used when the model | |
| 235 // changes. | |
| 236 void DeleteRootItems(); | |
| 237 | |
| 238 // Creates the root items in the treeview from the model. This is used when | |
| 239 // the model changes. | |
| 240 void CreateRootItems(); | |
| 241 | |
| 242 // Creates and adds an item to the treeview. parent_item identifies the | |
| 243 // parent and is null for root items. after dictates where among the | |
| 244 // children of parent_item the item is to be created. node is the node from | |
| 245 // the model. | |
| 246 void CreateItem(HTREEITEM parent_item, HTREEITEM after, | |
| 247 ui::TreeModelNode* node); | |
| 248 | |
| 249 // Removes entries from the map for item. This method will also | |
| 250 // remove the items from the TreeView because the process of | |
| 251 // deleting an item will send an TVN_GETDISPINFO message, consulting | |
| 252 // our internal map data. | |
| 253 void RecursivelyDelete(NodeDetails* node); | |
| 254 | |
| 255 // Returns the NodeDetails by node from the model. | |
| 256 NodeDetails* GetNodeDetails(ui::TreeModelNode* node); | |
| 257 | |
| 258 // Returns the NodeDetails by identifier (lparam of the HTREEITEM). | |
| 259 NodeDetails* GetNodeDetailsByID(int id); | |
| 260 | |
| 261 // Returns the NodeDetails by HTREEITEM. | |
| 262 NodeDetails* GetNodeDetailsByTreeItem(HTREEITEM tree_item); | |
| 263 | |
| 264 // Creates the image list to use for the tree. | |
| 265 HIMAGELIST CreateImageList(); | |
| 266 | |
| 267 // Returns the HTREEITEM for |node|. This is intended to be called when a | |
| 268 // model mutation event occur with |node| as the parent. This returns null | |
| 269 // if the user has never expanded |node| or all of its parents. | |
| 270 HTREEITEM GetTreeItemForNodeDuringMutation(ui::TreeModelNode* node); | |
| 271 | |
| 272 // The window function installed on the treeview. | |
| 273 static LRESULT CALLBACK TreeWndProc(HWND window, | |
| 274 UINT message, | |
| 275 WPARAM w_param, | |
| 276 LPARAM l_param); | |
| 277 | |
| 278 // Handle to the tree window. | |
| 279 HWND tree_view_; | |
| 280 | |
| 281 // The model, may be null. | |
| 282 ui::TreeModel* model_; | |
| 283 | |
| 284 // Maps from id to NodeDetails. | |
| 285 std::map<int, NodeDetails*> id_to_details_map_; | |
| 286 | |
| 287 // Maps from model entry to NodeDetails. | |
| 288 std::map<ui::TreeModelNode*, NodeDetails*> node_to_details_map_; | |
| 289 | |
| 290 // Whether to automatically expand children when a parent node is expanded. | |
| 291 bool auto_expand_children_; | |
| 292 | |
| 293 // Whether the user can edit the items. | |
| 294 bool editable_; | |
| 295 | |
| 296 // Next id to create. Any time an item is added this is incremented by one. | |
| 297 int next_id_; | |
| 298 | |
| 299 // The controller. | |
| 300 TreeViewController* controller_; | |
| 301 | |
| 302 // Node being edited. If null, not editing. | |
| 303 ui::TreeModelNode* editing_node_; | |
| 304 | |
| 305 // Whether or not the root is shown in the tree. | |
| 306 bool root_shown_; | |
| 307 | |
| 308 // Whether lines are drawn from the root to the children. | |
| 309 bool lines_at_root_; | |
| 310 | |
| 311 // Whether enter should be processed by the tree when not editing. | |
| 312 bool process_enter_; | |
| 313 | |
| 314 // Whether we notify context menu controller only when mouse is over node | |
| 315 // and node is selected. | |
| 316 bool show_context_menu_only_when_node_selected_; | |
| 317 | |
| 318 // Whether the selection is changed on right mouse down. | |
| 319 bool select_on_right_mouse_down_; | |
| 320 | |
| 321 // A wrapper around 'this', used for subclassing the TreeView control. | |
| 322 TreeViewWrapper wrapper_; | |
| 323 | |
| 324 // Original handler installed on the TreeView. | |
| 325 WNDPROC original_handler_; | |
| 326 | |
| 327 bool drag_enabled_; | |
| 328 | |
| 329 // Has an observer been added to the model? | |
| 330 bool observer_added_; | |
| 331 | |
| 332 // Did the model return a non-empty set of icons from GetIcons? | |
| 333 bool has_custom_icons_; | |
| 334 | |
| 335 HIMAGELIST image_list_; | |
| 336 | |
| 337 DISALLOW_COPY_AND_ASSIGN(TreeView); | |
| 338 }; | |
| 339 | |
| 340 } // namespace views | |
| 341 | |
| 342 #endif // VIEWS_CONTROLS_TREE_TREE_VIEW_H_ | |
| OLD | NEW |