1 // Copyright (c) 2011 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.
5 #ifndef UI_VIEWS_FOCUS_FOCUS_SEARCH_H_
6 #define UI_VIEWS_FOCUS_FOCUS_SEARCH_H_
8 #include "ui/views/view.h"
12 class FocusTraversable
;
14 // FocusSearch is an object that implements the algorithm to find the
15 // next view to focus.
16 class VIEWS_EXPORT FocusSearch
{
18 // The direction in which the focus traversal is going.
19 // TODO (jcampan): add support for lateral (left, right) focus traversal. The
20 // goal is to switch to focusable views on the same level when using the arrow
21 // keys (ala Windows: in a dialog box, arrow keys typically move between the
22 // dialog OK, Cancel buttons).
29 // - |root| is the root of the view hierarchy to traverse. Focus will be
31 // - |cycle| should be true if you want FindNextFocusableView to cycle back
32 // to the first view within this root when the traversal reaches
33 // the end. If this is true, then if you pass a valid starting
34 // view to FindNextFocusableView you will always get a valid view
35 // out, even if it's the same view.
36 // - |accessibility_mode| should be true if full keyboard accessibility is
37 // needed and you want to check IsAccessibilityFocusable(), rather than
39 FocusSearch(View
* root
, bool cycle
, bool accessibility_mode
);
40 virtual ~FocusSearch() {}
42 // Finds the next view that should be focused and returns it. If a
43 // FocusTraversable is found while searching for the focusable view,
44 // returns NULL and sets |focus_traversable| to the FocusTraversable
45 // and |focus_traversable_view| to the view associated with the
48 // Return NULL if the end of the focus loop is reached, unless this object
49 // was initialized with |cycle|=true, in which case it goes back to the
50 // beginning when it reaches the end of the traversal.
51 // - |starting_view| is the view that should be used as the starting point
52 // when looking for the previous/next view. It may be NULL (in which case
53 // the first/last view should be used depending if normal/reverse).
54 // - |reverse| whether we should find the next (reverse is false) or the
55 // previous (reverse is true) view.
56 // - |direction| specifies whether we are traversing down (meaning we should
57 // look into child views) or traversing up (don't look at child views).
58 // - |check_starting_view| is true if starting_view may obtain the next focus.
59 // - |focus_traversable| is set to the focus traversable that should be
60 // traversed if one is found (in which case the call returns NULL).
61 // - |focus_traversable_view| is set to the view associated with the
62 // FocusTraversable set in the previous parameter (it is used as the
63 // starting view when looking for the next focusable view).
64 virtual View
* FindNextFocusableView(View
* starting_view
,
67 bool check_starting_view
,
68 FocusTraversable
** focus_traversable
,
69 View
** focus_traversable_view
);
72 // Get the parent, but stay within the root. Returns NULL if asked for
73 // the parent of |root_|. Subclasses can override this if they need custom
74 // focus search behavior.
75 virtual View
* GetParent(View
* v
);
77 // Returns true if |v| is contained within the hierarchy rooted at |root|.
78 // Subclasses can override this if they need custom focus search behavior.
79 virtual bool Contains(View
* root
, const View
* v
);
81 View
* root() const { return root_
; }
84 // Convenience method that returns true if a view is focusable and does not
85 // belong to the specified group.
86 bool IsViewFocusableCandidate(View
* v
, int skip_group_id
);
88 // Convenience method; returns true if a view is not NULL and is focusable
89 // (checking IsAccessibilityFocusable() if |accessibility_mode_| is true).
90 bool IsFocusable(View
* v
);
92 // Returns the view selected for the group of the selected view. If the view
93 // does not belong to a group or if no view is selected in the group, the
94 // specified view is returned.
95 View
* FindSelectedViewForGroup(View
* view
);
97 // Returns the next focusable view or view containing a FocusTraversable
98 // (NULL if none was found), starting at the starting_view.
99 // |check_starting_view|, |can_go_up| and |can_go_down| controls the
100 // traversal of the views hierarchy. |skip_group_id| specifies a group_id,
101 // -1 means no group. All views from a group are traversed in one pass.
102 View
* FindNextFocusableViewImpl(View
* starting_view
,
103 bool check_starting_view
,
107 FocusTraversable
** focus_traversable
,
108 View
** focus_traversable_view
);
110 // Same as FindNextFocusableViewImpl but returns the previous focusable view.
111 View
* FindPreviousFocusableViewImpl(View
* starting_view
,
112 bool check_starting_view
,
116 FocusTraversable
** focus_traversable
,
117 View
** focus_traversable_view
);
121 bool accessibility_mode_
;
123 DISALLOW_COPY_AND_ASSIGN(FocusSearch
);
128 #endif // UI_VIEWS_FOCUS_FOCUS_SEARCH_H_