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. 4 5 #ifndef UI_VIEWS_CONTROLS_TREE_TREE_VIEW_VIEWS_H_ 6 #define UI_VIEWS_CONTROLS_TREE_TREE_VIEW_VIEWS_H_ 7 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/compiler_specific.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "ui/base/models/tree_node_model.h" 14 #include "ui/gfx/font.h" 15 #include "ui/gfx/image/image_skia.h" 16 #include "ui/views/controls/prefix_delegate.h" 17 #include "ui/views/controls/textfield/textfield_controller.h" 18 #include "ui/views/focus/focus_manager.h" 19 #include "ui/views/view.h" 20 21 namespace views { 22 23 class Textfield; 24 class TreeViewController; 25 class PrefixSelector; 26 27 // TreeView displays hierarchical data as returned from a TreeModel. The user 28 // can expand, collapse and edit the items. A Controller may be attached to 29 // receive notification of selection changes and restrict editing. 30 // 31 // Note on implementation. This implementation doesn't scale well. In particular 32 // it does not store any row information, but instead calculates it as 33 // necessary. But it's more than adequate for current uses. 34 class VIEWS_EXPORT TreeView : public ui::TreeModelObserver, 35 public TextfieldController, 36 public FocusChangeListener, 37 public PrefixDelegate { 38 public: 39 TreeView(); 40 virtual ~TreeView(); 41 42 // Returns new ScrollPane that contains the receiver. 43 View* CreateParentIfNecessary(); 44 45 // Sets the model. TreeView does not take ownership of the model. 46 void SetModel(ui::TreeModel* model); 47 ui::TreeModel* model() const { return model_; } 48 49 // Sets whether to automatically expand children when a parent node is 50 // expanded. The default is false. If true, when a node in the tree is 51 // expanded for the first time, its children are also automatically expanded. 52 // If a node is subsequently collapsed and expanded again, the children 53 // will not be automatically expanded. 54 void set_auto_expand_children(bool auto_expand_children) { 55 auto_expand_children_ = auto_expand_children; 56 } 57 58 // Sets whether the user can edit the nodes. The default is true. If true, 59 // the Controller is queried to determine if a particular node can be edited. 60 void SetEditable(bool editable); 61 62 // Edits the specified node. This cancels the current edit and expands all 63 // parents of node. 64 void StartEditing(ui::TreeModelNode* node); 65 66 // Cancels the current edit. Does nothing if not editing. 67 void CancelEdit(); 68 69 // Commits the current edit. Does nothing if not editing. 70 void CommitEdit(); 71 72 // If the user is editing a node, it is returned. If the user is not 73 // editing a node, NULL is returned. 74 ui::TreeModelNode* GetEditingNode(); 75 76 // Selects the specified node. This expands all the parents of node. 77 void SetSelectedNode(ui::TreeModelNode* model_node); 78 79 // Returns the selected node, or NULL if nothing is selected. 80 ui::TreeModelNode* GetSelectedNode(); 81 82 // Marks |model_node| as collapsed. This only effects the UI if node and all 83 // its parents are expanded (IsExpanded(model_node) returns true). 84 void Collapse(ui::TreeModelNode* model_node); 85 86 // Make sure node and all its parents are expanded. 87 void Expand(ui::TreeModelNode* node); 88 89 // Invoked from ExpandAll(). Expands the supplied node and recursively 90 // invokes itself with all children. 91 void ExpandAll(ui::TreeModelNode* node); 92 93 // Returns true if the specified node is expanded. 94 bool IsExpanded(ui::TreeModelNode* model_node); 95 96 // Sets whether the root is shown. If true, the root node of the tree is 97 // shown, if false only the children of the root are shown. The default is 98 // true. 99 void SetRootShown(bool root_visible); 100 101 // Sets the controller, which may be null. TreeView does not take ownership 102 // of the controller. 103 void SetController(TreeViewController* controller) { 104 controller_ = controller; 105 } 106 107 // Returns the node for the specified row, or NULL for an invalid row index. 108 ui::TreeModelNode* GetNodeForRow(int row); 109 110 // Maps a node to a row, returns -1 if node is not valid. 111 int GetRowForNode(ui::TreeModelNode* node); 112 113 views::Textfield* editor() { return editor_; } 114 115 // View overrides: 116 virtual void Layout() OVERRIDE; 117 virtual gfx::Size GetPreferredSize() OVERRIDE; 118 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE; 119 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; 120 virtual ui::TextInputClient* GetTextInputClient() OVERRIDE; 121 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; 122 virtual void ShowContextMenu(const gfx::Point& p, 123 ui::MenuSourceType source_type) OVERRIDE; 124 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; 125 126 // TreeModelObserver overrides: 127 virtual void TreeNodesAdded(ui::TreeModel* model, 128 ui::TreeModelNode* parent, 129 int start, 130 int count) OVERRIDE; 131 virtual void TreeNodesRemoved(ui::TreeModel* model, 132 ui::TreeModelNode* parent, 133 int start, 134 int count) OVERRIDE; 135 virtual void TreeNodeChanged(ui::TreeModel* model, 136 ui::TreeModelNode* model_node) OVERRIDE; 137 138 // TextfieldController overrides: 139 virtual void ContentsChanged(Textfield* sender, 140 const string16& new_contents) OVERRIDE; 141 virtual bool HandleKeyEvent(Textfield* sender, 142 const ui::KeyEvent& key_event) OVERRIDE; 143 144 // FocusChangeListener overrides: 145 virtual void OnWillChangeFocus(View* focused_before, 146 View* focused_now) OVERRIDE; 147 virtual void OnDidChangeFocus(View* focused_before, 148 View* focused_now) OVERRIDE; 149 150 // PrefixDelegate overrides: 151 virtual int GetRowCount() OVERRIDE; 152 virtual int GetSelectedRow() OVERRIDE; 153 virtual void SetSelectedRow(int row) OVERRIDE; 154 virtual string16 GetTextForRow(int row) OVERRIDE; 155 156 protected: 157 // View overrides: 158 virtual gfx::Point GetKeyboardContextMenuLocation() OVERRIDE; 159 virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE; 160 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; 161 virtual void OnFocus() OVERRIDE; 162 virtual void OnBlur() OVERRIDE; 163 164 private: 165 friend class TreeViewTest; 166 167 // Selects, expands or collapses nodes in the tree. Consistent behavior for 168 // tap gesture and click events. 169 bool OnClickOrTap(const ui::LocatedEvent& event); 170 171 // InternalNode is used to track information about the set of nodes displayed 172 // by TreeViewViews. 173 class InternalNode : public ui::TreeNode<InternalNode> { 174 public: 175 InternalNode(); 176 virtual ~InternalNode(); 177 178 // Resets the state from |node|. 179 void Reset(ui::TreeModelNode* node); 180 181 // The model node this InternalNode represents. 182 ui::TreeModelNode* model_node() { return model_node_; } 183 184 // Whether the node is expanded. 185 void set_is_expanded(bool expanded) { is_expanded_ = expanded; } 186 bool is_expanded() const { return is_expanded_; } 187 188 // Whether children have been loaded. 189 void set_loaded_children(bool value) { loaded_children_ = value; } 190 bool loaded_children() const { return loaded_children_; } 191 192 // Width needed to display the string. 193 void set_text_width(int width) { text_width_ = width; } 194 int text_width() const { return text_width_; } 195 196 // Returns the total number of descendants (including this node). 197 int NumExpandedNodes() const; 198 199 // Returns the max width of all descendants (including this node). |indent| 200 // is how many pixels each child is indented and |depth| is the depth of 201 // this node from its parent. 202 int GetMaxWidth(int indent, int depth); 203 204 private: 205 // The node from the model. 206 ui::TreeModelNode* model_node_; 207 208 // Whether the children have been loaded. 209 bool loaded_children_; 210 211 bool is_expanded_; 212 213 int text_width_; 214 215 DISALLOW_COPY_AND_ASSIGN(InternalNode); 216 }; 217 218 // Used by GetInternalNodeForModelNode. 219 enum GetInternalNodeCreateType { 220 // If an InternalNode hasn't been created yet, create it. 221 CREATE_IF_NOT_LOADED, 222 223 // Don't create an InternalNode if one hasn't been created yet. 224 DONT_CREATE_IF_NOT_LOADED, 225 }; 226 227 // Used by IncrementSelection. 228 enum IncrementType { 229 // Selects the next node. 230 INCREMENT_NEXT, 231 232 // Selects the previous node. 233 INCREMENT_PREVIOUS 234 }; 235 236 // Row of the root node. This varies depending upon whether the root is 237 // visible. 238 int root_row() const { return root_shown_ ? 0 : -1; } 239 240 // Depth of the root node. 241 int root_depth() const { return root_shown_ ? 0 : -1; } 242 243 // Loads the children of the specified node. 244 void LoadChildren(InternalNode* node); 245 246 // Configures an InternalNode from a node from the model. This is used 247 // when a node changes as well as when loading. 248 void ConfigureInternalNode(ui::TreeModelNode* model_node, InternalNode* node); 249 250 // Sets |node|s text_width. 251 void UpdateNodeTextWidth(InternalNode* node); 252 253 // Invoked when the set of drawn nodes changes. 254 void DrawnNodesChanged(); 255 256 // Updates |preferred_size_| from the state of the UI. 257 void UpdatePreferredSize(); 258 259 // Positions |editor_|. 260 void LayoutEditor(); 261 262 // Schedules a paint for |node|. 263 void SchedulePaintForNode(InternalNode* node); 264 265 // Recursively paints rows from |min_row| to |max_row|. |node| is the node for 266 // the row |*row|. |row| is updated as this walks the tree. Depth is the depth 267 // of |*row|. 268 void PaintRows(gfx::Canvas* canvas, 269 int min_row, 270 int max_row, 271 InternalNode* node, 272 int depth, 273 int* row); 274 275 // Invoked to paint a single node. 276 void PaintRow(gfx::Canvas* canvas, 277 InternalNode* node, 278 int row, 279 int depth); 280 281 // Paints the expand control given the specified nodes bounds. 282 void PaintExpandControl(gfx::Canvas* canvas, 283 const gfx::Rect& node_bounds, 284 bool expanded); 285 286 // Returns the InternalNode for a model node. |create_type| indicates wheter 287 // this should load InternalNode or not. 288 InternalNode* GetInternalNodeForModelNode( 289 ui::TreeModelNode* model_node, 290 GetInternalNodeCreateType create_type); 291 292 // Returns the bounds for a node. 293 gfx::Rect GetBoundsForNode(InternalNode* node); 294 295 // Implementation of GetBoundsForNode. Separated out as some callers already 296 // know the row/depth. 297 gfx::Rect GetBoundsForNodeImpl(InternalNode* node, int row, int depth); 298 299 // Returns the row and depth of a node. 300 int GetRowForInternalNode(InternalNode* node, int* depth); 301 302 // Returns the row and depth of the specified node. 303 InternalNode* GetNodeByRow(int row, int* depth); 304 305 // Implementation of GetNodeByRow. |curent_row| is updated as we iterate. 306 InternalNode* GetNodeByRowImpl(InternalNode* node, 307 int target_row, 308 int current_depth, 309 int* current_row, 310 int* node_depth); 311 312 // Increments the selection. Invoked in response to up/down arrow. 313 void IncrementSelection(IncrementType type); 314 315 // If the current node is expanded, it's collapsed, otherwise selection is 316 // moved to the parent. 317 void CollapseOrSelectParent(); 318 319 // If the selected node is collapsed, it's expanded. Otherwise the first child 320 // is seleected. 321 void ExpandOrSelectChild(); 322 323 // Implementation of Expand(). Returns true if at least one node was expanded 324 // that previously wasn't. 325 bool ExpandImpl(ui::TreeModelNode* model_node); 326 327 // The model, may be null. 328 ui::TreeModel* model_; 329 330 // Default icons for closed/open. 331 gfx::ImageSkia closed_icon_; 332 gfx::ImageSkia open_icon_; 333 334 // Icons from the model. 335 std::vector<gfx::ImageSkia> icons_; 336 337 // The root node. 338 InternalNode root_; 339 340 // The selected node, may be NULL. 341 InternalNode* selected_node_; 342 343 bool editing_; 344 345 // The editor; lazily created and never destroyed (well, until TreeView is 346 // destroyed). Hidden when no longer editing. We do this avoid destruction 347 // problems. 348 Textfield* editor_; 349 350 // Preferred size of |editor_| with no content. 351 gfx::Size empty_editor_size_; 352 353 // If non-NULL we've attached a listener to this focus manager. Used to know 354 // when focus is changing to another view so that we can cancel the edit. 355 FocusManager* focus_manager_; 356 357 // Whether to automatically expand children when a parent node is expanded. 358 bool auto_expand_children_; 359 360 // Whether the user can edit the items. 361 bool editable_; 362 363 // The controller. 364 TreeViewController* controller_; 365 366 // Whether or not the root is shown in the tree. 367 bool root_shown_; 368 369 // Did the model return a non-empty set of icons from GetIcons? 370 bool has_custom_icons_; 371 372 // Cached preferred size. 373 gfx::Size preferred_size_; 374 375 // Font used to display text. 376 gfx::Font font_; 377 378 // Height of each row. Based on font and some padding. 379 int row_height_; 380 381 // Offset the text is drawn at. This accounts for the size of the expand 382 // control, icon and offsets. 383 int text_offset_; 384 385 scoped_ptr<PrefixSelector> selector_; 386 387 DISALLOW_COPY_AND_ASSIGN(TreeView); 388 }; 389 390 } // namespace views 391 392 #endif // UI_VIEWS_CONTROLS_TREE_TREE_VIEW_VIEWS_H_ 393