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 3b4c49a816b76a435022c29597b0cf8518498b1b..c5d3e57209b9e913edcf2446610ce5a5ee61997a 100644 |
--- a/ui/message_center/views/notification_view_md.cc |
+++ b/ui/message_center/views/notification_view_md.cc |
@@ -50,10 +50,12 @@ 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::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); |
// Foreground of small icon image. |
constexpr SkColor kSmallImageBackgroundColor = SK_ColorWHITE; |
@@ -69,6 +71,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; |
@@ -290,6 +294,92 @@ NotificationButtonMD::CreateInkDropHighlight() const { |
return highlight; |
} |
+// LargeImageView ////////////////////////////////////////////////////////////// |
+ |
+class LargeImageView : public views::View { |
+ public: |
+ explicit LargeImageView(); |
+ ~LargeImageView() override; |
+ |
+ void SetImage(const gfx::ImageSkia& image); |
+ |
+ void OnPaint(gfx::Canvas* canvas) override; |
+ const char* GetClassName() const override; |
+ |
+ views::View* container() { return container_; } |
+ |
+ private: |
+ gfx::Size GetResizedImageSize(); |
+ |
+ views::View* container_ = nullptr; |
yoshiki
2017/07/28 06:13:03
Could you add const?
tetsui
2017/07/28 06:38:45
Done.
|
+ gfx::ImageSkia image_; |
+}; |
yoshiki
2017/07/28 06:13:03
Please add DISALLOW_COPY_AND_ASSIGN
tetsui
2017/07/28 06:38:45
Done.
|
+ |
+LargeImageView::LargeImageView() { |
+ SetBackground(views::CreateSolidBackground(kLargeImageBackgroundColor)); |
+ container_ = new views::View; |
+ container_->SetLayoutManager(new views::FillLayout()); |
+ container_->SetBorder(views::CreateEmptyBorder(kLargeImageContainerPadding)); |
+ container_->SetBackground( |
+ views::CreateSolidBackground(message_center::kImageBackgroundColor)); |
+ container_->AddChildView(this); |
+} |
+ |
+LargeImageView::~LargeImageView() { |
+ delete container_; |
+} |
+ |
+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(); |
+ } else { |
+ 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; |
+ } |
+} |
+ |
} // anonymous namespace |
// //////////////////////////////////////////////////////////// |
@@ -641,7 +731,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; |
@@ -668,43 +759,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_view_) { |
+ DCHECK(Contains(image_view_->container())); |
+ delete image_view_; |
+ image_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_view_) { |
+ image_view_ = new LargeImageView(); |
// Insert the created image container just after the |content_row_|. |
- AddChildViewAt(image_container_, GetIndexOf(content_row_) + 1); |
+ AddChildViewAt(image_view_->container(), GetIndexOf(content_row_) + 1); |
} |
- DCHECK(image_view_); |
- image_view_->SetImage(notification.image().AsImageSkia(), ideal_size); |
+ image_view_->SetImage(notification.image().AsImageSkia()); |
} |
void NotificationViewMD::CreateOrUpdateActionButtonViews( |
@@ -803,8 +873,8 @@ void NotificationViewMD::UpdateViewForExpandedState(bool expanded) { |
message_view_->SetLineLimit(expanded ? kMaxLinesForExpandedMessageView |
: kMaxLinesForMessageView); |
} |
- if (image_container_) |
- image_container_->SetVisible(expanded); |
+ if (image_view_) |
+ image_view_->container()->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); |