Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/message_center/notification_view.h" | 5 #include "ui/message_center/notification_view.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
| 9 #include "grit/ui_resources.h" | 9 #include "grit/ui_resources.h" |
| 10 #include "ui/base/accessibility/accessible_view_state.h" | 10 #include "ui/base/accessibility/accessible_view_state.h" |
| 11 #include "ui/base/resource/resource_bundle.h" | 11 #include "ui/base/resource/resource_bundle.h" |
| 12 #include "ui/base/text/text_elider.h" | 12 #include "ui/base/text/text_elider.h" |
| 13 #include "ui/gfx/canvas.h" | |
| 13 #include "ui/gfx/size.h" | 14 #include "ui/gfx/size.h" |
| 14 #include "ui/message_center/message_center_constants.h" | 15 #include "ui/message_center/message_center_constants.h" |
| 15 #include "ui/message_center/message_center_switches.h" | 16 #include "ui/message_center/message_center_switches.h" |
| 16 #include "ui/message_center/message_simple_view.h" | 17 #include "ui/message_center/message_simple_view.h" |
| 17 #include "ui/native_theme/native_theme.h" | 18 #include "ui/native_theme/native_theme.h" |
| 18 #include "ui/views/controls/button/image_button.h" | 19 #include "ui/views/controls/button/image_button.h" |
| 19 #include "ui/views/controls/image_view.h" | 20 #include "ui/views/controls/image_view.h" |
| 20 #include "ui/views/controls/label.h" | 21 #include "ui/views/controls/label.h" |
| 21 #include "ui/views/layout/box_layout.h" | 22 #include "ui/views/layout/box_layout.h" |
| 22 #include "ui/views/layout/fill_layout.h" | 23 #include "ui/views/layout/fill_layout.h" |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 50 // Static function to create an empty border to be used as padding. | 51 // Static function to create an empty border to be used as padding. |
| 51 views::Border* MakePadding(int top, int left, int bottom, int right) { | 52 views::Border* MakePadding(int top, int left, int bottom, int right) { |
| 52 return views::Border::CreateEmptyBorder(top, left, bottom, right); | 53 return views::Border::CreateEmptyBorder(top, left, bottom, right); |
| 53 } | 54 } |
| 54 | 55 |
| 55 // Static function to create an empty border to be used as padding. | 56 // Static function to create an empty border to be used as padding. |
| 56 views::Background* MakeBackground(SkColor color) { | 57 views::Background* MakeBackground(SkColor color) { |
| 57 return views::Background::CreateSolidBackground(color); | 58 return views::Background::CreateSolidBackground(color); |
| 58 } | 59 } |
| 59 | 60 |
| 61 // ContentViews just propagate their children's preferred size changes. | |
| 62 class ContentView : public views::View { | |
| 63 public: | |
| 64 ContentView(); | |
| 65 virtual ~ContentView(); | |
| 66 | |
| 67 // Overridden from views::View. | |
| 68 virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE; | |
| 69 | |
| 70 private: | |
| 71 DISALLOW_COPY_AND_ASSIGN(ContentView); | |
| 72 }; | |
| 73 | |
| 74 ContentView::ContentView() { | |
| 75 } | |
| 76 | |
| 77 ContentView::~ContentView() { | |
| 78 } | |
| 79 | |
| 80 void ContentView::ChildPreferredSizeChanged(views::View* child) { | |
| 81 PreferredSizeChanged(); | |
| 82 } | |
| 83 | |
| 60 // ItemViews are responsible for drawing each list notification item's title and | 84 // ItemViews are responsible for drawing each list notification item's title and |
| 61 // message next to each other within a single column. | 85 // message next to each other within a single column. |
| 62 class ItemView : public views::View { | 86 class ItemView : public views::View { |
| 63 public: | 87 public: |
| 64 ItemView(const message_center::NotificationItem& item); | 88 ItemView(const message_center::NotificationItem& item); |
| 65 virtual ~ItemView(); | 89 virtual ~ItemView(); |
| 66 | 90 |
| 67 private: | 91 private: |
| 68 DISALLOW_COPY_AND_ASSIGN(ItemView); | 92 DISALLOW_COPY_AND_ASSIGN(ItemView); |
| 69 }; | 93 }; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 86 message->SetBackgroundColor(kMessageBackgroundColor); | 110 message->SetBackgroundColor(kMessageBackgroundColor); |
| 87 AddChildView(message); | 111 AddChildView(message); |
| 88 | 112 |
| 89 PreferredSizeChanged(); | 113 PreferredSizeChanged(); |
| 90 SchedulePaint(); | 114 SchedulePaint(); |
| 91 } | 115 } |
| 92 | 116 |
| 93 ItemView::~ItemView() { | 117 ItemView::~ItemView() { |
| 94 } | 118 } |
| 95 | 119 |
| 96 // ProportionalImageViews match their heights to their widths to preserve the | 120 // ProportionalImageViews center their images to preserve their proportion. |
| 97 // proportions of their images. | 121 // Note that for this subclass of views::ImageView GetImageBounds() will return |
| 122 // potentially incorrect values (this can't be fixed because GetImageBounds() | |
| 123 // is not virtual) and horizontal and vertical alignments will be ignored. | |
| 98 class ProportionalImageView : public views::ImageView { | 124 class ProportionalImageView : public views::ImageView { |
| 99 public: | 125 public: |
| 100 ProportionalImageView(); | 126 ProportionalImageView(); |
| 101 virtual ~ProportionalImageView(); | 127 virtual ~ProportionalImageView(); |
| 102 | 128 |
| 103 // Overridden from views::View. | 129 // Overridden from views::View. |
| 104 virtual int GetHeightForWidth(int width) OVERRIDE; | 130 virtual int GetHeightForWidth(int width) OVERRIDE; |
| 131 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; | |
| 105 | 132 |
| 106 private: | 133 private: |
| 134 gfx::Size GetImageSizeForWidth(int width); | |
| 135 | |
| 107 DISALLOW_COPY_AND_ASSIGN(ProportionalImageView); | 136 DISALLOW_COPY_AND_ASSIGN(ProportionalImageView); |
| 108 }; | 137 }; |
| 109 | 138 |
| 110 ProportionalImageView::ProportionalImageView() { | 139 ProportionalImageView::ProportionalImageView() { |
| 111 } | 140 } |
| 112 | 141 |
| 113 ProportionalImageView::~ProportionalImageView() { | 142 ProportionalImageView::~ProportionalImageView() { |
| 114 } | 143 } |
| 115 | 144 |
| 116 int ProportionalImageView::GetHeightForWidth(int width) { | 145 int ProportionalImageView::GetHeightForWidth(int width) { |
| 117 int height = 0; | 146 return GetImageSizeForWidth(width).height(); |
| 118 gfx::ImageSkia image = GetImage(); | 147 } |
|
dharcourt
2013/02/23 04:32:00
SetImageSize() needed to be removed from GetImageS
| |
| 119 if (image.width() > 0 && image.height() > 0) { | 148 |
| 120 double proportion = image.height() / (double) image.width(); | 149 void ProportionalImageView::OnPaint(gfx::Canvas* canvas) { |
| 121 height = 0.5 + width * proportion; | 150 View::OnPaint(canvas); |
| 122 if (height > message_center::kNotificationMaximumImageHeight) { | 151 |
| 123 height = message_center::kNotificationMaximumImageHeight; | 152 gfx::Size draw_size(GetImageSizeForWidth(width())); |
| 124 width = 0.5 + height / proportion; | 153 if (!draw_size.IsEmpty()) { |
| 154 int x = (width() - draw_size.width()) / 2; | |
| 155 int y = (height() - draw_size.height()) / 2; | |
| 156 | |
| 157 gfx::Size image_size(GetImage().size()); | |
| 158 if (image_size == draw_size) { | |
| 159 canvas->DrawImageInt(GetImage(), x, y); | |
| 160 } else { | |
| 161 // Resize case | |
| 162 SkPaint paint; | |
| 163 paint.setFilterBitmap(true); | |
| 164 canvas->DrawImageInt(GetImage(), 0, 0, | |
| 165 image_size.width(), image_size.height(), x, y, | |
| 166 draw_size.width(), draw_size.height(), true, paint); | |
| 125 } | 167 } |
| 126 SetImageSize(gfx::Size(width, height)); | |
| 127 } | 168 } |
| 128 return height; | 169 } |
| 170 | |
| 171 gfx::Size ProportionalImageView::GetImageSizeForWidth(int width) { | |
| 172 gfx::Size size(GetImage().size()); | |
| 173 if (width > 0 && !size.IsEmpty()) { | |
| 174 double proportion = size.height() / (double) size.width(); | |
| 175 size.SetSize(width, std::max(0.5 + width * proportion, 1.0)); | |
| 176 if (size.height() > message_center::kNotificationMaximumImageHeight) { | |
| 177 int height = message_center::kNotificationMaximumImageHeight; | |
| 178 size.SetSize(std::max(0.5 + height / proportion, 1.0), height); | |
| 179 } | |
| 180 } | |
| 181 return size; | |
| 129 } | 182 } |
| 130 | 183 |
| 131 // NotificationsButtons render the action buttons of notifications. | 184 // NotificationsButtons render the action buttons of notifications. |
| 132 class NotificationButton : public views::CustomButton { | 185 class NotificationButton : public views::CustomButton { |
| 133 public: | 186 public: |
| 134 NotificationButton(views::ButtonListener* listener); | 187 NotificationButton(views::ButtonListener* listener); |
| 135 virtual ~NotificationButton(); | 188 virtual ~NotificationButton(); |
| 136 | 189 |
| 137 void SetIcon(const gfx::ImageSkia& icon); | 190 void SetIcon(const gfx::ImageSkia& icon); |
| 138 void SetTitle(const string16& title); | 191 void SetTitle(const string16& title); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 221 // functionality. | 274 // functionality. |
| 222 LOG(WARNING) << "Unable to fulfill request for unrecognized " | 275 LOG(WARNING) << "Unable to fulfill request for unrecognized " |
| 223 << "notification type " << notification.type << ". " | 276 << "notification type " << notification.type << ". " |
| 224 << "Falling back to simple notification type."; | 277 << "Falling back to simple notification type."; |
| 225 } | 278 } |
| 226 | 279 |
| 227 // Currently all roads lead to the generic NotificationView. | 280 // Currently all roads lead to the generic NotificationView. |
| 228 return new NotificationView(list_delegate, notification); | 281 return new NotificationView(list_delegate, notification); |
| 229 } | 282 } |
| 230 | 283 |
| 231 NotificationView::NotificationView( | 284 NotificationView::NotificationView(NotificationList::Delegate* list_delegate, |
| 232 NotificationList::Delegate* list_delegate, | 285 const Notification& notification) |
| 233 const Notification& notification) | 286 : MessageView(list_delegate, notification), |
| 234 : MessageView(list_delegate, notification) { | 287 content_view_(NULL), |
| 288 icon_view_(NULL) { | |
| 235 } | 289 } |
| 236 | 290 |
| 237 NotificationView::~NotificationView() { | 291 NotificationView::~NotificationView() { |
| 238 } | 292 } |
| 239 | 293 |
| 240 void NotificationView::Layout() { | 294 void NotificationView::Layout() { |
| 241 if (content_view_) { | 295 // Create the child views if necessary. Those are in two layers: The first |
| 242 gfx::Rect contents_bounds = GetContentsBounds(); | 296 // layer has the notification content (text, images, action buttons, ...). |
| 243 content_view_->SetBoundsRect(contents_bounds); | 297 // This is overlaid by a second layer that has the notification close and |
| 244 if (close_button()) { | 298 // expand buttons. This allows the close and expand buttons to overlap the |
| 245 gfx::Size size(close_button()->GetPreferredSize()); | 299 // content as needed to provide a large enough click area |
| 246 close_button()->SetBounds(contents_bounds.right() - size.width(), 0, | 300 // (<http://crbug.com/168822> and touch area <http://crbug.com/168856>). |
| 247 size.width(), size.height()); | 301 if (!content_view_) { |
| 302 AddChildView(MakeContentView()); | |
| 303 AddChildView(close_button()); | |
| 304 if (!IsExpanded()) { | |
| 305 AddChildView(expand_button()); | |
| 248 } | 306 } |
| 249 } | 307 } |
| 308 | |
| 309 gfx::Rect content_bounds(GetLocalBounds()); | |
| 310 content_bounds.Inset(GetInsets()); | |
| 311 content_view_->SetBoundsRect(content_bounds); | |
| 312 | |
| 313 gfx::Size close_size(close_button()->GetPreferredSize()); | |
| 314 close_button()->SetBounds(content_bounds.right() - close_size.width(), | |
| 315 content_bounds.y(), | |
| 316 close_size.width(), | |
| 317 close_size.height()); | |
| 318 | |
| 319 gfx::Rect icon_bounds(content_bounds.origin(), icon_view_->size()); | |
| 320 gfx::Size expand_size(expand_button()->GetPreferredSize()); | |
| 321 expand_button()->SetBounds(content_bounds.right() - expand_size.width(), | |
| 322 icon_bounds.bottom() - expand_size.height(), | |
| 323 expand_size.width(), | |
| 324 expand_size.height()); | |
| 250 } | 325 } |
| 251 | 326 |
| 252 gfx::Size NotificationView::GetPreferredSize() { | 327 gfx::Size NotificationView::GetPreferredSize() { |
| 253 if (!content_view_) | 328 gfx::Size size; |
| 254 return gfx::Size(); | 329 if (content_view_) { |
| 255 gfx::Size size = content_view_->GetPreferredSize(); | 330 size = content_view_->GetPreferredSize(); |
| 256 if (border()) { | 331 if (border()) { |
| 257 gfx::Insets border_insets = border()->GetInsets(); | 332 gfx::Insets insets = border()->GetInsets(); |
| 258 size.Enlarge(border_insets.width(), border_insets.height()); | 333 size.Enlarge(insets.width(), insets.height()); |
| 334 } | |
| 259 } | 335 } |
| 260 return size; | 336 return size; |
|
dharcourt
2013/02/23 04:32:00
Having a return gfx::Size() in the middle of this
| |
| 261 } | 337 } |
| 262 | 338 |
| 263 void NotificationView::SetUpView() { | 339 void NotificationView::ChildPreferredSizeChanged(views::View* child) { |
| 264 // This view is composed of two layers: The first layer has the notification | 340 PreferredSizeChanged(); |
| 265 // content (text, images, action buttons, ...). This is overlaid by a second | 341 } |
| 266 // layer that has the notification close button and will later also have the | 342 |
| 267 // expand button. This allows the close and expand buttons to overlap the | 343 void NotificationView::SetExpanded(bool expanded) { |
| 268 // content as needed to provide a large enough click area | 344 if (expanded != IsExpanded()) { |
| 269 // (<http://crbug.com/168822> and touch area <http://crbug.com/168856>). | 345 MessageView::SetExpanded(expanded); |
| 270 AddChildView(MakeContentView()); | 346 content_view_ = NULL; |
| 271 AddChildView(close_button()); | 347 icon_view_ = NULL; |
| 348 action_buttons_.clear(); | |
| 349 RemoveAllChildViews(true); | |
| 350 PreferredSizeChanged(); | |
| 351 SchedulePaint(); | |
| 352 } | |
| 272 } | 353 } |
| 273 | 354 |
| 274 void NotificationView::ButtonPressed(views::Button* sender, | 355 void NotificationView::ButtonPressed(views::Button* sender, |
| 275 const ui::Event& event) { | 356 const ui::Event& event) { |
| 276 for (size_t i = 0; i < action_buttons_.size(); ++i) { | 357 for (size_t i = 0; i < action_buttons_.size(); ++i) { |
| 277 if (action_buttons_[i] == sender) { | 358 if (sender == action_buttons_[i]) { |
| 278 list_delegate()->OnButtonClicked(notification().id, i); | 359 list_delegate()->OnButtonClicked(notification().id, i); |
| 279 return; | 360 return; |
| 280 } | 361 } |
| 281 } | 362 } |
| 282 MessageView::ButtonPressed(sender, event); | 363 MessageView::ButtonPressed(sender, event); |
| 283 } | 364 } |
| 284 | 365 |
| 285 views::View* NotificationView::MakeContentView() { | 366 views::View* NotificationView::MakeContentView() { |
| 286 content_view_ = new views::View(); | 367 content_view_ = new ContentView(); |
| 287 content_view_->set_background( | 368 content_view_->set_background( |
| 288 views::Background::CreateSolidBackground(kBackgroundColor)); | 369 views::Background::CreateSolidBackground(kBackgroundColor)); |
| 289 | 370 |
| 290 // The top part of the content view is composed of an icon view on the left | 371 // The top part of the content view is composed of an icon view on the left |
| 291 // and a certain number of text views on the right (title and message or list | 372 // and a certain number of text views on the right (title and message or list |
| 292 // items), followed by a padding view. Laying out the icon view will require | 373 // items), followed by a padding view. Laying out the icon view will require |
| 293 // information about the text views, so these are created first and collected | 374 // information about the text views, so these are created first and collected |
| 294 // in this vector. | 375 // in this vector. |
| 295 std::vector<views::View*> texts; | 376 std::vector<views::View*> text_views; |
| 296 | 377 |
| 297 // Title if it exists. | 378 // Title if it exists. |
| 298 if (!notification().title.empty()) { | 379 if (!notification().title.empty()) { |
| 299 views::Label* title = new views::Label(notification().title); | 380 views::Label* title = new views::Label(notification().title); |
| 300 title->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 381 title->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 301 title->SetElideBehavior(views::Label::ELIDE_AT_END); | 382 if (IsExpanded()) |
| 383 title->SetMultiLine(true); | |
| 384 else | |
| 385 title->SetElideBehavior(views::Label::ELIDE_AT_END); | |
| 302 title->SetFont(title->font().DeriveFont(4)); | 386 title->SetFont(title->font().DeriveFont(4)); |
| 303 title->SetEnabledColor(kTitleColor); | 387 title->SetEnabledColor(kTitleColor); |
| 304 title->SetBackgroundColor(kTitleBackgroundColor); | 388 title->SetBackgroundColor(kTitleBackgroundColor); |
| 305 title->set_border(MakePadding(kTextTopPadding, 0, 3, kTextRightPadding)); | 389 title->set_border(MakePadding(kTextTopPadding, 0, 3, kTextRightPadding)); |
| 306 texts.push_back(title); | 390 text_views.push_back(title); |
| 391 } | |
| 392 | |
| 393 // List notification items up to a maximum if appropriate. | |
| 394 int items = static_cast<int>(notification().items.size()); | |
| 395 items = std::min(items, IsExpanded() ? kNotificationMaximumItems : 0); | |
|
Jun Mukai
2013/02/26 02:23:30
as I wrote in _constants.h, I prefer to keep size_
dharcourt
2013/02/26 03:23:30
Done.
| |
| 396 for (int i = 0; i < items; ++i) { | |
| 397 ItemView* item = new ItemView(notification().items[i]); | |
| 398 item->set_border(MakePadding(0, 0, 4, kTextRightPadding)); | |
| 399 text_views.push_back(item); | |
| 307 } | 400 } |
|
dharcourt
2013/02/23 04:32:00
Item display had to be moved up here so the displa
| |
| 308 | 401 |
| 309 // Message if appropriate. | 402 // Message if appropriate. |
| 310 if (notification().items.size() == 0 && !notification().message.empty()) { | 403 if (items == 0 && !notification().message.empty()) { |
| 311 views::Label* message = new views::Label(notification().message); | 404 views::Label* message = new views::Label(notification().message); |
| 312 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 405 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 313 message->SetMultiLine(true); | 406 if (IsExpanded()) |
| 407 message->SetMultiLine(true); | |
| 408 else | |
| 409 message->SetElideBehavior(views::Label::ELIDE_AT_END); | |
| 314 message->SetEnabledColor(kMessageColor); | 410 message->SetEnabledColor(kMessageColor); |
| 315 message->SetBackgroundColor(kMessageBackgroundColor); | 411 message->SetBackgroundColor(kMessageBackgroundColor); |
| 316 message->set_border(MakePadding(0, 0, 3, kTextRightPadding)); | 412 message->set_border(MakePadding(0, 0, 3, kTextRightPadding)); |
| 317 texts.push_back(message); | 413 text_views.push_back(message); |
| 318 } | |
| 319 | |
| 320 // List notification items up to a maximum. | |
| 321 int items = std::min(notification().items.size(), kNotificationMaximumItems); | |
| 322 for (int i = 0; i < items; ++i) { | |
| 323 ItemView* item = new ItemView(notification().items[i]); | |
| 324 item->set_border(MakePadding(0, 0, 4, kTextRightPadding)); | |
| 325 texts.push_back(item); | |
| 326 } | 414 } |
| 327 | 415 |
| 328 // Set up the content view with a fixed-width icon column on the left and a | 416 // Set up the content view with a fixed-width icon column on the left and a |
| 329 // text column on the right that consumes the remaining space. To minimize the | 417 // text column on the right that consumes the remaining space. To minimize the |
| 330 // number of columns and simplify column spanning, padding is applied to each | 418 // number of columns and simplify column spanning, padding is applied to each |
| 331 // view within columns instead of through padding columns. | 419 // view within columns instead of through padding columns. |
| 332 views::GridLayout* layout = new views::GridLayout(content_view_); | 420 views::GridLayout* layout = new views::GridLayout(content_view_); |
| 333 content_view_->SetLayoutManager(layout); | 421 content_view_->SetLayoutManager(layout); |
| 334 views::ColumnSet* columns = layout->AddColumnSet(0); | 422 views::ColumnSet* columns = layout->AddColumnSet(0); |
| 335 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, | 423 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, |
| 336 0, views::GridLayout::FIXED, | 424 0, views::GridLayout::FIXED, |
| 337 kIconColumnWidth + kIconToTextPadding, | 425 kIconColumnWidth + kIconToTextPadding, |
| 338 kIconColumnWidth + kIconToTextPadding); | 426 kIconColumnWidth + kIconToTextPadding); |
| 339 // Padding + icon + padding. | 427 // Padding + icon + padding. |
| 340 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, | 428 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, |
| 341 100, views::GridLayout::USE_PREF, 0, 0); | 429 100, views::GridLayout::USE_PREF, 0, 0); |
| 342 // Text + padding. | 430 // Text + padding. |
| 343 | 431 |
| 344 // Create the first row and its icon view, which spans all the text views | 432 // Create the first row and its icon view, which spans all the text views |
| 345 // to its right as well as the padding view below them. | 433 // to its right as well as the padding view below them. |
| 346 layout->StartRow(0, 0); | 434 layout->StartRow(0, 0); |
| 347 views::ImageView* icon = new views::ImageView(); | 435 icon_view_ = new views::ImageView(); |
| 348 icon->SetImageSize(gfx::Size(message_center::kNotificationIconSize, | 436 icon_view_->SetImageSize(gfx::Size(message_center::kNotificationIconSize, |
| 349 message_center::kNotificationIconSize)); | 437 message_center::kNotificationIconSize)); |
| 350 icon->SetImage(notification().primary_icon); | 438 icon_view_->SetImage(notification().primary_icon); |
| 351 icon->SetHorizontalAlignment(views::ImageView::LEADING); | 439 icon_view_->SetHorizontalAlignment(views::ImageView::LEADING); |
| 352 icon->SetVerticalAlignment(views::ImageView::LEADING); | 440 icon_view_->SetVerticalAlignment(views::ImageView::LEADING); |
| 353 icon->set_border(MakePadding(0, 0, 0, kIconToTextPadding)); | 441 icon_view_->set_border(MakePadding(0, 0, 0, kIconToTextPadding)); |
| 354 layout->AddView(icon, 1, texts.size() + 1); | 442 layout->AddView(icon_view_, 1, text_views.size() + 1); |
| 355 | 443 |
| 356 // Add the text views, creating rows for them if necessary. | 444 // Add the text views, creating rows for them if necessary. |
| 357 for (size_t i = 0; i < texts.size(); ++i) { | 445 for (size_t i = 0; i < text_views.size(); ++i) { |
| 358 if (i > 0) { | 446 if (i > 0) { |
| 359 layout->StartRow(0, 0); | 447 layout->StartRow(0, 0); |
| 360 layout->SkipColumns(1); | 448 layout->SkipColumns(1); |
| 361 } | 449 } |
| 362 layout->AddView(texts[i]); | 450 layout->AddView(text_views[i]); |
| 363 } | 451 } |
| 364 | 452 |
| 365 // Add a text padding row if necessary. This adds some space between the last | 453 // Add a text padding row if necessary. This adds some space between the last |
| 366 // line of text and anything below it but it also ensures views above it are | 454 // line of text and anything below it but it also ensures views above it are |
| 367 // top-justified by expanding vertically to take up any extra space. | 455 // top-justified by expanding vertically to take up any extra space. |
| 368 if (texts.size() == 0) { | 456 if (text_views.size() == 0) { |
| 369 layout->SkipColumns(1); | 457 layout->SkipColumns(1); |
| 370 } else { | 458 } else { |
| 371 layout->StartRow(100, 0); | 459 layout->StartRow(100, 0); |
| 372 layout->SkipColumns(1); | 460 layout->SkipColumns(1); |
| 373 views::View* padding = new views::ImageView(); | 461 views::View* padding = new views::ImageView(); |
| 374 padding->set_border(MakePadding(kTextBottomPadding, 1, 0, 0)); | 462 padding->set_border(MakePadding(kTextBottomPadding, 1, 0, 0)); |
| 375 layout->AddView(padding); | 463 layout->AddView(padding); |
| 376 } | 464 } |
| 377 | 465 |
| 378 // Add an image row if appropriate. | 466 // Add an image row if appropriate. |
| 379 if (!notification().image.isNull()) { | 467 if (IsExpanded() && !notification().image.isNull()) { |
| 380 layout->StartRow(0, 0); | 468 layout->StartRow(0, 0); |
| 381 views::ImageView* image = new ProportionalImageView(); | 469 ProportionalImageView* image_view = new ProportionalImageView(); |
| 382 image->SetImageSize(notification().image.size()); | 470 image_view->SetImage(notification().image); |
| 383 image->SetImage(notification().image); | 471 layout->AddView(image_view, 2, 1); |
| 384 image->SetHorizontalAlignment(views::ImageView::CENTER); | |
| 385 image->SetVerticalAlignment(views::ImageView::LEADING); | |
| 386 layout->AddView(image, 2, 1); | |
| 387 } | 472 } |
| 388 | 473 |
| 389 // Add action button rows. | 474 // Add action button rows. |
| 390 for (size_t i = 0; i < notification().button_titles.size(); ++i) { | 475 for (size_t i = 0; i < notification().button_titles.size(); ++i) { |
| 391 views::View* separator = new views::View(); | 476 views::View* separator = new views::View(); |
| 392 separator->set_background(MakeBackground(kButtonSeparatorColor)); | 477 separator->set_background(MakeBackground(kButtonSeparatorColor)); |
| 393 layout->StartRow(0, 0); | 478 layout->StartRow(0, 0); |
| 394 layout->AddView(separator, 2, 1, | 479 layout->AddView(separator, 2, 1, |
| 395 views::GridLayout::FILL, views::GridLayout::FILL, 0, 1); | 480 views::GridLayout::FILL, views::GridLayout::FILL, 0, 1); |
| 396 NotificationButton* button = new NotificationButton(this); | 481 NotificationButton* button = new NotificationButton(this); |
| 397 button->SetTitle(notification().button_titles[i]); | 482 button->SetTitle(notification().button_titles[i]); |
| 398 button->SetIcon(notification().button_icons[i]); | 483 button->SetIcon(notification().button_icons[i]); |
| 399 action_buttons_.push_back(button); | 484 action_buttons_.push_back(button); |
| 400 layout->StartRow(0, 0); | 485 layout->StartRow(0, 0); |
| 401 layout->AddView(button, 2, 1, | 486 layout->AddView(button, 2, 1, |
| 402 views::GridLayout::FILL, views::GridLayout::FILL, 0, 40); | 487 views::GridLayout::FILL, views::GridLayout::FILL, 0, 40); |
| 403 } | 488 } |
| 404 | 489 |
| 405 return content_view_; | 490 return content_view_; |
| 406 } | 491 } |
| 407 | 492 |
| 408 } // namespace message_center | 493 } // namespace message_center |
| OLD | NEW |