Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(734)

Side by Side Diff: chrome/browser/views/accessible_toolbar_view.cc

Issue 396006: Revert 32012-32017 (Closed)
Patch Set: Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/logging.h"
6 #include "chrome/browser/view_ids.h"
7 #include "chrome/browser/views/frame/browser_view.h"
8 #include "chrome/browser/views/accessible_toolbar_view.h"
9 #include "views/controls/button/menu_button.h"
10 #include "views/focus/view_storage.h"
11 #include "views/widget/root_view.h"
12 #include "views/widget/tooltip_manager.h"
13 #include "views/widget/widget.h"
14
15 AccessibleToolbarView::AccessibleToolbarView()
16 : selected_focused_view_(NULL),
17 last_focused_view_storage_id_(
18 views::ViewStorage::GetSharedInstance()->CreateStorageID()) {
19 }
20
21 AccessibleToolbarView::~AccessibleToolbarView() {
22 }
23
24 void AccessibleToolbarView::InitiateTraversal() {
25 // We only traverse if accessibility is active.
26 if (selected_focused_view_ != NULL)
27 return;
28
29 // Save the last focused view so that when the user presses ESC, it will
30 // return back to the last focus.
31 views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance();
32 view_storage->StoreView(last_focused_view_storage_id_,
33 GetRootView()->GetFocusedView());
34
35 // Request focus to the toolbar.
36 RequestFocus();
37 }
38
39 int AccessibleToolbarView::GetNextAccessibleViewIndex(int view_index,
40 bool forward) {
41 int modifier = forward ? 1 : -1;
42 int current_view_index = view_index + modifier;
43
44 while ((current_view_index >= 0) &&
45 (current_view_index < GetChildViewCount())) {
46 // Try to find the next available view that can be interacted with. That
47 // view must be enabled, visible, and traversable.
48 views::View* current_view = GetChildViewAt(current_view_index);
49 if (current_view->IsEnabled() && current_view->IsVisible() &&
50 IsAccessibleViewTraversable(current_view)) {
51 return current_view_index;
52 }
53 current_view_index += modifier;
54 }
55
56 // No button is available in the specified direction.
57 return -1;
58 }
59
60 bool AccessibleToolbarView::IsAccessibleViewTraversable(views::View* view) {
61 return true;
62 }
63
64 void AccessibleToolbarView::DidGainFocus() {
65 // Check to see if the accessible focus should be restored to previously
66 // focused button. The must be enabled and visible in the toolbar.
67 if (!selected_focused_view_ ||
68 !selected_focused_view_->IsEnabled() ||
69 !selected_focused_view_->IsVisible()) {
70 // Find first accessible child (-1 to start search at parent).
71 int first_acc_child = GetNextAccessibleViewIndex(-1, true);
72
73 // No buttons enabled or visible.
74 if (first_acc_child == -1)
75 return;
76
77 selected_focused_view_ = GetChildViewAt(first_acc_child);
78 }
79
80 // Set the focus to the current accessible view.
81 SetFocusToAccessibleView();
82 }
83
84 void AccessibleToolbarView::WillLoseFocus() {
85 // Any tooltips that are active should be hidden when toolbar loses focus.
86 if (GetWidget() && GetWidget()->GetTooltipManager())
87 GetWidget()->GetTooltipManager()->HideKeyboardTooltip();
88
89 // Removes the child accessibility view's focus and the view from the
90 // ViewStorage, when toolbar loses focus.
91 if (selected_focused_view_) {
92 selected_focused_view_->SetHotTracked(false);
93 selected_focused_view_ = NULL;
94 views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance();
95 view_storage->RemoveView(last_focused_view_storage_id_);
96 }
97 }
98
99 void AccessibleToolbarView::ShowContextMenu(int x, int y,
100 bool is_mouse_gesture) {
101 if (selected_focused_view_)
102 selected_focused_view_->ShowContextMenu(x, y, is_mouse_gesture);
103 }
104
105 void AccessibleToolbarView::RequestFocus() {
106 // When the toolbar needs to request focus, the default implementation of
107 // View::RequestFocus requires the View to be focusable. Since ToolbarView is
108 // not technically focused, we need to temporarily set and remove focus so
109 // that it can focus back to its focused state. |selected_focused_view_| is
110 // not necessarily set since it can be null if this view has already lost
111 // focus, such as traversing through the context menu.
112 SetFocusable(true);
113 View::RequestFocus();
114 SetFocusable(false);
115 }
116
117 bool AccessibleToolbarView::OnKeyPressed(const views::KeyEvent& e) {
118 // Paranoia check, button should be initialized upon toolbar gaining focus.
119 if (!selected_focused_view_)
120 return View::OnKeyPressed(e);
121
122 int focused_view = GetChildIndex(selected_focused_view_);
123 int next_view = focused_view;
124
125 switch (e.GetKeyCode()) {
126 case base::VKEY_LEFT:
127 next_view = GetNextAccessibleViewIndex(focused_view, false);
128 break;
129 case base::VKEY_RIGHT:
130 next_view = GetNextAccessibleViewIndex(focused_view, true);
131 break;
132 case base::VKEY_DOWN:
133 case base::VKEY_RETURN:
134 if (selected_focused_view_->GetClassName() ==
135 views::MenuButton::kViewClassName) {
136 // If a menu button is activated and its menu is displayed, then the
137 // active tooltip should be hidden.
138 if (GetWidget()->GetTooltipManager())
139 GetWidget()->GetTooltipManager()->HideKeyboardTooltip();
140
141 // Safe to cast, given to above check.
142 static_cast<views::MenuButton*>(selected_focused_view_)->Activate();
143
144 // If activate did not trigger a focus change, the menu button should
145 // remain hot tracked since the view is still focused.
146 if (selected_focused_view_) {
147 // Re-enable hot-tracking, as Activate() will disable it.
148 selected_focused_view_->SetHotTracked(true);
149 }
150 return true;
151 }
152 default:
153 // If key is not handled explicitly, pass it on to view.
154 return selected_focused_view_->OnKeyPressed(e);
155 }
156
157 // No buttons enabled, visible, or focus hasn't moved.
158 if (next_view == -1)
159 return false;
160
161 // Remove hot-tracking from old focused button.
162 selected_focused_view_->SetHotTracked(false);
163
164 // All is well, update the focused child member variable.
165 selected_focused_view_ = GetChildViewAt(next_view);
166
167 // Set the focus to the current accessible view.
168 SetFocusToAccessibleView();
169 return true;
170 }
171
172 bool AccessibleToolbarView::OnKeyReleased(const views::KeyEvent& e) {
173 // Paranoia check, button should be initialized upon toolbar gaining focus.
174 if (!selected_focused_view_)
175 return false;
176
177 // Have keys be handled by the views themselves.
178 return selected_focused_view_->OnKeyReleased(e);
179 }
180
181 bool AccessibleToolbarView::SkipDefaultKeyEventProcessing(
182 const views::KeyEvent& e) {
183 // Accessibility focus must be present in order to handle ESC and TAB related
184 // key events.
185 if (!selected_focused_view_)
186 return false;
187
188 // The ancestor *must* be a BrowserView.
189 views::View* view = GetAncestorWithClassName(BrowserView::kViewClassName);
190 if (!view)
191 return false;
192
193 // Given the check above, we can ensure its a BrowserView.
194 BrowserView* browser_view = static_cast<BrowserView*>(view);
195
196 // Handle ESC and TAB events.
197 switch (e.GetKeyCode()) {
198 case base::VKEY_ESCAPE: {
199 // Retrieve the focused view from the storage so we can request focus back
200 // to it. If |focus_view| is null, we place focus on the default view.
201 // |selected_focused_view_| doesn't need to be reset here since it will be
202 // dealt within the WillLoseFocus method.
203 views::ViewStorage* view_storage =
204 views::ViewStorage::GetSharedInstance();
205 views::View* focused_view =
206 view_storage->RetrieveView(last_focused_view_storage_id_);
207 if (focused_view) {
208 view_storage->RemoveView(last_focused_view_storage_id_);
209 focused_view->RequestFocus();
210 } else {
211 browser_view->SetFocusToLocationBar();
212 }
213 return true;
214 }
215 case base::VKEY_TAB: {
216 if (e.IsShiftDown()) {
217 browser_view->TraverseNextAccessibleToolbar(false);
218 } else {
219 browser_view->TraverseNextAccessibleToolbar(true);
220 }
221 return true;
222 }
223 default: return false;
224 }
225 }
226
227 bool AccessibleToolbarView::GetAccessibleName(std::wstring* name) {
228 *name = accessible_name_;
229 return !accessible_name_.empty();
230 }
231
232 bool AccessibleToolbarView::GetAccessibleRole(AccessibilityTypes::Role* role) {
233 DCHECK(role);
234
235 *role = AccessibilityTypes::ROLE_TOOLBAR;
236 return true;
237 }
238
239 void AccessibleToolbarView::SetAccessibleName(const std::wstring& name) {
240 accessible_name_ = name;
241 }
242
243 void AccessibleToolbarView::ViewHierarchyChanged(bool is_add, View* parent,
244 View* child) {
245 // When the toolbar is removed, traverse to the next accessible toolbar.
246 if (!is_add && parent->GetClassName() == BrowserView::kViewClassName) {
247 // Given the check above, we can ensure its a BrowserView.
248 BrowserView* browser_view = static_cast<BrowserView*>(parent);
249 browser_view->TraverseNextAccessibleToolbar(true);
250 }
251 }
252
253 void AccessibleToolbarView::SetFocusToAccessibleView() {
254 // Hot-track new focused button.
255 selected_focused_view_->SetHotTracked(true);
256
257 // Show the tooltip for the view that got the focus.
258 if (GetWidget()->GetTooltipManager()) {
259 GetWidget()->GetTooltipManager()->ShowKeyboardTooltip(
260 selected_focused_view_);
261 }
262
263 #if defined(OS_WIN)
264 // Retrieve information to generate an accessible focus event.
265 gfx::NativeView wnd = GetWidget()->GetNativeView();
266 int view_id = selected_focused_view_->GetID();
267 // Notify Access Technology that there was a change in keyboard focus.
268 ::NotifyWinEvent(EVENT_OBJECT_FOCUS, wnd, OBJID_CLIENT,
269 static_cast<LONG>(view_id));
270 #else
271 NOTIMPLEMENTED();
272 #endif
273 }
OLDNEW
« no previous file with comments | « chrome/browser/views/accessible_toolbar_view.h ('k') | chrome/browser/views/bookmark_bar_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698