Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: ui/message_center/message_view.cc

Issue 12326091: Made notification center notifications collapsed and expandable. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased, which led to many changes. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/message_view.h" 5 #include "ui/message_center/message_view.h"
6 6
7 #include "grit/ui_resources.h" 7 #include "grit/ui_resources.h"
8 #include "grit/ui_strings.h" 8 #include "grit/ui_strings.h"
9 #include "ui/base/l10n/l10n_util.h" 9 #include "ui/base/l10n/l10n_util.h"
10 #include "ui/base/models/simple_menu_model.h" 10 #include "ui/base/models/simple_menu_model.h"
11 #include "ui/base/resource/resource_bundle.h" 11 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/compositor/scoped_layer_animation_settings.h" 12 #include "ui/compositor/scoped_layer_animation_settings.h"
13 #include "ui/gfx/canvas.h" 13 #include "ui/gfx/canvas.h"
14 #include "ui/gfx/shadow_value.h" 14 #include "ui/gfx/shadow_value.h"
15 #include "ui/gfx/skia_util.h" 15 #include "ui/gfx/skia_util.h"
16 #include "ui/message_center/message_center_util.h" 16 #include "ui/message_center/message_center_util.h"
17 #include "ui/views/controls/button/image_button.h" 17 #include "ui/views/controls/button/image_button.h"
18 #include "ui/views/controls/menu/menu_model_adapter.h" 18 #include "ui/views/controls/menu/menu_model_adapter.h"
19 #include "ui/views/controls/menu/menu_runner.h" 19 #include "ui/views/controls/menu/menu_runner.h"
20 #include "ui/views/controls/scroll_view.h" 20 #include "ui/views/controls/scroll_view.h"
21 #include "ui/views/widget/widget.h" 21 #include "ui/views/widget/widget.h"
22 22
23 namespace { 23 namespace {
24 24
25 const int kCloseButtonSize = 29; 25 const int kControlButtonSize = 29;
26 const int kCloseIconTopPadding = 5; 26 const int kCloseIconTopPadding = 5;
27 const int kCloseIconRightPadding = 5; 27 const int kCloseIconRightPadding = 5;
28 const int kExpandIconBottomPadding = 8;
29 const int kExpandIconRightPadding = 11;
30
28 const int kShadowOffset = 1; 31 const int kShadowOffset = 1;
29 const int kShadowBlur = 4; 32 const int kShadowBlur = 4;
30 33
31 const SkColor kShadowColor = SkColorSetARGB(0.3 * 255, 0, 0, 0); 34 const SkColor kShadowColor = SkColorSetARGB(0.3 * 255, 0, 0, 0);
32 const SkColor kTransparentColor = SkColorSetARGB(0, 0, 0, 0); 35 const SkColor kTransparentColor = SkColorSetARGB(0, 0, 0, 0);
33 36
34 // Menu constants 37 // Menu constants
35 const int kTogglePermissionCommand = 0; 38 const int kTogglePermissionCommand = 0;
36 const int kToggleExtensionCommand = 1; 39 const int kToggleExtensionCommand = 1;
37 const int kShowSettingsCommand = 2; 40 const int kShowSettingsCommand = 2;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 resource_id)); 100 resource_id));
98 } 101 }
99 102
100 void ControlButton::SetPressedImage(int resource_id) { 103 void ControlButton::SetPressedImage(int resource_id) {
101 SetImage(views::CustomButton::STATE_PRESSED, 104 SetImage(views::CustomButton::STATE_PRESSED,
102 ResourceBundle::GetSharedInstance().GetImageSkiaNamed( 105 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
103 resource_id)); 106 resource_id));
104 } 107 }
105 108
106 gfx::Size ControlButton::GetPreferredSize() { 109 gfx::Size ControlButton::GetPreferredSize() {
107 return gfx::Size(kCloseButtonSize, kCloseButtonSize); 110 return gfx::Size(kControlButtonSize, kControlButtonSize);
108 } 111 }
109 112
110 void ControlButton::OnPaint(gfx::Canvas* canvas) { 113 void ControlButton::OnPaint(gfx::Canvas* canvas) {
111 // This is the same implementation as ImageButton::OnPaint except 114 // This is the same implementation as ImageButton::OnPaint except
112 // that it calls ComputePaddedImagePaintPosition() instead of 115 // that it calls ComputePaddedImagePaintPosition() instead of
113 // ComputeImagePaintPosition(), in effect overriding that private method. 116 // ComputeImagePaintPosition(), in effect overriding that private method.
114 View::OnPaint(canvas); 117 View::OnPaint(canvas);
115 gfx::ImageSkia image = GetImageToPaint(); 118 gfx::ImageSkia image = GetImageToPaint();
116 if (!image.isNull()) { 119 if (!image.isNull()) {
117 gfx::Point position = ComputePaddedImagePaintPosition(image); 120 gfx::Point position = ComputePaddedImagePaintPosition(image);
(...skipping 26 matching lines...) Expand all
144 } 147 }
145 148
146 // A border to provide the shadow for each card. 149 // A border to provide the shadow for each card.
147 // Current shadow should look like css box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3) 150 // Current shadow should look like css box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3)
148 class ShadowBorder : public views::Border { 151 class ShadowBorder : public views::Border {
149 public: 152 public:
150 ShadowBorder() : views::Border() {} 153 ShadowBorder() : views::Border() {}
151 virtual ~ShadowBorder() {} 154 virtual ~ShadowBorder() {}
152 155
153 protected: 156 protected:
154 // views::Border overrides: 157 // Overridden from views::Border:
155 virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE; 158 virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE;
156 virtual gfx::Insets GetInsets() const OVERRIDE; 159 virtual gfx::Insets GetInsets() const OVERRIDE;
157 160
158 DISALLOW_COPY_AND_ASSIGN(ShadowBorder); 161 DISALLOW_COPY_AND_ASSIGN(ShadowBorder);
159 }; 162 };
160 163
161 void ShadowBorder::Paint(const views::View& view, gfx::Canvas* canvas) { 164 void ShadowBorder::Paint(const views::View& view, gfx::Canvas* canvas) {
162 SkPaint paint; 165 SkPaint paint;
163 std::vector<gfx::ShadowValue> shadows; 166 std::vector<gfx::ShadowValue> shadows;
164 shadows.push_back(gfx::ShadowValue(gfx::Point(), kShadowBlur, kShadowColor)); 167 shadows.push_back(gfx::ShadowValue(gfx::Point(), kShadowBlur, kShadowColor));
165 skia::RefPtr<SkDrawLooper> looper = gfx::CreateShadowDrawLooper(shadows); 168 skia::RefPtr<SkDrawLooper> looper = gfx::CreateShadowDrawLooper(shadows);
166 paint.setLooper(looper.get()); 169 paint.setLooper(looper.get());
167 paint.setColor(kTransparentColor); 170 paint.setColor(kTransparentColor);
168 paint.setStrokeJoin(SkPaint::kRound_Join); 171 paint.setStrokeJoin(SkPaint::kRound_Join);
169 gfx::Rect bounds(view.size()); 172 gfx::Rect bounds(view.size());
170 bounds.Inset(gfx::Insets(kShadowBlur / 2, kShadowBlur / 2, 173 bounds.Inset(gfx::Insets(kShadowBlur / 2, kShadowBlur / 2,
171 kShadowBlur / 2, kShadowBlur / 2)); 174 kShadowBlur / 2, kShadowBlur / 2));
172 canvas->DrawRect(bounds, paint); 175 canvas->DrawRect(bounds, paint);
173 } 176 }
174 177
175 gfx::Insets ShadowBorder::GetInsets() const { 178 gfx::Insets ShadowBorder::GetInsets() const {
176 return message_center::MessageView::GetShadowInsets(); 179 return message_center::MessageView::GetShadowInsets();
177 } 180 }
178 181
179 // A dropdown menu for notifications. 182 // A dropdown menu for notifications.
180 class MenuModel : public ui::SimpleMenuModel, 183 class MenuModel : public ui::SimpleMenuModel,
181 public ui::SimpleMenuModel::Delegate { 184 public ui::SimpleMenuModel::Delegate {
182 public: 185 public:
183 MenuModel(message_center::NotificationList::Delegate* list_delegate, 186 MenuModel(message_center::NotificationList::Delegate* delegate,
184 const std::string& notification_id, 187 const std::string& notification_id,
185 const string16& display_source, 188 const string16& display_source,
186 const std::string& extension_id); 189 const std::string& extension_id);
187 virtual ~MenuModel(); 190 virtual ~MenuModel();
188 191
189 // Overridden from ui::SimpleMenuModel::Delegate: 192 // Overridden from ui::SimpleMenuModel::Delegate:
190 virtual bool IsItemForCommandIdDynamic(int command_id) const OVERRIDE; 193 virtual bool IsItemForCommandIdDynamic(int command_id) const OVERRIDE;
191 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE; 194 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
192 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE; 195 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
193 virtual bool GetAcceleratorForCommandId( 196 virtual bool GetAcceleratorForCommandId(
194 int command_id, 197 int command_id,
195 ui::Accelerator* accelerator) OVERRIDE; 198 ui::Accelerator* accelerator) OVERRIDE;
196 virtual void ExecuteCommand(int command_id) OVERRIDE; 199 virtual void ExecuteCommand(int command_id) OVERRIDE;
197 200
198 private: 201 private:
199 message_center::NotificationList::Delegate* list_delegate_; 202 message_center::NotificationList::Delegate* delegate_; // Weak reference.
200 // Weak, global MessageCenter
201 std::string notification_id_; 203 std::string notification_id_;
202 204
203 DISALLOW_COPY_AND_ASSIGN(MenuModel); 205 DISALLOW_COPY_AND_ASSIGN(MenuModel);
204 }; 206 };
205 207
206 MenuModel::MenuModel(message_center::NotificationList::Delegate* list_delegate, 208 MenuModel::MenuModel(message_center::NotificationList::Delegate* delegate,
207 const std::string& notification_id, 209 const std::string& notification_id,
208 const string16& display_source, 210 const string16& display_source,
209 const std::string& extension_id) 211 const std::string& extension_id)
210 : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)), 212 : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)),
211 list_delegate_(list_delegate), 213 delegate_(delegate),
212 notification_id_(notification_id) { 214 notification_id_(notification_id) {
213 // Add 'disable notifications' menu item. 215 // Add 'disable notifications' menu item.
214 if (!extension_id.empty()) { 216 if (!extension_id.empty()) {
215 AddItem(kToggleExtensionCommand, 217 AddItem(kToggleExtensionCommand,
216 l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_EXTENSIONS_DISABLE)); 218 l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_EXTENSIONS_DISABLE));
217 } else if (!display_source.empty()) { 219 } else if (!display_source.empty()) {
218 AddItem(kTogglePermissionCommand, 220 AddItem(kTogglePermissionCommand,
219 l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_SITE_DISABLE, 221 l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_SITE_DISABLE,
220 display_source)); 222 display_source));
221 } 223 }
(...skipping 20 matching lines...) Expand all
242 } 244 }
243 245
244 bool MenuModel::GetAcceleratorForCommandId(int command_id, 246 bool MenuModel::GetAcceleratorForCommandId(int command_id,
245 ui::Accelerator* accelerator) { 247 ui::Accelerator* accelerator) {
246 return false; 248 return false;
247 } 249 }
248 250
249 void MenuModel::ExecuteCommand(int command_id) { 251 void MenuModel::ExecuteCommand(int command_id) {
250 switch (command_id) { 252 switch (command_id) {
251 case kToggleExtensionCommand: 253 case kToggleExtensionCommand:
252 list_delegate_->DisableNotificationByExtension(notification_id_); 254 delegate_->DisableNotificationByExtension(notification_id_);
253 break; 255 break;
254 case kTogglePermissionCommand: 256 case kTogglePermissionCommand:
255 list_delegate_->DisableNotificationByUrl(notification_id_); 257 delegate_->DisableNotificationByUrl(notification_id_);
256 break; 258 break;
257 case kShowSettingsCommand: 259 case kShowSettingsCommand:
258 list_delegate_->ShowNotificationSettings(notification_id_); 260 delegate_->ShowNotificationSettings(notification_id_);
259 break; 261 break;
260 default: 262 default:
261 NOTREACHED(); 263 NOTREACHED();
262 } 264 }
263 } 265 }
264 266
265 } // namespace 267 } // namespace
266 268
267 namespace message_center { 269 namespace message_center {
268 270
269 MessageView::MessageView(NotificationList::Delegate* list_delegate, 271 MessageView::MessageView(const Notification& notification,
270 const Notification& notification) 272 NotificationList::Delegate* delegate,
271 : list_delegate_(list_delegate), 273 bool expanded)
274 : delegate_(delegate),
272 notification_id_(notification.id()), 275 notification_id_(notification.id()),
273 display_source_(notification.display_source()), 276 display_source_(notification.display_source()),
274 extension_id_(notification.extension_id()), 277 extension_id_(notification.extension_id()),
275 scroller_(NULL) { 278 scroller_(NULL),
279 is_expanded_(expanded) {
276 ControlButton *close = new ControlButton(this); 280 ControlButton *close = new ControlButton(this);
277 close->SetPadding(-kCloseIconRightPadding, kCloseIconTopPadding); 281 close->SetPadding(-kCloseIconRightPadding, kCloseIconTopPadding);
278 close->SetNormalImage(IDR_NOTIFICATION_CLOSE); 282 close->SetNormalImage(IDR_NOTIFICATION_CLOSE);
279 close->SetHoveredImage(IDR_NOTIFICATION_CLOSE_HOVER); 283 close->SetHoveredImage(IDR_NOTIFICATION_CLOSE_HOVER);
280 close->SetPressedImage(IDR_NOTIFICATION_CLOSE_PRESSED); 284 close->SetPressedImage(IDR_NOTIFICATION_CLOSE_PRESSED);
285 close->set_owned_by_client();
281 close_button_.reset(close); 286 close_button_.reset(close);
287
288 ControlButton *expand = new ControlButton(this);
289 expand->SetPadding(-kExpandIconRightPadding, -kExpandIconBottomPadding);
290 expand->SetNormalImage(IDR_NOTIFICATIONS_EXPAND);
291 expand->SetHoveredImage(IDR_NOTIFICATIONS_EXPAND_HOVER);
292 expand->SetPressedImage(IDR_NOTIFICATIONS_EXPAND_PRESSED);
293 expand->set_owned_by_client();
294 expand_button_.reset(expand);
295
282 if (IsRichNotificationEnabled()) 296 if (IsRichNotificationEnabled())
283 set_border(new ShadowBorder()); 297 set_border(new ShadowBorder());
284 } 298 }
285 299
286 MessageView::MessageView() { 300 MessageView::MessageView() {
287 } 301 }
288 302
289 MessageView::~MessageView() { 303 MessageView::~MessageView() {
290 } 304 }
291 305
292 // static 306 // static
293 gfx::Insets MessageView::GetShadowInsets() { 307 gfx::Insets MessageView::GetShadowInsets() {
294 return gfx::Insets(kShadowBlur / 2 - kShadowOffset, 308 return gfx::Insets(kShadowBlur / 2 - kShadowOffset,
295 kShadowBlur / 2, 309 kShadowBlur / 2,
296 kShadowBlur / 2 + kShadowOffset, 310 kShadowBlur / 2 + kShadowOffset,
297 kShadowBlur / 2); 311 kShadowBlur / 2);
298 } 312 }
299 313
314 void MessageView::Update(const Notification& notification) {
315 notification_id_ = notification.id();
316 display_source_ = notification.display_source();
317 extension_id_ = notification.extension_id();
318 }
319
300 bool MessageView::OnMousePressed(const ui::MouseEvent& event) { 320 bool MessageView::OnMousePressed(const ui::MouseEvent& event) {
301 if (event.flags() & ui::EF_RIGHT_MOUSE_BUTTON) { 321 if (event.flags() & ui::EF_RIGHT_MOUSE_BUTTON) {
302 ShowMenu(event.location()); 322 ShowMenu(event.location());
303 return true; 323 return true;
304 } 324 }
305 list_delegate_->OnNotificationClicked(notification_id_); 325 delegate_->OnNotificationClicked(notification_id_);
306 return true; 326 return true;
307 } 327 }
308 328
309 void MessageView::OnGestureEvent(ui::GestureEvent* event) { 329 void MessageView::OnGestureEvent(ui::GestureEvent* event) {
310 if (event->type() == ui::ET_GESTURE_TAP) { 330 if (event->type() == ui::ET_GESTURE_TAP) {
311 list_delegate_->OnNotificationClicked(notification_id_); 331 delegate_->OnNotificationClicked(notification_id_);
312 event->SetHandled(); 332 event->SetHandled();
313 return; 333 return;
314 } 334 }
315 335
316 if (event->type() == ui::ET_GESTURE_LONG_PRESS) { 336 if (event->type() == ui::ET_GESTURE_LONG_PRESS) {
317 ShowMenu(event->location()); 337 ShowMenu(event->location());
318 event->SetHandled(); 338 event->SetHandled();
319 return; 339 return;
320 } 340 }
321 341
322 SlideOutView::OnGestureEvent(event); 342 SlideOutView::OnGestureEvent(event);
323 // Do not return here by checking handled(). SlideOutView calls SetHandled() 343 // Do not return here by checking handled(). SlideOutView calls SetHandled()
324 // even though the scroll gesture doesn't make no (or little) effects on the 344 // even though the scroll gesture doesn't make no (or little) effects on the
325 // slide-out behavior. See http://crbug.com/172991 345 // slide-out behavior. See http://crbug.com/172991
326 346
327 if (!event->IsScrollGestureEvent()) 347 if (!event->IsScrollGestureEvent())
328 return; 348 return;
329 349
330 if (scroller_) 350 if (scroller_)
331 scroller_->OnGestureEvent(event); 351 scroller_->OnGestureEvent(event);
332 event->SetHandled(); 352 event->SetHandled();
333 } 353 }
334 354
335 void MessageView::ButtonPressed(views::Button* sender, 355 void MessageView::ButtonPressed(views::Button* sender,
336 const ui::Event& event) { 356 const ui::Event& event) {
337 if (sender == close_button()) 357 if (sender == close_button()) {
338 list_delegate_->SendRemoveNotification(notification_id_, true); // By user. 358 delegate_->SendRemoveNotification(notification_id_, true); // By user.
359 } else if (sender == expand_button()) {
360 is_expanded_ = true;
361 delegate_->OnExpand(notification_id_);
362 }
339 } 363 }
340 364
341 void MessageView::ShowMenu(gfx::Point screen_location) { 365 void MessageView::ShowMenu(gfx::Point screen_location) {
342 MenuModel menu_model(list_delegate_, notification_id_, 366 MenuModel menu_model(delegate_, notification_id_,
343 display_source_, extension_id_); 367 display_source_, extension_id_);
344 if (menu_model.GetItemCount() == 0) 368 if (menu_model.GetItemCount() == 0)
345 return; 369 return;
346 370
347 views::MenuModelAdapter menu_model_adapter(&menu_model); 371 views::MenuModelAdapter menu_model_adapter(&menu_model);
348 views::MenuRunner menu_runner(menu_model_adapter.CreateMenu()); 372 views::MenuRunner menu_runner(menu_model_adapter.CreateMenu());
349 373
350 views::View::ConvertPointToScreen(this, &screen_location); 374 views::View::ConvertPointToScreen(this, &screen_location);
351 ignore_result(menu_runner.RunMenuAt( 375 ignore_result(menu_runner.RunMenuAt(
352 GetWidget()->GetTopLevelWidget(), 376 GetWidget()->GetTopLevelWidget(),
353 NULL, 377 NULL,
354 gfx::Rect(screen_location, gfx::Size()), 378 gfx::Rect(screen_location, gfx::Size()),
355 views::MenuItemView::TOPRIGHT, 379 views::MenuItemView::TOPRIGHT,
356 views::MenuRunner::HAS_MNEMONICS)); 380 views::MenuRunner::HAS_MNEMONICS));
357 } 381 }
358 382
359 void MessageView::OnSlideOut() { 383 void MessageView::OnSlideOut() {
360 list_delegate_->SendRemoveNotification(notification_id_, true); // By user. 384 delegate_->SendRemoveNotification(notification_id_, true); // By user.
361 } 385 }
362 386
363 } // namespace message_center 387 } // namespace message_center
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698