diff options
Diffstat (limited to 'ui/views/focus/focus_search.cc')
-rw-r--r-- | ui/views/focus/focus_search.cc | 273 |
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 |