| // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef UI_VIEWS_FOCUS_FOCUS_SEARCH_H_ | 
 | #define UI_VIEWS_FOCUS_FOCUS_SEARCH_H_ | 
 |  | 
 | #include "ui/views/view.h" | 
 |  | 
 | namespace views { | 
 |  | 
 | class FocusTraversable; | 
 |  | 
 | // FocusSearch is an object that implements the algorithm to find the | 
 | // next view to focus. | 
 | class VIEWS_EXPORT FocusSearch { | 
 |  public: | 
 |   // The direction in which the focus traversal is going. | 
 |   // TODO (jcampan): add support for lateral (left, right) focus traversal. The | 
 |   // goal is to switch to focusable views on the same level when using the arrow | 
 |   // keys (ala Windows: in a dialog box, arrow keys typically move between the | 
 |   // dialog OK, Cancel buttons). | 
 |   enum Direction { | 
 |     UP = 0, | 
 |     DOWN | 
 |   }; | 
 |  | 
 |   // Constructor. | 
 |   // - |root| is the root of the view hierarchy to traverse. Focus will be | 
 |   //   trapped inside. | 
 |   // - |cycle| should be true if you want FindNextFocusableView to cycle back | 
 |   //           to the first view within this root when the traversal reaches | 
 |   //           the end. If this is true, then if you pass a valid starting | 
 |   //           view to FindNextFocusableView you will always get a valid view | 
 |   //           out, even if it's the same view. | 
 |   // - |accessibility_mode| should be true if full keyboard accessibility is | 
 |   //   needed and you want to check IsAccessibilityFocusable(), rather than | 
 |   //   IsFocusable(). | 
 |   FocusSearch(View* root, bool cycle, bool accessibility_mode); | 
 |   virtual ~FocusSearch() {} | 
 |  | 
 |   // Finds the next view that should be focused and returns it. If a | 
 |   // FocusTraversable is found while searching for the focusable view, | 
 |   // returns NULL and sets |focus_traversable| to the FocusTraversable | 
 |   // and |focus_traversable_view| to the view associated with the | 
 |   // FocusTraversable. | 
 |   // | 
 |   // Return NULL if the end of the focus loop is reached, unless this object | 
 |   // was initialized with |cycle|=true, in which case it goes back to the | 
 |   // beginning when it reaches the end of the traversal. | 
 |   // - |starting_view| is the view that should be used as the starting point | 
 |   //   when looking for the previous/next view. It may be NULL (in which case | 
 |   //   the first/last view should be used depending if normal/reverse). | 
 |   // - |reverse| whether we should find the next (reverse is false) or the | 
 |   //   previous (reverse is true) view. | 
 |   // - |direction| specifies whether we are traversing down (meaning we should | 
 |   //   look into child views) or traversing up (don't look at child views). | 
 |   // - |check_starting_view| is true if starting_view may obtain the next focus. | 
 |   // - |focus_traversable| is set to the focus traversable that should be | 
 |   //   traversed if one is found (in which case the call returns NULL). | 
 |   // - |focus_traversable_view| is set to the view associated with the | 
 |   //   FocusTraversable set in the previous parameter (it is used as the | 
 |   //   starting view when looking for the next focusable view). | 
 |   virtual View* FindNextFocusableView(View* starting_view, | 
 |                                       bool reverse, | 
 |                                       Direction direction, | 
 |                                       bool check_starting_view, | 
 |                                       FocusTraversable** focus_traversable, | 
 |                                       View** focus_traversable_view); | 
 |  | 
 |  protected: | 
 |   // Get the parent, but stay within the root. Returns NULL if asked for | 
 |   // the parent of |root_|. Subclasses can override this if they need custom | 
 |   // focus search behavior. | 
 |   virtual View* GetParent(View* v); | 
 |  | 
 |   // Returns true if |v| is contained within the hierarchy rooted at |root|. | 
 |   // Subclasses can override this if they need custom focus search behavior. | 
 |   virtual bool Contains(View* root, const View* v); | 
 |  | 
 |   View* root() const { return root_; } | 
 |  | 
 |  private: | 
 |   // Convenience method that returns true if a view is focusable and does not | 
 |   // belong to the specified group. | 
 |   bool IsViewFocusableCandidate(View* v, int skip_group_id); | 
 |  | 
 |   // Convenience method; returns true if a view is not NULL and is focusable | 
 |   // (checking IsAccessibilityFocusable() if |accessibility_mode_| is true). | 
 |   bool IsFocusable(View* v); | 
 |  | 
 |   // Returns the view selected for the group of the selected view. If the view | 
 |   // does not belong to a group or if no view is selected in the group, the | 
 |   // specified view is returned. | 
 |   View* FindSelectedViewForGroup(View* view); | 
 |  | 
 |   // Returns the next focusable view or view containing a FocusTraversable | 
 |   // (NULL if none was found), starting at the starting_view. | 
 |   // |check_starting_view|, |can_go_up| and |can_go_down| controls the | 
 |   // traversal of the views hierarchy. |skip_group_id| specifies a group_id, | 
 |   // -1 means no group. All views from a group are traversed in one pass. | 
 |   View* FindNextFocusableViewImpl(View* starting_view, | 
 |                                   bool check_starting_view, | 
 |                                   bool can_go_up, | 
 |                                   bool can_go_down, | 
 |                                   int skip_group_id, | 
 |                                   FocusTraversable** focus_traversable, | 
 |                                   View** focus_traversable_view); | 
 |  | 
 |   // Same as FindNextFocusableViewImpl but returns the previous focusable view. | 
 |   View* FindPreviousFocusableViewImpl(View* starting_view, | 
 |                                       bool check_starting_view, | 
 |                                       bool can_go_up, | 
 |                                       bool can_go_down, | 
 |                                       int skip_group_id, | 
 |                                       FocusTraversable** focus_traversable, | 
 |                                       View** focus_traversable_view); | 
 |  | 
 |   View* root_; | 
 |   bool cycle_; | 
 |   bool accessibility_mode_; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(FocusSearch); | 
 | }; | 
 |  | 
 | }  // namespace views | 
 |  | 
 | #endif  // UI_VIEWS_FOCUS_FOCUS_SEARCH_H_ |