diff options
Diffstat (limited to 'ui/views/focus/focus_search.h')
-rw-r--r-- | ui/views/focus/focus_search.h | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/ui/views/focus/focus_search.h b/ui/views/focus/focus_search.h new file mode 100644 index 0000000..0b0c749 --- /dev/null +++ b/ui/views/focus/focus_search.h @@ -0,0 +1,122 @@ +// 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 ui { + +class FocusTraversable; + +// FocusSearch is an object that implements the algorithm to find the +// next view to focus. +class 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 IsAccessibilityFocusableInRootView(), + // rather than IsFocusableInRootView(). + 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 IsAccessibilityFocusableInRootView() 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 ui + +#endif // UI_VIEWS_FOCUS_FOCUS_SEARCH_H_ |