diff options
Diffstat (limited to 'views/widget/root_view.cc')
-rw-r--r-- | views/widget/root_view.cc | 228 |
1 files changed, 3 insertions, 225 deletions
diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc index 12faf68..ff08d29 100644 --- a/views/widget/root_view.cc +++ b/views/widget/root_view.cc @@ -62,6 +62,7 @@ RootView::RootView(Widget* widget) mouse_move_handler_(NULL), last_click_handler_(NULL), widget_(widget), + ALLOW_THIS_IN_INITIALIZER_LIST(focus_search_(this, false, false)), invalid_rect_urgent_(false), pending_paint_task_(NULL), paint_task_needed_(false), @@ -575,210 +576,8 @@ View* RootView::GetFocusedView() { return NULL; } -View* RootView::FindNextFocusableView(View* starting_view, - bool reverse, - Direction direction, - bool check_starting_view, - FocusTraversable** focus_traversable, - View** focus_traversable_view) { - *focus_traversable = NULL; - *focus_traversable_view = NULL; - - if (GetChildViewCount() == 0) { - NOTREACHED(); - // Nothing to focus on here. - return NULL; - } - - if (!starting_view) { - // Default to the first/last child - starting_view = reverse ? GetChildViewAt(GetChildViewCount() - 1) : - GetChildViewAt(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 part of this RootView. - DCHECK(IsParentOf(starting_view)); - } - - View* v = NULL; - if (!reverse) { - v = FindNextFocusableViewImpl(starting_view, check_starting_view, - true, - (direction == DOWN) ? true : false, - starting_view->GetGroup(), - 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) && !starting_view->IsFocusable(); - v = FindPreviousFocusableViewImpl(starting_view, check_starting_view, - true, - can_go_down, - starting_view->GetGroup(), - focus_traversable, - focus_traversable_view); - } - - // Doing some sanity checks. - if (v) { - DCHECK(v->IsFocusable()); - return v; - } - if (*focus_traversable) { - DCHECK(*focus_traversable_view); - return NULL; - } - // Nothing found. - return 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* RootView::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) { - 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 (v && v->IsFocusable()) - 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->GetChildViewCount() > 0) { - View* v = FindNextFocusableViewImpl(starting_view->GetChildViewAt(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 = starting_view->GetParent(); - while (parent) { - sibling = parent->GetNextFocusableView(); - if (sibling) { - return FindNextFocusableViewImpl(sibling, - true, true, true, - skip_group_id, - focus_traversable, - focus_traversable_view); - } - parent = parent->GetParent(); - } - } - - // 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* RootView::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) { - // 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->GetChildViewCount() > 0) { - View* view = - starting_view->GetChildViewAt(starting_view->GetChildViewCount() - 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 (v && v->IsFocusable()) - 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 = starting_view->GetParent(); - if (parent) - return FindPreviousFocusableViewImpl(parent, - true, true, false, - skip_group_id, - focus_traversable, - focus_traversable_view); - } - - // We found nothing. - return NULL; +FocusSearch* RootView::GetFocusSearch() { + return &focus_search_; } FocusTraversable* RootView::GetFocusTraversableParent() { @@ -803,27 +602,6 @@ void RootView::NotifyNativeViewHierarchyChanged(bool attached, PropagateNativeViewHierarchyChanged(attached, native_view, this); } -// static -View* RootView::FindSelectedViewForGroup(View* view) { - if (view->IsGroupFocusTraversable() || - view->GetGroup() == -1) // No group for that view. - return view; - - View* selected_view = view->GetSelectedViewForGroup(view->GetGroup()); - if (selected_view) - return selected_view; - - // No view selected for that group, default to the specified view. - return view; -} - -// static -bool RootView::IsViewFocusableCandidate(View* v, int skip_group_id) { - return v->IsFocusable() && - (v->IsGroupFocusTraversable() || skip_group_id == -1 || - v->GetGroup() != skip_group_id); -} - bool RootView::ProcessKeyEvent(const KeyEvent& event) { bool consumed = false; |