diff --git a/ash/app_list/views/app_list_bubble_apps_page.cc b/ash/app_list/views/app_list_bubble_apps_page.cc index 6cedd7ddf6053..c4c51187ca44d 100644 --- a/ash/app_list/views/app_list_bubble_apps_page.cc +++ b/ash/app_list/views/app_list_bubble_apps_page.cc @@ -30,6 +30,10 @@ using views::BoxLayout; namespace ash { +namespace { +constexpr int kContinueColumnCount = 2; +} // namespace + AppListBubbleAppsPage::AppListBubbleAppsPage( AppListViewDelegate* view_delegate, ApplicationDragAndDropHost* drag_and_drop_host) { @@ -56,8 +60,9 @@ AppListBubbleAppsPage::AppListBubbleAppsPage( layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kStretch); // Continue section row. - continue_section_ = scroll_contents->AddChildView( - std::make_unique<ContinueSectionView>(view_delegate)); + continue_section_ = + scroll_contents->AddChildView(std::make_unique<ContinueSectionView>( + view_delegate, kContinueColumnCount)); // Recent apps row. recent_apps_ = scroll_contents->AddChildView( diff --git a/ash/app_list/views/continue_section_view.cc b/ash/app_list/views/continue_section_view.cc index af83b1a866391..4ff34b76347e5 100644 --- a/ash/app_list/views/continue_section_view.cc +++ b/ash/app_list/views/continue_section_view.cc @@ -26,16 +26,17 @@ namespace ash { namespace { -// Horizontal space between suggestions in dips. -constexpr int kHorizontalSpacing = 8; +// Vertical space between header and content in dips. +constexpr int kVerticalSpacing = 8; -constexpr int kContinueColumnCount = 2; -constexpr int kContinueColumnSpacing = 16; -constexpr int kContinueRowSpacing = 10; +// Continue files section constants. +constexpr int kContinueColumnSpacing = 8; +constexpr int kContinueRowSpacing = 8; +constexpr int kMinFilesForContinueSection = 3; -std::unique_ptr<views::Label> CreateLabel(const std::u16string& text) { +std::unique_ptr<views::Label> CreateContinueLabel(const std::u16string& text) { auto label = std::make_unique<views::Label>(text); - bubble_utils::ApplyStyle(label.get(), bubble_utils::LabelStyle::kBody); + bubble_utils::ApplyStyle(label.get(), bubble_utils::LabelStyle::kSubtitle); return label; } @@ -75,23 +76,24 @@ std::vector<SearchResult*> GetTasksResultsFromSuggestionChips( } // namespace -ContinueSectionView::ContinueSectionView(AppListViewDelegate* view_delegate) - : view_delegate_(view_delegate) { +ContinueSectionView::ContinueSectionView(AppListViewDelegate* view_delegate, + int columns) + : view_delegate_(view_delegate), columns_(columns) { DCHECK(view_delegate_); auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical, gfx::Insets(), - kHorizontalSpacing)); - layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kCenter); + kVerticalSpacing)); + layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); // TODO(https://crbug.com/1204551): Localized strings. // TODO(https://crbug.com/1204551): Styling. - auto* continue_label = AddChildView(CreateLabel(u"Label")); + auto* continue_label = AddChildView(CreateContinueLabel(u"Continue")); continue_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); suggestions_container_ = AddChildView(std::make_unique<views::View>()); suggestions_container_->SetLayoutManager(std::make_unique<SimpleGridLayout>( - kContinueColumnCount, kContinueColumnSpacing, kContinueRowSpacing)); + columns_, kContinueColumnSpacing, kContinueRowSpacing)); std::vector<SearchResult*> tasks = GetTasksResultsFromSuggestionChips(view_delegate_->GetSearchModel()); @@ -100,7 +102,7 @@ ContinueSectionView::ContinueSectionView(AppListViewDelegate* view_delegate) suggestions_container_->AddChildView( std::make_unique<ContinueTaskView>(task)); } - SetVisible(!tasks.empty()); + SetVisible(GetTasksSuggestionsCount() > kMinFilesForContinueSection); } ContinueSectionView::~ContinueSectionView() = default; diff --git a/ash/app_list/views/continue_section_view.h b/ash/app_list/views/continue_section_view.h index 11b89d2739b8e..160697f3e9d3b 100644 --- a/ash/app_list/views/continue_section_view.h +++ b/ash/app_list/views/continue_section_view.h @@ -19,7 +19,7 @@ class ASH_EXPORT ContinueSectionView : public views::View { public: METADATA_HEADER(ContinueSectionView); - explicit ContinueSectionView(AppListViewDelegate* view_delegate); + ContinueSectionView(AppListViewDelegate* view_delegate, int columns); ContinueSectionView(const ContinueSectionView&) = delete; ContinueSectionView& operator=(const ContinueSectionView&) = delete; ~ContinueSectionView() override; @@ -30,6 +30,7 @@ class ASH_EXPORT ContinueSectionView : public views::View { private: AppListViewDelegate* const view_delegate_; + const int columns_; views::View* suggestions_container_ = nullptr; }; diff --git a/ash/app_list/views/continue_task_view.cc b/ash/app_list/views/continue_task_view.cc index dc1be4ded9fc8..dcc5c6ac5b2ab 100644 --- a/ash/app_list/views/continue_task_view.cc +++ b/ash/app_list/views/continue_task_view.cc @@ -9,34 +9,72 @@ #include <string> #include <utility> +#include "ash/app_list/app_list_util.h" #include "ash/app_list/model/search/search_result.h" #include "ash/bubble/bubble_utils.h" +#include "ash/style/ash_color_provider.h" #include "base/strings/string_util.h" #include "extensions/common/constants.h" #include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/gfx/image/image_skia_operations.h" +#include "ui/views/accessibility/view_accessibility.h" +#include "ui/views/background.h" +#include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" -#include "ui/views/layout/fill_layout.h" +#include "ui/views/layout/box_layout.h" namespace ash { +namespace { +constexpr int kIconSize = 36; +constexpr int kPreferredWidth = 242; +constexpr int kPreferredHeight = 52; +} // namespace ContinueTaskView::ContinueTaskView(SearchResult* task_result) : result_(task_result) { - SetLayoutManager(std::make_unique<views::FillLayout>()); - title_ = AddChildView(std::make_unique<views::Label>()); - SetText(result()->title()); + SetFocusBehavior(FocusBehavior::ALWAYS); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); + GetViewAccessibility().OverrideName(result()->title() + u" " + + result()->details()); + GetViewAccessibility().OverrideRole(ax::mojom::Role::kListItem); + + icon_ = AddChildView(std::make_unique<views::ImageView>()); + icon_->SetVerticalAlignment(views::ImageView::Alignment::kLeading); + SetIcon(result()->chip_icon()); + + auto* label_container = AddChildView(std::make_unique<views::View>()); + label_container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); + + title_ = label_container->AddChildView( + std::make_unique<views::Label>(result()->title())); title_->SetAccessibleName(result()->accessible_name()); + title_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); + subtitle_ = label_container->AddChildView( + std::make_unique<views::Label>(result()->details())); + subtitle_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); + + SetPreferredSize(gfx::Size(kPreferredWidth, kPreferredHeight)); } ContinueTaskView::~ContinueTaskView() = default; -void ContinueTaskView::SetText(const std::u16string& text) { - title_->SetText(text); - PreferredSizeChanged(); -} - void ContinueTaskView::OnThemeChanged() { views::View::OnThemeChanged(); bubble_utils::ApplyStyle(title_, bubble_utils::LabelStyle::kBody); + bubble_utils::ApplyStyle(subtitle_, bubble_utils::LabelStyle::kSubtitle); +} + +void ContinueTaskView::SetIcon(const gfx::ImageSkia& icon) { + gfx::ImageSkia resized(gfx::ImageSkiaOperations::CreateResizedImage( + icon, skia::ImageOperations::RESIZE_BEST, GetIconSize())); + icon_->SetImage(resized); + icon_->SetImageSize(GetIconSize()); +} + +gfx::Size ContinueTaskView::GetIconSize() const { + return gfx::Size(kIconSize, kIconSize); } BEGIN_METADATA(ContinueTaskView, views::View) diff --git a/ash/app_list/views/continue_task_view.h b/ash/app_list/views/continue_task_view.h index 555d231d713dc..8d122e185a80e 100644 --- a/ash/app_list/views/continue_task_view.h +++ b/ash/app_list/views/continue_task_view.h @@ -5,13 +5,11 @@ #ifndef ASH_APP_LIST_VIEWS_CONTINUE_TASK_VIEW_H_ #define ASH_APP_LIST_VIEWS_CONTINUE_TASK_VIEW_H_ -#include <memory> -#include <string> - #include "ash/ash_export.h" #include "ui/views/view.h" namespace views { +class ImageView; class Label; } @@ -34,10 +32,13 @@ class ASH_EXPORT ContinueTaskView : public views::View { SearchResult* result() { return result_; } private: - void SetText(const std::u16string& task_title); + void SetIcon(const gfx::ImageSkia& icon); + gfx::Size GetIconSize() const; SearchResult* result_; - views::Label* title_; + views::Label* title_ = nullptr; + views::Label* subtitle_ = nullptr; + views::ImageView* icon_ = nullptr; }; } // namespace ash diff --git a/ash/bubble/bubble_utils.cc b/ash/bubble/bubble_utils.cc index 99a64c5c6c889..3d33e7fb77257 100644 --- a/ash/bubble/bubble_utils.cc +++ b/ash/bubble/bubble_utils.cc @@ -96,31 +96,43 @@ bool ShouldCloseBubbleForEvent(const ui::LocatedEvent& event) { void ApplyStyle(views::Label* label, LabelStyle style) { label->SetAutoColorReadabilityEnabled(false); - label->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor( - AshColorProvider::ContentLayerType::kTextColorPrimary)); + AshColorProvider::ContentLayerType text_color; switch (style) { case LabelStyle::kBadge: + text_color = AshColorProvider::ContentLayerType::kTextColorPrimary; label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 14, gfx::Font::Weight::MEDIUM)); break; case LabelStyle::kBody: + text_color = AshColorProvider::ContentLayerType::kTextColorPrimary; label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 14, gfx::Font::Weight::NORMAL)); break; case LabelStyle::kChipBody: + text_color = AshColorProvider::ContentLayerType::kTextColorPrimary; label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 10, gfx::Font::Weight::MEDIUM)); break; case LabelStyle::kChipTitle: + text_color = AshColorProvider::ContentLayerType::kTextColorPrimary; label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 13, gfx::Font::Weight::NORMAL)); break; case LabelStyle::kHeader: + text_color = AshColorProvider::ContentLayerType::kTextColorPrimary; label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 16, gfx::Font::Weight::MEDIUM)); break; + case LabelStyle::kSubtitle: + text_color = AshColorProvider::ContentLayerType::kTextColorSecondary; + label->SetFontList(gfx::FontList({"Roboto"}, gfx::Font::NORMAL, 12, + gfx::Font::Weight::NORMAL)); + break; } + + label->SetEnabledColor( + AshColorProvider::Get()->GetContentLayerColor(text_color)); } std::unique_ptr<views::Label> CreateLabel(LabelStyle style, diff --git a/ash/bubble/bubble_utils.h b/ash/bubble/bubble_utils.h index 93ec6f64e4fa7..e0ea3434c0006 100644 --- a/ash/bubble/bubble_utils.h +++ b/ash/bubble/bubble_utils.h @@ -34,6 +34,7 @@ enum class LabelStyle { kChipBody, kChipTitle, kHeader, + kSubtitle, }; // Applies the specified `style` to the given `label`.