summaryrefslogtreecommitdiffstats
path: root/views/widget/root_view.cc
diff options
context:
space:
mode:
Diffstat (limited to 'views/widget/root_view.cc')
-rw-r--r--views/widget/root_view.cc114
1 files changed, 74 insertions, 40 deletions
diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc
index f5f57f4..367c720 100644
--- a/views/widget/root_view.cc
+++ b/views/widget/root_view.cc
@@ -570,7 +570,7 @@ View* RootView::GetFocusedView() {
View* RootView::FindNextFocusableView(View* starting_view,
bool reverse,
Direction direction,
- bool dont_loop,
+ bool check_starting_view,
FocusTraversable** focus_traversable,
View** focus_traversable_view) {
*focus_traversable = NULL;
@@ -582,14 +582,13 @@ View* RootView::FindNextFocusableView(View* starting_view,
return NULL;
}
- bool skip_starting_view = true;
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.
- skip_starting_view = false;
+ check_starting_view = true;
} else {
// The starting view should be part of this RootView.
DCHECK(IsParentOf(starting_view));
@@ -597,25 +596,31 @@ View* RootView::FindNextFocusableView(View* starting_view,
View* v = NULL;
if (!reverse) {
- v = FindNextFocusableViewImpl(starting_view, skip_starting_view,
+ v = FindNextFocusableViewImpl(starting_view, check_starting_view,
true,
(direction == DOWN) ? true : false,
- starting_view->GetGroup());
+ 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, true,
+ v = FindPreviousFocusableViewImpl(starting_view, check_starting_view,
true,
can_go_down,
- starting_view->GetGroup());
+ starting_view->GetGroup(),
+ focus_traversable,
+ focus_traversable_view);
}
+
+ // Doing some sanity checks.
if (v) {
- if (v->IsFocusable())
- return v;
- *focus_traversable = v->GetFocusTraversable();
- DCHECK(*focus_traversable);
- *focus_traversable_view = v;
+ DCHECK(v->IsFocusable());
+ return v;
+ }
+ if (*focus_traversable) {
+ DCHECK(*focus_traversable_view);
return NULL;
}
// Nothing found.
@@ -631,23 +636,31 @@ View* RootView::FindNextFocusableView(View* starting_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 skip_starting_view,
+ bool check_starting_view,
bool can_go_up,
bool can_go_down,
- int skip_group_id) {
- if (!skip_starting_view) {
+ int skip_group_id,
+ FocusTraversable** focus_traversable,
+ View** focus_traversable_view) {
+ if (check_starting_view) {
if (IsViewFocusableCandidate(starting_view, skip_group_id))
return FindSelectedViewForGroup(starting_view);
- if (starting_view->GetFocusTraversable())
- return starting_view;
+
+ *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),
- false, false, true, skip_group_id);
- if (v)
+ true, false, true, skip_group_id,
+ focus_traversable,
+ focus_traversable_view);
+ if (v || *focus_traversable)
return v;
}
}
@@ -656,8 +669,10 @@ View* RootView::FindNextFocusableViewImpl(View* starting_view,
View* sibling = starting_view->GetNextFocusableView();
if (sibling) {
View* v = FindNextFocusableViewImpl(sibling,
- false, false, true, skip_group_id);
- if (v)
+ true, false, true, skip_group_id,
+ focus_traversable,
+ focus_traversable_view);
+ if (v || *focus_traversable)
return v;
}
@@ -668,8 +683,10 @@ View* RootView::FindNextFocusableViewImpl(View* starting_view,
sibling = parent->GetNextFocusableView();
if (sibling) {
return FindNextFocusableViewImpl(sibling,
- false, true, true,
- skip_group_id);
+ true, true, true,
+ skip_group_id,
+ focus_traversable,
+ focus_traversable_view);
}
parent = parent->GetParent();
}
@@ -685,36 +702,51 @@ View* RootView::FindNextFocusableViewImpl(View* starting_view,
// - 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 skip_starting_view,
- bool can_go_up,
- bool can_go_down,
- int skip_group_id) {
+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, false, false, true,
- skip_group_id);
- if (v)
+ View* v = FindPreviousFocusableViewImpl(view, true, false, true,
+ skip_group_id,
+ focus_traversable,
+ focus_traversable_view);
+ if (v || *focus_traversable)
return v;
}
}
- if (!skip_starting_view) {
- if (IsViewFocusableCandidate(starting_view, skip_group_id))
- return FindSelectedViewForGroup(starting_view);
- if (starting_view->GetFocusTraversable())
- return starting_view;
+ // 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)) {
+ return FindSelectedViewForGroup(starting_view);
}
// Then try the left sibling.
View* sibling = starting_view->GetPreviousFocusableView();
if (sibling) {
return FindPreviousFocusableViewImpl(sibling,
- false, true, true,
- skip_group_id);
+ true, true, true,
+ skip_group_id,
+ focus_traversable,
+ focus_traversable_view);
}
// Then go up the parent.
@@ -722,8 +754,10 @@ View* RootView::FindPreviousFocusableViewImpl(View* starting_view,
View* parent = starting_view->GetParent();
if (parent)
return FindPreviousFocusableViewImpl(parent,
- false, true, false,
- skip_group_id);
+ true, true, false,
+ skip_group_id,
+ focus_traversable,
+ focus_traversable_view);
}
// We found nothing.