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/views/notification_view.h" | 5 #include "ui/message_center/views/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" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 views::Border* MakeBorder(int top, | 57 views::Border* MakeBorder(int top, |
| 58 int bottom, | 58 int bottom, |
| 59 int left = kTextLeftPadding, | 59 int left = kTextLeftPadding, |
| 60 int right = kTextRightPadding, | 60 int right = kTextRightPadding, |
| 61 SkColor color = 0x00000000) { | 61 SkColor color = 0x00000000) { |
| 62 return (color == 0x00000000) ? | 62 return (color == 0x00000000) ? |
| 63 views::Border::CreateEmptyBorder(top, left, bottom, right) : | 63 views::Border::CreateEmptyBorder(top, left, bottom, right) : |
| 64 views::Border::CreateSolidSidedBorder(top, left, bottom, right, color); | 64 views::Border::CreateSolidSidedBorder(top, left, bottom, right, color); |
| 65 } | 65 } |
| 66 | 66 |
| 67 // ContainerViews is a vertical BoxLayout view that propagates its childrens' | 67 // ContainerView /////////////////////////////////////////////////////////////// |
|
dharcourt
2013/03/13 22:47:51
It's becoming hard to find nested classes in this
| |
| 68 | |
| 69 // ContainerViews are vertical BoxLayout views that propagates their childrens' | |
| 68 // ChildPreferredSizeChanged() and ChildVisibilityChanged() calls. | 70 // ChildPreferredSizeChanged() and ChildVisibilityChanged() calls. |
| 69 class ContainerView : public views::View { | 71 class ContainerView : public views::View { |
| 70 public: | 72 public: |
| 71 ContainerView(); | 73 ContainerView(); |
| 72 virtual ~ContainerView(); | 74 virtual ~ContainerView(); |
| 73 | 75 |
| 74 protected: | 76 protected: |
| 75 virtual void ChildPreferredSizeChanged(View* child) OVERRIDE; | 77 virtual void ChildPreferredSizeChanged(View* child) OVERRIDE; |
| 76 virtual void ChildVisibilityChanged(View* child) OVERRIDE; | 78 virtual void ChildVisibilityChanged(View* child) OVERRIDE; |
| 77 | 79 |
| 78 private: | 80 private: |
| 79 DISALLOW_COPY_AND_ASSIGN(ContainerView); | 81 DISALLOW_COPY_AND_ASSIGN(ContainerView); |
| 80 }; | 82 }; |
| 81 | 83 |
| 82 ContainerView::ContainerView() { | 84 ContainerView::ContainerView() { |
| 83 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); | 85 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); |
| 84 } | 86 } |
| 85 | 87 |
| 86 ContainerView::~ContainerView() { | 88 ContainerView::~ContainerView() { |
| 87 } | 89 } |
| 88 | 90 |
| 89 void ContainerView::ChildPreferredSizeChanged(View* child) { | 91 void ContainerView::ChildPreferredSizeChanged(View* child) { |
| 90 PreferredSizeChanged(); | 92 PreferredSizeChanged(); |
| 91 } | 93 } |
| 92 | 94 |
| 93 void ContainerView::ChildVisibilityChanged(View* child) { | 95 void ContainerView::ChildVisibilityChanged(View* child) { |
| 94 PreferredSizeChanged(); | 96 PreferredSizeChanged(); |
| 95 } | 97 } |
| 96 | 98 |
| 99 // ItemView //////////////////////////////////////////////////////////////////// | |
| 100 | |
| 97 // ItemViews are responsible for drawing each list notification item's title and | 101 // ItemViews are responsible for drawing each list notification item's title and |
| 98 // message next to each other within a single column. | 102 // message next to each other within a single column. |
| 99 class ItemView : public views::View { | 103 class ItemView : public views::View { |
| 100 public: | 104 public: |
| 101 ItemView(const message_center::NotificationItem& item); | 105 ItemView(const message_center::NotificationItem& item); |
| 102 virtual ~ItemView(); | 106 virtual ~ItemView(); |
| 103 | 107 |
| 104 virtual void SetVisible(bool visible) OVERRIDE; | 108 virtual void SetVisible(bool visible) OVERRIDE; |
| 105 | 109 |
| 106 private: | 110 private: |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 133 | 137 |
| 134 ItemView::~ItemView() { | 138 ItemView::~ItemView() { |
| 135 } | 139 } |
| 136 | 140 |
| 137 void ItemView::SetVisible(bool visible) { | 141 void ItemView::SetVisible(bool visible) { |
| 138 views::View::SetVisible(visible); | 142 views::View::SetVisible(visible); |
| 139 for (int i = 0; i < child_count(); ++i) | 143 for (int i = 0; i < child_count(); ++i) |
| 140 child_at(i)->SetVisible(visible); | 144 child_at(i)->SetVisible(visible); |
| 141 } | 145 } |
| 142 | 146 |
| 147 // ProportionalImageView /////////////////////////////////////////////////////// | |
| 148 | |
| 143 // ProportionalImageViews center their images to preserve their proportion. | 149 // ProportionalImageViews center their images to preserve their proportion. |
| 144 // Note that for this subclass of views::ImageView GetImageBounds() will return | 150 class ProportionalImageView : public views::View { |
|
dharcourt
2013/03/13 22:47:51
Rather than having 3 lines of comment explaining w
| |
| 145 // potentially incorrect values (this can't be fixed because GetImageBounds() | |
| 146 // is not virtual) and horizontal and vertical alignments will be ignored. | |
| 147 class ProportionalImageView : public views::ImageView { | |
| 148 public: | 151 public: |
| 149 ProportionalImageView(); | 152 ProportionalImageView(const gfx::ImageSkia& image); |
| 150 virtual ~ProportionalImageView(); | 153 virtual ~ProportionalImageView(); |
| 151 | 154 |
| 152 // Overridden from views::View: | 155 // Overridden from views::View: |
| 153 virtual gfx::Size GetPreferredSize() OVERRIDE; | 156 virtual gfx::Size GetPreferredSize() OVERRIDE; |
| 154 virtual int GetHeightForWidth(int width) OVERRIDE; | 157 virtual int GetHeightForWidth(int width) OVERRIDE; |
| 155 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; | 158 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; |
| 156 | 159 |
| 157 private: | 160 private: |
| 158 gfx::Size GetImageSizeForWidth(int width); | 161 gfx::Size GetImageSizeForWidth(int width); |
| 159 | 162 |
| 163 gfx::ImageSkia image_; | |
| 164 | |
| 160 DISALLOW_COPY_AND_ASSIGN(ProportionalImageView); | 165 DISALLOW_COPY_AND_ASSIGN(ProportionalImageView); |
| 161 }; | 166 }; |
| 162 | 167 |
| 163 ProportionalImageView::ProportionalImageView() { | 168 ProportionalImageView::ProportionalImageView(const gfx::ImageSkia& image) |
| 169 : image_(image) { | |
| 164 } | 170 } |
| 165 | 171 |
| 166 ProportionalImageView::~ProportionalImageView() { | 172 ProportionalImageView::~ProportionalImageView() { |
| 167 } | 173 } |
| 168 | 174 |
| 169 gfx::Size ProportionalImageView::GetPreferredSize() { | 175 gfx::Size ProportionalImageView::GetPreferredSize() { |
| 170 gfx::Size size = GetImageSizeForWidth(GetImage().width()); | 176 gfx::Size size = GetImageSizeForWidth(image_.width()); |
| 171 return gfx::Size(size.width() + GetInsets().width(), | 177 return gfx::Size(size.width() + GetInsets().width(), |
| 172 size.height() + GetInsets().height()); | 178 size.height() + GetInsets().height()); |
| 173 } | 179 } |
| 174 | 180 |
| 175 int ProportionalImageView::GetHeightForWidth(int width) { | 181 int ProportionalImageView::GetHeightForWidth(int width) { |
| 176 return GetImageSizeForWidth(width).height(); | 182 return GetImageSizeForWidth(width).height(); |
| 177 } | 183 } |
| 178 | 184 |
| 179 void ProportionalImageView::OnPaint(gfx::Canvas* canvas) { | 185 void ProportionalImageView::OnPaint(gfx::Canvas* canvas) { |
| 180 View::OnPaint(canvas); | 186 views::View::OnPaint(canvas); |
| 181 | 187 |
| 182 gfx::Size draw_size(GetImageSizeForWidth(width())); | 188 gfx::Size draw_size(GetImageSizeForWidth(width())); |
| 183 if (!draw_size.IsEmpty()) { | 189 if (!draw_size.IsEmpty()) { |
| 184 int x = (width() - draw_size.width()) / 2; | 190 gfx::Rect draw_bounds = GetLocalBounds(); |
| 185 int y = (height() - draw_size.height()) / 2; | 191 draw_bounds.Inset(GetInsets()); |
| 192 draw_bounds.ClampToCenteredSize(draw_size); | |
|
dharcourt
2013/03/13 22:47:51
Fixed these calculations to work when there are in
| |
| 186 | 193 |
| 187 gfx::Size image_size(GetImage().size()); | 194 gfx::Size image_size(image_.size()); |
| 188 if (image_size == draw_size) { | 195 if (image_size == draw_size) { |
| 189 canvas->DrawImageInt(GetImage(), x, y); | 196 canvas->DrawImageInt(image_, draw_bounds.x(), draw_bounds.y()); |
| 190 } else { | 197 } else { |
| 191 // Resize case | 198 // Resize case |
| 192 SkPaint paint; | 199 SkPaint paint; |
| 193 paint.setFilterBitmap(true); | 200 paint.setFilterBitmap(true); |
| 194 canvas->DrawImageInt(GetImage(), 0, 0, | 201 canvas->DrawImageInt(image_, 0, 0, |
| 195 image_size.width(), image_size.height(), x, y, | 202 image_size.width(), image_size.height(), |
| 196 draw_size.width(), draw_size.height(), true, paint); | 203 draw_bounds.x(), draw_bounds.y(), |
| 204 draw_size.width(), draw_size.height(), | |
| 205 true, paint); | |
| 197 } | 206 } |
| 198 } | 207 } |
| 199 } | 208 } |
| 200 | 209 |
| 201 gfx::Size ProportionalImageView::GetImageSizeForWidth(int width) { | 210 gfx::Size ProportionalImageView::GetImageSizeForWidth(int width) { |
| 202 gfx::Size size = visible() ? GetImage().size() : gfx::Size(); | 211 gfx::Size size = visible() ? image_.size() : gfx::Size(); |
| 203 if (width > 0 && !size.IsEmpty()) { | 212 if (width > 0 && !size.IsEmpty()) { |
| 204 double proportion = size.height() / (double) size.width(); | 213 double proportion = size.height() / (double) size.width(); |
| 205 size.SetSize(width, std::max(0.5 + width * proportion, 1.0)); | 214 size.SetSize(width, std::max(0.5 + width * proportion, 1.0)); |
| 206 if (size.height() > message_center::kNotificationMaximumImageHeight) { | 215 if (size.height() > message_center::kNotificationMaximumImageHeight) { |
| 207 int height = message_center::kNotificationMaximumImageHeight; | 216 int height = message_center::kNotificationMaximumImageHeight; |
| 208 size.SetSize(std::max(0.5 + height / proportion, 1.0), height); | 217 size.SetSize(std::max(0.5 + height / proportion, 1.0), height); |
| 209 } | 218 } |
| 210 } | 219 } |
| 211 return size; | 220 return size; |
| 212 } | 221 } |
| 213 | 222 |
| 214 // NotificationsButtons render the action buttons of notifications. | 223 // NotificationButton ////////////////////////////////////////////////////////// |
| 224 | |
| 225 // NotificationButtons render the action buttons of notifications. | |
| 215 class NotificationButton : public views::CustomButton { | 226 class NotificationButton : public views::CustomButton { |
| 216 public: | 227 public: |
| 217 NotificationButton(views::ButtonListener* listener); | 228 NotificationButton(views::ButtonListener* listener); |
| 218 virtual ~NotificationButton(); | 229 virtual ~NotificationButton(); |
| 219 | 230 |
| 220 void SetIcon(const gfx::ImageSkia& icon); | 231 void SetIcon(const gfx::ImageSkia& icon); |
| 221 void SetTitle(const string16& title); | 232 void SetTitle(const string16& title); |
| 222 | 233 |
| 223 // Overridden from views::View: | 234 // Overridden from views::View: |
| 224 virtual gfx::Size GetPreferredSize() OVERRIDE; | 235 virtual gfx::Size GetPreferredSize() OVERRIDE; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 280 } | 291 } |
| 281 | 292 |
| 282 int NotificationButton::GetHeightForWidth(int width) { | 293 int NotificationButton::GetHeightForWidth(int width) { |
| 283 return kButtonHeight; | 294 return kButtonHeight; |
| 284 } | 295 } |
| 285 | 296 |
| 286 } // namespace | 297 } // namespace |
| 287 | 298 |
| 288 namespace message_center { | 299 namespace message_center { |
| 289 | 300 |
| 301 // NotificationView //////////////////////////////////////////////////////////// | |
| 302 | |
| 290 // static | 303 // static |
| 291 MessageView* NotificationView::Create(const Notification& notification, | 304 MessageView* NotificationView::Create(const Notification& notification, |
| 292 NotificationChangeObserver* observer, | 305 NotificationChangeObserver* observer, |
| 293 bool expanded) { | 306 bool expanded) { |
| 294 // For the time being, use MessageSimpleView for simple notifications unless | 307 // For the time being, use MessageSimpleView for simple notifications unless |
| 295 // one of the use-the-new-style flags are set. This preserves the appearance | 308 // one of the use-the-new-style flags are set. This preserves the appearance |
| 296 // of notifications created by existing code that uses webkitNotifications. | 309 // of notifications created by existing code that uses webkitNotifications. |
| 297 if (notification.type() == NOTIFICATION_TYPE_SIMPLE && | 310 if (notification.type() == NOTIFICATION_TYPE_SIMPLE && |
| 298 !IsRichNotificationEnabled() && | 311 !IsRichNotificationEnabled() && |
| 299 !CommandLine::ForCurrentProcess()->HasSwitch( | 312 !CommandLine::ForCurrentProcess()->HasSwitch( |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 373 std::vector<NotificationItem> items = notification.items(); | 386 std::vector<NotificationItem> items = notification.items(); |
| 374 for (size_t i = 0; i < items.size() && i < kNotificationMaximumItems; ++i) { | 387 for (size_t i = 0; i < items.size() && i < kNotificationMaximumItems; ++i) { |
| 375 ItemView* item_view = new ItemView(items[i]); | 388 ItemView* item_view = new ItemView(items[i]); |
| 376 item_view->SetVisible(is_expanded()); | 389 item_view->SetVisible(is_expanded()); |
| 377 item_view->set_border(MakeBorder(0, 4)); | 390 item_view->set_border(MakeBorder(0, 4)); |
| 378 item_views_.push_back(item_view); | 391 item_views_.push_back(item_view); |
| 379 top_view_->AddChildView(item_view); | 392 top_view_->AddChildView(item_view); |
| 380 } | 393 } |
| 381 | 394 |
| 382 // Create the notification icon view. | 395 // Create the notification icon view. |
| 383 icon_view_ = new ProportionalImageView(); | 396 icon_view_ = new ProportionalImageView(notification.icon().AsImageSkia()); |
| 384 icon_view_->SetImage(notification.icon().AsImageSkia()); | |
| 385 | 397 |
| 386 // Create the bottom_view_, which collects into a vertical box all content | 398 // Create the bottom_view_, which collects into a vertical box all content |
| 387 // below the notification icon except for the expand button. | 399 // below the notification icon except for the expand button. |
| 388 bottom_view_ = new ContainerView(); | 400 bottom_view_ = new ContainerView(); |
| 389 bottom_view_->set_background( | 401 bottom_view_->set_background( |
| 390 views::Background::CreateSolidBackground(kBackgroundColor)); | 402 views::Background::CreateSolidBackground(kBackgroundColor)); |
| 391 | 403 |
| 392 // Create the image view if appropriate. | 404 // Create the image view if appropriate. |
| 393 image_view_ = NULL; | 405 image_view_ = NULL; |
| 394 if (!notification.image().IsEmpty()) { | 406 if (!notification.image().IsEmpty()) { |
| 395 image_view_ = new ProportionalImageView(); | 407 image_view_ = new ProportionalImageView(notification.image().AsImageSkia()); |
| 396 image_view_->SetVisible(is_expanded()); | 408 image_view_->SetVisible(is_expanded()); |
| 397 image_view_->SetImage(notification.image().ToImageSkia()); | |
| 398 bottom_view_->AddChildView(image_view_); | 409 bottom_view_->AddChildView(image_view_); |
| 399 } | 410 } |
| 400 | 411 |
| 401 // Create action buttons if appropriate. | 412 // Create action buttons if appropriate. |
| 402 std::vector<ButtonInfo> buttons = notification.buttons(); | 413 std::vector<ButtonInfo> buttons = notification.buttons(); |
| 403 for (size_t i = 0; i < buttons.size(); ++i) { | 414 for (size_t i = 0; i < buttons.size(); ++i) { |
| 404 views::View* separator = new views::ImageView(); | 415 views::View* separator = new views::ImageView(); |
| 405 separator->set_border(MakeBorder(1, 0, 0, 0, kButtonSeparatorColor)); | 416 separator->set_border(MakeBorder(1, 0, 0, 0, kButtonSeparatorColor)); |
| 406 bottom_view_->AddChildView(separator); | 417 bottom_view_->AddChildView(separator); |
| 407 NotificationButton* button = new NotificationButton(this); | 418 NotificationButton* button = new NotificationButton(this); |
| 408 ButtonInfo button_info = buttons[i]; | 419 ButtonInfo button_info = buttons[i]; |
| 409 button->SetTitle(button_info.title); | 420 button->SetTitle(button_info.title); |
| 410 button->SetIcon(button_info.icon.AsImageSkia()); | 421 button->SetIcon(button_info.icon.AsImageSkia()); |
| 411 action_buttons_.push_back(button); | 422 action_buttons_.push_back(button); |
| 412 bottom_view_->AddChildView(button); | 423 bottom_view_->AddChildView(button); |
| 413 } | 424 } |
| 414 | 425 |
| 415 // Hide the expand button if appropriate. | 426 // Hide the expand button if appropriate. |
| 416 bool expandable = item_views_.size() || image_view_; | 427 bool expandable = item_views_.size() || image_view_; |
| 417 expand_button()->SetVisible(expandable && !is_expanded()); | 428 expand_button()->SetVisible(expandable && !is_expanded()); |
| 418 | 429 |
| 419 // Put together the different content and control views. Layering those allows | 430 // Put together the different content and control views. Layering those allows |
| 420 // for proper layout logit and it also allows the close and expand buttons to | 431 // for proper layout logic and it also allows the close and expand buttons to |
| 421 // overlap the content as needed to provide large enough click and touch areas | 432 // overlap the content as needed to provide large enough click and touch areas |
| 422 // (<http://crbug.com/168822> and <http://crbug.com/168856>). | 433 // (<http://crbug.com/168822> and <http://crbug.com/168856>). |
| 423 AddChildView(background_view_); | 434 AddChildView(background_view_); |
| 424 AddChildView(top_view_); | 435 AddChildView(top_view_); |
| 425 AddChildView(icon_view_); | 436 AddChildView(icon_view_); |
| 426 AddChildView(bottom_view_); | 437 AddChildView(bottom_view_); |
| 427 AddChildView(close_button()); | 438 AddChildView(close_button()); |
| 428 AddChildView(expand_button()); | 439 AddChildView(expand_button()); |
| 429 } | 440 } |
| 430 | 441 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 item_views_[i]->SetVisible(true); | 507 item_views_[i]->SetVisible(true); |
| 497 if (image_view_) | 508 if (image_view_) |
| 498 image_view_->SetVisible(true); | 509 image_view_->SetVisible(true); |
| 499 expand_button()->SetVisible(false); | 510 expand_button()->SetVisible(false); |
| 500 PreferredSizeChanged(); | 511 PreferredSizeChanged(); |
| 501 SchedulePaint(); | 512 SchedulePaint(); |
| 502 } | 513 } |
| 503 } | 514 } |
| 504 | 515 |
| 505 } // namespace message_center | 516 } // namespace message_center |
| OLD | NEW |