Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Unified Diff: ui/message_center/views/notification_view_md.cc

Issue 2969603003: Implement new-style image notification resizing. (Closed)
Patch Set: Fix nits. Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);
« no previous file with comments | « ui/message_center/views/notification_view_md.h ('k') | ui/message_center/views/notification_view_md_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698