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

Side by Side Diff: ash/system/web_notification/web_notification_tray.cc

Issue 10514008: Add WebNotificationTray (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 6 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ash/system/web_notification/web_notification_tray.h"
6
7 #include "ash/shell.h"
8 #include "ash/system/tray/system_tray.h"
9 #include "ash/system/tray/system_tray_bubble_view.h"
10 #include "ash/system/tray/tray_constants.h"
11 #include "ash/system/tray/tray_views.h"
12 #include "grit/ash_strings.h"
13 #include "grit/ui_resources.h"
14 #include "grit/ui_resources_standard.h"
15 #include "ui/aura/event.h"
16 #include "ui/aura/window.h"
17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/models/simple_menu_model.h"
19 #include "ui/base/resource/resource_bundle.h"
20 #include "ui/views/controls/button/button.h"
21 #include "ui/views/controls/button/menu_button.h"
22 #include "ui/views/controls/button/menu_button_listener.h"
23 #include "ui/views/controls/label.h"
24 #include "ui/views/controls/menu/menu_model_adapter.h"
25 #include "ui/views/controls/menu/menu_runner.h"
26 #include "ui/views/layout/box_layout.h"
27 #include "ui/views/layout/fill_layout.h"
28 #include "ui/views/layout/grid_layout.h"
29
30 namespace {
31
32 const int kIconBorder = 4;
33 const int kImageWidth = 40;
34 const int kImageHeight = 25;
35 const int kWebNotificationBubbleMinHeight = 50;
36 const int kWebNotificationBubbleMaxHeight = 400;
37 const int kWebNotificationWidth = 400;
38 const int kWebNotificationButtonWidth = 32;
39
40 // The image has three icons: 1 notifiaction, 2 notifications, and 3+.
41 SkBitmap GetNotificationImage(int notification_count) {
42 SkBitmap image;
43 gfx::Image all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
44 IDR_AURA_UBER_TRAY_WEB_NOTIFICATON);
45
46 int image_index = notification_count - 1;
47 image_index = std::max(0, std::min(image_index, 2));
48
49 SkIRect region = SkIRect::MakeXYWH(
50 0, image_index * kImageHeight, kImageWidth, kImageHeight);
51 all.ToSkBitmap()->extractSubset(&image, region);
52 return image;
53 }
54
55 } // namespace
56
57 namespace ash {
58
59 namespace internal {
60
61 struct WebNotification {
62 WebNotification(const std::string& i,
63 const string16& t,
64 const string16& m,
65 const string16& s,
66 const std::string& e) :
sadrul 2012/06/06 19:19:19 the ':' should be in the next line
stevenjb 2012/06/06 23:12:15 Done.
67 id(i),
68 title(t),
69 message(m),
70 display_source(s),
71 extension_id(e) {
72 }
73 std::string id;
sadrul 2012/06/06 19:19:19 newline between 72/73
stevenjb 2012/06/06 23:12:15 Done.
74 string16 title;
75 string16 message;
76 string16 display_source;
77 std::string extension_id;
78 SkBitmap image;
79 };
80
81 // A helper class to manage the list of notifications.
82 class WebNotificationList {
83 public:
84 typedef std::list<WebNotification> Notifications;
85
86 WebNotificationList() {
87 }
88
89 void AddNotification(const std::string& id,
90 const string16& title,
91 const string16& message,
92 const string16& source,
93 const std::string& extension) {
94 Notifications::iterator iter = GetNotification(id);
95 if (iter != notifications_.end()) {
96 iter->title = title;
97 iter->message = message;
98 iter->display_source = source;
99 iter->extension_id = extension;
100 } else {
101 notifications_.push_back(
102 WebNotification(id, title, message, source, extension));
103 }
104 }
105
106 bool RemoveNotification(const std::string& id) {
107 Notifications::iterator iter = GetNotification(id);
108 if (iter == notifications_.end())
109 return false;
110 notifications_.erase(iter);
111 return true;
112 }
113
114 void RemoveNotificationsBySource(const std::string& id) {
115 Notifications::iterator source_iter = GetNotification(id);
116 if (source_iter == notifications_.end())
117 return;
118 string16 display_source = source_iter->display_source;
119 for (Notifications::iterator loopiter = notifications_.begin();
120 loopiter != notifications_.end(); ) {
sadrul 2012/06/06 19:19:19 Can you just ++loopiter here instead of below? ..
stevenjb 2012/06/06 23:12:15 Correct.
121 Notifications::iterator curiter = loopiter++;
122 if (curiter->display_source == display_source)
123 notifications_.erase(curiter);
124 }
125 }
126
127 void RemoveNotificationsByExtension(const std::string& id) {
128 Notifications::iterator source_iter = GetNotification(id);
129 if (source_iter == notifications_.end())
130 return;
131 std::string extension_id = source_iter->extension_id;
132 for (Notifications::iterator loopiter = notifications_.begin();
133 loopiter != notifications_.end(); ) {
134 Notifications::iterator curiter = loopiter++;
135 if (curiter->extension_id == extension_id)
136 notifications_.erase(curiter);
137 }
138 }
139
140 bool SetNotificationImage(const std::string& id,
141 const SkBitmap& image) {
142 Notifications::iterator iter = GetNotification(id);
143 if (iter == notifications_.end())
144 return false;
145 iter->image = image;
146 return true;
147 }
148
149 const Notifications& notifications() const { return notifications_; }
150
151 private:
152 Notifications::iterator GetNotification(const std::string& id) {
153 for (Notifications::iterator iter = notifications_.begin();
154 iter != notifications_.end(); ++iter) {
155 if (iter->id == id)
156 return iter;
157 }
158 return notifications_.end();
159 }
160
161 Notifications notifications_;
162
163 DISALLOW_COPY_AND_ASSIGN(WebNotificationList);
164 };
165
166 // A simple view for the text (title and message) of a notification.
167 class WebNotificationMessageView : public views::View {
168 public:
169 explicit WebNotificationMessageView(const WebNotification& notification) {
170 views::Label* title = new views::Label(notification.title);
171 title->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
172 title->SetFont(title->font().DeriveFont(0, gfx::Font::BOLD));
173 views::Label* message = new views::Label(notification.message);
174 message->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
175 message->SetMultiLine(true);
176
177 SetLayoutManager(
178 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
179 AddChildView(title);
180 AddChildView(message);
181 }
182
183 virtual ~WebNotificationMessageView() {
184 }
185
186 private:
187 DISALLOW_COPY_AND_ASSIGN(WebNotificationMessageView);
188 };
189
190 const int kTogglePermissionCommand = 0;
191 const int kToggleExtensionCommand = 1;
192 const int kShowSettingsCommand = 2;
sadrul 2012/06/06 19:19:19 These could be in the anonymous namespace
stevenjb 2012/06/06 23:12:15 Done.
193
194 // A dropdown menu for notifications.
195 class WebNotificationMenuModel : public ui::SimpleMenuModel,
196 public ui::SimpleMenuModel::Delegate {
197 public:
198 explicit WebNotificationMenuModel(WebNotificationTray* tray,
199 const WebNotification& notification)
200 : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)),
201 tray_(tray),
202 notification_(notification) {
203 // Add 'disable notifications' menu item.
204 if (!notification.extension_id.empty()) {
205 AddItem(kToggleExtensionCommand,
206 GetLabelForCommandId(kToggleExtensionCommand));
207 } else if (!notification.display_source.empty()) {
208 AddItem(kTogglePermissionCommand,
209 GetLabelForCommandId(kTogglePermissionCommand));
210 }
211 // Add settings menu item.
212 if (!notification.display_source.empty()) {
213 AddItem(kShowSettingsCommand,
214 GetLabelForCommandId(kShowSettingsCommand));
215 }
216 }
217
218 virtual ~WebNotificationMenuModel() {
219 }
220
221 // Overridden from ui::SimpleMenuModel:
222 virtual string16 GetLabelForCommandId(int command_id) const OVERRIDE {
223 switch (command_id) {
224 case kToggleExtensionCommand:
225 return l10n_util::GetStringUTF16(
226 IDS_ASH_WEB_NOTFICATION_TRAY_EXTENSIONS_DISABLE);
227 case kTogglePermissionCommand:
228 return l10n_util::GetStringFUTF16(
229 IDS_ASH_WEB_NOTFICATION_TRAY_SITE_DISABLE,
230 notification_.display_source);
231 case kShowSettingsCommand:
232 return l10n_util::GetStringUTF16(
233 IDS_ASH_WEB_NOTFICATION_TRAY_SETTINGS);
234 default:
235 NOTREACHED();
236 }
237 return string16();
238 }
239
240 // Overridden from ui::SimpleMenuModel::Delegate:
241 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE {
242 return false;
243 }
244
245 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE {
246 return true;
247 }
248
249 virtual bool GetAcceleratorForCommandId(
250 int command_id,
251 ui::Accelerator* accelerator) OVERRIDE {
252 return false;
253 }
254
255 virtual void ExecuteCommand(int command_id) OVERRIDE {
256 switch (command_id) {
257 case kToggleExtensionCommand:
258 tray_->DisableByExtension(notification_.id);
259 break;
260 case kTogglePermissionCommand:
261 tray_->DisableByUrl(notification_.id);
262 break;
263 case kShowSettingsCommand:
264 tray_->ShowSettings(notification_.id);
265 break;
266 default:
267 NOTREACHED();
268 }
269 }
270
271 private:
272 WebNotificationTray* tray_;
273 WebNotification notification_;
274
275 DISALLOW_COPY_AND_ASSIGN(WebNotificationMenuModel);
276 };
277
278 // The view for a notification entry (icon + message + buttons).
279 class WebNotificationView : public views::View,
280 public views::ButtonListener,
281 public views::MenuButtonListener {
282 public:
283 WebNotificationView(WebNotificationTray* tray,
284 const WebNotification& notification)
285 : tray_(tray),
286 notification_(notification),
287 icon_(NULL),
288 menu_button_(NULL),
289 close_button_(NULL) {
290 InitView(tray, notification);
291 }
292
293 virtual ~WebNotificationView() {
294 }
295
296 void InitView(WebNotificationTray* tray,
297 const WebNotification& notification) {
298 set_border(views::Border::CreateSolidSidedBorder(
299 1, 0, 0, 0, kBorderLightColor));
300 set_background(views::Background::CreateSolidBackground(kBackgroundColor));
301
302 icon_ = new views::ImageView;
303 icon_->SetImage(notification.image);
304
305 WebNotificationMessageView* message_view
306 = new WebNotificationMessageView(notification);
307
308 close_button_ = new views::ImageButton(this);
309 close_button_->SetImage(
310 views::CustomButton::BS_NORMAL,
311 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
312 IDR_AURA_WINDOW_CLOSE));
313
314 menu_button_ = new views::MenuButton(NULL, string16(), this, true);
315 menu_button_->set_border(NULL);
316
317 views::GridLayout* layout = new views::GridLayout(this);
318 SetLayoutManager(layout);
319
320 views::ColumnSet* columns = layout->AddColumnSet(0);
321
322 columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2);
323
324 // Notification Icon.
325 columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
326 0, /* resize percent */
327 views::GridLayout::FIXED,
328 kNotificationIconWidth, kNotificationIconWidth);
329
330 columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2);
331
332 // Notification message text.
333 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
334 100, /* resize percent */
335 views::GridLayout::USE_PREF, 0, 0);
336
337 columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2);
338
339 // Close and menu buttons.
340 columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
341 0, /* resize percent */
342 views::GridLayout::FIXED,
343 kWebNotificationButtonWidth,
344 kWebNotificationButtonWidth);
345
346 columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2);
347
348 // Layout rows
349 layout->AddPaddingRow(0, kTrayPopupPaddingBetweenItems);
350
351 layout->StartRow(0, 0);
352 layout->AddView(icon_, 1, 2);
353 layout->AddView(message_view, 1, 2);
354 layout->AddView(close_button_);
355
356 layout->StartRow(0, 0);
357 layout->SkipColumns(4);
358 layout->AddView(menu_button_);
359
360 layout->AddPaddingRow(0, kTrayPopupPaddingBetweenItems);
361 }
362
363 // Overridden from ButtonListener.
364 virtual void ButtonPressed(views::Button* sender,
365 const views::Event& event) OVERRIDE {
366 if (sender == close_button_)
367 tray_->RemoveNotification(notification_.id);
368 }
369
370 // Overridden from MenuButtonListener.
371 virtual void OnMenuButtonClicked(View* source, const gfx::Point& point) {
372 if (source != menu_button_)
373 return;
374 WebNotificationMenuModel menu_model(tray_, notification_);
375 views::MenuModelAdapter menu_model_adapter(&menu_model);
376 views::MenuRunner menu_runner(menu_model_adapter.CreateMenu());
377
378 gfx::Point screen_location;
379 views::View::ConvertPointToScreen(menu_button_, &screen_location);
380 if (menu_runner.RunMenuAt(
381 source->GetWidget()->GetTopLevelWidget(),
382 menu_button_,
383 gfx::Rect(screen_location, menu_button_->size()),
384 views::MenuItemView::TOPRIGHT,
385 views::MenuRunner::HAS_MNEMONICS)
386 == views::MenuRunner::MENU_DELETED) {
sadrul 2012/06/06 19:19:19 == should be in the line above
stevenjb 2012/06/06 23:12:15 Used ignore_result instead.
387 return;
388 }
389 }
390
391
392 private:
393 WebNotificationTray* tray_;
394 WebNotification notification_;
395 views::ImageView* icon_;
396 views::MenuButton* menu_button_;
397 views::ImageButton* close_button_;
398
399 DISALLOW_COPY_AND_ASSIGN(WebNotificationView);
400 };
401
402 } // namespace internal
403
404 using internal::WebNotificationList;
405 using internal::WebNotificationView;
406
407 class WebNotificationTray::BubbleContentsView : public views::View {
408 public:
409 explicit BubbleContentsView(WebNotificationTray* tray)
410 : tray_(tray) {
411 SetLayoutManager(new views::FillLayout);
412 set_background(views::Background::CreateSolidBackground(kBackgroundColor));
413
414 scroll_content_ = new views::View;
415 scroll_content_->SetLayoutManager(
416 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
417 scroller_ = new internal::FixedSizedScrollView;
418 scroller_->SetContentsView(scroll_content_);
419
420 AddChildView(scroller_);
421 }
422
423 void Update(const WebNotificationList::Notifications& notifications) {
424 scroll_content_->RemoveAllChildViews(true);
425 for (WebNotificationList::Notifications::const_iterator iter =
426 notifications.begin(); iter != notifications.end(); ++iter) {
427 WebNotificationView* view = new WebNotificationView(tray_, *iter);
428 scroll_content_->AddChildView(view);
429 }
430 scroller_->Layout();
431 SizeToPreferredSize();
432 Layout();
433 PreferredSizeChanged();
434 SchedulePaint();
435 }
436
437 // views::View overrides.
438 virtual gfx::Size GetPreferredSize() {
439 gfx::Size preferred_size = scroll_content_->GetPreferredSize();
440 int height = std::min(
441 std::max(preferred_size.height(), kWebNotificationBubbleMinHeight),
442 kWebNotificationBubbleMaxHeight);
443 preferred_size.set_height(height);
444 return preferred_size;
445 }
446
447 private:
448 WebNotificationTray* tray_;
449 internal::FixedSizedScrollView* scroller_;
450 views::View* scroll_content_;
451
452 DISALLOW_COPY_AND_ASSIGN(BubbleContentsView);
453 };
454
455 class WebNotificationTray::Bubble
456 : public internal::SystemTrayBubbleView::Host {
457 public:
458 explicit Bubble(WebNotificationTray* tray) :
sadrul 2012/06/06 19:19:19 : should be in the next line
stevenjb 2012/06/06 23:12:15 Done.
459 tray_(tray),
460 bubble_view_(NULL),
461 bubble_widget_(NULL),
462 contents_view_(NULL) {
463 views::View* anchor = tray->tray_container();
464 views::BubbleBorder::ArrowLocation arrow_location;
465 int arrow_offset = 0;
466 if (tray_->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) {
467 arrow_location = views::BubbleBorder::BOTTOM_RIGHT;
468 arrow_offset = anchor->GetContentsBounds().width() / 2;
469 } else if (tray_->shelf_alignment() == SHELF_ALIGNMENT_LEFT) {
470 arrow_location = views::BubbleBorder::LEFT_BOTTOM;
471 } else {
472 arrow_location = views::BubbleBorder::RIGHT_BOTTOM;
473 }
474 bubble_view_ = new internal::SystemTrayBubbleView(
475 anchor, arrow_location, this, false);
476 bubble_view_->SetMaxHeight(kWebNotificationBubbleMaxHeight);
477 bubble_view_->set_bubble_width(kWebNotificationWidth);
478
479 bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_);
480
481 bubble_view_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
482 bubble_widget_->non_client_view()->frame_view()->set_background(NULL);
483 bubble_view_->SetBubbleBorder(arrow_offset);
484
485 contents_view_ = new BubbleContentsView(tray);
486 bubble_view_->AddChildView(contents_view_);
487
488 Update();
489 bubble_view_->Show();
490
491 // Don't show any system notifications while we are viewing web
492 // notifications. As soon as the web notification tray looses focus,
493 // this will be destroyed and any hidden or suppressed system notifications
494 // will be displayed (see ~Bubble below).
495 ash::Shell::GetInstance()->system_tray()->SetHideNotifications(true);
496 }
497
498 ~Bubble() {
sadrul 2012/06/06 19:19:19 virtual?
stevenjb 2012/06/06 23:12:15 Oops! Done.
499 if (bubble_view_)
500 bubble_view_->reset_host();
501 if (bubble_widget_)
502 bubble_widget_->Close();
503
504 // Show any hidden or suppressed system notifications.
505 ash::Shell::GetInstance()->system_tray()->SetHideNotifications(false);
506 }
507
508 // Overridden from SystemTrayBubbleView::Host.
509 virtual void BubbleViewDestroyed() OVERRIDE {
510 }
511
512 virtual gfx::Rect GetAnchorRect() const OVERRIDE {
513 gfx::Rect anchor_rect = tray_->tray_container()->GetScreenBounds();
514 return anchor_rect;
515 }
516
517 virtual void OnMouseEnteredView() OVERRIDE {
518 }
519
520 virtual void OnMoiseExitedView() OVERRIDE {
521 }
522
523 void Update() {
524 contents_view_->Update(tray_->notification_list()->notifications());
525 bubble_view_->Layout();
526 bubble_view_->SchedulePaint();
527 }
528
529 views::Widget* bubble_widget() const { return bubble_widget_; }
530
531 private:
532 WebNotificationTray* tray_;
533 internal::SystemTrayBubbleView* bubble_view_;
534 views::Widget* bubble_widget_;
535 BubbleContentsView* contents_view_;
536 };
537
538 WebNotificationTray::WebNotificationTray()
539 : notification_list_(new WebNotificationList()),
540 tray_container_(NULL),
541 icon_(NULL),
542 delegate_(NULL) {
543 tray_container_ = new views::View;
544 tray_container_->set_border(views::Border::CreateEmptyBorder(
545 kIconBorder, kIconBorder, kIconBorder, kIconBorder));
546 SetShelfAlignment(shelf_alignment());
547
548 icon_ = new views::ImageView;
549 tray_container_->AddChildView(icon_);
550 UpdateIcon(); // Hides the tray initially.
551
552 SetContents(tray_container_);
553
554 Shell::GetInstance()->AddEnvEventFilter(this);
555 }
556
557 WebNotificationTray::~WebNotificationTray() {
558 Shell::GetInstance()->RemoveEnvEventFilter(this);
559 }
560
561 bool WebNotificationTray::PreHandleKeyEvent(aura::Window* target,
562 aura::KeyEvent* event) {
563 return false;
564 }
565
566 bool WebNotificationTray::PreHandleMouseEvent(aura::Window* target,
567 aura::MouseEvent* event) {
568 if (event->type() == ui::ET_MOUSE_PRESSED)
569 ProcessLocatedEvent(*event);
570 return false;
571 }
572
573 ui::TouchStatus WebNotificationTray::PreHandleTouchEvent(aura::Window* target,
574 aura::TouchEvent* event) {
575 if (event->type() == ui::ET_TOUCH_PRESSED)
576 ProcessLocatedEvent(*event);
577 return ui::TOUCH_STATUS_UNKNOWN;
578 }
579
580 ui::GestureStatus WebNotificationTray::PreHandleGestureEvent(
581 aura::Window* target,
582 aura::GestureEvent* event) {
583 return ui::GESTURE_STATUS_UNKNOWN;
584 }
585
586 void WebNotificationTray::SetShelfAlignment(ShelfAlignment alignment) {
587 internal::TrayBackgroundView::SetShelfAlignment(alignment);
588 tray_container_->SetLayoutManager(new views::BoxLayout(
589 alignment == SHELF_ALIGNMENT_BOTTOM ?
590 views::BoxLayout::kHorizontal : views::BoxLayout::kVertical,
591 0, 0, 0));
592 }
593
594 bool WebNotificationTray::PerformAction(const views::Event& event) {
595 if (bubble())
596 bubble_.reset();
597 else
598 bubble_.reset(new Bubble(this));
599 return true;
600 }
601
602 void WebNotificationTray::SetDelegate(Delegate* delegate) {
603 DCHECK(!delegate_);
604 delegate_ = delegate;
605 }
606
607 void WebNotificationTray::AddNotification(const std::string& id,
608 const string16& title,
609 const string16& message,
610 const string16& source,
611 const std::string& extension) {
612 notification_list_->AddNotification(id, title, message, source, extension);
613 UpdateIcon();
614 if (bubble()) {
615 bubble_->Update();
616 } else {
617 // Only show the web notification bubble if the system tray is not shown.
618 if (!ash::Shell::GetInstance()->system_tray()->IsBubbleVisible())
619 bubble_.reset(new Bubble(this));
sadrul 2012/06/06 19:19:19 This seems unfortunate. It would be nice to say 's
stevenjb 2012/06/06 23:12:15 I can put this in the status area. I was going to
620 }
621 }
622
623 void WebNotificationTray::RemoveNotification(const std::string& id) {
624 if (!notification_list_->RemoveNotification(id))
625 return;
626 if (delegate_)
627 delegate_->NotificationRemoved(id);
628 UpdateBubbleAndIcon();
629 }
630
631 void WebNotificationTray::SetNotificationImage(const std::string& id,
632 const SkBitmap& image) {
633 if (notification_list_->SetNotificationImage(id, image)) {
634 if (bubble())
sadrul 2012/06/06 19:19:19 if (notification_list_ ... && bubble()) bubble_-
stevenjb 2012/06/06 23:12:15 I personally dislike combining functions that do s
635 bubble_->Update();
636 }
637 }
638
639 void WebNotificationTray::DisableByExtension(const std::string& id) {
640 notification_list_->RemoveNotificationsByExtension(id);
641 UpdateBubbleAndIcon();
642 if (delegate_)
643 delegate_->DisableExtension(id);
644 }
645
646 void WebNotificationTray::DisableByUrl(const std::string& id) {
647 notification_list_->RemoveNotificationsBySource(id);
648 UpdateBubbleAndIcon();
649 if (delegate_)
650 delegate_->DisableNotificationsFromSource(id);
651 }
652
653 void WebNotificationTray::ShowSettings(const std::string& id) {
654 if (delegate_)
655 delegate_->ShowSettings(id);
656 }
657
658 int WebNotificationTray::GetNotificationCount() const {
659 return notification_list()->notifications().size();
660 }
661
662 void WebNotificationTray::UpdateIcon() {
663 int count = GetNotificationCount();
664 if (count == 0) {
665 SetVisible(false);
666 } else {
667 icon_->SetImage(GetNotificationImage(count));
668 SetVisible(true);
669 }
670 PreferredSizeChanged();
671 }
672
673 void WebNotificationTray::UpdateBubbleAndIcon() {
674 UpdateIcon();
675 if (bubble()) {
676 if (GetNotificationCount() == 0)
677 bubble_.reset();
678 else
679 bubble_->Update();
680 }
681 }
682
683 void WebNotificationTray::ProcessLocatedEvent(const aura::LocatedEvent& event) {
684 if (!bubble())
685 return;
686 gfx::Rect bounds =
687 bubble_->bubble_widget()->GetNativeWindow()->GetBoundsInRootWindow();
688 if (!bounds.Contains(event.root_location()))
689 bubble_.reset();
690 }
691
692 } // namespace ash
OLDNEW
« no previous file with comments | « ash/system/web_notification/web_notification_tray.h ('k') | ash/system/web_notification/web_notification_tray_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698