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

Side by Side Diff: ash/system/tray/system_tray.cc

Issue 10235010: Prepare SystemTray to support notifications (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 8 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
« no previous file with comments | « ash/system/tray/system_tray.h ('k') | ash/system/tray/system_tray_item.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "ash/system/tray/system_tray.h" 5 #include "ash/system/tray/system_tray.h"
6 6
7 #include "ash/shell.h" 7 #include "ash/shell.h"
8 #include "ash/shell/panel_window.h" 8 #include "ash/shell/panel_window.h"
9 #include "ash/shell_window_ids.h" 9 #include "ash/shell_window_ids.h"
10 #include "ash/system/audio/tray_volume.h" 10 #include "ash/system/audio/tray_volume.h"
(...skipping 15 matching lines...) Expand all
26 #include "ash/system/tray_caps_lock.h" 26 #include "ash/system/tray_caps_lock.h"
27 #include "ash/system/tray_update.h" 27 #include "ash/system/tray_update.h"
28 #include "ash/system/user/tray_user.h" 28 #include "ash/system/user/tray_user.h"
29 #include "ash/system/user/login_status.h" 29 #include "ash/system/user/login_status.h"
30 #include "ash/wm/shadow_types.h" 30 #include "ash/wm/shadow_types.h"
31 #include "ash/wm/shelf_layout_manager.h" 31 #include "ash/wm/shelf_layout_manager.h"
32 #include "ash/wm/window_animations.h" 32 #include "ash/wm/window_animations.h"
33 #include "base/i18n/rtl.h" 33 #include "base/i18n/rtl.h"
34 #include "base/logging.h" 34 #include "base/logging.h"
35 #include "base/message_loop.h" 35 #include "base/message_loop.h"
36 #include "base/message_pump_observer.h"
36 #include "base/timer.h" 37 #include "base/timer.h"
37 #include "base/utf_string_conversions.h" 38 #include "base/utf_string_conversions.h"
38 #include "grit/ash_strings.h" 39 #include "grit/ash_strings.h"
39 #include "third_party/skia/include/core/SkCanvas.h" 40 #include "third_party/skia/include/core/SkCanvas.h"
40 #include "third_party/skia/include/core/SkColor.h" 41 #include "third_party/skia/include/core/SkColor.h"
41 #include "third_party/skia/include/core/SkPaint.h" 42 #include "third_party/skia/include/core/SkPaint.h"
42 #include "third_party/skia/include/core/SkPath.h" 43 #include "third_party/skia/include/core/SkPath.h"
43 #include "ui/aura/root_window.h" 44 #include "ui/aura/root_window.h"
44 #include "ui/base/events.h" 45 #include "ui/base/events.h"
45 #include "ui/base/accessibility/accessible_view_state.h" 46 #include "ui/base/accessibility/accessible_view_state.h"
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 SkScalar radius = SkIntToScalar(kTrayRoundedBorderRadius); 247 SkScalar radius = SkIntToScalar(kTrayRoundedBorderRadius);
247 path.addRoundRect(gfx::RectToSkRect(bounds), radius, radius); 248 path.addRoundRect(gfx::RectToSkRect(bounds), radius, radius);
248 canvas->DrawPath(path, paint); 249 canvas->DrawPath(path, paint);
249 } 250 }
250 251
251 int alpha_; 252 int alpha_;
252 253
253 DISALLOW_COPY_AND_ASSIGN(SystemTrayBackground); 254 DISALLOW_COPY_AND_ASSIGN(SystemTrayBackground);
254 }; 255 };
255 256
256 class SystemTrayBubble : public views::BubbleDelegateView { 257 class SystemTrayBubble;
258
259 class SystemTrayBubbleView : public views::BubbleDelegateView {
260 public:
261 SystemTrayBubbleView(views::View* anchor,
262 SystemTrayBubble* host,
263 bool can_activate);
264 virtual ~SystemTrayBubbleView();
265
266 // Called when the host is destroyed.
267 void reset_host() { host_ = NULL; }
268
269 private:
270 // Overridden from views::BubbleDelegateView.
271 virtual void Init() OVERRIDE;
272 virtual gfx::Rect GetAnchorRect() OVERRIDE;
273 // Overridden from views::View.
274 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
275 virtual bool CanActivate() const OVERRIDE;
276 virtual gfx::Size GetPreferredSize() OVERRIDE;
277 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE;
278 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE;
279
280 SystemTrayBubble* host_;
281 bool can_activate_;
282
283 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleView);
284 };
285
286 class SystemTrayBubble : public base::MessagePumpObserver,
287 public views::Widget::Observer {
257 public: 288 public:
258 SystemTrayBubble(ash::SystemTray* tray, 289 SystemTrayBubble(ash::SystemTray* tray,
259 views::View* anchor,
260 std::vector<ash::SystemTrayItem*>& items, 290 std::vector<ash::SystemTrayItem*>& items,
261 bool detailed) 291 bool detailed);
262 : views::BubbleDelegateView(anchor, views::BubbleBorder::BOTTOM_RIGHT), 292 virtual ~SystemTrayBubble();
263 tray_(tray),
264 items_(items),
265 detailed_(detailed),
266 can_activate_(true),
267 autoclose_delay_(0) {
268 set_margin(0);
269 set_parent_window(ash::Shell::GetInstance()->GetContainer(
270 ash::internal::kShellWindowId_SettingBubbleContainer));
271 set_notify_enter_exit_on_child(true);
272 }
273 293
274 virtual ~SystemTrayBubble() { 294 // Creates |bubble_view_| and a child views for each member of |items_|.
275 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin(); 295 // Also creates |bubble_widget_| and sets up animations.
276 it != items_.end(); 296 void InitView(views::View* anchor,
277 ++it) { 297 bool can_activate,
278 if (detailed_) 298 ash::user::LoginStatus login_status);
279 (*it)->DestroyDetailedView();
280 else
281 (*it)->DestroyDefaultView();
282 }
283 }
284 299
285 bool detailed() const { return detailed_; } 300 bool detailed() const { return detailed_; }
286 void set_can_activate(bool activate) { can_activate_ = activate; } 301 SystemTrayBubbleView* bubble_view() const { return bubble_view_; }
287 302
288 void StartAutoCloseTimer(int seconds) { 303 void DestroyItemViews();
289 autoclose_.Stop(); 304 views::Widget* GetTrayWidget() const;
290 autoclose_delay_ = seconds; 305 void StartAutoCloseTimer(int seconds);
291 if (autoclose_delay_) { 306 void StopAutoCloseTimer();
292 autoclose_.Start(FROM_HERE, 307 void RestartAutoCloseTimer();
293 base::TimeDelta::FromSeconds(autoclose_delay_), 308 void Hide();
294 this, &SystemTrayBubble::AutoClose); 309 void Show();
295 } 310 bool IsVisible() const;
296 }
297 311
298 private: 312 private:
299 void AutoClose() { 313 // Overridden from base::MessagePumpObserver.
300 GetWidget()->Close(); 314 virtual base::EventStatus WillProcessEvent(
301 } 315 const base::NativeEvent& event) OVERRIDE;
316 virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
317 // Overridden from views::Widget::Observer.
318 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
319 virtual void OnWidgetVisibilityChanged(views::Widget* widget,
320 bool visible) OVERRIDE;
302 321
303 // Overridden from views::BubbleDelegateView. 322 void AutoClose();
304 virtual void Init() OVERRIDE {
305 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
306 1, 1, 1));
307 set_background(new SystemTrayBubbleBackground(this));
308 323
309 ash::SystemTrayDelegate* delegate = 324 ash::SystemTray* tray_;
310 ash::Shell::GetInstance()->tray_delegate(); 325 SystemTrayBubbleView* bubble_view_;
311 ash::user::LoginStatus login_status = delegate->GetUserLoginStatus(); 326 views::Widget* bubble_widget_;
312 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin(); 327 std::vector<ash::SystemTrayItem*> items_;
313 it != items_.end(); 328 bool detailed_;
314 ++it) {
315 views::View* view = detailed_ ? (*it)->CreateDetailedView(login_status) :
316 (*it)->CreateDefaultView(login_status);
317 if (view)
318 AddChildView(new TrayPopupItemContainer(view));
319 }
320 }
321 329
322 virtual gfx::Rect GetAnchorRect() OVERRIDE { 330 int autoclose_delay_;
323 views::Widget* widget = tray_->GetWidget(); 331 base::OneShotTimer<SystemTrayBubble> autoclose_;
332
333 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubble);
334 };
335
336 // SystemTrayBubbleView
337
338 SystemTrayBubbleView::SystemTrayBubbleView(views::View* anchor,
339 SystemTrayBubble* host,
340 bool can_activate)
341 : views::BubbleDelegateView(anchor, views::BubbleBorder::BOTTOM_RIGHT),
342 host_(host),
343 can_activate_(can_activate) {
344 set_margin(0);
345 set_parent_window(ash::Shell::GetInstance()->GetContainer(
346 ash::internal::kShellWindowId_SettingBubbleContainer));
347 set_notify_enter_exit_on_child(true);
348 }
349
350 SystemTrayBubbleView::~SystemTrayBubbleView() {
351 // Inform host items (models) that their views are being destroyed.
352 if (host_)
353 host_->DestroyItemViews();
354 }
355
356 void SystemTrayBubbleView::Init() {
357 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 1, 1, 1));
358 set_background(new SystemTrayBubbleBackground(this));
359 }
360
361 gfx::Rect SystemTrayBubbleView::GetAnchorRect() OVERRIDE {
362 if (host_) {
363 views::Widget* widget = host_->GetTrayWidget();
324 if (widget->IsVisible()) { 364 if (widget->IsVisible()) {
325 gfx::Rect rect = widget->GetWindowScreenBounds(); 365 gfx::Rect rect = widget->GetWindowScreenBounds();
326 rect.Inset( 366 rect.Inset(
327 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 0, 0, 367 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 0, 0,
328 base::i18n::IsRTL() ? 0 : kPaddingFromRightEdgeOfScreen, 368 base::i18n::IsRTL() ? 0 : kPaddingFromRightEdgeOfScreen,
329 kPaddingFromBottomOfScreen); 369 kPaddingFromBottomOfScreen);
330 return rect; 370 return rect;
331 } 371 }
332 gfx::Rect rect = gfx::Screen::GetPrimaryMonitor().bounds(); 372 }
333 return gfx::Rect(base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 373 gfx::Rect rect = gfx::Screen::GetPrimaryMonitor().bounds();
334 rect.width() - kPaddingFromRightEdgeOfScreen, 374 return gfx::Rect(base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen :
335 rect.height() - kPaddingFromBottomOfScreen, 375 rect.width() - kPaddingFromRightEdgeOfScreen,
336 0, 0); 376 rect.height() - kPaddingFromBottomOfScreen,
377 0, 0);
378 }
379
380 void SystemTrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) {
381 if (can_activate_) {
382 state->role = ui::AccessibilityTypes::ROLE_WINDOW;
383 state->name = l10n_util::GetStringUTF16(
384 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
385 }
386 }
387
388 bool SystemTrayBubbleView::CanActivate() const {
389 return can_activate_;
390 }
391
392 gfx::Size SystemTrayBubbleView::GetPreferredSize() {
393 gfx::Size size = views::BubbleDelegateView::GetPreferredSize();
394 return gfx::Size(kTrayPopupWidth, size.height());
395 }
396
397 void SystemTrayBubbleView::OnMouseEntered(const views::MouseEvent& event) {
398 if (host_)
399 host_->StopAutoCloseTimer();
400 }
401
402 void SystemTrayBubbleView::OnMouseExited(const views::MouseEvent& event) {
403 if (host_)
404 host_->RestartAutoCloseTimer();
405 }
406
407 // SystemTrayBubble
408
409 SystemTrayBubble::SystemTrayBubble(ash::SystemTray* tray,
410 std::vector<ash::SystemTrayItem*>& items,
411 bool detailed)
412 : tray_(tray),
413 bubble_view_(NULL),
414 bubble_widget_(NULL),
415 items_(items),
416 detailed_(detailed),
417 autoclose_delay_(0) {
418 MessageLoopForUI::current()->AddObserver(this);
419 }
420
421 SystemTrayBubble::~SystemTrayBubble() {
422 MessageLoopForUI::current()->RemoveObserver(this);
423 DestroyItemViews();
424 // Reset the host pointer in bubble_view_ in case its destruction is deferred.
425 if (bubble_view_)
426 bubble_view_->reset_host();
427 if (bubble_widget_) {
428 bubble_widget_->RemoveObserver(this);
429 // This triggers the destruction of bubble_view_.
430 bubble_widget_->Close();
431 }
432 }
433
434 void SystemTrayBubble::InitView(views::View* anchor,
435 bool can_activate,
436 ash::user::LoginStatus login_status) {
437 DCHECK(bubble_view_ == NULL);
438 bubble_view_ = new SystemTrayBubbleView(anchor, this, can_activate);
439 // Don't close this on deactivation, just hide it.
440 bubble_view_->set_close_on_deactivate(false);
sadrul 2012/04/30 17:46:19 Is there a reason for this change?
stevenjb 2012/04/30 19:09:54 Yes, as described, this makes the window hide on d
441
442 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
443 it != items_.end();
444 ++it) {
445 views::View* view = detailed_ ?
446 (*it)->CreateDetailedView(login_status) :
447 (*it)->CreateDefaultView(login_status);
448 if (view)
449 bubble_view_->AddChildView(new TrayPopupItemContainer(view));
337 } 450 }
338 451
339 // Overridden from views::View. 452 DCHECK(bubble_widget_ == NULL);
340 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE { 453 bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_);
341 if (can_activate_) { 454
342 state->role = ui::AccessibilityTypes::ROLE_WINDOW; 455 // Must occur after call to CreateBubble()
343 state->name = l10n_util::GetStringUTF16( 456 bubble_view_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
344 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); 457 bubble_widget_->non_client_view()->frame_view()->set_background(NULL);
458 bubble_widget_->non_client_view()->frame_view()->set_border(
459 new SystemTrayBubbleBorder(bubble_view_));
460
461 bubble_widget_->AddObserver(this);
462
463 // Setup animation.
464 ash::SetWindowVisibilityAnimationType(
465 bubble_widget_->GetNativeWindow(),
466 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
467 ash::SetWindowVisibilityAnimationTransition(
468 bubble_widget_->GetNativeWindow(),
469 ash::ANIMATE_BOTH);
470 ash::SetWindowVisibilityAnimationDuration(
471 bubble_widget_->GetNativeWindow(),
472 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
473
474 bubble_view_->Show();
475 }
476
477 void SystemTrayBubble::DestroyItemViews() {
478 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
479 it != items_.end();
480 ++it) {
481 if (detailed_)
482 (*it)->DestroyDetailedView();
483 else
484 (*it)->DestroyDefaultView();
485 }
486 }
487
488 views::Widget* SystemTrayBubble::GetTrayWidget() const {
489 return tray_->GetWidget();
490 }
491
492 void SystemTrayBubble::StartAutoCloseTimer(int seconds) {
493 autoclose_.Stop();
494 autoclose_delay_ = seconds;
495 if (autoclose_delay_) {
496 autoclose_.Start(FROM_HERE,
497 base::TimeDelta::FromSeconds(autoclose_delay_),
498 this, &SystemTrayBubble::AutoClose);
499 }
500 }
501
502 void SystemTrayBubble::StopAutoCloseTimer() {
503 autoclose_.Stop();
504 }
505
506 void SystemTrayBubble::RestartAutoCloseTimer() {
507 if (autoclose_delay_)
508 StartAutoCloseTimer(autoclose_delay_);
509 }
510
511 void SystemTrayBubble::Hide() {
512 if (bubble_widget_)
513 bubble_widget_->Hide();
514 }
515
516 void SystemTrayBubble::Show() {
517 DCHECK(bubble_widget_);
518 bubble_widget_->Show();
519 }
520
521 bool SystemTrayBubble::IsVisible() const {
522 return bubble_widget_ && bubble_widget_->IsVisible();
523 }
524
525 base::EventStatus SystemTrayBubble::WillProcessEvent(
526 const base::NativeEvent& event) {
527 // Check if the user clicked outside of the bubble and hide it if they did.
528 if (ui::EventTypeFromNative(event) == ui::ET_MOUSE_PRESSED) {
529 gfx::Point cursor_in_view = ui::EventLocationFromNative(event);
530 views::View::ConvertPointFromScreen(bubble_view_, &cursor_in_view);
531 if (!bubble_view_->HitTest(cursor_in_view)) {
532 bubble_widget_->Hide();
sadrul 2012/04/30 17:46:19 This should, in fact, close the bubble.
stevenjb 2012/04/30 19:09:54 Done. See above.
345 } 533 }
346 } 534 }
535 return base::EVENT_CONTINUE;
536 }
347 537
348 virtual bool CanActivate() const OVERRIDE { 538 void SystemTrayBubble::DidProcessEvent(const base::NativeEvent& event) {
349 return can_activate_; 539 }
350 }
351 540
352 virtual gfx::Size GetPreferredSize() OVERRIDE { 541 void SystemTrayBubble::OnWidgetClosing(views::Widget* widget) {
353 gfx::Size size = views::BubbleDelegateView::GetPreferredSize(); 542 CHECK_EQ(bubble_widget_, widget);
354 return gfx::Size(kTrayPopupWidth, size.height()); 543 MessageLoopForUI::current()->RemoveObserver(this);
355 } 544 bubble_widget_ = NULL;
545 tray_->RemoveBubble(this);
546 }
356 547
357 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE { 548 void SystemTrayBubble::OnWidgetVisibilityChanged(views::Widget* widget,
358 autoclose_.Stop(); 549 bool visible) {
359 } 550 if (!visible)
551 MessageLoopForUI::current()->RemoveObserver(this);
552 else
553 MessageLoopForUI::current()->AddObserver(this);
554 }
360 555
361 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE { 556 void SystemTrayBubble::AutoClose() {
362 if (autoclose_delay_) { 557 bubble_view_->GetWidget()->Close();
363 autoclose_.Stop(); 558 }
364 autoclose_.Start(FROM_HERE,
365 base::TimeDelta::FromSeconds(autoclose_delay_),
366 this, &SystemTrayBubble::AutoClose);
367 }
368 }
369
370 ash::SystemTray* tray_;
371 std::vector<ash::SystemTrayItem*> items_;
372 bool detailed_;
373 bool can_activate_;
374
375 int autoclose_delay_;
376 base::OneShotTimer<SystemTrayBubble> autoclose_;
377
378 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubble);
379 };
380 559
381 } // namespace internal 560 } // namespace internal
382 561
562 // From system_tray_delegate.h
563
383 NetworkIconInfo::NetworkIconInfo() 564 NetworkIconInfo::NetworkIconInfo()
384 : highlight(false), 565 : highlight(false),
385 tray_icon_visible(true) { 566 tray_icon_visible(true) {
386 } 567 }
387 568
388 NetworkIconInfo::~NetworkIconInfo() { 569 NetworkIconInfo::~NetworkIconInfo() {
389 } 570 }
390 571
391 BluetoothDeviceInfo::BluetoothDeviceInfo() 572 BluetoothDeviceInfo::BluetoothDeviceInfo()
392 : connected(false) { 573 : connected(false) {
393 } 574 }
394 575
395 BluetoothDeviceInfo::~BluetoothDeviceInfo() { 576 BluetoothDeviceInfo::~BluetoothDeviceInfo() {
396 } 577 }
397 578
398 IMEInfo::IMEInfo() 579 IMEInfo::IMEInfo()
399 : selected(false) { 580 : selected(false) {
400 } 581 }
401 582
402 IMEInfo::~IMEInfo() { 583 IMEInfo::~IMEInfo() {
403 } 584 }
404 585
405 IMEPropertyInfo::IMEPropertyInfo() 586 IMEPropertyInfo::IMEPropertyInfo()
406 : selected(false) { 587 : selected(false) {
407 } 588 }
408 589
409 IMEPropertyInfo::~IMEPropertyInfo() { 590 IMEPropertyInfo::~IMEPropertyInfo() {
410 } 591 }
411 592
593 // SystemTray
594
412 SystemTray::SystemTray() 595 SystemTray::SystemTray()
413 : items_(), 596 : items_(),
414 accessibility_observer_(NULL), 597 accessibility_observer_(NULL),
415 audio_observer_(NULL), 598 audio_observer_(NULL),
416 bluetooth_observer_(NULL), 599 bluetooth_observer_(NULL),
417 brightness_observer_(NULL), 600 brightness_observer_(NULL),
418 caps_lock_observer_(NULL), 601 caps_lock_observer_(NULL),
419 clock_observer_(NULL), 602 clock_observer_(NULL),
420 ime_observer_(NULL), 603 ime_observer_(NULL),
421 network_observer_(NULL), 604 network_observer_(NULL),
422 power_status_observer_(NULL), 605 power_status_observer_(NULL),
423 update_observer_(NULL), 606 update_observer_(NULL),
424 user_observer_(NULL), 607 user_observer_(NULL),
425 widget_(NULL), 608 widget_(NULL),
426 bubble_(NULL), 609 bubble_(NULL),
427 popup_(NULL),
428 background_(new internal::SystemTrayBackground), 610 background_(new internal::SystemTrayBackground),
429 should_show_launcher_(false), 611 should_show_launcher_(false),
430 ALLOW_THIS_IN_INITIALIZER_LIST(hide_background_animator_(this, 612 ALLOW_THIS_IN_INITIALIZER_LIST(hide_background_animator_(this,
431 0, kTrayBackgroundAlpha)), 613 0, kTrayBackgroundAlpha)),
432 ALLOW_THIS_IN_INITIALIZER_LIST(hover_background_animator_(this, 614 ALLOW_THIS_IN_INITIALIZER_LIST(hover_background_animator_(this,
433 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha)) { 615 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha)) {
434 container_ = new views::View; 616 container_ = new views::View;
435 container_->SetLayoutManager(new views::BoxLayout( 617 container_->SetLayoutManager(new views::BoxLayout(
436 views::BoxLayout::kHorizontal, 0, 0, 0)); 618 views::BoxLayout::kHorizontal, 0, 0, 0));
437 container_->set_background(background_); 619 container_->set_background(background_);
438 container_->set_border( 620 container_->set_border(
439 views::Border::CreateEmptyBorder(1, 1, 1, 1)); 621 views::Border::CreateEmptyBorder(1, 1, 1, 1));
440 set_border(views::Border::CreateEmptyBorder(0, 0, 622 set_border(views::Border::CreateEmptyBorder(0, 0,
441 kPaddingFromBottomOfScreen, kPaddingFromRightEdgeOfScreen)); 623 kPaddingFromBottomOfScreen, kPaddingFromRightEdgeOfScreen));
442 set_notify_enter_exit_on_child(true); 624 set_notify_enter_exit_on_child(true);
443 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); 625 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
444 AddChildView(container_); 626 AddChildView(container_);
445 627
446 // Initially we want to paint the background, but without the hover effect. 628 // Initially we want to paint the background, but without the hover effect.
447 SetPaintsBackground(true, internal::BackgroundAnimator::CHANGE_IMMEDIATE); 629 SetPaintsBackground(true, internal::BackgroundAnimator::CHANGE_IMMEDIATE);
448 hover_background_animator_.SetPaintsBackground(false, 630 hover_background_animator_.SetPaintsBackground(false,
449 internal::BackgroundAnimator::CHANGE_IMMEDIATE); 631 internal::BackgroundAnimator::CHANGE_IMMEDIATE);
450 } 632 }
451 633
452 SystemTray::~SystemTray() { 634 SystemTray::~SystemTray() {
635 delete bubble_;
453 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); 636 for (std::vector<SystemTrayItem*>::iterator it = items_.begin();
454 it != items_.end(); 637 it != items_.end();
455 ++it) { 638 ++it) {
456 (*it)->DestroyTrayView(); 639 (*it)->DestroyTrayView();
457 } 640 }
458 if (popup_)
459 popup_->CloseNow();
460 } 641 }
461 642
462 void SystemTray::CreateItems() { 643 void SystemTray::CreateItems() {
463 internal::TrayVolume* tray_volume = new internal::TrayVolume(); 644 internal::TrayVolume* tray_volume = new internal::TrayVolume();
464 internal::TrayBluetooth* tray_bluetooth = new internal::TrayBluetooth(); 645 internal::TrayBluetooth* tray_bluetooth = new internal::TrayBluetooth();
465 internal::TrayBrightness* tray_brightness = new internal::TrayBrightness(); 646 internal::TrayBrightness* tray_brightness = new internal::TrayBrightness();
466 internal::TrayDate* tray_date = new internal::TrayDate(); 647 internal::TrayDate* tray_date = new internal::TrayDate();
467 internal::TrayPower* tray_power = new internal::TrayPower(); 648 internal::TrayPower* tray_power = new internal::TrayPower();
468 internal::TrayNetwork* tray_network = new internal::TrayNetwork; 649 internal::TrayNetwork* tray_network = new internal::TrayNetwork;
469 internal::TrayUser* tray_user = new internal::TrayUser; 650 internal::TrayUser* tray_user = new internal::TrayUser;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 container_->AddChildViewAt(tray_item, 0); 713 container_->AddChildViewAt(tray_item, 0);
533 PreferredSizeChanged(); 714 PreferredSizeChanged();
534 } 715 }
535 } 716 }
536 717
537 void SystemTray::RemoveTrayItem(SystemTrayItem* item) { 718 void SystemTray::RemoveTrayItem(SystemTrayItem* item) {
538 NOTIMPLEMENTED(); 719 NOTIMPLEMENTED();
539 } 720 }
540 721
541 void SystemTray::ShowDefaultView() { 722 void SystemTray::ShowDefaultView() {
542 if (popup_) { 723 if (bubble_ && !bubble_->detailed()) {
543 MessageLoopForUI::current()->RemoveObserver(this); 724 bubble_->Show();
544 popup_->RemoveObserver(this); 725 return;
545 popup_->Close();
546 } 726 }
547 popup_ = NULL; 727 delete bubble_;
548 bubble_ = NULL; 728 bubble_ = NULL;
549
550 ShowItems(items_.get(), false, true); 729 ShowItems(items_.get(), false, true);
551 } 730 }
552 731
553 void SystemTray::ShowDetailedView(SystemTrayItem* item, 732 void SystemTray::ShowDetailedView(SystemTrayItem* item,
554 int close_delay, 733 int close_delay,
555 bool activate) { 734 bool activate) {
556 if (popup_) { 735 delete bubble_;
557 MessageLoopForUI::current()->RemoveObserver(this);
558 popup_->RemoveObserver(this);
559 popup_->Close();
560 }
561 popup_ = NULL;
562 bubble_ = NULL; 736 bubble_ = NULL;
563
564 std::vector<SystemTrayItem*> items; 737 std::vector<SystemTrayItem*> items;
565 items.push_back(item); 738 items.push_back(item);
566 ShowItems(items, true, activate); 739 ShowItems(items, true, activate);
567 bubble_->StartAutoCloseTimer(close_delay); 740 bubble_->StartAutoCloseTimer(close_delay);
568 } 741 }
569 742
570 void SystemTray::SetDetailedViewCloseDelay(int close_delay) { 743 void SystemTray::SetDetailedViewCloseDelay(int close_delay) {
571 if (bubble_ && bubble_->detailed()) 744 if (bubble_ && bubble_->detailed())
572 bubble_->StartAutoCloseTimer(close_delay); 745 bubble_->StartAutoCloseTimer(close_delay);
573 } 746 }
574 747
575 void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) { 748 void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) {
576 if (popup_) 749 delete bubble_;
577 popup_->CloseNow(); 750 bubble_ = NULL;
578 751
579 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); 752 for (std::vector<SystemTrayItem*>::iterator it = items_.begin();
580 it != items_.end(); 753 it != items_.end();
581 ++it) { 754 ++it) {
582 (*it)->UpdateAfterLoginStatusChange(login_status); 755 (*it)->UpdateAfterLoginStatusChange(login_status);
583 } 756 }
584 757
585 SetVisible(true); 758 SetVisible(true);
586 PreferredSizeChanged(); 759 PreferredSizeChanged();
587 } 760 }
588 761
762 void SystemTray::RemoveBubble(internal::SystemTrayBubble* bubble) {
763 CHECK_EQ(bubble_, bubble);
764 delete bubble_;
765 bubble_ = NULL;
766
767 if (should_show_launcher_) {
768 // No need to show the launcher if the mouse isn't over the status area
769 // anymore.
770 aura::RootWindow* root = GetWidget()->GetNativeView()->GetRootWindow();
771 should_show_launcher_ = GetWidget()->GetWindowScreenBounds().Contains(
772 root->last_mouse_location());
773 if (!should_show_launcher_)
774 Shell::GetInstance()->shelf()->UpdateAutoHideState();
775 }
776 }
777
589 void SystemTray::SetPaintsBackground( 778 void SystemTray::SetPaintsBackground(
590 bool value, 779 bool value,
591 internal::BackgroundAnimator::ChangeType change_type) { 780 internal::BackgroundAnimator::ChangeType change_type) {
592 hide_background_animator_.SetPaintsBackground(value, change_type); 781 hide_background_animator_.SetPaintsBackground(value, change_type);
593 } 782 }
594 783
595 void SystemTray::ShowItems(std::vector<SystemTrayItem*>& items, 784 void SystemTray::ShowItems(std::vector<SystemTrayItem*>& items,
596 bool detailed, 785 bool detailed,
597 bool activate) { 786 bool can_activate) {
598 CHECK(!popup_);
599 CHECK(!bubble_); 787 CHECK(!bubble_);
600 bubble_ = new internal::SystemTrayBubble(this, container_, items, detailed); 788 bubble_ = new internal::SystemTrayBubble(this, items, detailed);
601 bubble_->set_can_activate(activate); 789 ash::SystemTrayDelegate* delegate =
602 popup_ = views::BubbleDelegateView::CreateBubble(bubble_); 790 ash::Shell::GetInstance()->tray_delegate();
791 bubble_->InitView(container_, can_activate, delegate->GetUserLoginStatus());
603 // If we have focus the shelf should be visible and we need to continue 792 // If we have focus the shelf should be visible and we need to continue
604 // showing the shelf when the popup is shown. 793 // showing the shelf when the popup is shown.
605 if (GetWidget()->IsActive()) 794 if (GetWidget()->IsActive())
606 should_show_launcher_ = true; 795 should_show_launcher_ = true;
607 bubble_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
608 popup_->non_client_view()->frame_view()->set_background(NULL);
609 popup_->non_client_view()->frame_view()->set_border(
610 new SystemTrayBubbleBorder(bubble_));
611 MessageLoopForUI::current()->AddObserver(this);
612 popup_->AddObserver(this);
613
614 // Setup animation.
615 ash::SetWindowVisibilityAnimationType(popup_->GetNativeWindow(),
616 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
617 ash::SetWindowVisibilityAnimationTransition(popup_->GetNativeWindow(),
618 ash::ANIMATE_BOTH);
619 ash::SetWindowVisibilityAnimationDuration(popup_->GetNativeWindow(),
620 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
621
622 bubble_->Show();
623 } 796 }
624 797
625 bool SystemTray::PerformAction(const views::Event& event) { 798 bool SystemTray::PerformAction(const views::Event& event) {
626 // If we're already showing the default view, hide it; otherwise, show it 799 // If we're already showing the default view, hide it; otherwise, show it
627 // (and hide any popup that's currently shown). 800 // (and hide any popup that's currently shown).
628 if (popup_ && bubble_ && !bubble_->detailed()) 801 if (bubble_ && !bubble_->detailed() && bubble_->IsVisible())
629 popup_->Hide(); 802 bubble_->Hide();
630 else 803 else
631 ShowDefaultView(); 804 ShowDefaultView();
632 return true; 805 return true;
633 } 806 }
634 807
635 void SystemTray::OnMouseEntered(const views::MouseEvent& event) { 808 void SystemTray::OnMouseEntered(const views::MouseEvent& event) {
636 should_show_launcher_ = true; 809 should_show_launcher_ = true;
637 hover_background_animator_.SetPaintsBackground(true, 810 hover_background_animator_.SetPaintsBackground(true,
638 internal::BackgroundAnimator::CHANGE_ANIMATE); 811 internal::BackgroundAnimator::CHANGE_ANIMATE);
639 } 812 }
640 813
641 void SystemTray::OnMouseExited(const views::MouseEvent& event) { 814 void SystemTray::OnMouseExited(const views::MouseEvent& event) {
642 // When the popup closes we'll update |should_show_launcher_|. 815 // When the popup closes we'll update |should_show_launcher_|.
643 if (!popup_) 816 if (!bubble_)
644 should_show_launcher_ = false; 817 should_show_launcher_ = false;
645 hover_background_animator_.SetPaintsBackground(false, 818 hover_background_animator_.SetPaintsBackground(false,
646 internal::BackgroundAnimator::CHANGE_ANIMATE); 819 internal::BackgroundAnimator::CHANGE_ANIMATE);
647 } 820 }
648 821
649 void SystemTray::AboutToRequestFocusFromTabTraversal(bool reverse) { 822 void SystemTray::AboutToRequestFocusFromTabTraversal(bool reverse) {
650 views::View* v = GetNextFocusableView(); 823 views::View* v = GetNextFocusableView();
651 if (v) 824 if (v)
652 v->AboutToRequestFocusFromTabTraversal(reverse); 825 v->AboutToRequestFocusFromTabTraversal(reverse);
653 } 826 }
654 827
655 void SystemTray::GetAccessibleState(ui::AccessibleViewState* state) { 828 void SystemTray::GetAccessibleState(ui::AccessibleViewState* state) {
656 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; 829 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
657 state->name = l10n_util::GetStringUTF16( 830 state->name = l10n_util::GetStringUTF16(
658 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); 831 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
659 } 832 }
660 833
661 void SystemTray::OnPaintFocusBorder(gfx::Canvas* canvas) { 834 void SystemTray::OnPaintFocusBorder(gfx::Canvas* canvas) {
662 // The tray itself expands to the right and bottom edge of the screen to make 835 // The tray itself expands to the right and bottom edge of the screen to make
663 // sure clicking on the edges brings up the popup. However, the focus border 836 // sure clicking on the edges brings up the popup. However, the focus border
664 // should be only around the container. 837 // should be only around the container.
665 if (GetWidget() && GetWidget()->IsActive()) 838 if (GetWidget() && GetWidget()->IsActive())
666 canvas->DrawFocusRect(container_->bounds()); 839 canvas->DrawFocusRect(container_->bounds());
667 } 840 }
668 841
669 void SystemTray::OnWidgetClosing(views::Widget* widget) {
670 CHECK_EQ(popup_, widget);
671 MessageLoopForUI::current()->RemoveObserver(this);
672 popup_ = NULL;
673 bubble_ = NULL;
674 if (should_show_launcher_) {
675 // No need to show the launcher if the mouse isn't over the status area
676 // anymore.
677 aura::RootWindow* root = GetWidget()->GetNativeView()->GetRootWindow();
678 should_show_launcher_ = GetWidget()->GetWindowScreenBounds().Contains(
679 root->last_mouse_location());
680 if (!should_show_launcher_)
681 Shell::GetInstance()->shelf()->UpdateAutoHideState();
682 }
683 }
684
685 void SystemTray::OnWidgetVisibilityChanged(views::Widget* widget,
686 bool visible) {
687 if (!visible)
688 MessageLoopForUI::current()->RemoveObserver(this);
689 }
690
691 void SystemTray::UpdateBackground(int alpha) { 842 void SystemTray::UpdateBackground(int alpha) {
692 background_->set_alpha(hide_background_animator_.alpha() + 843 background_->set_alpha(hide_background_animator_.alpha() +
693 hover_background_animator_.alpha()); 844 hover_background_animator_.alpha());
694 SchedulePaint(); 845 SchedulePaint();
695 } 846 }
696 847
697 base::EventStatus SystemTray::WillProcessEvent(const base::NativeEvent& event) {
698 // Check if the user clicked outside of the system tray bubble and hide it
699 // if they did.
700 if (bubble_ && ui::EventTypeFromNative(event) == ui::ET_MOUSE_PRESSED) {
701 gfx::Point cursor_in_view = ui::EventLocationFromNative(event);
702 View::ConvertPointFromScreen(bubble_, &cursor_in_view);
703 if (!bubble_->HitTest(cursor_in_view)) {
704 popup_->Hide();
705 }
706 }
707 return base::EVENT_CONTINUE;
708 }
709
710 void SystemTray::DidProcessEvent(const base::NativeEvent& event) {
711 }
712
713 } // namespace ash 848 } // namespace ash
OLDNEW
« no previous file with comments | « ash/system/tray/system_tray.h ('k') | ash/system/tray/system_tray_item.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698