summaryrefslogtreecommitdiffstats
path: root/ui/views/focus/focus_search.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ui/views/focus/focus_search.cc')
-rw-r--r--ui/views/focus/focus_search.cc273
1 files changed, 0 insertions, 273 deletions
diff --git a/ui/views/focus/focus_search.cc b/ui/views/focus/focus_search.cc
deleted file mode 100644
index 083fc7c..0000000
--- a/ui/views/focus/focus_search.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-// 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.
-
-#include "base/logging.h"
-#include "ui/views/focus/focus_manager.h"
-#include "ui/views/focus/focus_search.h"
-#include "ui/views/view.h"
-
-namespace ui {
-
-FocusSearch::FocusSearch(View* root, bool cycle, bool accessibility_mode)
- : root_(root),
- cycle_(cycle),
- accessibility_mode_(accessibility_mode) {
-}
-
-View* FocusSearch::FindNextFocusableView(View* starting_view,
- bool reverse,
- Direction direction,
- bool check_starting_view,
- FocusTraversable** focus_traversable,
- View** focus_traversable_view) const {
- *focus_traversable = NULL;
- *focus_traversable_view = NULL;
-
- if (root_->children_empty()) {
- NOTREACHED();
- // Nothing to focus on here.
- return NULL;
- }
-
- View* initial_starting_view = starting_view;
- int starting_view_group = -1;
- if (starting_view)
- starting_view_group = starting_view->group();
-
- if (!starting_view) {
- // Default to the first/last child
- starting_view =
- reverse ?
- root_->child_at(root_->children_size() - 1) :
- root_->child_at(0);
- // If there was no starting view, then the one we select is a potential
- // focus candidate.
- check_starting_view = true;
- } else {
- // The starting view should be a direct or indirect child of the root.
- DCHECK(root_->Contains(*starting_view));
- }
-
- View* v = NULL;
- if (!reverse) {
- v = FindNextFocusableViewImpl(starting_view, check_starting_view,
- true,
- (direction == DOWN) ? true : false,
- starting_view_group,
- focus_traversable,
- focus_traversable_view);
- } else {
- // If the starting view is focusable, we don't want to go down, as we are
- // traversing the view hierarchy tree bottom-up.
- bool can_go_down = (direction == DOWN) && !IsFocusable(starting_view);
- v = FindPreviousFocusableViewImpl(starting_view, check_starting_view,
- true,
- can_go_down,
- starting_view_group,
- focus_traversable,
- focus_traversable_view);
- }
-
- // Don't set the focus to something outside of this view hierarchy.
- if (v && v != root_ && !root_->Contains(*v))
- v = NULL;
-
- // If |cycle_| is true, prefer to keep cycling rather than returning NULL.
- if (cycle_ && !v && initial_starting_view) {
- v = FindNextFocusableView(NULL, reverse, direction, check_starting_view,
- focus_traversable, focus_traversable_view);
- DCHECK(IsFocusable(v));
- return v;
- }
-
- // Doing some sanity checks.
- if (v) {
- DCHECK(IsFocusable(v));
- return v;
- }
- if (*focus_traversable) {
- DCHECK(*focus_traversable_view);
- return NULL;
- }
- // Nothing found.
- return NULL;
-}
-
-bool FocusSearch::IsViewFocusableCandidate(View* v, int skip_group_id) const {
- return IsFocusable(v) &&
- (v->IsGroupFocusTraversable() || skip_group_id == -1 ||
- v->group() != skip_group_id);
-}
-
-bool FocusSearch::IsFocusable(View* v) const {
- if (accessibility_mode_)
- return v && v->IsAccessibilityFocusableInRootView();
-
- return v && v->IsFocusableInRootView();
-}
-
-View* FocusSearch::FindSelectedViewForGroup(View* view) const {
- // No group for that view.
- if (view->IsGroupFocusTraversable() || view->group() == -1)
- return view;
-
- View* selected_view = view->GetSelectedViewForGroup(view->group());
- if (selected_view)
- return selected_view;
-
- // No view selected for that group, default to the specified view.
- return view;
-}
-
-View* FocusSearch::GetParent(View* v) const {
- return root_->Contains(*v) ? v->parent() : NULL;
-}
-
-// Strategy for finding the next focusable view:
-// - keep going down the first child, stop when you find a focusable view or
-// a focus traversable view (in that case return it) or when you reach a view
-// with no children.
-// - go to the right sibling and start the search from there (by invoking
-// FindNextFocusableViewImpl on that view).
-// - if the view has no right sibling, go up the parents until you find a parent
-// with a right sibling and start the search from there.
-View* FocusSearch::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) const {
- if (check_starting_view) {
- if (IsViewFocusableCandidate(starting_view, skip_group_id)) {
- View* v = FindSelectedViewForGroup(starting_view);
- // The selected view might not be focusable (if it is disabled for
- // example).
- if (IsFocusable(v))
- return v;
- }
-
- *focus_traversable = starting_view->GetFocusTraversable();
- if (*focus_traversable) {
- *focus_traversable_view = starting_view;
- return NULL;
- }
- }
-
- // First let's try the left child.
- if (can_go_down) {
- if (!starting_view->children_empty()) {
- View* v = FindNextFocusableViewImpl(starting_view->child_at(0),
- true, false, true, skip_group_id,
- focus_traversable,
- focus_traversable_view);
- if (v || *focus_traversable)
- return v;
- }
- }
-
- // Then try the right sibling.
- View* sibling = starting_view->GetNextFocusableView();
- if (sibling) {
- View* v = FindNextFocusableViewImpl(sibling,
- true, false, true, skip_group_id,
- focus_traversable,
- focus_traversable_view);
- if (v || *focus_traversable)
- return v;
- }
-
- // Then go up to the parent sibling.
- if (can_go_up) {
- View* parent = GetParent(starting_view);
- while (parent) {
- sibling = parent->GetNextFocusableView();
- if (sibling) {
- return FindNextFocusableViewImpl(sibling,
- true, true, true,
- skip_group_id,
- focus_traversable,
- focus_traversable_view);
- }
- parent = GetParent(parent);
- }
- }
-
- // We found nothing.
- return NULL;
-}
-
-// Strategy for finding the previous focusable view:
-// - keep going down on the right until you reach a view with no children, if it
-// it is a good candidate return it.
-// - start the search on the left sibling.
-// - if there are no left sibling, start the search on the parent (without going
-// down).
-View* FocusSearch::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) const {
- // Let's go down and right as much as we can.
- if (can_go_down) {
- // Before we go into the direct children, we have to check if this view has
- // a FocusTraversable.
- *focus_traversable = starting_view->GetFocusTraversable();
- if (*focus_traversable) {
- *focus_traversable_view = starting_view;
- return NULL;
- }
-
- if (!starting_view->children_empty()) {
- View* view = starting_view->child_at(starting_view->children_size() - 1);
- View* v = FindPreviousFocusableViewImpl(view, true, false, true,
- skip_group_id,
- focus_traversable,
- focus_traversable_view);
- if (v || *focus_traversable)
- return v;
- }
- }
-
- // Then look at this view. Here, we do not need to see if the view has
- // a FocusTraversable, since we do not want to go down any more.
- if (check_starting_view &&
- IsViewFocusableCandidate(starting_view, skip_group_id)) {
- View* v = FindSelectedViewForGroup(starting_view);
- // The selected view might not be focusable (if it is disabled for
- // example).
- if (IsFocusable(v))
- return v;
- }
-
- // Then try the left sibling.
- View* sibling = starting_view->GetPreviousFocusableView();
- if (sibling) {
- return FindPreviousFocusableViewImpl(sibling,
- true, true, true,
- skip_group_id,
- focus_traversable,
- focus_traversable_view);
- }
-
- // Then go up the parent.
- if (can_go_up) {
- View* parent = GetParent(starting_view);
- if (parent)
- return FindPreviousFocusableViewImpl(parent,
- true, true, false,
- skip_group_id,
- focus_traversable,
- focus_traversable_view);
- }
-
- // We found nothing.
- return NULL;
-}
-
-} // namespace ui