0

Update launcher "hide continue section" feature to new UX spec

This CL updates the clamshell mode launcher:
- The "Continue where you left off" label now always shows (even when
  the privacy toast is showing).
- A new "continue label container" is added to AppListBubbleAppsPage
  to hold both the continue label and the toggle continue section
  button.
- IconButton is updated to support "tiny" buttons (circle size 24x24)
  and custom vector icon sizes (the chevrons are supposed to be 16x16).

Screenshots:
https://screenshot.googleplex.com/7RXbf4GQxKJhNFd
https://screenshot.googleplex.com/5vNnVdQKaU5A75Y
https://screenshot.googleplex.com/3BcBJgAnq2DBANK

TODO: Update the feature for tablet mode
TODO: Animations

Bug: 1334337
Test: updated ash_unittests
Change-Id: Ic888ea00e8be92ec115d2311c7f9c255810987cf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3699110
Reviewed-by: Toni Barzic <tbarzic@chromium.org>
Commit-Queue: James Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1014199}
This commit is contained in:
James Cook
2022-06-14 23:29:15 +00:00
committed by Chromium LUCI CQ
parent 7294e4d782
commit b5d2be9a9b
12 changed files with 215 additions and 61 deletions

@@ -30,7 +30,7 @@
#include "ash/public/cpp/style/color_provider.h" #include "ash/public/cpp/style/color_provider.h"
#include "ash/resources/vector_icons/vector_icons.h" #include "ash/resources/vector_icons/vector_icons.h"
#include "ash/strings/grit/ash_strings.h" #include "ash/strings/grit/ash_strings.h"
#include "ash/style/pill_button.h" #include "ash/style/icon_button.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/check.h" #include "base/check.h"
#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_functions.h"
@@ -55,6 +55,7 @@
#include "ui/views/controls/textfield/textfield.h" #include "ui/views/controls/textfield/textfield.h"
#include "ui/views/focus/focus_manager.h" #include "ui/views/focus/focus_manager.h"
#include "ui/views/layout/box_layout.h" #include "ui/views/layout/box_layout.h"
#include "ui/views/view_class_properties.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
using views::BoxLayout; using views::BoxLayout;
@@ -72,6 +73,9 @@ constexpr auto kVerticalScrollInsets = gfx::Insets::TLBR(1, 0, 1, 1);
// interior apps page container margin. // interior apps page container margin.
constexpr int kVerticalPaddingBetweenSections = 16; constexpr int kVerticalPaddingBetweenSections = 16;
// Label container padding in DIPs.
constexpr auto kContinueLabelContainerPadding = gfx::Insets::TLBR(0, 16, 0, 16);
// The horizontal interior margin for the apps page container - i.e. the margin // The horizontal interior margin for the apps page container - i.e. the margin
// between the apps page bounds and the page content. // between the apps page bounds and the page content.
constexpr int kHorizontalInteriorMargin = 16; constexpr int kHorizontalInteriorMargin = 16;
@@ -160,25 +164,11 @@ AppListBubbleAppsPage::AppListBubbleAppsPage(
kVerticalPaddingBetweenSections)); kVerticalPaddingBetweenSections));
layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kStretch); layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kStretch);
// Add the button to show the continue section, wrapped in a view to center it // When feature LauncherHideContinueSection is enabled, the "Continue where
// horizontally. // you left off" label is in a container that is a child of this view.
{ // Otherwise the label is a child of the ContinueSectionView.
auto* container = if (features::IsLauncherHideContinueSectionEnabled())
scroll_contents->AddChildView(std::make_unique<views::View>()); InitContinueLabelContainer(scroll_contents.get());
auto* layout = container->SetLayoutManager(
std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical));
layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kCenter);
show_continue_section_button_ =
container->AddChildView(std::make_unique<PillButton>(
base::BindRepeating(
&AppListBubbleAppsPage::OnPressShowContinueSection,
base::Unretained(this)),
l10n_util::GetStringUTF16(IDS_ASH_LAUNCHER_SHOW_CONTINUE_SECTION),
PillButton::Type::kIcon, &kExpandAllIcon));
show_continue_section_button_->SetUseDefaultLabelFont();
// Put the icon on the right.
show_continue_section_button_->SetHorizontalAlignment(gfx::ALIGN_RIGHT);
}
// Continue section row. // Continue section row.
continue_section_ = continue_section_ =
@@ -188,6 +178,12 @@ AppListBubbleAppsPage::AppListBubbleAppsPage(
continue_section_->SetBorder( continue_section_->SetBorder(
views::CreateEmptyBorder(kContinueSectionInsets)); views::CreateEmptyBorder(kContinueSectionInsets));
continue_section_->SetNudgeController(app_list_nudge_controller_.get()); continue_section_->SetNudgeController(app_list_nudge_controller_.get());
if (features::IsLauncherHideContinueSectionEnabled()) {
// Decrease the between-sections spacing so the continue label is closer to
// the continue tasks section.
continue_section_->SetProperty(views::kMarginsKey,
gfx::Insets::TLBR(-14, 0, 0, 0));
}
// Observe changes in continue section visibility, to keep separator // Observe changes in continue section visibility, to keep separator
// visibility in sync. // visibility in sync.
@@ -289,9 +285,19 @@ void AppListBubbleAppsPage::AnimateShowLauncher(bool is_side_shelf) {
// build a single animation with conditional parts. https://crbug.com/1266020 // build a single animation with conditional parts. https://crbug.com/1266020
const int section_offset = is_side_shelf ? -20 : 20; const int section_offset = is_side_shelf ? -20 : 20;
int vertical_offset = 0; int vertical_offset = 0;
const bool animate_continue_label_container =
continue_label_container_ && continue_label_container_->GetVisible();
if (animate_continue_label_container) {
vertical_offset += section_offset;
SlideViewIntoPosition(continue_label_container_, vertical_offset,
slide_duration);
}
if (continue_section_->GetVisible() && if (continue_section_->GetVisible() &&
continue_section_->GetTasksSuggestionsCount() > 0) { continue_section_->GetTasksSuggestionsCount() > 0) {
vertical_offset += section_offset; // Only offset if this is the top section, otherwise animate next to the
// continue label container above.
if (!animate_continue_label_container)
vertical_offset += section_offset;
SlideViewIntoPosition(continue_section_, vertical_offset, slide_duration); SlideViewIntoPosition(continue_section_, vertical_offset, slide_duration);
} }
if (recent_apps_->GetVisible() && recent_apps_->GetItemViewCount() > 0) { if (recent_apps_->GetVisible() && recent_apps_->GetItemViewCount() > 0) {
@@ -646,19 +652,74 @@ ui::Layer* AppListBubbleAppsPage::GetPageAnimationLayerForTest() {
return scroll_view_->contents()->layer(); return scroll_view_->contents()->layer();
} }
////////////////////////////////////////////////////////////////////////////////
// private:
void AppListBubbleAppsPage::InitContinueLabelContainer(
views::View* scroll_contents) {
continue_label_container_ =
scroll_contents->AddChildView(std::make_unique<views::View>());
continue_label_container_->SetBorder(
views::CreateEmptyBorder(kContinueLabelContainerPadding));
auto* layout = continue_label_container_->SetLayoutManager(
std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal));
layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kCenter);
continue_label_ =
continue_label_container_->AddChildView(std::make_unique<views::Label>(
l10n_util::GetStringUTF16(IDS_ASH_LAUNCHER_CONTINUE_SECTION_LABEL)));
bubble_utils::ApplyStyle(continue_label_,
bubble_utils::LabelStyle::kSubtitle);
continue_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
// Button should be right aligned, so flex label to fill empty space.
layout->SetFlexForView(continue_label_, 1);
toggle_continue_section_button_ =
continue_label_container_->AddChildView(std::make_unique<IconButton>(
base::BindRepeating(&AppListBubbleAppsPage::OnToggleContinueSection,
base::Unretained(this)),
IconButton::Type::kTinyFloating, &kChevronUpIcon,
/*is_togglable=*/false,
/*has_border=*/false));
// The icon is scaled down since the button is tiny.
toggle_continue_section_button_->SetIconSize(16);
}
void AppListBubbleAppsPage::UpdateContinueSectionVisibility() { void AppListBubbleAppsPage::UpdateContinueSectionVisibility() {
// Show the "Show continue section" button if the continue section is hidden.
bool hide_continue_section = view_delegate_->ShouldHideContinueSection();
show_continue_section_button_->SetVisible(hide_continue_section);
// The continue section view and recent apps view manage their own visibility // The continue section view and recent apps view manage their own visibility
// internally. // internally.
continue_section_->UpdateElementsVisibility(); continue_section_->UpdateElementsVisibility();
recent_apps_->UpdateVisibility(); recent_apps_->UpdateVisibility();
UpdateContinueLabelContainer();
UpdateSeparatorVisibility(); UpdateSeparatorVisibility();
} }
void AppListBubbleAppsPage::UpdateContinueLabelContainer() {
if (!continue_label_container_)
return;
// If there are no suggested tasks and no recent apps, it doesn't make sense
// to show the continue label. This can happen for brand-new users.
continue_label_container_->SetVisible(
continue_section_->GetTasksSuggestionsCount() > 0 ||
recent_apps_->GetItemViewCount() > 0);
// Update the toggle continue section button tooltip and image.
bool is_hidden = view_delegate_->ShouldHideContinueSection();
toggle_continue_section_button_->SetTooltipText(l10n_util::GetStringUTF16(
is_hidden ? IDS_ASH_LAUNCHER_SHOW_CONTINUE_SECTION_TOOLTIP
: IDS_ASH_LAUNCHER_HIDE_CONTINUE_SECTION_TOOLTIP));
toggle_continue_section_button_->SetVectorIcon(is_hidden ? kChevronDownIcon
: kChevronUpIcon);
}
void AppListBubbleAppsPage::UpdateSeparatorVisibility() { void AppListBubbleAppsPage::UpdateSeparatorVisibility() {
separator_->SetVisible(recent_apps_->GetVisible() || // The separator only hides if the user has the continue section shown but
// there are no suggested tasks and no apps. This is rare.
separator_->SetVisible(view_delegate_->ShouldHideContinueSection() ||
recent_apps_->GetVisible() ||
continue_section_->GetVisible()); continue_section_->GetVisible());
} }
@@ -819,9 +880,10 @@ void AppListBubbleAppsPage::SlideViewIntoPosition(views::View* view,
kSlideAnimationTweenType, cleanup); kSlideAnimationTweenType, cleanup);
} }
void AppListBubbleAppsPage::OnPressShowContinueSection(const ui::Event& event) { void AppListBubbleAppsPage::OnToggleContinueSection() {
view_delegate_->SetHideContinueSection(false); bool should_hide = !view_delegate_->ShouldHideContinueSection();
UpdateContinueSectionVisibility(); view_delegate_->SetHideContinueSection(should_hide);
// AppListControllerImpl will trigger UpdateContinueSectionVisibility().
} }
BEGIN_METADATA(AppListBubbleAppsPage, views::View) BEGIN_METADATA(AppListBubbleAppsPage, views::View)

@@ -28,6 +28,7 @@ class Layer;
} // namespace ui } // namespace ui
namespace views { namespace views {
class Label;
class Separator; class Separator;
} // namespace views } // namespace views
@@ -40,7 +41,7 @@ class AppListFolderController;
class AppListNudgeController; class AppListNudgeController;
class AppListViewDelegate; class AppListViewDelegate;
class ContinueSectionView; class ContinueSectionView;
class PillButton; class IconButton;
class RecentAppsView; class RecentAppsView;
class RoundedScrollBar; class RoundedScrollBar;
class SearchResultPageDialogController; class SearchResultPageDialogController;
@@ -151,8 +152,11 @@ class ASH_EXPORT AppListBubbleAppsPage
// Which layer animates is an implementation detail. // Which layer animates is an implementation detail.
ui::Layer* GetPageAnimationLayerForTest(); ui::Layer* GetPageAnimationLayerForTest();
PillButton* show_continue_section_button_for_test() { views::View* continue_label_container_for_test() {
return show_continue_section_button_; return continue_label_container_;
}
IconButton* toggle_continue_section_button_for_test() {
return toggle_continue_section_button_;
} }
RecentAppsView* recent_apps_for_test() { return recent_apps_; } RecentAppsView* recent_apps_for_test() { return recent_apps_; }
views::Separator* separator_for_test() { return separator_; } views::Separator* separator_for_test() { return separator_; }
@@ -171,6 +175,14 @@ class ASH_EXPORT AppListBubbleAppsPage
private: private:
friend class AppListTestHelper; friend class AppListTestHelper;
// Creates the `continue_label_container_` view and its contents, the
// continue label and the toggle continue section button.
void InitContinueLabelContainer(views::View* scroll_contents);
// Updates the continue label container and its child views, including the
// container visibility and the toggle button state.
void UpdateContinueLabelContainer();
void UpdateSeparatorVisibility(); void UpdateSeparatorVisibility();
// Destroys the layer for `view`. Not static so it can be used with weak // Destroys the layer for `view`. Not static so it can be used with weak
@@ -206,13 +218,19 @@ class ASH_EXPORT AppListBubbleAppsPage
int vertical_offset, int vertical_offset,
base::TimeDelta duration); base::TimeDelta duration);
// Button press callback for `show_continue_section_button_`. // Pressed callback for `toggle_continue_section_button_`.
void OnPressShowContinueSection(const ui::Event& event); void OnToggleContinueSection();
AppListViewDelegate* view_delegate_ = nullptr; AppListViewDelegate* view_delegate_ = nullptr;
views::ScrollView* scroll_view_ = nullptr; views::ScrollView* scroll_view_ = nullptr;
RoundedScrollBar* scroll_bar_ = nullptr; RoundedScrollBar* scroll_bar_ = nullptr;
PillButton* show_continue_section_button_ = nullptr;
// Wraps both the continue label and the toggle continue section button.
// Only exists when feature LauncherHideContinueSection is enabled.
views::View* continue_label_container_ = nullptr;
views::Label* continue_label_ = nullptr;
IconButton* toggle_continue_section_button_ = nullptr;
ContinueSectionView* continue_section_ = nullptr; ContinueSectionView* continue_section_ = nullptr;
RecentAppsView* recent_apps_ = nullptr; RecentAppsView* recent_apps_ = nullptr;
views::Separator* separator_ = nullptr; views::Separator* separator_ = nullptr;

@@ -20,7 +20,7 @@
#include "ash/constants/ash_features.h" #include "ash/constants/ash_features.h"
#include "ash/public/cpp/app_list/app_list_controller.h" #include "ash/public/cpp/app_list/app_list_controller.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/style/pill_button.h" #include "ash/style/icon_button.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "ash/test/layer_animation_stopped_waiter.h" #include "ash/test/layer_animation_stopped_waiter.h"
#include "base/test/bind.h" #include "base/test/bind.h"
@@ -249,17 +249,27 @@ TEST_F(AppListBubbleAppsPageTest, ContinueSectionVisibleByDefault) {
helper->AddAppItems(5); helper->AddAppItems(5);
helper->ShowAppList(); helper->ShowAppList();
// The show continue section button is hidden.
auto* apps_page = helper->GetBubbleAppsPage();
EXPECT_FALSE(
apps_page->show_continue_section_button_for_test()->GetVisible());
// The continue section and recent apps are visible. // The continue section and recent apps are visible.
auto* apps_page = helper->GetBubbleAppsPage();
EXPECT_TRUE(helper->GetBubbleContinueSectionView()->GetVisible()); EXPECT_TRUE(helper->GetBubbleContinueSectionView()->GetVisible());
EXPECT_TRUE(helper->GetBubbleRecentAppsView()->GetVisible()); EXPECT_TRUE(helper->GetBubbleRecentAppsView()->GetVisible());
EXPECT_TRUE(apps_page->separator_for_test()->GetVisible()); EXPECT_TRUE(apps_page->separator_for_test()->GetVisible());
} }
TEST_F(AppListBubbleAppsPageTest, ContinueLabelHiddenWhenNoTasksAndNoRecents) {
base::test::ScopedFeatureList feature_list(
features::kLauncherHideContinueSection);
// Show the app list with no continue suggestions and no recent apps.
auto* helper = GetAppListTestHelper();
helper->AddAppItems(5);
helper->ShowAppList();
auto* apps_page = helper->GetBubbleAppsPage();
ASSERT_TRUE(apps_page->continue_label_container_for_test());
EXPECT_FALSE(apps_page->continue_label_container_for_test()->GetVisible());
}
TEST_F(AppListBubbleAppsPageTest, CanHideContinueSection) { TEST_F(AppListBubbleAppsPageTest, CanHideContinueSection) {
base::test::ScopedFeatureList feature_list( base::test::ScopedFeatureList feature_list(
features::kLauncherHideContinueSection); features::kLauncherHideContinueSection);
@@ -272,19 +282,24 @@ TEST_F(AppListBubbleAppsPageTest, CanHideContinueSection) {
helper->AddAppItems(5); helper->AddAppItems(5);
helper->ShowAppList(); helper->ShowAppList();
// Hide the continue section. // The toggle continue section button has the "hide" tooltip.
Shell::Get()->app_list_controller()->SetHideContinueSection(true);
// The show continue section button appears.
auto* apps_page = helper->GetBubbleAppsPage(); auto* apps_page = helper->GetBubbleAppsPage();
auto* show_continue_section_button = IconButton* toggle_continue_section_button =
apps_page->show_continue_section_button_for_test(); apps_page->toggle_continue_section_button_for_test();
EXPECT_TRUE(show_continue_section_button->GetVisible()); ASSERT_TRUE(toggle_continue_section_button);
EXPECT_EQ(toggle_continue_section_button->GetTooltipText(),
u"Hide all suggestions");
// Hide the continue section.
LeftClickOn(toggle_continue_section_button);
// Continue section and recent apps are hidden. // Continue section and recent apps are hidden.
EXPECT_FALSE(helper->GetBubbleContinueSectionView()->GetVisible()); EXPECT_FALSE(helper->GetBubbleContinueSectionView()->GetVisible());
EXPECT_FALSE(helper->GetBubbleRecentAppsView()->GetVisible()); EXPECT_FALSE(helper->GetBubbleRecentAppsView()->GetVisible());
EXPECT_FALSE(apps_page->separator_for_test()->GetVisible());
// Label container and separator stay visible.
EXPECT_TRUE(apps_page->continue_label_container_for_test()->GetVisible());
EXPECT_TRUE(apps_page->separator_for_test()->GetVisible());
} }
TEST_F(AppListBubbleAppsPageTest, CanShowContinueSectionByClickingButton) { TEST_F(AppListBubbleAppsPageTest, CanShowContinueSectionByClickingButton) {
@@ -302,22 +317,21 @@ TEST_F(AppListBubbleAppsPageTest, CanShowContinueSectionByClickingButton) {
helper->AddAppItems(5); helper->AddAppItems(5);
helper->ShowAppList(); helper->ShowAppList();
// The show continue section button appears. // The toggle continue section button has the "show" tooltip.
auto* apps_page = helper->GetBubbleAppsPage(); auto* apps_page = helper->GetBubbleAppsPage();
auto* show_continue_section_button = IconButton* toggle_continue_section_button =
apps_page->show_continue_section_button_for_test(); apps_page->toggle_continue_section_button_for_test();
EXPECT_TRUE(show_continue_section_button->GetVisible()); ASSERT_TRUE(toggle_continue_section_button);
EXPECT_EQ(toggle_continue_section_button->GetTooltipText(),
u"Show all suggestions");
// Continue section and recent apps are hidden. // Continue section and recent apps are hidden.
EXPECT_FALSE(helper->GetBubbleContinueSectionView()->GetVisible()); EXPECT_FALSE(helper->GetBubbleContinueSectionView()->GetVisible());
EXPECT_FALSE(helper->GetBubbleRecentAppsView()->GetVisible()); EXPECT_FALSE(helper->GetBubbleRecentAppsView()->GetVisible());
EXPECT_FALSE(apps_page->separator_for_test()->GetVisible()); EXPECT_TRUE(apps_page->separator_for_test()->GetVisible());
// Click the show continue section button. // Click the show continue section button.
LeftClickOn(show_continue_section_button); LeftClickOn(toggle_continue_section_button);
// The button hides.
EXPECT_FALSE(show_continue_section_button->GetVisible());
// The continue section and recent apps are visible. // The continue section and recent apps are visible.
EXPECT_TRUE(helper->GetBubbleContinueSectionView()->GetVisible()); EXPECT_TRUE(helper->GetBubbleContinueSectionView()->GetVisible());

@@ -21,6 +21,7 @@
#include "ash/app_list/views/continue_task_view.h" #include "ash/app_list/views/continue_task_view.h"
#include "ash/app_list/views/search_result_page_dialog_controller.h" #include "ash/app_list/views/search_result_page_dialog_controller.h"
#include "ash/bubble/bubble_utils.h" #include "ash/bubble/bubble_utils.h"
#include "ash/constants/ash_features.h"
#include "ash/public/cpp/app_list/app_list_config.h" #include "ash/public/cpp/app_list/app_list_config.h"
#include "ash/resources/vector_icons/vector_icons.h" #include "ash/resources/vector_icons/vector_icons.h"
#include "ash/session/session_controller_impl.h" #include "ash/session/session_controller_impl.h"
@@ -108,7 +109,9 @@ ContinueSectionView::ContinueSectionView(
views::MinimumFlexSizeRule::kScaleToMinimumSnapToZero, views::MinimumFlexSizeRule::kScaleToMinimumSnapToZero,
views::MaximumFlexSizeRule::kUnbounded)); views::MaximumFlexSizeRule::kUnbounded));
if (!tablet_mode) { // The launcher "hide continue section" feature makes the label a child of
// AppListBubbleAppsPage.
if (!tablet_mode && !features::IsLauncherHideContinueSectionEnabled()) {
continue_label_ = AddChildView(CreateContinueLabel( continue_label_ = AddChildView(CreateContinueLabel(
l10n_util::GetStringUTF16(IDS_ASH_LAUNCHER_CONTINUE_SECTION_LABEL))); l10n_util::GetStringUTF16(IDS_ASH_LAUNCHER_CONTINUE_SECTION_LABEL)));
continue_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); continue_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);

@@ -4568,6 +4568,12 @@ Here are some things you can try to get started.
<message name="IDS_ASH_LAUNCHER_HIDE_CONTINUE_SECTION" desc="Context menu label to hide the launcher continue section (which defaults to being shown)."> <message name="IDS_ASH_LAUNCHER_HIDE_CONTINUE_SECTION" desc="Context menu label to hide the launcher continue section (which defaults to being shown).">
Hide all suggestions Hide all suggestions
</message> </message>
<message name="IDS_ASH_LAUNCHER_SHOW_CONTINUE_SECTION_TOOLTIP" desc="Tooltip for button that shows the launcher continue section after it has been hidden.">
Show all suggestions
</message>
<message name="IDS_ASH_LAUNCHER_HIDE_CONTINUE_SECTION_TOOLTIP" desc="Tooltip for button that hides the launcher continue section (which defaults to being shown).">
Hide all suggestions
</message>
<message name="IDS_ASH_LAUNCHER_CONTINUE_SECTION_PRIVACY_TEXT" desc="Text for the privacy notice of the continue section of the launcher in clamshell mode, which shows recent files and apps that the user can continue using."> <message name="IDS_ASH_LAUNCHER_CONTINUE_SECTION_PRIVACY_TEXT" desc="Text for the privacy notice of the continue section of the launcher in clamshell mode, which shows recent files and apps that the user can continue using.">
Youll see recommendations so you can continue where you left off. You can right-click to remove recommendations. Youll see recommendations so you can continue where you left off. You can right-click to remove recommendations.
</message> </message>

@@ -0,0 +1 @@
ed6eb6890e5465b0c4bd15d923e24f6d34de4bc7

@@ -0,0 +1 @@
52fb662658e02186d2dc3b47a3acff6f85d4dcbe

@@ -61,7 +61,9 @@ aggregate_vector_icons("ash_vector_icons") {
"caret_right.icon", "caret_right.icon",
"check.icon", "check.icon",
"check_circle.icon", "check_circle.icon",
"chevron_down.icon",
"chevron_right.icon", "chevron_right.icon",
"chevron_up.icon",
"clipboard.icon", "clipboard.icon",
"clipboard_empty.icon", "clipboard_empty.icon",
"clipboard_launcher_inner.icon", "clipboard_launcher_inner.icon",

@@ -0,0 +1,13 @@
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
CANVAS_DIMENSIONS, 20,
MOVE_TO, 5.41f, 6,
LINE_TO, 10, 10.95f,
LINE_TO, 14.59f, 6,
LINE_TO, 16, 7.52f,
LINE_TO, 10, 14,
LINE_TO, 4, 7.52f,
LINE_TO, 5.41f, 6,
CLOSE

@@ -0,0 +1,13 @@
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
CANVAS_DIMENSIONS, 20,
MOVE_TO, 5.41f, 14,
LINE_TO, 10, 9.06f,
LINE_TO, 14.59f, 14,
LINE_TO, 16, 12.48f,
LINE_TO, 10, 6,
R_LINE_TO, -6, 6.48f,
LINE_TO, 5.41f, 14,
CLOSE

@@ -26,6 +26,7 @@
namespace ash { namespace ash {
namespace { namespace {
constexpr int kTinyButtonSize = 24;
constexpr int kSmallButtonSize = 32; constexpr int kSmallButtonSize = 32;
constexpr int kMediumButtonSize = 36; constexpr int kMediumButtonSize = 36;
constexpr int kLargeButtonSize = 48; constexpr int kLargeButtonSize = 48;
@@ -41,6 +42,9 @@ constexpr gfx::Insets kFocusRingPadding(1);
int GetButtonSizeOnType(IconButton::Type type) { int GetButtonSizeOnType(IconButton::Type type) {
switch (type) { switch (type) {
case IconButton::Type::kTiny:
case IconButton::Type::kTinyFloating:
return kTinyButtonSize;
case IconButton::Type::kSmall: case IconButton::Type::kSmall:
case IconButton::Type::kSmallFloating: case IconButton::Type::kSmallFloating:
return kSmallButtonSize; return kSmallButtonSize;
@@ -54,7 +58,8 @@ int GetButtonSizeOnType(IconButton::Type type) {
} }
bool IsFloatingIconButton(IconButton::Type type) { bool IsFloatingIconButton(IconButton::Type type) {
return type == IconButton::Type::kSmallFloating || return type == IconButton::Type::kTinyFloating ||
type == IconButton::Type::kSmallFloating ||
type == IconButton::Type::kMediumFloating || type == IconButton::Type::kMediumFloating ||
type == IconButton::Type::kLargeFloating; type == IconButton::Type::kLargeFloating;
} }
@@ -157,6 +162,13 @@ void IconButton::SetIconColor(const SkColor icon_color) {
UpdateVectorIcon(); UpdateVectorIcon();
} }
void IconButton::SetIconSize(int size) {
if (icon_size_ == size)
return;
icon_size_ = size;
UpdateVectorIcon();
}
void IconButton::SetToggled(bool toggled) { void IconButton::SetToggled(bool toggled) {
if (!is_togglable_ || toggled_ == toggled) if (!is_togglable_ || toggled_ == toggled)
return; return;
@@ -249,6 +261,7 @@ void IconButton::UpdateVectorIcon() {
const SkColor toggled_icon_color = color_provider->GetContentLayerColor( const SkColor toggled_icon_color = color_provider->GetContentLayerColor(
AshColorProvider::ContentLayerType::kButtonIconColorPrimary); AshColorProvider::ContentLayerType::kButtonIconColorPrimary);
const SkColor icon_color = toggled_ ? toggled_icon_color : normal_icon_color; const SkColor icon_color = toggled_ ? toggled_icon_color : normal_icon_color;
const int icon_size = icon_size_.value_or(kIconSize);
// Skip repainting if the incoming icon is the same as the current icon. If // Skip repainting if the incoming icon is the same as the current icon. If
// the icon has been painted before, |gfx::CreateVectorIcon()| will simply // the icon has been painted before, |gfx::CreateVectorIcon()| will simply
@@ -256,7 +269,7 @@ void IconButton::UpdateVectorIcon() {
// assumes that toggled/disabled images changes at the same time as the normal // assumes that toggled/disabled images changes at the same time as the normal
// image, which it currently does. // image, which it currently does.
const gfx::ImageSkia new_normal_image = const gfx::ImageSkia new_normal_image =
gfx::CreateVectorIcon(*icon_, kIconSize, icon_color); gfx::CreateVectorIcon(*icon_, icon_size, icon_color);
const gfx::ImageSkia& old_normal_image = const gfx::ImageSkia& old_normal_image =
GetImage(views::Button::STATE_NORMAL); GetImage(views::Button::STATE_NORMAL);
if (!new_normal_image.isNull() && !old_normal_image.isNull() && if (!new_normal_image.isNull() && !old_normal_image.isNull() &&
@@ -267,7 +280,7 @@ void IconButton::UpdateVectorIcon() {
SetImage(views::Button::STATE_NORMAL, new_normal_image); SetImage(views::Button::STATE_NORMAL, new_normal_image);
SetImage(views::Button::STATE_DISABLED, SetImage(views::Button::STATE_DISABLED,
gfx::CreateVectorIcon( gfx::CreateVectorIcon(
*icon_, kIconSize, *icon_, icon_size,
AshColorProvider::GetDisabledColor(normal_icon_color))); AshColorProvider::GetDisabledColor(normal_icon_color)));
} }

@@ -31,9 +31,11 @@ class ASH_EXPORT IconButton : public views::ImageButton {
METADATA_HEADER(IconButton); METADATA_HEADER(IconButton);
enum class Type { enum class Type {
kTiny,
kSmall, kSmall,
kMedium, kMedium,
kLarge, kLarge,
kTinyFloating,
kSmallFloating, kSmallFloating,
kMediumFloating, kMediumFloating,
kLargeFloating kLargeFloating
@@ -97,6 +99,9 @@ class ASH_EXPORT IconButton : public views::ImageButton {
// when it's not toggled. // when it's not toggled.
void SetIconColor(const SkColor icon_color); void SetIconColor(const SkColor icon_color);
// Sets the size to use for the vector icon in DIPs.
void SetIconSize(int size);
// Updates the `toggled_` state of the button. // Updates the `toggled_` state of the button.
void SetToggled(bool toggled); void SetToggled(bool toggled);
@@ -126,6 +131,9 @@ class ASH_EXPORT IconButton : public views::ImageButton {
absl::optional<SkColor> background_color_; absl::optional<SkColor> background_color_;
absl::optional<SkColor> icon_color_; absl::optional<SkColor> icon_color_;
// Custom value for icon size (usually used to make the icon smaller).
absl::optional<int> icon_size_;
DisabledButtonBehavior button_behavior_ = DisabledButtonBehavior::kNone; DisabledButtonBehavior button_behavior_ = DisabledButtonBehavior::kNone;
}; };