Chromium Code Reviews| 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/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: |
| 59 void OnStateChanged() override; | 82 void OnStateChanged() override; |
| 60 | 83 |
| 61 // Overridden from View: | 84 // Overridden from View: |
| 62 gfx::Size GetPreferredSize() const override; | 85 gfx::Size GetPreferredSize() const override; |
| 63 void OnFocus() override; | 86 void OnFocus() override; |
| 64 void OnBlur() override; | 87 void OnBlur() override; |
| 65 | 88 |
| 66 private: | 89 private: |
| 67 DISALLOW_COPY_AND_ASSIGN(MdTab); | 90 DISALLOW_COPY_AND_ASSIGN(MdTab); |
| 68 }; | 91 }; |
| 69 | 92 |
| 70 // The tab strip shown above the tab contents. | |
| 71 class TabStrip : public View { | |
| 72 public: | |
| 73 // Internal class name. | |
| 74 static const char kViewClassName[]; | |
| 75 | |
| 76 TabStrip(); | |
| 77 ~TabStrip() override; | |
| 78 | |
| 79 // Called by TabStrip when the selected tab changes. This function is only | |
| 80 // called if |from_tab| is not null, i.e., there was a previously selected | |
| 81 // tab. | |
| 82 virtual void OnSelectedTabChanged(Tab* from_tab, Tab* to_tab); | |
| 83 | |
| 84 // Overridden from View: | |
| 85 const char* GetClassName() const override; | |
| 86 void OnPaintBorder(gfx::Canvas* canvas) override; | |
| 87 | |
| 88 Tab* GetSelectedTab() const; | |
| 89 Tab* GetTabAtDeltaFromSelected(int delta) const; | |
| 90 Tab* GetTabAtIndex(int index) const; | |
| 91 int GetSelectedTabIndex() const; | |
| 92 | |
| 93 private: | |
| 94 DISALLOW_COPY_AND_ASSIGN(TabStrip); | |
| 95 }; | |
| 96 | |
| 97 // A subclass of TabStrip that implements the Harmony visual styling. This | 93 // A subclass of TabStrip that implements the Harmony visual styling. This |
| 98 // class uses a BoxLayout to position tabs. | 94 // class uses a BoxLayout to position tabs. |
| 99 class MdTabStrip : public TabStrip, public gfx::AnimationDelegate { | 95 class MdTabStrip : public TabStrip, public gfx::AnimationDelegate { |
| 100 public: | 96 public: |
| 101 MdTabStrip(); | 97 MdTabStrip(); |
| 102 ~MdTabStrip() override; | 98 ~MdTabStrip() override; |
| 103 | 99 |
| 104 // Overridden from TabStrip: | 100 // Overridden from TabStrip: |
| 105 void OnSelectedTabChanged(Tab* from_tab, Tab* to_tab) override; | 101 void OnSelectedTabChanged(Tab* from_tab, Tab* to_tab) override; |
| 106 | 102 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 125 gfx::Range animating_to_; | 121 gfx::Range animating_to_; |
| 126 | 122 |
| 127 DISALLOW_COPY_AND_ASSIGN(MdTabStrip); | 123 DISALLOW_COPY_AND_ASSIGN(MdTabStrip); |
| 128 }; | 124 }; |
| 129 | 125 |
| 130 // static | 126 // static |
| 131 const char Tab::kViewClassName[] = "Tab"; | 127 const char Tab::kViewClassName[] = "Tab"; |
| 132 | 128 |
| 133 Tab::Tab(TabbedPane* tabbed_pane, const base::string16& title, View* contents) | 129 Tab::Tab(TabbedPane* tabbed_pane, const base::string16& title, View* contents) |
| 134 : tabbed_pane_(tabbed_pane), | 130 : tabbed_pane_(tabbed_pane), |
| 135 title_(new Label( | 131 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), | 132 tab_state_(TAB_ACTIVE), |
| 142 contents_(contents) { | 133 contents_(contents) { |
| 143 // Calculate this now while the font list is guaranteed to be bold. | 134 // Calculate this now while the font list is guaranteed to be bold. |
| 144 preferred_title_size_ = title_->GetPreferredSize(); | 135 preferred_title_size_ = title_->GetPreferredSize(); |
| 145 | 136 |
| 146 const int kTabVerticalPadding = 5; | 137 const int kTabVerticalPadding = 5; |
| 147 const int kTabHorizontalPadding = 10; | 138 const int kTabHorizontalPadding = 10; |
| 148 | 139 |
| 149 SetBorder(CreateEmptyBorder( | 140 SetBorder(CreateEmptyBorder( |
| 150 gfx::Insets(kTabVerticalPadding, kTabHorizontalPadding))); | 141 gfx::Insets(kTabVerticalPadding, kTabHorizontalPadding))); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 } | 222 } |
| 232 | 223 |
| 233 void Tab::SetState(TabState tab_state) { | 224 void Tab::SetState(TabState tab_state) { |
| 234 if (tab_state == tab_state_) | 225 if (tab_state == tab_state_) |
| 235 return; | 226 return; |
| 236 tab_state_ = tab_state; | 227 tab_state_ = tab_state; |
| 237 OnStateChanged(); | 228 OnStateChanged(); |
| 238 SchedulePaint(); | 229 SchedulePaint(); |
| 239 } | 230 } |
| 240 | 231 |
| 232 void Tab::GetAccessibleNodeData(ui::AXNodeData* data) { | |
| 233 data->role = ui::AX_ROLE_TAB; | |
| 234 data->SetName(title()->text()); | |
| 235 data->AddStateFlag(ui::AX_STATE_SELECTABLE); | |
| 236 if (selected()) | |
| 237 data->AddStateFlag(ui::AX_STATE_SELECTED); | |
| 238 } | |
| 239 | |
| 240 bool Tab::HandleAccessibleAction(const ui::AXActionData& action_data) { | |
| 241 if (action_data.action != ui::AX_ACTION_SET_SELECTION || !enabled()) | |
| 242 return false; | |
| 243 // It's not clear what should happen if a tab is 'deselected', so having the | |
|
tapted
2017/01/10 16:22:18
nit: blank line before, delete "having"
Patti Lor
2017/01/11 05:51:44
Done.
| |
| 244 // AX_ACTION_SET_SELECTION action always selects the tab. | |
|
tapted
2017/01/10 16:22:19
nit: selects -> select
Patti Lor
2017/01/11 05:51:44
Done.
| |
| 245 tabbed_pane_->SelectTab(this); | |
| 246 return true; | |
| 247 } | |
| 248 | |
| 241 void Tab::OnFocus() { | 249 void Tab::OnFocus() { |
| 242 OnStateChanged(); | 250 OnStateChanged(); |
| 243 // When the tab gains focus, send an accessibility event indicating that the | 251 // 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 | 252 // 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 | 253 // with focus will send an AX_EVENT_FOCUS of its own, so there's no need to |
| 246 // send one in OnBlur(). | 254 // send one in OnBlur(). |
| 247 if (contents()) | 255 if (contents()) |
| 248 contents()->NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true); | 256 contents()->NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true); |
| 249 SchedulePaint(); | 257 SchedulePaint(); |
| 250 } | 258 } |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 619 | 627 |
| 620 View* TabbedPane::GetSelectedTabContentView() { | 628 View* TabbedPane::GetSelectedTabContentView() { |
| 621 return GetSelectedTab() ? GetSelectedTab()->contents() : nullptr; | 629 return GetSelectedTab() ? GetSelectedTab()->contents() : nullptr; |
| 622 } | 630 } |
| 623 | 631 |
| 624 void TabbedPane::GetAccessibleNodeData(ui::AXNodeData* node_data) { | 632 void TabbedPane::GetAccessibleNodeData(ui::AXNodeData* node_data) { |
| 625 node_data->role = ui::AX_ROLE_TAB_LIST; | 633 node_data->role = ui::AX_ROLE_TAB_LIST; |
| 626 } | 634 } |
| 627 | 635 |
| 628 } // namespace views | 636 } // namespace views |
| OLD | NEW |