OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ui/views/accessible_pane_view.h" | 5 #include "ui/views/accessible_pane_view.h" |
6 | 6 |
7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
8 #include "ui/base/accessibility/accessible_view_state.h" | 8 #include "ui/base/accessibility/accessible_view_state.h" |
9 #include "ui/views/focus/focus_search.h" | 9 #include "ui/views/focus/focus_search.h" |
10 #include "ui/views/focus/view_storage.h" | 10 #include "ui/views/focus/view_storage.h" |
11 #include "ui/views/widget/widget.h" | 11 #include "ui/views/widget/widget.h" |
12 | 12 |
13 namespace views { | 13 namespace views { |
14 | 14 |
| 15 // Create tiny subclass of FocusSearch that overrides GetParent and Contains, |
| 16 // delegating these to methods in AccessiblePaneView. This is needed so that |
| 17 // subclasses of AccessiblePaneView can customize the focus search logic and |
| 18 // include views that aren't part of the AccessiblePaneView's view |
| 19 // hierarchy in the focus order. |
| 20 class AccessiblePaneViewFocusSearch : public FocusSearch { |
| 21 public: |
| 22 explicit AccessiblePaneViewFocusSearch(AccessiblePaneView* pane_view) |
| 23 : FocusSearch(pane_view, true, true), |
| 24 accessible_pane_view_(pane_view) {} |
| 25 |
| 26 protected: |
| 27 virtual View* GetParent(View* v) OVERRIDE { |
| 28 return accessible_pane_view_->ContainsForFocusSearch(root(), v) ? |
| 29 accessible_pane_view_->GetParentForFocusSearch(v) : NULL; |
| 30 } |
| 31 |
| 32 // Returns true if |v| is contained within the hierarchy rooted at |root|. |
| 33 // Subclasses can override this if they need custom focus search behavior. |
| 34 virtual bool Contains(View* root, const View* v) OVERRIDE { |
| 35 return accessible_pane_view_->ContainsForFocusSearch(root, v); |
| 36 } |
| 37 |
| 38 private: |
| 39 AccessiblePaneView* accessible_pane_view_; |
| 40 DISALLOW_COPY_AND_ASSIGN(AccessiblePaneViewFocusSearch); |
| 41 }; |
| 42 |
15 AccessiblePaneView::AccessiblePaneView() | 43 AccessiblePaneView::AccessiblePaneView() |
16 : pane_has_focus_(false), | 44 : pane_has_focus_(false), |
17 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), | 45 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), |
18 focus_manager_(NULL), | 46 focus_manager_(NULL), |
19 home_key_(ui::VKEY_HOME, ui::EF_NONE), | 47 home_key_(ui::VKEY_HOME, ui::EF_NONE), |
20 end_key_(ui::VKEY_END, ui::EF_NONE), | 48 end_key_(ui::VKEY_END, ui::EF_NONE), |
21 escape_key_(ui::VKEY_ESCAPE, ui::EF_NONE), | 49 escape_key_(ui::VKEY_ESCAPE, ui::EF_NONE), |
22 left_key_(ui::VKEY_LEFT, ui::EF_NONE), | 50 left_key_(ui::VKEY_LEFT, ui::EF_NONE), |
23 right_key_(ui::VKEY_RIGHT, ui::EF_NONE) { | 51 right_key_(ui::VKEY_RIGHT, ui::EF_NONE) { |
24 focus_search_.reset(new views::FocusSearch(this, true, true)); | 52 focus_search_.reset(new AccessiblePaneViewFocusSearch(this)); |
25 } | 53 } |
26 | 54 |
27 AccessiblePaneView::~AccessiblePaneView() { | 55 AccessiblePaneView::~AccessiblePaneView() { |
28 if (pane_has_focus_) { | 56 if (pane_has_focus_) { |
29 focus_manager_->RemoveFocusChangeListener(this); | 57 focus_manager_->RemoveFocusChangeListener(this); |
30 } | 58 } |
31 } | 59 } |
32 | 60 |
33 bool AccessiblePaneView::SetPaneFocus(views::View* initial_focus) { | 61 bool AccessiblePaneView::SetPaneFocus(views::View* initial_focus) { |
34 if (!visible()) | 62 if (!visible()) |
35 return false; | 63 return false; |
36 | 64 |
37 if (!focus_manager_) | 65 if (!focus_manager_) |
38 focus_manager_ = GetFocusManager(); | 66 focus_manager_ = GetFocusManager(); |
39 | 67 |
40 focus_manager_->StoreFocusedView(); | 68 focus_manager_->StoreFocusedView(); |
41 | 69 |
42 // Use the provided initial focus if it's visible and enabled, otherwise | 70 // Use the provided initial focus if it's visible and enabled, otherwise |
43 // use the first focusable child. | 71 // use the first focusable child. |
44 if (!initial_focus || | 72 if (!initial_focus || |
45 !Contains(initial_focus) || | 73 !ContainsForFocusSearch(this, initial_focus) || |
46 !initial_focus->visible() || | 74 !initial_focus->visible() || |
47 !initial_focus->enabled()) { | 75 !initial_focus->enabled()) { |
48 initial_focus = GetFirstFocusableChild(); | 76 initial_focus = GetFirstFocusableChild(); |
49 } | 77 } |
50 | 78 |
51 // Return false if there are no focusable children. | 79 // Return false if there are no focusable children. |
52 if (!initial_focus) | 80 if (!initial_focus) |
53 return false; | 81 return false; |
54 | 82 |
55 focus_manager_->SetFocusedView(initial_focus); | 83 focus_manager_->SetFocusedView(initial_focus); |
(...skipping 17 matching lines...) Expand all Loading... |
73 } | 101 } |
74 | 102 |
75 bool AccessiblePaneView::SetPaneFocusAndFocusDefault() { | 103 bool AccessiblePaneView::SetPaneFocusAndFocusDefault() { |
76 return SetPaneFocus(GetDefaultFocusableChild()); | 104 return SetPaneFocus(GetDefaultFocusableChild()); |
77 } | 105 } |
78 | 106 |
79 views::View* AccessiblePaneView::GetDefaultFocusableChild() { | 107 views::View* AccessiblePaneView::GetDefaultFocusableChild() { |
80 return NULL; | 108 return NULL; |
81 } | 109 } |
82 | 110 |
| 111 View* AccessiblePaneView::GetParentForFocusSearch(View* v) { |
| 112 return v->parent(); |
| 113 } |
| 114 |
| 115 bool AccessiblePaneView::ContainsForFocusSearch(View* root, const View* v) { |
| 116 return root->Contains(v); |
| 117 } |
| 118 |
83 void AccessiblePaneView::RemovePaneFocus() { | 119 void AccessiblePaneView::RemovePaneFocus() { |
84 focus_manager_->RemoveFocusChangeListener(this); | 120 focus_manager_->RemoveFocusChangeListener(this); |
85 pane_has_focus_ = false; | 121 pane_has_focus_ = false; |
86 | 122 |
87 focus_manager_->UnregisterAccelerator(home_key_, this); | 123 focus_manager_->UnregisterAccelerator(home_key_, this); |
88 focus_manager_->UnregisterAccelerator(end_key_, this); | 124 focus_manager_->UnregisterAccelerator(end_key_, this); |
89 focus_manager_->UnregisterAccelerator(escape_key_, this); | 125 focus_manager_->UnregisterAccelerator(escape_key_, this); |
90 focus_manager_->UnregisterAccelerator(left_key_, this); | 126 focus_manager_->UnregisterAccelerator(left_key_, this); |
91 focus_manager_->UnregisterAccelerator(right_key_, this); | 127 focus_manager_->UnregisterAccelerator(right_key_, this); |
92 } | 128 } |
(...skipping 21 matching lines...) Expand all Loading... |
114 if (pane_has_focus_) | 150 if (pane_has_focus_) |
115 return this; | 151 return this; |
116 else | 152 else |
117 return NULL; | 153 return NULL; |
118 } | 154 } |
119 | 155 |
120 bool AccessiblePaneView::AcceleratorPressed( | 156 bool AccessiblePaneView::AcceleratorPressed( |
121 const ui::Accelerator& accelerator) { | 157 const ui::Accelerator& accelerator) { |
122 | 158 |
123 const views::View* focused_view = focus_manager_->GetFocusedView(); | 159 const views::View* focused_view = focus_manager_->GetFocusedView(); |
124 if (!Contains(focused_view)) | 160 if (!ContainsForFocusSearch(this, focused_view)) |
125 return false; | 161 return false; |
126 | 162 |
127 switch (accelerator.key_code()) { | 163 switch (accelerator.key_code()) { |
128 case ui::VKEY_ESCAPE: | 164 case ui::VKEY_ESCAPE: |
129 RemovePaneFocus(); | 165 RemovePaneFocus(); |
130 focus_manager_->RestoreFocusedView(); | 166 focus_manager_->RestoreFocusedView(); |
131 return true; | 167 return true; |
132 case ui::VKEY_LEFT: | 168 case ui::VKEY_LEFT: |
133 focus_manager_->AdvanceFocus(true); | 169 focus_manager_->AdvanceFocus(true); |
134 return true; | 170 return true; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 } | 205 } |
170 | 206 |
171 void AccessiblePaneView::OnDidChangeFocus(views::View* focused_before, | 207 void AccessiblePaneView::OnDidChangeFocus(views::View* focused_before, |
172 views::View* focused_now) { | 208 views::View* focused_now) { |
173 if (!focused_now) | 209 if (!focused_now) |
174 return; | 210 return; |
175 | 211 |
176 views::FocusManager::FocusChangeReason reason = | 212 views::FocusManager::FocusChangeReason reason = |
177 focus_manager_->focus_change_reason(); | 213 focus_manager_->focus_change_reason(); |
178 | 214 |
179 if (!Contains(focused_now) || | 215 if (!ContainsForFocusSearch(this, focused_now) || |
180 reason == views::FocusManager::kReasonDirectFocusChange) { | 216 reason == views::FocusManager::kReasonDirectFocusChange) { |
181 // We should remove pane focus (i.e. make most of the controls | 217 // We should remove pane focus (i.e. make most of the controls |
182 // not focusable again) because the focus has left the pane, | 218 // not focusable again) because the focus has left the pane, |
183 // or because the focus changed within the pane due to the user | 219 // or because the focus changed within the pane due to the user |
184 // directly focusing to a specific view (e.g., clicking on it). | 220 // directly focusing to a specific view (e.g., clicking on it). |
185 RemovePaneFocus(); | 221 RemovePaneFocus(); |
186 } | 222 } |
187 } | 223 } |
188 | 224 |
189 //////////////////////////////////////////////////////////////////////////////// | 225 //////////////////////////////////////////////////////////////////////////////// |
190 // FocusTraversable overrides: | 226 // FocusTraversable overrides: |
191 | 227 |
192 views::FocusSearch* AccessiblePaneView::GetFocusSearch() { | 228 views::FocusSearch* AccessiblePaneView::GetFocusSearch() { |
193 DCHECK(pane_has_focus_); | 229 DCHECK(pane_has_focus_); |
194 return focus_search_.get(); | 230 return focus_search_.get(); |
195 } | 231 } |
196 | 232 |
197 views::FocusTraversable* AccessiblePaneView::GetFocusTraversableParent() { | 233 views::FocusTraversable* AccessiblePaneView::GetFocusTraversableParent() { |
198 DCHECK(pane_has_focus_); | 234 DCHECK(pane_has_focus_); |
199 return NULL; | 235 return NULL; |
200 } | 236 } |
201 | 237 |
202 views::View* AccessiblePaneView::GetFocusTraversableParentView() { | 238 views::View* AccessiblePaneView::GetFocusTraversableParentView() { |
203 DCHECK(pane_has_focus_); | 239 DCHECK(pane_has_focus_); |
204 return NULL; | 240 return NULL; |
205 } | 241 } |
206 | 242 |
207 } // namespace views | 243 } // namespace views |
OLD | NEW |