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/utf_string_conversions.h" | 7 #include "base/utf_string_conversions.h" |
8 #include "grit/ui_resources.h" | 8 #include "grit/ui_resources.h" |
9 #include "ui/base/accessibility/accessible_view_state.h" | 9 #include "ui/base/accessibility/accessible_view_state.h" |
10 #include "ui/base/resource/resource_bundle.h" | 10 #include "ui/base/resource/resource_bundle.h" |
11 #include "ui/base/text/text_elider.h" | 11 #include "ui/base/text/text_elider.h" |
12 #include "ui/gfx/canvas.h" | 12 #include "ui/gfx/canvas.h" |
13 #include "ui/gfx/size.h" | 13 #include "ui/gfx/size.h" |
14 #include "ui/message_center/message_center_constants.h" | 14 #include "ui/message_center/message_center_constants.h" |
15 #include "ui/native_theme/native_theme.h" | 15 #include "ui/native_theme/native_theme.h" |
16 #include "ui/views/controls/button/image_button.h" | 16 #include "ui/views/controls/button/image_button.h" |
17 #include "ui/views/controls/image_view.h" | 17 #include "ui/views/controls/image_view.h" |
18 #include "ui/views/controls/label.h" | 18 #include "ui/views/controls/label.h" |
19 #include "ui/views/layout/box_layout.h" | 19 #include "ui/views/layout/box_layout.h" |
20 #include "ui/views/layout/grid_layout.h" | 20 #include "ui/views/layout/grid_layout.h" |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 // Notification dimensions. | 24 // Notification dimensions. |
| 25 const int kIconTopPadding = 0; |
25 const int kIconLeftPadding = 0; | 26 const int kIconLeftPadding = 0; |
| 27 const int kIconBottomPadding = 0; |
26 const int kIconColumnWidth = message_center::kNotificationIconWidth; | 28 const int kIconColumnWidth = message_center::kNotificationIconWidth; |
27 const int kIconToTextPadding = 15; | 29 const int kIconToTextPadding = 15; |
| 30 const int kTextTopPadding = 9; |
| 31 const int kTextBottomPadding = 12; |
28 const int kTextToClosePadding = 10; | 32 const int kTextToClosePadding = 10; |
| 33 const int kCloseTopPadding = 6; |
| 34 const int kCloseRightPadding = 6; |
29 const int kCloseColumnWidth = 8; | 35 const int kCloseColumnWidth = 8; |
30 const int kCloseRightPadding = 6; | |
31 const int kIconTopPadding = 0; | |
32 const int kTextTopPadding = 9; | |
33 const int kCloseTopPadding = 6; | |
34 const int kIconBottomPadding = 0; | |
35 const int kTextBottomPadding = 12; | |
36 const int kItemTitleToDetailsPadding = 3; | 36 const int kItemTitleToDetailsPadding = 3; |
| 37 const int kImageTopPadding = 0; |
| 38 const int kImageLeftPadding = 0; |
| 39 const int kImageBottomPadding = 0; |
| 40 const int kImageRightPadding = 0; |
37 | 41 |
38 // Notification colors. The text background colors below are used only to keep | 42 // Notification colors. The text background colors below are used only to keep |
39 // view::Label from modifying the text color and will not actually be drawn. | 43 // view::Label from modifying the text color and will not actually be drawn. |
40 // See view::Label's SetEnabledColor() and SetBackgroundColor() for details. | 44 // See view::Label's SetEnabledColor() and SetBackgroundColor() for details. |
41 const SkColor kBackgroundColor = SkColorSetRGB(255, 255, 255); | 45 const SkColor kBackgroundColor = SkColorSetRGB(255, 255, 255); |
42 const SkColor kTitleColor = SkColorSetRGB(68, 68, 68); | 46 const SkColor kTitleColor = SkColorSetRGB(68, 68, 68); |
43 const SkColor kTitleBackgroundColor = SK_ColorWHITE; | 47 const SkColor kTitleBackgroundColor = SK_ColorWHITE; |
44 const SkColor kMessageColor = SkColorSetRGB(136, 136, 136); | 48 const SkColor kMessageColor = SkColorSetRGB(136, 136, 136); |
45 const SkColor kMessageBackgroundColor = SK_ColorBLACK; | 49 const SkColor kMessageBackgroundColor = SK_ColorBLACK; |
46 | 50 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 details->SetBackgroundColor(kMessageBackgroundColor); | 85 details->SetBackgroundColor(kMessageBackgroundColor); |
82 AddChildViewAt(details, 1); | 86 AddChildViewAt(details, 1); |
83 | 87 |
84 PreferredSizeChanged(); | 88 PreferredSizeChanged(); |
85 SchedulePaint(); | 89 SchedulePaint(); |
86 } | 90 } |
87 | 91 |
88 ItemView::~ItemView() { | 92 ItemView::~ItemView() { |
89 } | 93 } |
90 | 94 |
| 95 // ProportionalImageViews match their heights to their widths to preserve the |
| 96 // proportions of their images. |
| 97 class ProportionalImageView : public views::ImageView { |
| 98 public: |
| 99 ProportionalImageView(); |
| 100 virtual ~ProportionalImageView(); |
| 101 |
| 102 // Overridden from views::View. |
| 103 virtual int GetHeightForWidth(int width) OVERRIDE; |
| 104 }; |
| 105 |
| 106 ProportionalImageView::ProportionalImageView() { |
| 107 } |
| 108 |
| 109 ProportionalImageView::~ProportionalImageView() { |
| 110 } |
| 111 |
| 112 int ProportionalImageView::GetHeightForWidth(int width) { |
| 113 int height = 0; |
| 114 gfx::ImageSkia image = GetImage(); |
| 115 if (image.width() > 0 && image.height() > 0) { |
| 116 double proportion = image.height() / (double) image.width(); |
| 117 height = 0.5 + width * proportion; |
| 118 if (height > message_center::kNotificationMaximumImageHeight) { |
| 119 height = message_center::kNotificationMaximumImageHeight; |
| 120 width = 0.5 + height / proportion; |
| 121 } |
| 122 SetImageSize(gfx::Size(width, height)); |
| 123 } |
| 124 return height; |
| 125 } |
| 126 |
91 } // namespace | 127 } // namespace |
92 | 128 |
93 namespace message_center { | 129 namespace message_center { |
94 | 130 |
95 NotificationView::NotificationView( | 131 NotificationView::NotificationView( |
96 NotificationList::Delegate* list_delegate, | 132 NotificationList::Delegate* list_delegate, |
97 const NotificationList::Notification& notification) | 133 const NotificationList::Notification& notification) |
98 : MessageView(list_delegate, notification) { | 134 : MessageView(list_delegate, notification) { |
99 } | 135 } |
100 | 136 |
(...skipping 20 matching lines...) Expand all Loading... |
121 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, | 157 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, |
122 100, views::GridLayout::USE_PREF, | 158 100, views::GridLayout::USE_PREF, |
123 0, 0); | 159 0, 0); |
124 // Text + padding (kTextToClosePadding). | 160 // Text + padding (kTextToClosePadding). |
125 columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, | 161 columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, |
126 0, views::GridLayout::FIXED, | 162 0, views::GridLayout::FIXED, |
127 kCloseColumnWidth + kCloseRightPadding, | 163 kCloseColumnWidth + kCloseRightPadding, |
128 kCloseColumnWidth + kCloseRightPadding); | 164 kCloseColumnWidth + kCloseRightPadding); |
129 // Close button + padding. | 165 // Close button + padding. |
130 | 166 |
131 // First row: Icon. This vertically spans the close button padding row, the | 167 // Figure out how many rows the icon should span. |
132 // close button row, and all item rows. | 168 int span = 2; // Two rows for the close button padding and close button. |
| 169 int displayed_item_count = |
| 170 std::min(notification_.items.size(), kNotificationMaximumItems); |
| 171 if (displayed_item_count > 0) |
| 172 span += displayed_item_count; // + one row per item. |
| 173 else |
| 174 span += 1; // + one row for the message. |
| 175 |
| 176 // First row: Icon. |
133 layout->StartRow(0, 0); | 177 layout->StartRow(0, 0); |
134 views::ImageView* icon = new views::ImageView(); | 178 views::ImageView* icon = new views::ImageView(); |
135 icon->SetImageSize(gfx::Size(message_center::kNotificationIconWidth, | 179 icon->SetImageSize(gfx::Size(message_center::kNotificationIconWidth, |
136 message_center::kNotificationIconWidth)); | 180 message_center::kNotificationIconWidth)); |
137 icon->SetImage(notification_.primary_icon); | 181 icon->SetImage(notification_.primary_icon); |
138 icon->SetHorizontalAlignment(views::ImageView::LEADING); | 182 icon->SetHorizontalAlignment(views::ImageView::LEADING); |
139 icon->SetVerticalAlignment(views::ImageView::LEADING); | 183 icon->SetVerticalAlignment(views::ImageView::LEADING); |
140 icon->set_border(MakePadding(kIconTopPadding, kIconLeftPadding, | 184 icon->set_border(MakePadding(kIconTopPadding, kIconLeftPadding, |
141 kIconBottomPadding, kIconToTextPadding)); | 185 kIconBottomPadding, kIconToTextPadding)); |
142 int displayed_item_count = | 186 layout->AddView(icon, 1, span); |
143 std::min(notification_.items.size(), kNotificationMaxItems); | |
144 layout->AddView(icon, 1, 2 + displayed_item_count); | |
145 | 187 |
146 // First row: Title. This vertically spans the close button padding row and | 188 // First row: Title. This vertically spans the close button padding row and |
147 // the close button row. | 189 // the close button row. |
148 // TODO(dharcourt): Skip the title Label when there's no title text. | 190 // TODO(dharcourt): Skip the title Label when there's no title text. |
149 views::Label* title = new views::Label(notification_.title); | 191 views::Label* title = new views::Label(notification_.title); |
150 title->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 192 title->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
151 title->SetElideBehavior(views::Label::ELIDE_AT_END); | 193 title->SetElideBehavior(views::Label::ELIDE_AT_END); |
152 title->SetFont(title->font().DeriveFont(4)); | 194 title->SetFont(title->font().DeriveFont(4)); |
153 title->SetEnabledColor(kTitleColor); | 195 title->SetEnabledColor(kTitleColor); |
154 title->SetBackgroundColor(kTitleBackgroundColor); | 196 title->SetBackgroundColor(kTitleBackgroundColor); |
155 title->set_border(MakePadding(kTextTopPadding, 0, 3, kTextToClosePadding)); | 197 title->set_border(MakePadding(kTextTopPadding, 0, 3, kTextToClosePadding)); |
156 layout->AddView(title, 1, 2); | 198 layout->AddView(title, 1, 2, |
| 199 views::GridLayout::LEADING, views::GridLayout::LEADING); |
157 | 200 |
158 // First row: Close button padding. | 201 // First row: Close button padding. |
159 views::View* padding = new views::ImageView(); | 202 views::View* padding = new views::ImageView(); |
160 padding->set_border(MakePadding(kCloseTopPadding, 1, 0, 0)); | 203 padding->set_border(MakePadding(kCloseTopPadding, 1, 0, 0)); |
161 layout->AddView(padding); | 204 layout->AddView(padding); |
162 | 205 |
163 // Second row: Close button, which has to be on a row of its own because its | 206 // Second row: Close button, which has to be on a row of its own because its |
164 // top padding can't be set using empty borders (ImageButtons don't support | 207 // top padding can't be set using empty borders (ImageButtons don't support |
165 // borders). The resize factor of this row (100) is much higher than that of | 208 // borders). The resize factor of this row (1) is higher than that of the |
166 // other rows (0) to ensure the first row's height stays at kCloseTopPadding. | 209 // first rows (0) to ensure the first row's height stays at kCloseTopPadding. |
167 layout->StartRow(100, 0); | 210 layout->StartRow(1, 0); |
168 layout->SkipColumns(2); | 211 layout->SkipColumns(2); |
169 DCHECK(close_button_); | 212 DCHECK(close_button_); |
170 layout->AddView(close_button_); | 213 layout->AddView(close_button_); |
171 | 214 |
172 // One row for each notification item, including appropriate padding. | 215 // One row for the message if appropriate. The resize factor of this row (2) |
173 for (int i = 0; i < displayed_item_count; ++i) { | 216 // is higher than that of preceding rows (0 and 1) to ensure the content of |
174 int bottom_padding = | 217 // the notification is top-aligned. |
175 (i < displayed_item_count - 1) ? 4 : (kTextBottomPadding - 2); | 218 if (notification_.items.size() == 0) { |
176 layout->StartRow(0, 0); | 219 layout->StartRow(2, 0); |
| 220 layout->SkipColumns(1); |
| 221 views::Label* message = new views::Label(notification_.message); |
| 222 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 223 message->SetElideBehavior(views::Label::ELIDE_AT_END); |
| 224 message->SetEnabledColor(kMessageColor); |
| 225 message->SetBackgroundColor(kMessageBackgroundColor); |
| 226 message->set_border(MakePadding(0, 0, 3, kTextToClosePadding)); |
| 227 layout->AddView(message, 1, 1, |
| 228 views::GridLayout::LEADING, views::GridLayout::LEADING); |
| 229 layout->SkipColumns(1); |
| 230 } |
| 231 |
| 232 // One row for each notification item, including appropriate padding. The |
| 233 // resize factor of the last row of items (3) is higher than that of all |
| 234 // preceding rows (0, 1, and 2) to ensure the content of the notification is |
| 235 // top-aligned. |
| 236 for (int i = 0, n = displayed_item_count; i < n; ++i) { |
| 237 int bottom_padding = (i < n - 1) ? 4 : (kTextBottomPadding - 2); |
| 238 int resize_factor = (i < n - 1) ? 2 : 3; |
| 239 layout->StartRow(resize_factor, 0); |
177 layout->SkipColumns(1); | 240 layout->SkipColumns(1); |
178 ItemView* item = new ItemView(notification_.items[i]); | 241 ItemView* item = new ItemView(notification_.items[i]); |
179 item->set_border(MakePadding(0, 0, bottom_padding, kTextToClosePadding)); | 242 item->set_border(MakePadding(0, 0, bottom_padding, kTextToClosePadding)); |
180 layout->AddView(item); | 243 layout->AddView(item); |
181 layout->SkipColumns(1); | 244 layout->SkipColumns(1); |
182 } | 245 } |
| 246 |
| 247 // One row for the image. |
| 248 layout->StartRow(0, 0); |
| 249 views::ImageView* image = new ProportionalImageView(); |
| 250 image->SetImageSize(notification_.image.size()); |
| 251 image->SetImage(notification_.image); |
| 252 image->SetHorizontalAlignment(views::ImageView::CENTER); |
| 253 image->SetVerticalAlignment(views::ImageView::LEADING); |
| 254 image->set_border(MakePadding(kImageTopPadding, kImageLeftPadding, |
| 255 kImageBottomPadding, kImageRightPadding)); |
| 256 layout->AddView(image, 3, 1, |
| 257 views::GridLayout::FILL, views::GridLayout::LEADING); |
183 } | 258 } |
184 | 259 |
185 } // namespace message_center | 260 } // namespace message_center |
OLD | NEW |