| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/system/phonehub/app_stream_launcher_item.h" |
| |
| #include <utility> |
| |
| #include "ash/strings/grit/ash_strings.h" |
| #include "base/functional/callback.h" |
| #include "base/hash/hash.h" |
| #include "base/strings/string_piece.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/metadata/metadata_header_macros.h" |
| #include "ui/base/metadata/metadata_impl_macros.h" |
| #include "ui/gfx/geometry/insets.h" |
| #include "ui/gfx/image/image.h" |
| #include "ui/gfx/image/image_skia_operations.h" |
| #include "ui/gfx/text_constants.h" |
| #include "ui/views/border.h" |
| #include "ui/views/controls/button/label_button.h" |
| #include "ui/views/controls/label.h" |
| #include "ui/views/layout/box_layout.h" |
| |
| namespace ash { |
| |
| namespace { |
| |
| constexpr int kEcheAppItemWidth = 50; |
| constexpr int kEcheAppItemHeight = 60; |
| constexpr gfx::Size kEcheAppItemSize(kEcheAppItemWidth, kEcheAppItemHeight); |
| constexpr int kEcheAppItemSpacing = 4; |
| constexpr int kEcheAppNameLabelLineHeight = 14; |
| constexpr int kEcheAppNameLabelFontSize = 11; |
| constexpr double kAlphaValueForInhibitedIconOpacity = 0.38; |
| |
| void ConfigureLabel(views::Label* label, int line_height, int font_size) { |
| label->SetLineHeight(line_height); |
| label->SetTruncateLength(kEcheAppItemWidth); |
| |
| gfx::Font default_font; |
| gfx::Font label_font = |
| default_font.Derive(font_size - default_font.GetFontSize(), |
| gfx::Font::NORMAL, gfx::Font::Weight::NORMAL); |
| gfx::FontList font_list(label_font); |
| label->SetFontList(font_list); |
| } |
| |
| class AppNameLabel : public views::LabelButton { |
| METADATA_HEADER(AppNameLabel, views::LabelButton) |
| |
| public: |
| explicit AppNameLabel(PressedCallback callback = PressedCallback(), |
| const std::u16string& text = std::u16string()) |
| : LabelButton(std::move(callback), text) { |
| ConfigureLabel(label(), kEcheAppNameLabelLineHeight, |
| kEcheAppNameLabelFontSize); |
| SetBorder(views::CreateEmptyBorder(gfx::Insets())); |
| SetHorizontalAlignment(gfx::ALIGN_CENTER); |
| } |
| |
| ~AppNameLabel() override = default; |
| AppNameLabel(AppNameLabel&) = delete; |
| AppNameLabel operator=(AppNameLabel&) = delete; |
| }; |
| |
| BEGIN_METADATA(AppNameLabel) |
| END_METADATA |
| |
| } // namespace |
| |
| AppStreamLauncherItem::AppStreamLauncherItem( |
| base::RepeatingClosure callback, |
| const phonehub::Notification::AppMetadata& app_metadata) { |
| SetPreferredSize(kEcheAppItemSize); |
| auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( |
| views::BoxLayout::Orientation::kVertical, gfx::Insets(), |
| kEcheAppItemSpacing)); |
| layout->set_cross_axis_alignment( |
| views::BoxLayout::CrossAxisAlignment::kCenter); |
| |
| const bool enabled = app_metadata.app_streamability_status == |
| phonehub::proto::AppStreamabilityStatus::STREAMABLE; |
| gfx::Image image = app_metadata.color_icon; |
| if (!enabled) { |
| // Fade the image in order to make it look like grayed out. |
| image = gfx::Image(gfx::ImageSkiaOperations::CreateTransparentImage( |
| image.AsImageSkia(), kAlphaValueForInhibitedIconOpacity)); |
| } |
| |
| std::u16string accessible_name; |
| switch (app_metadata.app_streamability_status) { |
| case phonehub::proto::STREAMABLE: |
| accessible_name = app_metadata.visible_app_name; |
| break; |
| case phonehub::proto::BLOCKED_BY_APP: |
| accessible_name = l10n_util::GetStringUTF16( |
| IDS_ASH_PHONE_HUB_STREAM_NOT_SUPPORTED_BY_APP); |
| break; |
| case phonehub::proto::BLOCK_LISTED: |
| default: |
| accessible_name = |
| l10n_util::GetStringUTF16(IDS_ASH_PHONE_HUB_STREAM_NOT_SUPPORTED); |
| break; |
| } |
| recent_app_button_ = AddChildView(std::make_unique<PhoneHubRecentAppButton>( |
| image, app_metadata.visible_app_name, callback)); |
| recent_app_button_->SetAccessibleName(accessible_name); |
| recent_app_button_->SetTooltipText(accessible_name); |
| recent_app_button_->SetEnabled(enabled); |
| |
| label_ = AddChildView(std::make_unique<AppNameLabel>( |
| std::move(callback), app_metadata.visible_app_name)); |
| label_->SetEnabled(enabled); |
| label_->SetAccessibleName(accessible_name); |
| label_->SetTooltipText(accessible_name); |
| } |
| |
| AppStreamLauncherItem::~AppStreamLauncherItem() = default; |
| |
| bool AppStreamLauncherItem::HasFocus() const { |
| return recent_app_button_->HasFocus() || label_->HasFocus(); |
| } |
| |
| void AppStreamLauncherItem::RequestFocus() { |
| recent_app_button_->RequestFocus(); |
| } |
| |
| views::LabelButton* AppStreamLauncherItem::GetLabelForTest() { |
| return label_; |
| } |
| PhoneHubRecentAppButton* AppStreamLauncherItem::GetIconForTest() { |
| return recent_app_button_; |
| } |
| |
| BEGIN_METADATA(AppStreamLauncherItem) |
| END_METADATA |
| |
| } // namespace ash |