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