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