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

Side by Side Diff: ui/views/controls/tabbed_pane/tabbed_pane.cc

Issue 2578303003: a11y: Add a11y information to views::Tab and manually ignore its a11y children. (Closed)
Patch Set: Add tests. Created 3 years, 11 months 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
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/controls/tabbed_pane/tabbed_pane.h" 5 #include "ui/views/controls/tabbed_pane/tabbed_pane.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/macros.h" 8 #include "base/macros.h"
9 #include "third_party/skia/include/core/SkPaint.h" 9 #include "third_party/skia/include/core/SkPaint.h"
10 #include "third_party/skia/include/core/SkPath.h" 10 #include "third_party/skia/include/core/SkPath.h"
11 #include "ui/accessibility/ax_action_data.h"
11 #include "ui/accessibility/ax_node_data.h" 12 #include "ui/accessibility/ax_node_data.h"
12 #include "ui/base/default_style.h" 13 #include "ui/base/default_style.h"
13 #include "ui/base/material_design/material_design_controller.h" 14 #include "ui/base/material_design/material_design_controller.h"
14 #include "ui/base/resource/resource_bundle.h" 15 #include "ui/base/resource/resource_bundle.h"
15 #include "ui/events/keycodes/keyboard_codes.h" 16 #include "ui/events/keycodes/keyboard_codes.h"
16 #include "ui/gfx/animation/animation_delegate.h" 17 #include "ui/gfx/animation/animation_delegate.h"
17 #include "ui/gfx/animation/linear_animation.h" 18 #include "ui/gfx/animation/linear_animation.h"
18 #include "ui/gfx/animation/tween.h" 19 #include "ui/gfx/animation/tween.h"
19 #include "ui/gfx/canvas.h" 20 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/font_list.h" 21 #include "ui/gfx/font_list.h"
21 #include "ui/native_theme/native_theme.h" 22 #include "ui/native_theme/native_theme.h"
22 #include "ui/views/border.h" 23 #include "ui/views/border.h"
23 #include "ui/views/controls/label.h" 24 #include "ui/views/controls/label.h"
24 #include "ui/views/controls/tabbed_pane/tabbed_pane_listener.h" 25 #include "ui/views/controls/tabbed_pane/tabbed_pane_listener.h"
25 #include "ui/views/layout/box_layout.h" 26 #include "ui/views/layout/box_layout.h"
26 #include "ui/views/layout/fill_layout.h" 27 #include "ui/views/layout/fill_layout.h"
27 #include "ui/views/layout/layout_manager.h" 28 #include "ui/views/layout/layout_manager.h"
28 #include "ui/views/widget/widget.h" 29 #include "ui/views/widget/widget.h"
29 30
31 namespace views {
32
30 namespace { 33 namespace {
31 34
32 // TODO(markusheintz|msw): Use NativeTheme colors. 35 // TODO(markusheintz|msw): Use NativeTheme colors.
33 const SkColor kTabTitleColor_Inactive = SkColorSetRGB(0x64, 0x64, 0x64); 36 const SkColor kTabTitleColor_Inactive = SkColorSetRGB(0x64, 0x64, 0x64);
34 const SkColor kTabTitleColor_Active = SK_ColorBLACK; 37 const SkColor kTabTitleColor_Active = SK_ColorBLACK;
35 const SkColor kTabTitleColor_Hovered = SK_ColorBLACK; 38 const SkColor kTabTitleColor_Hovered = SK_ColorBLACK;
36 const SkColor kTabBorderColor = SkColorSetRGB(0xC8, 0xC8, 0xC8); 39 const SkColor kTabBorderColor = SkColorSetRGB(0xC8, 0xC8, 0xC8);
37 const SkScalar kTabBorderThickness = 1.0f; 40 const SkScalar kTabBorderThickness = 1.0f;
38 41
39 const gfx::Font::Weight kHoverWeight = gfx::Font::Weight::NORMAL; 42 const gfx::Font::Weight kHoverWeight = gfx::Font::Weight::NORMAL;
40 const gfx::Font::Weight kActiveWeight = gfx::Font::Weight::BOLD; 43 const gfx::Font::Weight kActiveWeight = gfx::Font::Weight::BOLD;
41 const gfx::Font::Weight kInactiveWeight = gfx::Font::Weight::NORMAL; 44 const gfx::Font::Weight kInactiveWeight = gfx::Font::Weight::NORMAL;
42 45
43 const int kHarmonyTabStripTabHeight = 40; 46 const int kHarmonyTabStripTabHeight = 40;
44 47
48 // The View containing the text for each tab in the tab strip.
49 class TabLabel : public Label {
50 public:
51 explicit TabLabel(const base::string16& tab_title)
52 : Label(tab_title,
53 ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(
54 ui::kLabelFontSizeDelta,
55 gfx::Font::NORMAL,
56 kActiveWeight)) {}
57
58 // Label:
59 void GetAccessibleNodeData(ui::AXNodeData* data) override {
60 // views::Tab shouldn't expose any of its children in the a11y tree.
61 // Instead, it should provide the a11y information itself. Normally,
62 // non-keyboard-focusable children of keyboard-focusable parents are
63 // ignored, but Tabs only mark the currently selected tab as
64 // keyboard-focusable. This means all unselected Tabs expose their children
65 // to the a11y tree. To fix, manually ignore the children.
66 data->role = ui::AX_ROLE_IGNORED;
67 }
68 };
69
45 } // namespace 70 } // namespace
46 71
47 namespace views {
48
49 // static 72 // static
50 const char TabbedPane::kViewClassName[] = "TabbedPane"; 73 const char TabbedPane::kViewClassName[] = "TabbedPane";
51 74
52 // A subclass of Tab that implements the Harmony visual styling. 75 // A subclass of Tab that implements the Harmony visual styling.
53 class MdTab : public Tab { 76 class MdTab : public Tab {
54 public: 77 public:
55 MdTab(TabbedPane* tabbed_pane, const base::string16& title, View* contents); 78 MdTab(TabbedPane* tabbed_pane, const base::string16& title, View* contents);
56 ~MdTab() override; 79 ~MdTab() override;
57 80
58 // Overridden from Tab: 81 // Overridden from Tab:
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 gfx::Range animating_to_; 148 gfx::Range animating_to_;
126 149
127 DISALLOW_COPY_AND_ASSIGN(MdTabStrip); 150 DISALLOW_COPY_AND_ASSIGN(MdTabStrip);
128 }; 151 };
129 152
130 // static 153 // static
131 const char Tab::kViewClassName[] = "Tab"; 154 const char Tab::kViewClassName[] = "Tab";
132 155
133 Tab::Tab(TabbedPane* tabbed_pane, const base::string16& title, View* contents) 156 Tab::Tab(TabbedPane* tabbed_pane, const base::string16& title, View* contents)
134 : tabbed_pane_(tabbed_pane), 157 : tabbed_pane_(tabbed_pane),
135 title_(new Label( 158 title_(new TabLabel(title)),
136 title,
137 ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(
138 ui::kLabelFontSizeDelta,
139 gfx::Font::NORMAL,
140 kActiveWeight))),
141 tab_state_(TAB_ACTIVE), 159 tab_state_(TAB_ACTIVE),
142 contents_(contents) { 160 contents_(contents) {
143 // Calculate this now while the font list is guaranteed to be bold. 161 // Calculate this now while the font list is guaranteed to be bold.
144 preferred_title_size_ = title_->GetPreferredSize(); 162 preferred_title_size_ = title_->GetPreferredSize();
145 163
146 const int kTabVerticalPadding = 5; 164 const int kTabVerticalPadding = 5;
147 const int kTabHorizontalPadding = 10; 165 const int kTabHorizontalPadding = 10;
148 166
149 SetBorder(CreateEmptyBorder( 167 SetBorder(CreateEmptyBorder(
150 gfx::Insets(kTabVerticalPadding, kTabHorizontalPadding))); 168 gfx::Insets(kTabVerticalPadding, kTabHorizontalPadding)));
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 } 249 }
232 250
233 void Tab::SetState(TabState tab_state) { 251 void Tab::SetState(TabState tab_state) {
234 if (tab_state == tab_state_) 252 if (tab_state == tab_state_)
235 return; 253 return;
236 tab_state_ = tab_state; 254 tab_state_ = tab_state;
237 OnStateChanged(); 255 OnStateChanged();
238 SchedulePaint(); 256 SchedulePaint();
239 } 257 }
240 258
259 void Tab::GetAccessibleNodeData(ui::AXNodeData* data) {
260 data->role = ui::AX_ROLE_TAB;
261 data->SetName(title()->text());
262 data->AddStateFlag(ui::AX_STATE_SELECTABLE);
263 if (selected())
264 data->AddStateFlag(ui::AX_STATE_SELECTED);
265 }
266
267 bool Tab::HandleAccessibleAction(const ui::AXActionData& action_data) {
268 if (action_data.action != ui::AX_ACTION_SET_SELECTION || !enabled())
269 return false;
270 // It's not clear what should happen if a tab is 'deselected', so having the
271 // AX_ACTION_SET_SELECTION action always selects the tab.
272 tabbed_pane_->SelectTab(this);
273 return true;
274 }
275
241 void Tab::OnFocus() { 276 void Tab::OnFocus() {
242 OnStateChanged(); 277 OnStateChanged();
243 // When the tab gains focus, send an accessibility event indicating that the 278 // When the tab gains focus, send an accessibility event indicating that the
244 // contents are focused. When the tab loses focus, whichever new View ends up 279 // contents are focused. When the tab loses focus, whichever new View ends up
245 // with focus will send an AX_EVENT_FOCUS of its own, so there's no need to 280 // with focus will send an AX_EVENT_FOCUS of its own, so there's no need to
246 // send one in OnBlur(). 281 // send one in OnBlur().
247 if (contents()) 282 if (contents())
248 contents()->NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true); 283 contents()->NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true);
249 SchedulePaint(); 284 SchedulePaint();
250 } 285 }
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 654
620 View* TabbedPane::GetSelectedTabContentView() { 655 View* TabbedPane::GetSelectedTabContentView() {
621 return GetSelectedTab() ? GetSelectedTab()->contents() : nullptr; 656 return GetSelectedTab() ? GetSelectedTab()->contents() : nullptr;
622 } 657 }
623 658
624 void TabbedPane::GetAccessibleNodeData(ui::AXNodeData* node_data) { 659 void TabbedPane::GetAccessibleNodeData(ui::AXNodeData* node_data) {
625 node_data->role = ui::AX_ROLE_TAB_LIST; 660 node_data->role = ui::AX_ROLE_TAB_LIST;
626 } 661 }
627 662
628 } // namespace views 663 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698