blob: d576137e743eebeb666f686b4f640e0793355d73 [file] [log] [blame]
// Copyright 2020 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.
#include "ash/system/holding_space/pinned_files_section.h"
#include "ash/public/cpp/holding_space/holding_space_client.h"
#include "ash/public/cpp/holding_space/holding_space_constants.h"
#include "ash/public/cpp/holding_space/holding_space_controller.h"
#include "ash/public/cpp/holding_space/holding_space_item.h"
#include "ash/public/cpp/holding_space/holding_space_prefs.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/ash_color_provider.h"
#include "ash/system/holding_space/holding_space_item_chip_view.h"
#include "ash/system/holding_space/holding_space_item_chips_container.h"
#include "ash/system/holding_space/holding_space_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/button.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/layout/box_layout.h"
namespace ash {
namespace {
// Appearance.
constexpr int kFilesAppChipChildSpacing = 8;
constexpr int kFilesAppChipHeight = 32;
constexpr int kFilesAppChipIconSize = 20;
constexpr gfx::Insets kFilesAppChipInsets(0, 8, 0, 16);
constexpr int kPlaceholderChildSpacing = 16;
// Helpers ---------------------------------------------------------------------
// Returns whether the active user has ever pinned a file to holding space.
bool HasEverPinnedHoldingSpaceItem() {
PrefService* active_pref_service =
Shell::Get()->session_controller()->GetActivePrefService();
return active_pref_service
? holding_space_prefs::GetTimeOfFirstPin(active_pref_service)
.has_value()
: false;
}
// FilesAppChip ----------------------------------------------------------------
class FilesAppChip : public views::Button {
public:
FilesAppChip() { Init(); }
FilesAppChip(const FilesAppChip&) = delete;
FilesAppChip& operator=(const FilesAppChip&) = delete;
~FilesAppChip() override = default;
private:
// views::Button:
gfx::Size CalculatePreferredSize() const override {
const int width = views::Button::CalculatePreferredSize().width();
return gfx::Size(width, GetHeightForWidth(width));
}
int GetHeightForWidth(int width) const override {
return kFilesAppChipHeight;
}
void Init() {
SetAccessibleName(l10n_util::GetStringUTF16(
IDS_ASH_HOLDING_SPACE_PINNED_FILES_APP_CHIP_TEXT));
SetCallback(
base::BindRepeating(&FilesAppChip::OnPressed, base::Unretained(this)));
SetID(kHoldingSpaceFilesAppChipId);
// Background.
AshColorProvider* const ash_color_provider = AshColorProvider::Get();
SetBackground(views::CreateRoundedRectBackground(
ash_color_provider->GetControlsLayerColor(
AshColorProvider::ControlsLayerType::
kControlBackgroundColorInactive),
kFilesAppChipHeight / 2));
// Focus ring.
focus_ring()->SetColor(ash_color_provider->GetControlsLayerColor(
AshColorProvider::ControlsLayerType::kFocusRingColor));
// Ink drop.
const AshColorProvider::RippleAttributes ripple_attributes =
ash_color_provider->GetRippleAttributes();
SetInkDropMode(InkDropMode::ON);
SetInkDropBaseColor(ripple_attributes.base_color);
SetInkDropVisibleOpacity(ripple_attributes.inkdrop_opacity);
views::InstallRoundRectHighlightPathGenerator(this, gfx::Insets(),
kFilesAppChipHeight / 2);
// Layout.
auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal, kFilesAppChipInsets,
kFilesAppChipChildSpacing));
layout->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::kCenter);
// Icon.
auto* icon = AddChildView(std::make_unique<views::ImageView>());
icon->SetImage(gfx::CreateVectorIcon(kFilesAppIcon, kFilesAppChipIconSize,
gfx::kPlaceholderColor));
// Label.
auto* label = AddChildView(
holding_space_util::CreateLabel(holding_space_util::LabelStyle::kChip));
label->SetText(l10n_util::GetStringUTF16(
IDS_ASH_HOLDING_SPACE_PINNED_FILES_APP_CHIP_TEXT));
layout->SetFlexForView(label, 1);
}
void OnPressed(const ui::Event& event) {
HoldingSpaceController::Get()->client()->OpenMyFiles(base::DoNothing());
}
};
} // namespace
// PinnedFilesSection ----------------------------------------------------------
PinnedFilesSection::PinnedFilesSection(HoldingSpaceItemViewDelegate* delegate)
: HoldingSpaceItemViewsSection(delegate,
/*supported_types=*/
{HoldingSpaceItem::Type::kPinnedFile},
/*max_count=*/base::nullopt) {}
PinnedFilesSection::~PinnedFilesSection() = default;
const char* PinnedFilesSection::GetClassName() const {
return "PinnedFilesSection";
}
std::unique_ptr<views::View> PinnedFilesSection::CreateHeader() {
auto header = holding_space_util::CreateLabel(
holding_space_util::LabelStyle::kHeader,
l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_PINNED_TITLE));
header->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
header->SetPaintToLayer();
header->layer()->SetFillsBoundsOpaquely(false);
return header;
}
std::unique_ptr<views::View> PinnedFilesSection::CreateContainer() {
return std::make_unique<HoldingSpaceItemChipsContainer>();
}
std::unique_ptr<HoldingSpaceItemView> PinnedFilesSection::CreateView(
const HoldingSpaceItem* item) {
// When `PinnedFilesSection::CreateView()` is called it implies that the user
// has at some point in time pinned a file to holding space. That being the
// case, the placeholder is no longer relevant and can be destroyed.
DestroyPlaceholder();
return std::make_unique<HoldingSpaceItemChipView>(delegate(), item);
}
std::unique_ptr<views::View> PinnedFilesSection::CreatePlaceholder() {
if (HasEverPinnedHoldingSpaceItem())
return nullptr;
auto placeholder = std::make_unique<views::View>();
placeholder->SetPaintToLayer();
placeholder->layer()->SetFillsBoundsOpaquely(false);
auto* layout =
placeholder->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical, gfx::Insets(),
kPlaceholderChildSpacing));
layout->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::kStart);
// Prompt.
auto* prompt = placeholder->AddChildView(holding_space_util::CreateLabel(
holding_space_util::LabelStyle::kBody,
l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_PINNED_EMPTY_PROMPT)));
prompt->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
prompt->SetMultiLine(true);
// Files app chip.
placeholder->AddChildView(std::make_unique<FilesAppChip>());
return placeholder;
}
} // namespace ash