Skip to content

Commit

Permalink
[App Shortcuts] Add methods to set and observe host badge icon.
Browse files Browse the repository at this point in the history
Bug: 1412708
Change-Id: Ic6d40411dbce4f1333875099fb9d6bfa6887a175
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4948912
Reviewed-by: Maggie Cai <mxcai@chromium.org>
Auto-Submit: Owen Zhang <owenzhang@google.com>
Reviewed-by: Toni Barzic <tbarzic@chromium.org>
Commit-Queue: Owen Zhang <owenzhang@google.com>
Cr-Commit-Position: refs/heads/main@{#1216186}
  • Loading branch information
Owen Zhang authored and Chromium LUCI CQ committed Oct 27, 2023
1 parent d89b900 commit 2a5778d
Show file tree
Hide file tree
Showing 11 changed files with 241 additions and 12 deletions.
11 changes: 11 additions & 0 deletions ash/app_list/model/app_list_item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ void AppListItem::SetIconVersion(int icon_version) {
}
}

const gfx::ImageSkia& AppListItem::GetHostBadgeIcon() const {
return metadata_->badge_icon;
}

void AppListItem::SetHostBadgeIcon(const gfx::ImageSkia host_badge_icon) {
metadata_->badge_icon = host_badge_icon;
for (auto& observer : observers_) {
observer.ItemHostBadgeIconChanged();
}
}

SkColor AppListItem::GetNotificationBadgeColor() const {
return metadata_->badge_color;
}
Expand Down
4 changes: 3 additions & 1 deletion ash/app_list/model/app_list_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "base/observer_list.h"
#include "components/sync/model/string_ordinal.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/view.h"

namespace ash {
enum class AppListConfigType;
Expand Down Expand Up @@ -59,6 +58,9 @@ class APP_LIST_MODEL_EXPORT AppListItem {
// and UI would be updated since it also observe ItemIconChanged.
void SetIconVersion(int icon_version);

const gfx::ImageSkia& GetHostBadgeIcon() const;
void SetHostBadgeIcon(const gfx::ImageSkia bage_icon);

SkColor GetNotificationBadgeColor() const;
void SetNotificationBadgeColor(const SkColor color);

Expand Down
3 changes: 3 additions & 0 deletions ash/app_list/model/app_list_item_observer.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class APP_LIST_MODEL_EXPORT AppListItemObserver : public base::CheckedObserver {
// Invoked after item's name is changed.
virtual void ItemNameChanged() {}

// Invoked after item's host badge icon is changed.
virtual void ItemHostBadgeIconChanged() {}

// Invoked when the item's notification badge visibility is changed.
virtual void ItemBadgeVisibilityChanged() {}

Expand Down
123 changes: 123 additions & 0 deletions ash/app_list/views/app_list_item_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include "ui/color/color_provider.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_owner.h"
#include "ui/compositor/layer_type.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/events/event.h"
Expand All @@ -67,21 +68,30 @@
#include "ui/gfx/font_list.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/transform_util.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/image/canvas_image_source.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/text_constants.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/animation/animation_builder.h"
#include "ui/views/animation/ink_drop.h"
#include "ui/views/animation/ink_drop_state.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
#include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/view.h"
#include "ui/views/view_class_properties.h"
#include "ui/views/view_utils.h"
#include "ui/views/widget/widget.h"
Expand Down Expand Up @@ -548,6 +558,8 @@ AppListItemView::AppListItemView(const AppListConfig* app_list_config,
item_weak_->GetMetadata()->app_status == AppStatus::kPending ||
item_weak_->GetMetadata()->app_status == AppStatus::kInstalling;

has_host_badge_ = !item_weak_->GetMetadata()->badge_icon.isNull();

// Draw the promise ring for the first time before waiting for updates.
if (is_promise_app_) {
ItemProgressUpdated();
Expand Down Expand Up @@ -615,6 +627,10 @@ AppListItemView::AppListItemView(const AppListConfig* app_list_config,

if (use_item_icon_) {
// If the item icon is used, set the icon in ImageView and paint the view.
if (chromeos::features::IsSeparateWebAppShortcutBadgeIconEnabled()) {
shortcut_background_container_ =
AddChildView(std::make_unique<views::View>());
}
icon_ = AddChildView(std::make_unique<views::ImageView>());
icon_->SetCanProcessEventsWithinSubtree(false);
icon_->SetVerticalAlignment(views::ImageView::Alignment::kLeading);
Expand Down Expand Up @@ -739,6 +755,50 @@ void AppListItemView::SetIcon(const gfx::ImageSkia& icon) {
Layout();
}

void AppListItemView::SetHostBadgeIcon(const gfx::ImageSkia& host_badge_icon,
bool update_host_badge_icon) {
// This function is only used when AppListItem host icons are used for
// painting.
CHECK(use_item_icon_);

// Clear host badge icon and bail out if host badge icon is empty.
if (host_badge_icon.isNull()) {
host_badge_icon_view_->SetImage(nullptr);
host_badge_icon_image_ = gfx::ImageSkia();
has_host_badge_ = false;
return;
}
host_badge_icon_image_ = host_badge_icon;

const gfx::Size host_badge_icon_size = gfx::ScaleToRoundedSize(
gfx::Size(app_list_config_->shortcut_host_badge_icon_dimension(),
app_list_config_->shortcut_host_badge_icon_dimension()),
icon_scale_);

gfx::ImageSkia resized = gfx::ImageSkiaOperations::CreateResizedImage(
host_badge_icon, skia::ImageOperations::RESIZE_BEST,
host_badge_icon_size);

if (!host_badge_icon_view_) {
host_badge_icon_container_ = AddChildView(std::make_unique<views::View>());

auto* host_badge_icon_container_layout =
host_badge_icon_container_->SetLayoutManager(
std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical, gfx::Insets(), 0));
host_badge_icon_container_layout->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::kCenter);
host_badge_icon_container_layout->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kCenter);
host_badge_icon_view_ = host_badge_icon_container_->AddChildView(
std::make_unique<views::ImageView>());
}
host_badge_icon_view_->SetImage(resized);
has_host_badge_ = true;

Layout();
}

void AppListItemView::UpdateAppListConfig(
const AppListConfig* app_list_config) {
app_list_config_ = app_list_config;
Expand Down Expand Up @@ -1296,6 +1356,36 @@ void AppListItemView::Layout() {
gfx::ScaleToRoundedSize(icon_size, GetAdjustedIconScaleForProgressRing()),
icon_scale_);

const int shortcut_background_container_dimension =
app_list_config_->GetShortcutBackgroundContainerDimension();
const int shotcut_host_badge_icon_container_dimension =
app_list_config_->GetShortcutHostBadgeIconContainerDimension();

const gfx::Size shortcut_background_container_size =
gfx::Size(shortcut_background_container_dimension,
shortcut_background_container_dimension);

const gfx::Size shotcut_host_badge_icon_container_size =
gfx::Size(shotcut_host_badge_icon_container_dimension,
shotcut_host_badge_icon_container_dimension);

if (shortcut_background_container_ && has_host_badge_) {
shortcut_background_container_->SetBackground(
views::CreateThemedRoundedRectBackground(
cros_tokens::kCrosSysSystemOnBaseOpaque,
shortcut_background_container_dimension / 2, 0));

const gfx::Rect shortcut_background_container_bounds =
GetIconBoundsForTargetViewBounds(
app_list_config_, rect,
gfx::ScaleToRoundedSize(shortcut_background_container_size,
GetAdjustedIconScaleForProgressRing()),
icon_scale_);

shortcut_background_container_->SetBoundsRect(
shortcut_background_container_bounds);
}

GetIconView()->SetBoundsRect(icon_bounds);
UpdateBackgroundLayerBounds();
SetBackgroundExtendedState(is_icon_extended_, /*animate=*/false);
Expand All @@ -1318,6 +1408,23 @@ void AppListItemView::Layout() {
kNewInstallDotSize, kNewInstallDotSize);
}

if (host_badge_icon_container_ && host_badge_icon_view_ &&
chromeos::features::IsSeparateWebAppShortcutBadgeIconEnabled()) {
gfx::Rect host_badge_icon_container_bounds =
GetHostBadgeIconContainerBoundsForTargetViewBounds(
icon_bounds,
gfx::ScaleToRoundedSize(shotcut_host_badge_icon_container_size,
icon_scale_),
icon_scale_);

host_badge_icon_container_->SetBackground(
views::CreateThemedRoundedRectBackground(
cros_tokens::kCrosSysSystemOnBaseOpaque,
shortcut_background_container_dimension / 2, 0));

host_badge_icon_container_->SetBoundsRect(host_badge_icon_container_bounds);
}

const float indicator_size =
icon_bounds.width() * kNotificationIndicatorWidthRatio;
const float indicator_padding =
Expand Down Expand Up @@ -1824,6 +1931,17 @@ gfx::Rect AppListItemView::GetIconBoundsForTargetViewBounds(
return rect;
}

// static
gfx::Rect AppListItemView::GetHostBadgeIconContainerBoundsForTargetViewBounds(
const gfx::Rect& main_icon_bounds,
const gfx::Size& host_badge_icon_with_background_size,
const float icon_scale) {
gfx::Rect rect(main_icon_bounds.CenterPoint(),
host_badge_icon_with_background_size);
rect.ClampToCenteredSize(host_badge_icon_with_background_size);
return rect;
}

// static
gfx::Rect AppListItemView::GetTitleBoundsForTargetViewBounds(
const AppListConfig* config,
Expand Down Expand Up @@ -1860,6 +1978,11 @@ void AppListItemView::ItemNameChanged() {
base::UTF8ToUTF16(item_weak_->GetAccessibleName()));
}

void AppListItemView::ItemHostBadgeIconChanged() {
DCHECK(item_weak_);
SetHostBadgeIcon(item_weak_->GetHostBadgeIcon(), true);
}

void AppListItemView::ItemBadgeVisibilityChanged() {
if (GetIconView()) {
notification_indicator_->SetVisible(item_weak_->has_notification_badge());
Expand Down
31 changes: 31 additions & 0 deletions ash/app_list/views/app_list_item_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@
#include "ash/app_list/model/app_icon_load_helper.h"
#include "ash/app_list/model/app_list_item_observer.h"
#include "ash/ash_export.h"
#include "ash/public/cpp/app_list/app_list_config.h"
#include "base/memory/raw_ptr.h"
#include "base/timer/timer.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_tree_owner.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/views/context_menu_controller.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/image_view.h"
Expand Down Expand Up @@ -174,6 +177,9 @@ class ASH_EXPORT AppListItemView : public views::Button,

void SetItemAccessibleName(const std::u16string& name);

void SetHostBadgeIcon(const gfx::ImageSkia& host_badge_icon,
bool update_host_badge_icon);

void GetAccessibleNodeData(ui::AXNodeData* node_data) override;

void CancelContextMenu();
Expand Down Expand Up @@ -222,6 +228,14 @@ class ASH_EXPORT AppListItemView : public views::Button,
const gfx::Size& icon_size,
float icon_scale);

// Returns the host badge icon bounds using the centerpoint of
// `main_icon_bounds` and given `host_badge_icon_container_size and the
// `icon_scale` if the icon was scaled from the original display size.
static gfx::Rect GetHostBadgeIconContainerBoundsForTargetViewBounds(
const gfx::Rect& main_icon_bounds,
const gfx::Size& host_badge_icon_container_size,
float icon_scale);

// Returns the title bounds for with |target_bounds| as the bounds of this
// view and given |title_size| and the |icon_scale| if the icon was scaled
// from the original display size.
Expand Down Expand Up @@ -400,6 +414,7 @@ class ASH_EXPORT AppListItemView : public views::Button,
// AppListItemObserver overrides:
void ItemIconChanged(AppListConfigType config_type) override;
void ItemNameChanged() override;
void ItemHostBadgeIconChanged() override;
void ItemBadgeVisibilityChanged() override;
void ItemBadgeColorChanged() override;
void ItemIsNewInstallChanged() override;
Expand Down Expand Up @@ -476,6 +491,14 @@ class ASH_EXPORT AppListItemView : public views::Button,
// The folder icon view used for refreshed folders.
raw_ptr<FolderIconView, ExperimentalAsh> folder_icon_ = nullptr;

// The main icon container view used for app shortcuts.
raw_ptr<views::View, ExperimentalAsh> shortcut_background_container_ =
nullptr;
// The host badge icon container view used for app shortcuts.
raw_ptr<views::View, ExperimentalAsh> host_badge_icon_container_ = nullptr;
// The host badge icon view used for app shortcuts.
raw_ptr<views::ImageView, ExperimentalAsh> host_badge_icon_view_ = nullptr;

raw_ptr<views::Label, ExperimentalAsh> title_ = nullptr;

// The background layer added under the `icon_` layer to paint the background
Expand Down Expand Up @@ -526,6 +549,9 @@ class ASH_EXPORT AppListItemView : public views::Button,
// The bitmap image for this app list item.
gfx::ImageSkia icon_image_;

// The bitmap image for this app list item's host badge icon.
gfx::ImageSkia host_badge_icon_image_;

// The current item's drag state.
DragState drag_state_ = DragState::kNone;

Expand Down Expand Up @@ -568,6 +594,11 @@ class ASH_EXPORT AppListItemView : public views::Button,
// app status).
bool is_promise_app_ = false;

// Whether the app is a shortcut (i.e. a deeplink created with shortcut via
// Chrome or other third party installed apps) and should render the host
// badge icon.
bool has_host_badge_ = false;

// An object that draws and updates the progress ring around promise app
// icons.
std::unique_ptr<ProgressIndicator> progress_indicator_;
Expand Down
23 changes: 21 additions & 2 deletions ash/public/cpp/app_list/app_list_config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,10 @@ AppListConfig::AppListConfig(AppListConfigType type)
icon_extended_background_radius_(IconExtendedBackgroundRadius(type)),
item_icon_in_folder_icon_dimension_(
ItemIconInFolderIconDimensionForType(type)),
item_icon_in_folder_icon_margin_(ItemIconInFolderIconMargin()) {}
item_icon_in_folder_icon_margin_(ItemIconInFolderIconMargin()),
shortcut_host_badge_icon_dimension_(24),
shortcut_host_badge_icon_border_dimension_(4),
shortcut_background_border_dimension_(6) {}

AppListConfig::AppListConfig(const AppListConfig& base_config, float scale_x)
: type_(base_config.type_),
Expand Down Expand Up @@ -240,8 +243,24 @@ AppListConfig::AppListConfig(const AppListConfig& base_config, float scale_x)
item_icon_in_folder_icon_dimension_(
Scale(base_config.item_icon_in_folder_icon_dimension_, scale_x)),
item_icon_in_folder_icon_margin_(
Scale(base_config.item_icon_in_folder_icon_margin_, scale_x)) {}
Scale(base_config.item_icon_in_folder_icon_margin_, scale_x)),
shortcut_host_badge_icon_dimension_(
Scale(base_config.shortcut_host_badge_icon_dimension_, scale_x)),
shortcut_host_badge_icon_border_dimension_(
Scale(base_config.shortcut_host_badge_icon_border_dimension_,
scale_x)),
shortcut_background_border_dimension_(
Scale(base_config.shortcut_background_border_dimension_, scale_x)) {}

AppListConfig::~AppListConfig() = default;

int AppListConfig::GetShortcutHostBadgeIconContainerDimension() const {
return shortcut_host_badge_icon_dimension_ +
shortcut_host_badge_icon_border_dimension_;
}

int AppListConfig::GetShortcutBackgroundContainerDimension() const {
return grid_icon_dimension_ + shortcut_host_badge_icon_border_dimension_;
}

} // namespace ash

0 comments on commit 2a5778d

Please sign in to comment.