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 |