1 // Copyright 2020 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 "ash/system/accessibility/switch_access_menu_button.h"
6 
7 #include "ash/style/ash_color_provider.h"
8 #include "base/bind.h"
9 #include "ui/accessibility/ax_node_data.h"
10 #include "ui/accessibility/mojom/ax_node_data.mojom-shared.h"
11 #include "ui/base/l10n/l10n_util.h"
12 #include "ui/gfx/canvas.h"
13 #include "ui/gfx/paint_vector_icon.h"
14 #include "ui/gfx/vector_icon_types.h"
15 #include "ui/views/controls/image_view.h"
16 #include "ui/views/controls/label.h"
17 #include "ui/views/layout/box_layout.h"
18 #include "ui/views/metadata/metadata_impl_macros.h"
19 #include "ui/views/style/typography.h"
20 
21 namespace ash {
22 
23 namespace {
24 constexpr int kButtonBottomPaddingDefaultDip = 8;
25 constexpr int kButtonBottomPaddingSmallDip = 1;
26 constexpr int kButtonTopPaddingDip = 16;
27 constexpr int kIconSizeDip = 20;
28 constexpr int kLabelMinSidePaddingDip = 8;
29 constexpr int kLabelMaxWidthDip =
30     SwitchAccessMenuButton::kWidthDip - 2 * kLabelMinSidePaddingDip;
31 constexpr int kLabelTopPaddingDefaultDip = 16;
32 constexpr int kLabelTopPaddingSmallDip = 8;
33 constexpr int kTextLineHeightDip = 20;
34 }  // namespace
35 
SwitchAccessMenuButton(std::string action_name,const gfx::VectorIcon & icon,int label_text_id)36 SwitchAccessMenuButton::SwitchAccessMenuButton(std::string action_name,
37                                                const gfx::VectorIcon& icon,
38                                                int label_text_id)
39     : views::Button(
40           base::BindRepeating(&SwitchAccessMenuButton::OnButtonPressed,
41                               base::Unretained(this))),
42       action_name_(action_name) {
43   SkColor icon_color = AshColorProvider::Get()->GetContentLayerColor(
44       AshColorProvider::ContentLayerType::kIconColorPrimary);
45   SkColor label_color = AshColorProvider::Get()->GetContentLayerColor(
46       AshColorProvider::ContentLayerType::kTextColorPrimary);
47 
48   views::Builder<SwitchAccessMenuButton>(this)
49       .SetFocusBehavior(views::View::FocusBehavior::ACCESSIBLE_ONLY)
50       .AddChildren(
51           {views::Builder<views::ImageView>()
52                .CopyAddressTo(&image_view_)
53                .SetImage(gfx::CreateVectorIcon(icon, kIconSizeDip, icon_color)),
54            views::Builder<views::Label>()
55                .CopyAddressTo(&label_)
56                .SetText(l10n_util::GetStringUTF16(label_text_id))
57                .SetTextContext(views::style::CONTEXT_BUTTON)
58                .SetAutoColorReadabilityEnabled(false)
59                .SetEnabledColor(label_color)
60                .SetMultiLine(true)
61                .SetMaximumWidth(kLabelMaxWidthDip)})
62       .BuildChildren();
63 
64   std::unique_ptr<views::BoxLayout> layout = std::make_unique<views::BoxLayout>(
65       views::BoxLayout::Orientation::kVertical,
66       gfx::Insets(kButtonTopPaddingDip, kLabelMinSidePaddingDip,
67                   kButtonBottomPaddingDefaultDip, kLabelMinSidePaddingDip),
68       kLabelTopPaddingDefaultDip);
69 
70   // The layout padding changes with the size of the text label.
71   gfx::Size label_size = label_->CalculatePreferredSize();
72   int left_padding_dip = (kWidthDip - label_size.width()) / 2;
73   int right_padding_dip = kWidthDip - left_padding_dip - label_size.width();
74   int bottom_padding_dip = kButtonBottomPaddingDefaultDip;
75   if (label_size.height() > kTextLineHeightDip) {
76     bottom_padding_dip = kButtonBottomPaddingSmallDip;
77     layout->set_between_child_spacing(kLabelTopPaddingSmallDip);
78   }
79   layout->set_inside_border_insets(
80       gfx::Insets(kButtonTopPaddingDip, left_padding_dip, bottom_padding_dip,
81                   right_padding_dip));
82   SetLayoutManager(std::move(layout));
83 }
84 
GetAccessibleNodeData(ui::AXNodeData * node_data)85 void SwitchAccessMenuButton::GetAccessibleNodeData(ui::AXNodeData* node_data) {
86   views::Button::GetAccessibleNodeData(node_data);
87   node_data->AddStringAttribute(ax::mojom::StringAttribute::kValue,
88                                 action_name_);
89 }
90 
OnButtonPressed()91 void SwitchAccessMenuButton::OnButtonPressed() {
92   NotifyAccessibilityEvent(ax::mojom::Event::kClicked,
93                            /*send_native_event=*/false);
94 }
95 
96 BEGIN_METADATA(SwitchAccessMenuButton, views::Button)
97 END_METADATA
98 
99 }  // namespace ash
100