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