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:

committed by
Chromium LUCI CQ

parent
7294e4d782
commit
b5d2be9a9b
ash
app_list
views
ash_strings_grd
IDS_ASH_LAUNCHER_HIDE_CONTINUE_SECTION_TOOLTIP.png.sha1IDS_ASH_LAUNCHER_SHOW_CONTINUE_SECTION_TOOLTIP.png.sha1
resources
vector_icons
style
@ -30,7 +30,7 @@
|
||||
#include "ash/public/cpp/style/color_provider.h"
|
||||
#include "ash/resources/vector_icons/vector_icons.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/check.h"
|
||||
#include "base/metrics/histogram_functions.h"
|
||||
@ -55,6 +55,7 @@
|
||||
#include "ui/views/controls/textfield/textfield.h"
|
||||
#include "ui/views/focus/focus_manager.h"
|
||||
#include "ui/views/layout/box_layout.h"
|
||||
#include "ui/views/view_class_properties.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
using views::BoxLayout;
|
||||
@ -72,6 +73,9 @@ constexpr auto kVerticalScrollInsets = gfx::Insets::TLBR(1, 0, 1, 1);
|
||||
// interior apps page container margin.
|
||||
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
|
||||
// between the apps page bounds and the page content.
|
||||
constexpr int kHorizontalInteriorMargin = 16;
|
||||
@ -160,25 +164,11 @@ AppListBubbleAppsPage::AppListBubbleAppsPage(
|
||||
kVerticalPaddingBetweenSections));
|
||||
layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kStretch);
|
||||
|
||||
// Add the button to show the continue section, wrapped in a view to center it
|
||||
// horizontally.
|
||||
{
|
||||
auto* container =
|
||||
scroll_contents->AddChildView(std::make_unique<views::View>());
|
||||
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);
|
||||
}
|
||||
// When feature LauncherHideContinueSection is enabled, the "Continue where
|
||||
// you left off" label is in a container that is a child of this view.
|
||||
// Otherwise the label is a child of the ContinueSectionView.
|
||||
if (features::IsLauncherHideContinueSectionEnabled())
|
||||
InitContinueLabelContainer(scroll_contents.get());
|
||||
|
||||
// Continue section row.
|
||||
continue_section_ =
|
||||
@ -188,6 +178,12 @@ AppListBubbleAppsPage::AppListBubbleAppsPage(
|
||||
continue_section_->SetBorder(
|
||||
views::CreateEmptyBorder(kContinueSectionInsets));
|
||||
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
|
||||
// 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
|
||||
const int section_offset = is_side_shelf ? -20 : 20;
|
||||
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() &&
|
||||
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);
|
||||
}
|
||||
if (recent_apps_->GetVisible() && recent_apps_->GetItemViewCount() > 0) {
|
||||
@ -646,19 +652,74 @@ ui::Layer* AppListBubbleAppsPage::GetPageAnimationLayerForTest() {
|
||||
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() {
|
||||
// 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
|
||||
// internally.
|
||||
continue_section_->UpdateElementsVisibility();
|
||||
recent_apps_->UpdateVisibility();
|
||||
UpdateContinueLabelContainer();
|
||||
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() {
|
||||
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());
|
||||
}
|
||||
|
||||
@ -819,9 +880,10 @@ void AppListBubbleAppsPage::SlideViewIntoPosition(views::View* view,
|
||||
kSlideAnimationTweenType, cleanup);
|
||||
}
|
||||
|
||||
void AppListBubbleAppsPage::OnPressShowContinueSection(const ui::Event& event) {
|
||||
view_delegate_->SetHideContinueSection(false);
|
||||
UpdateContinueSectionVisibility();
|
||||
void AppListBubbleAppsPage::OnToggleContinueSection() {
|
||||
bool should_hide = !view_delegate_->ShouldHideContinueSection();
|
||||
view_delegate_->SetHideContinueSection(should_hide);
|
||||
// AppListControllerImpl will trigger UpdateContinueSectionVisibility().
|
||||
}
|
||||
|
||||
BEGIN_METADATA(AppListBubbleAppsPage, views::View)
|
||||
|
@ -28,6 +28,7 @@ class Layer;
|
||||
} // namespace ui
|
||||
|
||||
namespace views {
|
||||
class Label;
|
||||
class Separator;
|
||||
} // namespace views
|
||||
|
||||
@ -40,7 +41,7 @@ class AppListFolderController;
|
||||
class AppListNudgeController;
|
||||
class AppListViewDelegate;
|
||||
class ContinueSectionView;
|
||||
class PillButton;
|
||||
class IconButton;
|
||||
class RecentAppsView;
|
||||
class RoundedScrollBar;
|
||||
class SearchResultPageDialogController;
|
||||
@ -151,8 +152,11 @@ class ASH_EXPORT AppListBubbleAppsPage
|
||||
// Which layer animates is an implementation detail.
|
||||
ui::Layer* GetPageAnimationLayerForTest();
|
||||
|
||||
PillButton* show_continue_section_button_for_test() {
|
||||
return show_continue_section_button_;
|
||||
views::View* continue_label_container_for_test() {
|
||||
return continue_label_container_;
|
||||
}
|
||||
IconButton* toggle_continue_section_button_for_test() {
|
||||
return toggle_continue_section_button_;
|
||||
}
|
||||
RecentAppsView* recent_apps_for_test() { return recent_apps_; }
|
||||
views::Separator* separator_for_test() { return separator_; }
|
||||
@ -171,6 +175,14 @@ class ASH_EXPORT AppListBubbleAppsPage
|
||||
private:
|
||||
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();
|
||||
|
||||
// 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,
|
||||
base::TimeDelta duration);
|
||||
|
||||
// Button press callback for `show_continue_section_button_`.
|
||||
void OnPressShowContinueSection(const ui::Event& event);
|
||||
// Pressed callback for `toggle_continue_section_button_`.
|
||||
void OnToggleContinueSection();
|
||||
|
||||
AppListViewDelegate* view_delegate_ = nullptr;
|
||||
views::ScrollView* scroll_view_ = 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;
|
||||
RecentAppsView* recent_apps_ = nullptr;
|
||||
views::Separator* separator_ = nullptr;
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "ash/constants/ash_features.h"
|
||||
#include "ash/public/cpp/app_list/app_list_controller.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/layer_animation_stopped_waiter.h"
|
||||
#include "base/test/bind.h"
|
||||
@ -249,17 +249,27 @@ TEST_F(AppListBubbleAppsPageTest, ContinueSectionVisibleByDefault) {
|
||||
helper->AddAppItems(5);
|
||||
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.
|
||||
auto* apps_page = helper->GetBubbleAppsPage();
|
||||
EXPECT_TRUE(helper->GetBubbleContinueSectionView()->GetVisible());
|
||||
EXPECT_TRUE(helper->GetBubbleRecentAppsView()->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) {
|
||||
base::test::ScopedFeatureList feature_list(
|
||||
features::kLauncherHideContinueSection);
|
||||
@ -272,19 +282,24 @@ TEST_F(AppListBubbleAppsPageTest, CanHideContinueSection) {
|
||||
helper->AddAppItems(5);
|
||||
helper->ShowAppList();
|
||||
|
||||
// Hide the continue section.
|
||||
Shell::Get()->app_list_controller()->SetHideContinueSection(true);
|
||||
|
||||
// The show continue section button appears.
|
||||
// The toggle continue section button has the "hide" tooltip.
|
||||
auto* apps_page = helper->GetBubbleAppsPage();
|
||||
auto* show_continue_section_button =
|
||||
apps_page->show_continue_section_button_for_test();
|
||||
EXPECT_TRUE(show_continue_section_button->GetVisible());
|
||||
IconButton* toggle_continue_section_button =
|
||||
apps_page->toggle_continue_section_button_for_test();
|
||||
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.
|
||||
EXPECT_FALSE(helper->GetBubbleContinueSectionView()->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) {
|
||||
@ -302,22 +317,21 @@ TEST_F(AppListBubbleAppsPageTest, CanShowContinueSectionByClickingButton) {
|
||||
helper->AddAppItems(5);
|
||||
helper->ShowAppList();
|
||||
|
||||
// The show continue section button appears.
|
||||
// The toggle continue section button has the "show" tooltip.
|
||||
auto* apps_page = helper->GetBubbleAppsPage();
|
||||
auto* show_continue_section_button =
|
||||
apps_page->show_continue_section_button_for_test();
|
||||
EXPECT_TRUE(show_continue_section_button->GetVisible());
|
||||
IconButton* toggle_continue_section_button =
|
||||
apps_page->toggle_continue_section_button_for_test();
|
||||
ASSERT_TRUE(toggle_continue_section_button);
|
||||
EXPECT_EQ(toggle_continue_section_button->GetTooltipText(),
|
||||
u"Show all suggestions");
|
||||
|
||||
// Continue section and recent apps are hidden.
|
||||
EXPECT_FALSE(helper->GetBubbleContinueSectionView()->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.
|
||||
LeftClickOn(show_continue_section_button);
|
||||
|
||||
// The button hides.
|
||||
EXPECT_FALSE(show_continue_section_button->GetVisible());
|
||||
LeftClickOn(toggle_continue_section_button);
|
||||
|
||||
// The continue section and recent apps are visible.
|
||||
EXPECT_TRUE(helper->GetBubbleContinueSectionView()->GetVisible());
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "ash/app_list/views/continue_task_view.h"
|
||||
#include "ash/app_list/views/search_result_page_dialog_controller.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/resources/vector_icons/vector_icons.h"
|
||||
#include "ash/session/session_controller_impl.h"
|
||||
@ -108,7 +109,9 @@ ContinueSectionView::ContinueSectionView(
|
||||
views::MinimumFlexSizeRule::kScaleToMinimumSnapToZero,
|
||||
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(
|
||||
l10n_util::GetStringUTF16(IDS_ASH_LAUNCHER_CONTINUE_SECTION_LABEL)));
|
||||
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).">
|
||||
Hide all suggestions
|
||||
</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.">
|
||||
You’ll see recommendations so you can continue where you left off. You can right-click to remove recommendations.
|
||||
</message>
|
||||
|
@ -0,0 +1 @@
|
||||
ed6eb6890e5465b0c4bd15d923e24f6d34de4bc7
|
@ -0,0 +1 @@
|
||||
52fb662658e02186d2dc3b47a3acff6f85d4dcbe
|
@ -61,7 +61,9 @@ aggregate_vector_icons("ash_vector_icons") {
|
||||
"caret_right.icon",
|
||||
"check.icon",
|
||||
"check_circle.icon",
|
||||
"chevron_down.icon",
|
||||
"chevron_right.icon",
|
||||
"chevron_up.icon",
|
||||
"clipboard.icon",
|
||||
"clipboard_empty.icon",
|
||||
"clipboard_launcher_inner.icon",
|
||||
|
13
ash/resources/vector_icons/chevron_down.icon
Normal file
13
ash/resources/vector_icons/chevron_down.icon
Normal file
@ -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
|
13
ash/resources/vector_icons/chevron_up.icon
Normal file
13
ash/resources/vector_icons/chevron_up.icon
Normal file
@ -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 {
|
||||
|
||||
constexpr int kTinyButtonSize = 24;
|
||||
constexpr int kSmallButtonSize = 32;
|
||||
constexpr int kMediumButtonSize = 36;
|
||||
constexpr int kLargeButtonSize = 48;
|
||||
@ -41,6 +42,9 @@ constexpr gfx::Insets kFocusRingPadding(1);
|
||||
|
||||
int GetButtonSizeOnType(IconButton::Type type) {
|
||||
switch (type) {
|
||||
case IconButton::Type::kTiny:
|
||||
case IconButton::Type::kTinyFloating:
|
||||
return kTinyButtonSize;
|
||||
case IconButton::Type::kSmall:
|
||||
case IconButton::Type::kSmallFloating:
|
||||
return kSmallButtonSize;
|
||||
@ -54,7 +58,8 @@ int GetButtonSizeOnType(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::kLargeFloating;
|
||||
}
|
||||
@ -157,6 +162,13 @@ void IconButton::SetIconColor(const SkColor icon_color) {
|
||||
UpdateVectorIcon();
|
||||
}
|
||||
|
||||
void IconButton::SetIconSize(int size) {
|
||||
if (icon_size_ == size)
|
||||
return;
|
||||
icon_size_ = size;
|
||||
UpdateVectorIcon();
|
||||
}
|
||||
|
||||
void IconButton::SetToggled(bool toggled) {
|
||||
if (!is_togglable_ || toggled_ == toggled)
|
||||
return;
|
||||
@ -249,6 +261,7 @@ void IconButton::UpdateVectorIcon() {
|
||||
const SkColor toggled_icon_color = color_provider->GetContentLayerColor(
|
||||
AshColorProvider::ContentLayerType::kButtonIconColorPrimary);
|
||||
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
|
||||
// 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
|
||||
// image, which it currently does.
|
||||
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 =
|
||||
GetImage(views::Button::STATE_NORMAL);
|
||||
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_DISABLED,
|
||||
gfx::CreateVectorIcon(
|
||||
*icon_, kIconSize,
|
||||
*icon_, icon_size,
|
||||
AshColorProvider::GetDisabledColor(normal_icon_color)));
|
||||
}
|
||||
|
||||
|
@ -31,9 +31,11 @@ class ASH_EXPORT IconButton : public views::ImageButton {
|
||||
METADATA_HEADER(IconButton);
|
||||
|
||||
enum class Type {
|
||||
kTiny,
|
||||
kSmall,
|
||||
kMedium,
|
||||
kLarge,
|
||||
kTinyFloating,
|
||||
kSmallFloating,
|
||||
kMediumFloating,
|
||||
kLargeFloating
|
||||
@ -97,6 +99,9 @@ class ASH_EXPORT IconButton : public views::ImageButton {
|
||||
// when it's not toggled.
|
||||
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.
|
||||
void SetToggled(bool toggled);
|
||||
|
||||
@ -126,6 +131,9 @@ class ASH_EXPORT IconButton : public views::ImageButton {
|
||||
absl::optional<SkColor> background_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;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user