| Index: ui/message_center/views/notification_view_md.cc
|
| diff --git a/ui/message_center/views/notification_view_md.cc b/ui/message_center/views/notification_view_md.cc
|
| index 37a6d2e94d6bcf2da3594dff65c4460763b6232e..0cbbb7f4b12014bcd8cde7493aa58221c3b20310 100644
|
| --- a/ui/message_center/views/notification_view_md.cc
|
| +++ b/ui/message_center/views/notification_view_md.cc
|
| @@ -12,6 +12,7 @@
|
| #include "ui/base/l10n/l10n_util.h"
|
| #include "ui/gfx/canvas.h"
|
| #include "ui/gfx/geometry/size.h"
|
| +#include "ui/gfx/image/image_skia_operations.h"
|
| #include "ui/gfx/paint_vector_icon.h"
|
| #include "ui/gfx/skia_util.h"
|
| #include "ui/gfx/text_elider.h"
|
| @@ -49,11 +50,13 @@ namespace {
|
| constexpr gfx::Insets kContentRowPadding(4, 12, 12, 12);
|
| constexpr gfx::Insets kActionsRowPadding(8, 8, 8, 8);
|
| constexpr int kActionsRowHorizontalSpacing = 8;
|
| -constexpr gfx::Insets kImageContainerPadding(0, 12, 12, 12);
|
| constexpr gfx::Insets kActionButtonPadding(0, 12, 0, 12);
|
| constexpr gfx::Insets kStatusTextPadding(4, 0, 0, 0);
|
| constexpr gfx::Size kActionButtonMinSize(88, 32);
|
| constexpr gfx::Size kIconViewSize(30, 30);
|
| +constexpr gfx::Insets kLargeImageContainerPadding(0, 12, 12, 12);
|
| +constexpr gfx::Size kLargeImageMinSize(328, 0);
|
| +constexpr gfx::Size kLargeImageMaxSize(328, 218);
|
|
|
| // Background of inline actions area.
|
| const SkColor kActionsRowBackgroundColor = SkColorSetRGB(0xee, 0xee, 0xee);
|
| @@ -65,6 +68,8 @@ const float kActionButtonInkDropRippleVisibleOpacity = 0.08f;
|
| const float kActionButtonInkDropHighlightVisibleOpacity = 0.08f;
|
| // Text color of action button.
|
| const SkColor kActionButtonTextColor = SkColorSetRGB(0x33, 0x67, 0xD6);
|
| +// Background color of the large image.
|
| +const SkColor kLargeImageBackgroundColor = SkColorSetRGB(0xf5, 0xf5, 0xf5);
|
|
|
| // Max number of lines for message_view_.
|
| constexpr int kMaxLinesForMessageView = 1;
|
| @@ -255,6 +260,119 @@ NotificationButtonMD::CreateInkDropHighlight() const {
|
| return highlight;
|
| }
|
|
|
| +// LargeImageView //////////////////////////////////////////////////////////////
|
| +
|
| +class LargeImageView : public views::View {
|
| + public:
|
| + LargeImageView();
|
| + ~LargeImageView() override;
|
| +
|
| + void SetImage(const gfx::ImageSkia& image);
|
| +
|
| + void OnPaint(gfx::Canvas* canvas) override;
|
| + const char* GetClassName() const override;
|
| +
|
| + private:
|
| + gfx::Size GetResizedImageSize();
|
| +
|
| + gfx::ImageSkia image_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(LargeImageView);
|
| +};
|
| +
|
| +LargeImageView::LargeImageView() {
|
| + SetBackground(views::CreateSolidBackground(kLargeImageBackgroundColor));
|
| +}
|
| +
|
| +LargeImageView::~LargeImageView() = default;
|
| +
|
| +void LargeImageView::SetImage(const gfx::ImageSkia& image) {
|
| + image_ = image;
|
| + gfx::Size preferred_size = GetResizedImageSize();
|
| + preferred_size.SetToMax(kLargeImageMinSize);
|
| + preferred_size.SetToMin(kLargeImageMaxSize);
|
| + SetPreferredSize(preferred_size);
|
| + SchedulePaint();
|
| + Layout();
|
| +}
|
| +
|
| +void LargeImageView::OnPaint(gfx::Canvas* canvas) {
|
| + views::View::OnPaint(canvas);
|
| +
|
| + gfx::Size resized_size = GetResizedImageSize();
|
| + gfx::Size drawn_size = resized_size;
|
| + drawn_size.SetToMin(kLargeImageMaxSize);
|
| + gfx::Rect drawn_bounds = GetContentsBounds();
|
| + drawn_bounds.ClampToCenteredSize(drawn_size);
|
| +
|
| + gfx::ImageSkia resized_image = gfx::ImageSkiaOperations::CreateResizedImage(
|
| + image_, skia::ImageOperations::RESIZE_BEST, resized_size);
|
| +
|
| + // Cut off the overflown part.
|
| + gfx::ImageSkia drawn_image = gfx::ImageSkiaOperations::ExtractSubset(
|
| + resized_image, gfx::Rect(drawn_size));
|
| +
|
| + canvas->DrawImageInt(drawn_image, drawn_bounds.x(), drawn_bounds.y());
|
| +}
|
| +
|
| +const char* LargeImageView::GetClassName() const {
|
| + return "LargeImageView";
|
| +}
|
| +
|
| +// Returns expected size of the image right after resizing.
|
| +// The GetResizedImageSize().width() <= kLargeImageMaxSize.width() holds, but
|
| +// GetResizedImageSize().height() may be larger than kLargeImageMaxSize.height()
|
| +// In this case, the overflown part will be just cutted off from the view.
|
| +gfx::Size LargeImageView::GetResizedImageSize() {
|
| + gfx::Size original_size = image_.size();
|
| + if (original_size.width() <= kLargeImageMaxSize.width())
|
| + return image_.size();
|
| +
|
| + const double proportion =
|
| + original_size.height() / static_cast<double>(original_size.width());
|
| + gfx::Size resized_size;
|
| + resized_size.SetSize(kLargeImageMaxSize.width(),
|
| + kLargeImageMaxSize.width() * proportion);
|
| + return resized_size;
|
| +}
|
| +
|
| +// LargeImageContainerView /////////////////////////////////////////////////////
|
| +
|
| +// We have a container view outside LargeImageView, because we want to fill
|
| +// area that is not coverted by the image by background color.
|
| +class LargeImageContainerView : public views::View {
|
| + public:
|
| + LargeImageContainerView();
|
| + ~LargeImageContainerView() override;
|
| +
|
| + void SetImage(const gfx::ImageSkia& image);
|
| + const char* GetClassName() const override;
|
| +
|
| + private:
|
| + LargeImageView* const image_view_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(LargeImageContainerView);
|
| +};
|
| +
|
| +LargeImageContainerView::LargeImageContainerView()
|
| + : image_view_(new LargeImageView()) {
|
| + SetLayoutManager(new views::FillLayout());
|
| + SetBorder(views::CreateEmptyBorder(kLargeImageContainerPadding));
|
| + SetBackground(
|
| + views::CreateSolidBackground(message_center::kImageBackgroundColor));
|
| + AddChildView(image_view_);
|
| +}
|
| +
|
| +LargeImageContainerView::~LargeImageContainerView() = default;
|
| +
|
| +void LargeImageContainerView::SetImage(const gfx::ImageSkia& image) {
|
| + image_view_->SetImage(image);
|
| +}
|
| +
|
| +const char* LargeImageContainerView::GetClassName() const {
|
| + return "LargeImageContainerView";
|
| +}
|
| +
|
| } // anonymous namespace
|
|
|
| // ////////////////////////////////////////////////////////////
|
| @@ -637,7 +755,8 @@ void NotificationViewMD::CreateOrUpdateListItemViews(
|
| void NotificationViewMD::CreateOrUpdateIconView(
|
| const Notification& notification) {
|
| if (notification.type() == NOTIFICATION_TYPE_PROGRESS ||
|
| - notification.type() == NOTIFICATION_TYPE_MULTIPLE) {
|
| + notification.type() == NOTIFICATION_TYPE_MULTIPLE ||
|
| + notification.type() == NOTIFICATION_TYPE_IMAGE) {
|
| DCHECK(!icon_view_ || right_content_->Contains(icon_view_));
|
| delete icon_view_;
|
| icon_view_ = nullptr;
|
| @@ -663,43 +782,22 @@ void NotificationViewMD::CreateOrUpdateSmallIconView(
|
|
|
| void NotificationViewMD::CreateOrUpdateImageView(
|
| const Notification& notification) {
|
| - // |image_view_| is the view representing the area covered by the
|
| - // notification's image, including background and border. Its size can be
|
| - // specified in advance and images will be scaled to fit including a border if
|
| - // necessary.
|
| if (notification.image().IsEmpty()) {
|
| - if (image_container_) {
|
| - DCHECK(image_view_);
|
| - DCHECK(Contains(image_container_));
|
| - delete image_container_;
|
| - image_container_ = NULL;
|
| - image_view_ = NULL;
|
| - } else {
|
| - DCHECK(!image_view_);
|
| + if (image_container_view_) {
|
| + DCHECK(Contains(image_container_view_));
|
| + delete image_container_view_;
|
| + image_container_view_ = nullptr;
|
| }
|
| return;
|
| }
|
|
|
| - gfx::Size ideal_size(kNotificationPreferredImageWidth,
|
| - kNotificationPreferredImageHeight);
|
| -
|
| - if (!image_container_) {
|
| - image_container_ = new views::View();
|
| - image_container_->SetLayoutManager(new views::FillLayout());
|
| - image_container_->SetBorder(
|
| - views::CreateEmptyBorder(kImageContainerPadding));
|
| - image_container_->SetBackground(
|
| - views::CreateSolidBackground(message_center::kImageBackgroundColor));
|
| -
|
| - DCHECK(!image_view_);
|
| - image_view_ = new message_center::ProportionalImageView(ideal_size);
|
| - image_container_->AddChildView(image_view_);
|
| + if (!image_container_view_) {
|
| + image_container_view_ = new LargeImageContainerView();
|
| // Insert the created image container just after the |content_row_|.
|
| - AddChildViewAt(image_container_, GetIndexOf(content_row_) + 1);
|
| + AddChildViewAt(image_container_view_, GetIndexOf(content_row_) + 1);
|
| }
|
|
|
| - DCHECK(image_view_);
|
| - image_view_->SetImage(notification.image().AsImageSkia(), ideal_size);
|
| + image_container_view_->SetImage(notification.image().AsImageSkia());
|
| }
|
|
|
| void NotificationViewMD::CreateOrUpdateActionButtonViews(
|
| @@ -778,7 +876,7 @@ bool NotificationViewMD::IsExpandable() {
|
| return true;
|
|
|
| // Expandable if the notification has image.
|
| - if (image_view_)
|
| + if (image_container_view_)
|
| return true;
|
|
|
| // Expandable if there are multiple list items.
|
| @@ -804,8 +902,8 @@ void NotificationViewMD::UpdateViewForExpandedState(bool expanded) {
|
| message_view_->SetLineLimit(expanded ? kMaxLinesForExpandedMessageView
|
| : kMaxLinesForMessageView);
|
| }
|
| - if (image_container_)
|
| - image_container_->SetVisible(expanded);
|
| + if (image_container_view_)
|
| + image_container_view_->SetVisible(expanded);
|
| actions_row_->SetVisible(expanded && actions_row_->has_children());
|
| for (size_t i = kMaxLinesForMessageView; i < item_views_.size(); ++i) {
|
| item_views_[i]->SetVisible(expanded);
|
|
|