• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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);
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.
set_auto_expand_children(bool auto_expand_children)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.
SetController(TreeViewController * 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 
editor()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.
model_node()190     ui::TreeModelNode* model_node() { return model_node_; }
191 
192     // Whether the node is expanded.
set_is_expanded(bool expanded)193     void set_is_expanded(bool expanded) { is_expanded_ = expanded; }
is_expanded()194     bool is_expanded() const { return is_expanded_; }
195 
196     // Whether children have been loaded.
set_loaded_children(bool value)197     void set_loaded_children(bool value) { loaded_children_ = value; }
loaded_children()198     bool loaded_children() const { return loaded_children_; }
199 
200     // Width needed to display the string.
set_text_width(int width)201     void set_text_width(int width) { text_width_ = width; }
text_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.
root_row()246   int root_row() const { return root_shown_ ? 0 : -1; }
247 
248   // Depth of the root node.
root_depth()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_
398