| // 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_ |
| #pragma once |
| |
| #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); |
| |
| 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); |
| |
| // Get the parent, but stay within the root. Returns NULL if asked for |
| // the parent of root_. |
| View* GetParent(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_ |