blob: c60190c19af1d63065af5c30943e3ae1bfcaf2a1 [file] [log] [blame]
// Copyright 2021 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/capture_mode/capture_mode_notification_view.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/ash_color_provider.h"
#include "ash/style/scoped_light_mode_as_default.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/background.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/view.h"
namespace ash {
namespace {
// Constants related to the banner view on the image capture notification.
constexpr int kBannerHeightDip = 36;
constexpr int kBannerHorizontalInsetDip = 12;
constexpr int kBannerVerticalInsetDip = 8;
constexpr int kBannerIconTextSpacingDip = 8;
constexpr int kBannerIconSizeDip = 20;
// Creates the banner view that will show on top of the notification image.
std::unique_ptr<views::View> CreateBannerViewImpl() {
std::unique_ptr<views::View> banner_view = std::make_unique<views::View>();
// Use the light mode as default as notification is still using light
// theme as the default theme.
ScopedLightModeAsDefault scoped_light_mode_as_default;
auto* color_provider = AshColorProvider::Get();
const SkColor background_color = color_provider->GetControlsLayerColor(
AshColorProvider::ControlsLayerType::kControlBackgroundColorActive);
// The text and icon are showing on the background with |background_color|
// so its color is same with kButtonLabelColorPrimary although they're
// not theoretically showing on a button.
const SkColor text_icon_color = color_provider->GetContentLayerColor(
AshColorProvider::ContentLayerType::kButtonLabelColorPrimary);
auto layout = std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal,
gfx::Insets(kBannerVerticalInsetDip, kBannerHorizontalInsetDip),
kBannerIconTextSpacingDip);
banner_view->SetLayoutManager(std::move(layout));
banner_view->SetBackground(views::CreateSolidBackground(background_color));
views::ImageView* icon =
banner_view->AddChildView(std::make_unique<views::ImageView>());
icon->SetImage(gfx::CreateVectorIcon(kCaptureModeCopiedToClipboardIcon,
kBannerIconSizeDip, text_icon_color));
views::Label* label = banner_view->AddChildView(
std::make_unique<views::Label>(l10n_util::GetStringUTF16(
IDS_ASH_SCREEN_CAPTURE_SCREENSHOT_COPIED_TO_CLIPBOARD)));
label->SetBackgroundColor(background_color);
label->SetEnabledColor(text_icon_color);
return banner_view;
}
} // namespace
CaptureModeNotificationView::CaptureModeNotificationView(
const message_center::Notification& notification)
: message_center::NotificationViewMD(notification) {
// Create the banner view if notification image is not empty. The banner
// will show on top of the notification image.
if (!notification.image().IsEmpty())
CreateBannerView();
// We need to observe this view as |this| view will be re-used for
// notifications for with/without image scenarios if |this| is not destroyed
// by the user or by the timeout before the next notification shows up.
views::View::AddObserver(this);
}
CaptureModeNotificationView::~CaptureModeNotificationView() = default;
// static
std::unique_ptr<message_center::MessageView>
CaptureModeNotificationView::Create(
const message_center::Notification& notification) {
return std::make_unique<CaptureModeNotificationView>(notification);
}
void CaptureModeNotificationView::Layout() {
message_center::NotificationViewMD::Layout();
if (!banner_view_)
return;
// Calculate the banner view's desired bounds.
gfx::Rect banner_bounds = image_container_view()->GetContentsBounds();
banner_bounds.set_y(banner_bounds.bottom() - kBannerHeightDip);
banner_bounds.set_height(kBannerHeightDip);
banner_view_->SetBoundsRect(banner_bounds);
}
void CaptureModeNotificationView::OnChildViewAdded(views::View* observed_view,
views::View* child) {
if (observed_view == this && child == image_container_view())
CreateBannerView();
}
void CaptureModeNotificationView::OnChildViewRemoved(views::View* observed_view,
views::View* child) {
if (observed_view == this && child == image_container_view())
banner_view_ = nullptr;
}
void CaptureModeNotificationView::OnViewIsDeleting(View* observed_view) {
DCHECK_EQ(observed_view, this);
views::View::RemoveObserver(this);
}
void CaptureModeNotificationView::CreateBannerView() {
DCHECK(image_container_view());
DCHECK(!image_container_view()->children().empty());
DCHECK(!banner_view_);
banner_view_ = image_container_view()->AddChildView(CreateBannerViewImpl());
}
} // namespace ash