OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/logging.h" | 5 #include "base/logging.h" |
6 #include "ui/views/focus/focus_manager.h" | 6 #include "ui/views/focus/focus_manager.h" |
7 #include "ui/views/focus/focus_search.h" | 7 #include "ui/views/focus/focus_search.h" |
8 #include "ui/views/view.h" | 8 #include "ui/views/view.h" |
9 | 9 |
10 namespace views { | 10 namespace views { |
(...skipping 26 matching lines...) Expand all Loading... |
37 | 37 |
38 if (!starting_view) { | 38 if (!starting_view) { |
39 // Default to the first/last child | 39 // Default to the first/last child |
40 starting_view = reverse ? root_->child_at(root_->child_count() - 1) : | 40 starting_view = reverse ? root_->child_at(root_->child_count() - 1) : |
41 root_->child_at(0); | 41 root_->child_at(0); |
42 // If there was no starting view, then the one we select is a potential | 42 // If there was no starting view, then the one we select is a potential |
43 // focus candidate. | 43 // focus candidate. |
44 check_starting_view = true; | 44 check_starting_view = true; |
45 } else { | 45 } else { |
46 // The starting view should be a direct or indirect child of the root. | 46 // The starting view should be a direct or indirect child of the root. |
47 DCHECK(root_->Contains(starting_view)); | 47 DCHECK(Contains(root_, starting_view)); |
48 } | 48 } |
49 | 49 |
50 View* v = NULL; | 50 View* v = NULL; |
51 if (!reverse) { | 51 if (!reverse) { |
52 v = FindNextFocusableViewImpl(starting_view, check_starting_view, | 52 v = FindNextFocusableViewImpl(starting_view, check_starting_view, |
53 true, | 53 true, |
54 (direction == DOWN) ? true : false, | 54 (direction == DOWN) ? true : false, |
55 starting_view_group, | 55 starting_view_group, |
56 focus_traversable, | 56 focus_traversable, |
57 focus_traversable_view); | 57 focus_traversable_view); |
58 } else { | 58 } else { |
59 // If the starting view is focusable, we don't want to go down, as we are | 59 // If the starting view is focusable, we don't want to go down, as we are |
60 // traversing the view hierarchy tree bottom-up. | 60 // traversing the view hierarchy tree bottom-up. |
61 bool can_go_down = (direction == DOWN) && !IsFocusable(starting_view); | 61 bool can_go_down = (direction == DOWN) && !IsFocusable(starting_view); |
62 v = FindPreviousFocusableViewImpl(starting_view, check_starting_view, | 62 v = FindPreviousFocusableViewImpl(starting_view, check_starting_view, |
63 true, | 63 true, |
64 can_go_down, | 64 can_go_down, |
65 starting_view_group, | 65 starting_view_group, |
66 focus_traversable, | 66 focus_traversable, |
67 focus_traversable_view); | 67 focus_traversable_view); |
68 } | 68 } |
69 | 69 |
70 // Don't set the focus to something outside of this view hierarchy. | 70 // Don't set the focus to something outside of this view hierarchy. |
71 if (v && v != root_ && !root_->Contains(v)) | 71 if (v && v != root_ && !Contains(root_, v)) |
72 v = NULL; | 72 v = NULL; |
73 | 73 |
74 // If |cycle_| is true, prefer to keep cycling rather than returning NULL. | 74 // If |cycle_| is true, prefer to keep cycling rather than returning NULL. |
75 if (cycle_ && !v && initial_starting_view) { | 75 if (cycle_ && !v && initial_starting_view) { |
76 v = FindNextFocusableView(NULL, reverse, direction, check_starting_view, | 76 v = FindNextFocusableView(NULL, reverse, direction, check_starting_view, |
77 focus_traversable, focus_traversable_view); | 77 focus_traversable, focus_traversable_view); |
78 DCHECK(IsFocusable(v)); | 78 DCHECK(IsFocusable(v)); |
79 return v; | 79 return v; |
80 } | 80 } |
81 | 81 |
(...skipping 29 matching lines...) Expand all Loading... |
111 | 111 |
112 View* selected_view = view->GetSelectedViewForGroup(view->GetGroup()); | 112 View* selected_view = view->GetSelectedViewForGroup(view->GetGroup()); |
113 if (selected_view) | 113 if (selected_view) |
114 return selected_view; | 114 return selected_view; |
115 | 115 |
116 // No view selected for that group, default to the specified view. | 116 // No view selected for that group, default to the specified view. |
117 return view; | 117 return view; |
118 } | 118 } |
119 | 119 |
120 View* FocusSearch::GetParent(View* v) { | 120 View* FocusSearch::GetParent(View* v) { |
121 return root_->Contains(v) ? v->parent() : NULL; | 121 return Contains(root_, v) ? v->parent() : NULL; |
| 122 } |
| 123 |
| 124 bool FocusSearch::Contains(View* root, const View* v) { |
| 125 return root->Contains(v); |
122 } | 126 } |
123 | 127 |
124 // Strategy for finding the next focusable view: | 128 // Strategy for finding the next focusable view: |
125 // - keep going down the first child, stop when you find a focusable view or | 129 // - keep going down the first child, stop when you find a focusable view or |
126 // a focus traversable view (in that case return it) or when you reach a view | 130 // a focus traversable view (in that case return it) or when you reach a view |
127 // with no children. | 131 // with no children. |
128 // - go to the right sibling and start the search from there (by invoking | 132 // - go to the right sibling and start the search from there (by invoking |
129 // FindNextFocusableViewImpl on that view). | 133 // FindNextFocusableViewImpl on that view). |
130 // - if the view has no right sibling, go up the parents until you find a parent | 134 // - if the view has no right sibling, go up the parents until you find a parent |
131 // with a right sibling and start the search from there. | 135 // with a right sibling and start the search from there. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 true, false, true, skip_group_id, | 176 true, false, true, skip_group_id, |
173 focus_traversable, | 177 focus_traversable, |
174 focus_traversable_view); | 178 focus_traversable_view); |
175 if (v || *focus_traversable) | 179 if (v || *focus_traversable) |
176 return v; | 180 return v; |
177 } | 181 } |
178 | 182 |
179 // Then go up to the parent sibling. | 183 // Then go up to the parent sibling. |
180 if (can_go_up) { | 184 if (can_go_up) { |
181 View* parent = GetParent(starting_view); | 185 View* parent = GetParent(starting_view); |
182 while (parent) { | 186 while (parent && parent != root_) { |
183 sibling = parent->GetNextFocusableView(); | 187 sibling = parent->GetNextFocusableView(); |
184 if (sibling) { | 188 if (sibling) { |
185 return FindNextFocusableViewImpl(sibling, | 189 return FindNextFocusableViewImpl(sibling, |
186 true, true, true, | 190 true, true, true, |
187 skip_group_id, | 191 skip_group_id, |
188 focus_traversable, | 192 focus_traversable, |
189 focus_traversable_view); | 193 focus_traversable_view); |
190 } | 194 } |
191 parent = GetParent(parent); | 195 parent = GetParent(parent); |
192 } | 196 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 skip_group_id, | 266 skip_group_id, |
263 focus_traversable, | 267 focus_traversable, |
264 focus_traversable_view); | 268 focus_traversable_view); |
265 } | 269 } |
266 | 270 |
267 // We found nothing. | 271 // We found nothing. |
268 return NULL; | 272 return NULL; |
269 } | 273 } |
270 | 274 |
271 } // namespace views | 275 } // namespace views |
OLD | NEW |