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/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.">
|
||||||
You’ll see recommendations so you can continue where you left off. You can right-click to remove recommendations.
|
You’ll 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",
|
||||||
|
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 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user