Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: ui/views/controls/tree/tree_view.h

Issue 851853002: It is time. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Trying to reup because the last upload failed. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/views/controls/throbber.cc ('k') | ui/views/controls/tree/tree_view.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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_
OLDNEW
« no previous file with comments | « ui/views/controls/throbber.cc ('k') | ui/views/controls/tree/tree_view.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698