#include <string>
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/style/checkbox_group.h"
#include "ash/style/icon_button.h"
#include "ash/style/icon_switch.h"
#include "ash/style/radio_button_group.h"
#include "ash/style/tab_slider.h"
#include "ash/style/tab_slider_button.h"
#include "ash/test/ash_test_base.h"
#include "base/run_loop.h"
#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
#include "ui/gfx/vector_icon_types.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/view_test_api.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
namespace ash {
namespace {
const gfx::VectorIcon& kTestIcon = kFolderIcon;
enum class TabSliderType {
kIconSlider,
kLabelSlider,
kIconLabelSlider,
};
class WidgetWithSystemUIComponentView : public views::WidgetDelegateView {
public:
explicit WidgetWithSystemUIComponentView(
std::unique_ptr<views::View> component) {
SetLayoutManager(std::make_unique<views::FillLayout>());
AddChildView(std::move(component));
}
WidgetWithSystemUIComponentView(const WidgetWithSystemUIComponentView&) =
delete;
WidgetWithSystemUIComponentView& operator=(
const WidgetWithSystemUIComponentView&) = delete;
~WidgetWithSystemUIComponentView() override = default;
};
std::unique_ptr<views::Widget> CreateWidgetWithComponent(
std::unique_ptr<views::View> component) {
return AshTestBase::CreateTestWidget(
new WidgetWithSystemUIComponentView(std::move(component)));
}
}
using SystemComponentsTest = AshTestBase;
TEST_F(SystemComponentsTest,
DISABLED_IconButtonWithBackgroundColorIdDoesNotCrash) {
auto icon_button = std::make_unique<IconButton>(
IconButton::PressedCallback(), IconButton::Type::kSmall, &kTestIcon,
u"button 1",
false, false);
auto* icon_button_ptr = icon_button.get();
icon_button->SetBackgroundColorId(cros_tokens::kCrosSysSystemOnBase);
auto widget = CreateWidgetWithComponent(std::move(icon_button));
icon_button_ptr->SchedulePaint();
EXPECT_TRUE(views::ViewTestApi(icon_button_ptr).needs_paint());
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(views::ViewTestApi(icon_button_ptr).needs_paint());
}
TEST_F(SystemComponentsTest, IconSwitch) {
auto icon_switch = std::make_unique<IconSwitch>();
auto* button_1 = icon_switch->AddButton(IconButton::PressedCallback(),
&kTestIcon, u"button 1");
auto* button_2 = icon_switch->AddButton(IconButton::PressedCallback(),
&kTestIcon, u"button 2");
auto* button_3 = icon_switch->AddButton(IconButton::PressedCallback(),
&kTestIcon, u"button 3");
auto* switch_raw_ptr = icon_switch.get();
auto widget = CreateWidgetWithComponent(std::move(icon_switch));
EXPECT_FALSE(button_1->toggled());
EXPECT_FALSE(button_2->toggled());
EXPECT_FALSE(button_3->toggled());
button_1->SetToggled(true);
EXPECT_TRUE(button_1->toggled());
EXPECT_FALSE(button_2->toggled());
EXPECT_FALSE(button_3->toggled());
LeftClickOn(button_2);
EXPECT_FALSE(button_1->toggled());
EXPECT_TRUE(button_2->toggled());
EXPECT_FALSE(button_3->toggled());
switch_raw_ptr->ToggleButtonOnAtIndex(2);
EXPECT_FALSE(button_1->toggled());
EXPECT_FALSE(button_2->toggled());
EXPECT_TRUE(button_3->toggled());
button_1->SetToggled(true);
EXPECT_TRUE(button_1->toggled());
EXPECT_FALSE(button_2->toggled());
EXPECT_FALSE(button_3->toggled());
switch_raw_ptr->SetEnabled(false);
EXPECT_FALSE(button_1->GetEnabled());
EXPECT_FALSE(button_2->GetEnabled());
EXPECT_FALSE(button_3->GetEnabled());
}
TEST_F(SystemComponentsTest, RadioButtonGroup) {
std::unique_ptr<RadioButtonGroup> radio_button_group =
std::make_unique<RadioButtonGroup>(198);
auto* button_1 = radio_button_group->AddButton(RadioButton::PressedCallback(),
u"Test Button1");
auto* button_2 = radio_button_group->AddButton(RadioButton::PressedCallback(),
u"Test Button2");
auto* button_3 = radio_button_group->AddButton(RadioButton::PressedCallback(),
u"Test Button3");
auto* switch_raw_ptr = radio_button_group.get();
auto widget = CreateWidgetWithComponent(std::move(radio_button_group));
EXPECT_FALSE(button_1->selected());
EXPECT_FALSE(button_2->selected());
EXPECT_FALSE(button_3->selected());
button_1->SetSelected(true);
EXPECT_TRUE(button_1->selected());
EXPECT_FALSE(button_2->selected());
EXPECT_FALSE(button_3->selected());
LeftClickOn(button_2);
EXPECT_FALSE(button_1->selected());
EXPECT_TRUE(button_2->selected());
EXPECT_FALSE(button_3->selected());
switch_raw_ptr->SelectButtonAtIndex(2);
EXPECT_FALSE(button_1->selected());
EXPECT_FALSE(button_2->selected());
EXPECT_TRUE(button_3->selected());
button_1->SetSelected(true);
EXPECT_TRUE(button_1->selected());
EXPECT_FALSE(button_2->selected());
EXPECT_FALSE(button_3->selected());
switch_raw_ptr->SetEnabled(false);
EXPECT_FALSE(button_1->GetEnabled());
EXPECT_FALSE(button_2->GetEnabled());
EXPECT_FALSE(button_3->GetEnabled());
}
TEST_F(SystemComponentsTest, CheckboxGroup) {
std::unique_ptr<CheckboxGroup> checkbox_group =
std::make_unique<CheckboxGroup>(198);
auto* button_1 =
checkbox_group->AddButton(Checkbox::PressedCallback(), u"Test Button1");
auto* button_2 =
checkbox_group->AddButton(Checkbox::PressedCallback(), u"Test Button2");
auto* button_3 =
checkbox_group->AddButton(Checkbox::PressedCallback(), u"Test Button3");
auto* button_4 =
checkbox_group->AddButton(Checkbox::PressedCallback(), u"Test Button4");
auto* switch_raw_ptr = checkbox_group.get();
auto widget = CreateWidgetWithComponent(std::move(checkbox_group));
EXPECT_FALSE(button_1->selected());
EXPECT_FALSE(button_2->selected());
EXPECT_FALSE(button_3->selected());
EXPECT_FALSE(button_4->selected());
button_1->SetSelected(true);
EXPECT_TRUE(button_1->selected());
EXPECT_FALSE(button_2->selected());
EXPECT_FALSE(button_3->selected());
EXPECT_FALSE(button_4->selected());
LeftClickOn(button_2);
EXPECT_TRUE(button_1->selected());
EXPECT_TRUE(button_2->selected());
EXPECT_FALSE(button_3->selected());
EXPECT_FALSE(button_4->selected());
LeftClickOn(button_2);
EXPECT_FALSE(button_2->selected());
switch_raw_ptr->SelectButtonAtIndex(2);
EXPECT_TRUE(button_3->selected());
button_4->SetSelected(true);
EXPECT_TRUE(button_1->selected());
EXPECT_FALSE(button_2->selected());
EXPECT_TRUE(button_3->selected());
EXPECT_TRUE(button_4->selected());
switch_raw_ptr->SetEnabled(false);
EXPECT_FALSE(button_1->GetEnabled());
EXPECT_FALSE(button_2->GetEnabled());
EXPECT_FALSE(button_3->GetEnabled());
EXPECT_FALSE(button_4->GetEnabled());
}
struct TabSliderTestParams {
TabSliderType type;
bool distribute_space_evenly;
absl::optional<TabSlider::LayoutParams> custom_layout;
int button_num;
std::vector<std::u16string> labels_text;
};
class TabSliderTest : public SystemComponentsTest,
public testing::WithParamInterface<TabSliderTestParams> {
public:
TabSliderTest() = default;
TabSliderTest(const TabSliderTest&) = delete;
TabSliderTest& operator=(const TabSliderTest&) = delete;
~TabSliderTest() override = default;
};
const TabSliderTestParams kTabSliderLayoutTestParams[] = {
{TabSliderType::kIconSlider,
true,
absl::nullopt,
2,
{u"", u""}},
{TabSliderType::kIconSlider,
false,
absl::nullopt,
2,
{u"", u""}},
{TabSliderType::kIconSlider,
true,
absl::nullopt,
3,
{u"", u"", u""}},
{TabSliderType::kIconSlider,
false,
absl::nullopt,
3,
{u"", u"", u""}},
{TabSliderType::kIconSlider,
true,
TabSlider::LayoutParams{3, 5},
2,
{u"", u""}},
{TabSliderType::kIconSlider,
false,
TabSlider::LayoutParams{3, 5},
2,
{u"", u""}},
{TabSliderType::kIconSlider,
true,
TabSlider::LayoutParams{3, 5},
3,
{u"", u"", u""}},
{TabSliderType::kIconSlider,
false,
TabSlider::LayoutParams{3, 5},
3,
{u"", u"", u""}},
{TabSliderType::kLabelSlider,
true,
absl::nullopt,
2,
{u"one", u"one two three"}},
{TabSliderType::kLabelSlider,
false,
absl::nullopt,
2,
{u"one", u"one two three"}},
{TabSliderType::kLabelSlider,
true,
absl::nullopt,
3,
{u"one", u"one two three", u"one two three four five"}},
{TabSliderType::kLabelSlider,
false,
absl::nullopt,
3,
{u"one", u"one two three", u"one two three four five"}},
{TabSliderType::kLabelSlider,
true,
TabSlider::LayoutParams{3, 5},
2,
{u"one", u"one two three"}},
{TabSliderType::kLabelSlider,
false,
TabSlider::LayoutParams{3, 5},
2,
{u"one", u"one two three"}},
{TabSliderType::kLabelSlider,
true,
TabSlider::LayoutParams{3, 5},
3,
{u"one", u"one two three", u"one two three four five"}},
{TabSliderType::kLabelSlider,
false,
TabSlider::LayoutParams{3, 5},
3,
{u"one", u"one two three", u"one two three four five"}},
{TabSliderType::kIconLabelSlider,
true,
absl::nullopt,
2,
{u"one", u"one two three"}},
{TabSliderType::kIconLabelSlider,
false,
absl::nullopt,
2,
{u"one", u"one two three"}},
{TabSliderType::kIconLabelSlider,
true,
absl::nullopt,
3,
{u"one", u"one two three", u"one two three four five"}},
{TabSliderType::kIconLabelSlider,
false,
absl::nullopt,
3,
{u"one", u"one two three", u"one two three four five"}},
{TabSliderType::kIconLabelSlider,
true,
TabSlider::LayoutParams{3, 5},
2,
{u"one", u"one two three"}},
{TabSliderType::kIconLabelSlider,
false,
TabSlider::LayoutParams{3, 5},
2,
{u"one", u"one two three"}},
{TabSliderType::kIconLabelSlider,
true,
TabSlider::LayoutParams{3, 5},
3,
{u"one", u"one two three", u"one two three four five"}},
{TabSliderType::kIconLabelSlider,
false,
TabSlider::LayoutParams{3, 5},
3,
{u"one", u"one two three", u"one two three four five"}},
};
INSTANTIATE_TEST_SUITE_P(TabSliderStyle,
TabSliderTest,
testing::ValuesIn(kTabSliderLayoutTestParams));
TEST_P(TabSliderTest, TabSliderLayout) {
TabSliderTestParams params = GetParam();
auto tab_slider =
std::make_unique<TabSlider>(true, true, params.distribute_space_evenly);
TabSlider::LayoutParams layout_params;
int max_button_width = 0;
int max_button_height = 0;
std::vector<TabSliderButton*> buttons(params.button_num, nullptr);
for (int i = 0; i < params.button_num; i++) {
switch (params.type) {
case TabSliderType::kIconSlider:
buttons[i] = tab_slider->AddButton<IconSliderButton>(
IconSliderButton::PressedCallback(), &kTestIcon,
u"icon slider button");
break;
case TabSliderType::kLabelSlider:
buttons[i] = tab_slider->AddButton<LabelSliderButton>(
LabelSliderButton::PressedCallback(), params.labels_text[i],
u"label slider button");
break;
case TabSliderType::kIconLabelSlider:
buttons[i] = tab_slider->AddButton<IconLabelSliderButton>(
IconLabelSliderButton::PressedCallback(), &kTestIcon,
params.labels_text[i], u"icon label slider button");
break;
}
if (auto recommended_layout = buttons[i]->GetRecommendedSliderLayout()) {
layout_params = *recommended_layout;
}
gfx::Size pref_size = buttons[i]->GetPreferredSize();
max_button_width = std::max(max_button_width, pref_size.width());
max_button_height = std::max(max_button_height, pref_size.height());
}
if (params.custom_layout) {
tab_slider->SetCustomLayout(*params.custom_layout);
layout_params = *params.custom_layout;
}
auto widget = CreateWidgetWithComponent(std::move(tab_slider));
int x = layout_params.internal_border_padding;
const int y = layout_params.internal_border_padding;
for (int i = 0; i < params.button_num; i++) {
const gfx::Size pref_size = buttons[i]->GetPreferredSize();
const int expect_width =
params.distribute_space_evenly ? max_button_width : pref_size.width();
const int expect_height =
params.distribute_space_evenly ? max_button_height : pref_size.height();
EXPECT_EQ(buttons[i]->bounds(),
gfx::Rect(x, y, expect_width, expect_height));
x += expect_width + layout_params.between_buttons_spacing;
}
}
}