Home | History | Annotate | Download | only in tree
      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_
    398