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

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: Close instead of hide. Created 8 years, 7 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
« ash/system/tray/system_tray.h ('K') | « ash/system/tray/system_tray.h ('k') | no next file » | 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 Close();
294 this, &SystemTrayBubble::AutoClose);
295 }
296 }
297 309
298 private: 310 private:
299 void AutoClose() { 311 // Overridden from base::MessagePumpObserver.
300 GetWidget()->Close(); 312 virtual base::EventStatus WillProcessEvent(
301 } 313 const base::NativeEvent& event) OVERRIDE;
314 virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
315 // Overridden from views::Widget::Observer.
316 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
317 virtual void OnWidgetVisibilityChanged(views::Widget* widget,
318 bool visible) OVERRIDE;
302 319
303 // Overridden from views::BubbleDelegateView. 320 ash::SystemTray* tray_;
304 virtual void Init() OVERRIDE { 321 SystemTrayBubbleView* bubble_view_;
305 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 322 views::Widget* bubble_widget_;
306 1, 1, 1)); 323 std::vector<ash::SystemTrayItem*> items_;
307 set_background(new SystemTrayBubbleBackground(this)); 324 bool detailed_;
308 325
309 ash::SystemTrayDelegate* delegate = 326 int autoclose_delay_;
310 ash::Shell::GetInstance()->tray_delegate(); 327 base::OneShotTimer<SystemTrayBubble> autoclose_;
311 ash::user::LoginStatus login_status = delegate->GetUserLoginStatus();
312 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
313 it != items_.end();
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 328
322 virtual gfx::Rect GetAnchorRect() OVERRIDE { 329 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubble);
323 views::Widget* widget = tray_->GetWidget(); 330 };
331
332 // SystemTrayBubbleView
333
334 SystemTrayBubbleView::SystemTrayBubbleView(views::View* anchor,
335 SystemTrayBubble* host,
336 bool can_activate)
337 : views::BubbleDelegateView(anchor, views::BubbleBorder::BOTTOM_RIGHT),
338 host_(host),
339 can_activate_(can_activate) {
340 set_margin(0);
341 set_parent_window(ash::Shell::GetInstance()->GetContainer(
342 ash::internal::kShellWindowId_SettingBubbleContainer));
343 set_notify_enter_exit_on_child(true);
344 }
345
346 SystemTrayBubbleView::~SystemTrayBubbleView() {
347 // Inform host items (models) that their views are being destroyed.
348 if (host_)
349 host_->DestroyItemViews();
350 }
351
352 void SystemTrayBubbleView::Init() {
353 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 1, 1, 1));
354 set_background(new SystemTrayBubbleBackground(this));
355 }
356
357 gfx::Rect SystemTrayBubbleView::GetAnchorRect() OVERRIDE {
358 if (host_) {
359 views::Widget* widget = host_->GetTrayWidget();
324 if (widget->IsVisible()) { 360 if (widget->IsVisible()) {
325 gfx::Rect rect = widget->GetWindowScreenBounds(); 361 gfx::Rect rect = widget->GetWindowScreenBounds();
326 rect.Inset( 362 rect.Inset(
327 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 0, 0, 363 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 0, 0,
328 base::i18n::IsRTL() ? 0 : kPaddingFromRightEdgeOfScreen, 364 base::i18n::IsRTL() ? 0 : kPaddingFromRightEdgeOfScreen,
329 kPaddingFromBottomOfScreen); 365 kPaddingFromBottomOfScreen);
330 return rect; 366 return rect;
331 } 367 }
332 gfx::Rect rect = gfx::Screen::GetPrimaryMonitor().bounds(); 368 }
333 return gfx::Rect(base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 369 gfx::Rect rect = gfx::Screen::GetPrimaryMonitor().bounds();
334 rect.width() - kPaddingFromRightEdgeOfScreen, 370 return gfx::Rect(base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen :
335 rect.height() - kPaddingFromBottomOfScreen, 371 rect.width() - kPaddingFromRightEdgeOfScreen,
336 0, 0); 372 rect.height() - kPaddingFromBottomOfScreen,
373 0, 0);
374 }
375
376 void SystemTrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) {
377 if (can_activate_) {
378 state->role = ui::AccessibilityTypes::ROLE_WINDOW;
379 state->name = l10n_util::GetStringUTF16(
380 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
381 }
382 }
383
384 bool SystemTrayBubbleView::CanActivate() const {
385 return can_activate_;
386 }
387
388 gfx::Size SystemTrayBubbleView::GetPreferredSize() {
389 gfx::Size size = views::BubbleDelegateView::GetPreferredSize();
390 return gfx::Size(kTrayPopupWidth, size.height());
391 }
392
393 void SystemTrayBubbleView::OnMouseEntered(const views::MouseEvent& event) {
394 if (host_)
395 host_->StopAutoCloseTimer();
396 }
397
398 void SystemTrayBubbleView::OnMouseExited(const views::MouseEvent& event) {
399 if (host_)
400 host_->RestartAutoCloseTimer();
401 }
402
403 // SystemTrayBubble
404
405 SystemTrayBubble::SystemTrayBubble(ash::SystemTray* tray,
406 std::vector<ash::SystemTrayItem*>& items,
407 bool detailed)
408 : tray_(tray),
409 bubble_view_(NULL),
410 bubble_widget_(NULL),
411 items_(items),
412 detailed_(detailed),
413 autoclose_delay_(0) {
414 MessageLoopForUI::current()->AddObserver(this);
415 }
416
417 SystemTrayBubble::~SystemTrayBubble() {
418 MessageLoopForUI::current()->RemoveObserver(this);
419 DestroyItemViews();
420 // Reset the host pointer in bubble_view_ in case its destruction is deferred.
421 if (bubble_view_)
422 bubble_view_->reset_host();
423 if (bubble_widget_) {
424 bubble_widget_->RemoveObserver(this);
425 // This triggers the destruction of bubble_view_.
426 bubble_widget_->Close();
427 }
428 }
429
430 void SystemTrayBubble::InitView(views::View* anchor,
431 bool can_activate,
432 ash::user::LoginStatus login_status) {
433 DCHECK(bubble_view_ == NULL);
434 bubble_view_ = new SystemTrayBubbleView(anchor, this, can_activate);
435
436 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
437 it != items_.end();
438 ++it) {
439 views::View* view = detailed_ ?
440 (*it)->CreateDetailedView(login_status) :
441 (*it)->CreateDefaultView(login_status);
442 if (view)
443 bubble_view_->AddChildView(new TrayPopupItemContainer(view));
337 } 444 }
338 445
339 // Overridden from views::View. 446 DCHECK(bubble_widget_ == NULL);
340 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE { 447 bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_);
341 if (can_activate_) { 448
342 state->role = ui::AccessibilityTypes::ROLE_WINDOW; 449 // Must occur after call to CreateBubble()
343 state->name = l10n_util::GetStringUTF16( 450 bubble_view_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
344 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); 451 bubble_widget_->non_client_view()->frame_view()->set_background(NULL);
452 bubble_widget_->non_client_view()->frame_view()->set_border(
453 new SystemTrayBubbleBorder(bubble_view_));
454
455 bubble_widget_->AddObserver(this);
456
457 // Setup animation.
458 ash::SetWindowVisibilityAnimationType(
459 bubble_widget_->GetNativeWindow(),
460 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
461 ash::SetWindowVisibilityAnimationTransition(
462 bubble_widget_->GetNativeWindow(),
463 ash::ANIMATE_BOTH);
464 ash::SetWindowVisibilityAnimationDuration(
465 bubble_widget_->GetNativeWindow(),
466 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
467
468 bubble_view_->Show();
469 }
470
471 void SystemTrayBubble::DestroyItemViews() {
472 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
473 it != items_.end();
474 ++it) {
475 if (detailed_)
476 (*it)->DestroyDetailedView();
477 else
478 (*it)->DestroyDefaultView();
479 }
480 }
481
482 views::Widget* SystemTrayBubble::GetTrayWidget() const {
483 return tray_->GetWidget();
484 }
485
486 void SystemTrayBubble::StartAutoCloseTimer(int seconds) {
487 autoclose_.Stop();
488 autoclose_delay_ = seconds;
489 if (autoclose_delay_) {
490 autoclose_.Start(FROM_HERE,
491 base::TimeDelta::FromSeconds(autoclose_delay_),
492 this, &SystemTrayBubble::Close);
493 }
494 }
495
496 void SystemTrayBubble::StopAutoCloseTimer() {
497 autoclose_.Stop();
498 }
499
500 void SystemTrayBubble::RestartAutoCloseTimer() {
501 if (autoclose_delay_)
502 StartAutoCloseTimer(autoclose_delay_);
503 }
504
505 void SystemTrayBubble::Close() {
506 if (bubble_widget_)
507 bubble_widget_->Close();
508 }
509
510 base::EventStatus SystemTrayBubble::WillProcessEvent(
511 const base::NativeEvent& event) {
512 // Check if the user clicked outside of the bubble and close it if they did.
513 if (ui::EventTypeFromNative(event) == ui::ET_MOUSE_PRESSED) {
514 gfx::Point cursor_in_view = ui::EventLocationFromNative(event);
515 views::View::ConvertPointFromScreen(bubble_view_, &cursor_in_view);
516 if (!bubble_view_->HitTest(cursor_in_view)) {
517 bubble_widget_->Close();
345 } 518 }
346 } 519 }
520 return base::EVENT_CONTINUE;
521 }
347 522
348 virtual bool CanActivate() const OVERRIDE { 523 void SystemTrayBubble::DidProcessEvent(const base::NativeEvent& event) {
349 return can_activate_; 524 }
350 }
351 525
352 virtual gfx::Size GetPreferredSize() OVERRIDE { 526 void SystemTrayBubble::OnWidgetClosing(views::Widget* widget) {
353 gfx::Size size = views::BubbleDelegateView::GetPreferredSize(); 527 CHECK_EQ(bubble_widget_, widget);
354 return gfx::Size(kTrayPopupWidth, size.height()); 528 MessageLoopForUI::current()->RemoveObserver(this);
355 } 529 bubble_widget_ = NULL;
530 tray_->RemoveBubble(this);
531 }
356 532
357 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE { 533 void SystemTrayBubble::OnWidgetVisibilityChanged(views::Widget* widget,
358 autoclose_.Stop(); 534 bool visible) {
359 } 535 if (!visible)
360 536 MessageLoopForUI::current()->RemoveObserver(this);
361 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE { 537 else
362 if (autoclose_delay_) { 538 MessageLoopForUI::current()->AddObserver(this);
363 autoclose_.Stop(); 539 }
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 540
381 } // namespace internal 541 } // namespace internal
382 542
543 // From system_tray_delegate.h
544
383 NetworkIconInfo::NetworkIconInfo() 545 NetworkIconInfo::NetworkIconInfo()
384 : highlight(false), 546 : highlight(false),
385 tray_icon_visible(true) { 547 tray_icon_visible(true) {
386 } 548 }
387 549
388 NetworkIconInfo::~NetworkIconInfo() { 550 NetworkIconInfo::~NetworkIconInfo() {
389 } 551 }
390 552
391 BluetoothDeviceInfo::BluetoothDeviceInfo() 553 BluetoothDeviceInfo::BluetoothDeviceInfo()
392 : connected(false) { 554 : connected(false) {
393 } 555 }
394 556
395 BluetoothDeviceInfo::~BluetoothDeviceInfo() { 557 BluetoothDeviceInfo::~BluetoothDeviceInfo() {
396 } 558 }
397 559
398 IMEInfo::IMEInfo() 560 IMEInfo::IMEInfo()
399 : selected(false) { 561 : selected(false) {
400 } 562 }
401 563
402 IMEInfo::~IMEInfo() { 564 IMEInfo::~IMEInfo() {
403 } 565 }
404 566
405 IMEPropertyInfo::IMEPropertyInfo() 567 IMEPropertyInfo::IMEPropertyInfo()
406 : selected(false) { 568 : selected(false) {
407 } 569 }
408 570
409 IMEPropertyInfo::~IMEPropertyInfo() { 571 IMEPropertyInfo::~IMEPropertyInfo() {
410 } 572 }
411 573
574 // SystemTray
575
412 SystemTray::SystemTray() 576 SystemTray::SystemTray()
413 : items_(), 577 : items_(),
414 accessibility_observer_(NULL), 578 accessibility_observer_(NULL),
415 audio_observer_(NULL), 579 audio_observer_(NULL),
416 bluetooth_observer_(NULL), 580 bluetooth_observer_(NULL),
417 brightness_observer_(NULL), 581 brightness_observer_(NULL),
418 caps_lock_observer_(NULL), 582 caps_lock_observer_(NULL),
419 clock_observer_(NULL), 583 clock_observer_(NULL),
420 ime_observer_(NULL), 584 ime_observer_(NULL),
421 network_observer_(NULL), 585 network_observer_(NULL),
422 power_status_observer_(NULL), 586 power_status_observer_(NULL),
423 update_observer_(NULL), 587 update_observer_(NULL),
424 user_observer_(NULL), 588 user_observer_(NULL),
425 widget_(NULL), 589 widget_(NULL),
426 bubble_(NULL), 590 bubble_(NULL),
427 popup_(NULL),
428 background_(new internal::SystemTrayBackground), 591 background_(new internal::SystemTrayBackground),
429 should_show_launcher_(false), 592 should_show_launcher_(false),
430 ALLOW_THIS_IN_INITIALIZER_LIST(hide_background_animator_(this, 593 ALLOW_THIS_IN_INITIALIZER_LIST(hide_background_animator_(this,
431 0, kTrayBackgroundAlpha)), 594 0, kTrayBackgroundAlpha)),
432 ALLOW_THIS_IN_INITIALIZER_LIST(hover_background_animator_(this, 595 ALLOW_THIS_IN_INITIALIZER_LIST(hover_background_animator_(this,
433 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha)) { 596 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha)) {
434 container_ = new views::View; 597 container_ = new views::View;
435 container_->SetLayoutManager(new views::BoxLayout( 598 container_->SetLayoutManager(new views::BoxLayout(
436 views::BoxLayout::kHorizontal, 0, 0, 0)); 599 views::BoxLayout::kHorizontal, 0, 0, 0));
437 container_->set_background(background_); 600 container_->set_background(background_);
438 container_->set_border( 601 container_->set_border(
439 views::Border::CreateEmptyBorder(1, 1, 1, 1)); 602 views::Border::CreateEmptyBorder(1, 1, 1, 1));
440 set_border(views::Border::CreateEmptyBorder(0, 0, 603 set_border(views::Border::CreateEmptyBorder(0, 0,
441 kPaddingFromBottomOfScreen, kPaddingFromRightEdgeOfScreen)); 604 kPaddingFromBottomOfScreen, kPaddingFromRightEdgeOfScreen));
442 set_notify_enter_exit_on_child(true); 605 set_notify_enter_exit_on_child(true);
443 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); 606 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
444 AddChildView(container_); 607 AddChildView(container_);
445 608
446 // Initially we want to paint the background, but without the hover effect. 609 // Initially we want to paint the background, but without the hover effect.
447 SetPaintsBackground(true, internal::BackgroundAnimator::CHANGE_IMMEDIATE); 610 SetPaintsBackground(true, internal::BackgroundAnimator::CHANGE_IMMEDIATE);
448 hover_background_animator_.SetPaintsBackground(false, 611 hover_background_animator_.SetPaintsBackground(false,
449 internal::BackgroundAnimator::CHANGE_IMMEDIATE); 612 internal::BackgroundAnimator::CHANGE_IMMEDIATE);
450 } 613 }
451 614
452 SystemTray::~SystemTray() { 615 SystemTray::~SystemTray() {
616 delete bubble_;
453 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); 617 for (std::vector<SystemTrayItem*>::iterator it = items_.begin();
454 it != items_.end(); 618 it != items_.end();
455 ++it) { 619 ++it) {
456 (*it)->DestroyTrayView(); 620 (*it)->DestroyTrayView();
457 } 621 }
458 if (popup_)
459 popup_->CloseNow();
460 } 622 }
461 623
462 void SystemTray::CreateItems() { 624 void SystemTray::CreateItems() {
463 internal::TrayVolume* tray_volume = new internal::TrayVolume(); 625 internal::TrayVolume* tray_volume = new internal::TrayVolume();
464 internal::TrayBluetooth* tray_bluetooth = new internal::TrayBluetooth(); 626 internal::TrayBluetooth* tray_bluetooth = new internal::TrayBluetooth();
465 internal::TrayBrightness* tray_brightness = new internal::TrayBrightness(); 627 internal::TrayBrightness* tray_brightness = new internal::TrayBrightness();
466 internal::TrayDate* tray_date = new internal::TrayDate(); 628 internal::TrayDate* tray_date = new internal::TrayDate();
467 internal::TrayPower* tray_power = new internal::TrayPower(); 629 internal::TrayPower* tray_power = new internal::TrayPower();
468 internal::TrayNetwork* tray_network = new internal::TrayNetwork; 630 internal::TrayNetwork* tray_network = new internal::TrayNetwork;
469 internal::TrayUser* tray_user = new internal::TrayUser; 631 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); 694 container_->AddChildViewAt(tray_item, 0);
533 PreferredSizeChanged(); 695 PreferredSizeChanged();
534 } 696 }
535 } 697 }
536 698
537 void SystemTray::RemoveTrayItem(SystemTrayItem* item) { 699 void SystemTray::RemoveTrayItem(SystemTrayItem* item) {
538 NOTIMPLEMENTED(); 700 NOTIMPLEMENTED();
539 } 701 }
540 702
541 void SystemTray::ShowDefaultView() { 703 void SystemTray::ShowDefaultView() {
542 if (popup_) { 704 delete bubble_;
543 MessageLoopForUI::current()->RemoveObserver(this);
544 popup_->RemoveObserver(this);
545 popup_->Close();
546 }
547 popup_ = NULL;
548 bubble_ = NULL; 705 bubble_ = NULL;
549
550 ShowItems(items_.get(), false, true); 706 ShowItems(items_.get(), false, true);
551 } 707 }
552 708
553 void SystemTray::ShowDetailedView(SystemTrayItem* item, 709 void SystemTray::ShowDetailedView(SystemTrayItem* item,
554 int close_delay, 710 int close_delay,
555 bool activate) { 711 bool activate) {
556 if (popup_) { 712 delete bubble_;
557 MessageLoopForUI::current()->RemoveObserver(this);
558 popup_->RemoveObserver(this);
559 popup_->Close();
560 }
561 popup_ = NULL;
562 bubble_ = NULL; 713 bubble_ = NULL;
563
564 std::vector<SystemTrayItem*> items; 714 std::vector<SystemTrayItem*> items;
565 items.push_back(item); 715 items.push_back(item);
566 ShowItems(items, true, activate); 716 ShowItems(items, true, activate);
567 bubble_->StartAutoCloseTimer(close_delay); 717 bubble_->StartAutoCloseTimer(close_delay);
568 } 718 }
569 719
570 void SystemTray::SetDetailedViewCloseDelay(int close_delay) { 720 void SystemTray::SetDetailedViewCloseDelay(int close_delay) {
571 if (bubble_ && bubble_->detailed()) 721 if (bubble_ && bubble_->detailed())
572 bubble_->StartAutoCloseTimer(close_delay); 722 bubble_->StartAutoCloseTimer(close_delay);
573 } 723 }
574 724
575 void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) { 725 void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) {
576 if (popup_) 726 delete bubble_;
577 popup_->CloseNow(); 727 bubble_ = NULL;
578 728
579 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); 729 for (std::vector<SystemTrayItem*>::iterator it = items_.begin();
580 it != items_.end(); 730 it != items_.end();
581 ++it) { 731 ++it) {
582 (*it)->UpdateAfterLoginStatusChange(login_status); 732 (*it)->UpdateAfterLoginStatusChange(login_status);
583 } 733 }
584 734
585 SetVisible(true); 735 SetVisible(true);
586 PreferredSizeChanged(); 736 PreferredSizeChanged();
587 } 737 }
588 738
739 void SystemTray::RemoveBubble(internal::SystemTrayBubble* bubble) {
740 CHECK_EQ(bubble_, bubble);
741 delete bubble_;
742 bubble_ = NULL;
sadrul 2012/04/30 20:01:52 Perhaps it makes sense to have bubble_ as a scoped
stevenjb 2012/04/30 20:26:00 Yes, good call, that makes a lot of sense. Done.
743
744 if (should_show_launcher_) {
745 // No need to show the launcher if the mouse isn't over the status area
746 // anymore.
747 aura::RootWindow* root = GetWidget()->GetNativeView()->GetRootWindow();
748 should_show_launcher_ = GetWidget()->GetWindowScreenBounds().Contains(
749 root->last_mouse_location());
750 if (!should_show_launcher_)
751 Shell::GetInstance()->shelf()->UpdateAutoHideState();
752 }
753 }
754
589 void SystemTray::SetPaintsBackground( 755 void SystemTray::SetPaintsBackground(
590 bool value, 756 bool value,
591 internal::BackgroundAnimator::ChangeType change_type) { 757 internal::BackgroundAnimator::ChangeType change_type) {
592 hide_background_animator_.SetPaintsBackground(value, change_type); 758 hide_background_animator_.SetPaintsBackground(value, change_type);
593 } 759 }
594 760
595 void SystemTray::ShowItems(std::vector<SystemTrayItem*>& items, 761 void SystemTray::ShowItems(std::vector<SystemTrayItem*>& items,
596 bool detailed, 762 bool detailed,
597 bool activate) { 763 bool can_activate) {
598 CHECK(!popup_);
599 CHECK(!bubble_); 764 CHECK(!bubble_);
600 bubble_ = new internal::SystemTrayBubble(this, container_, items, detailed); 765 bubble_ = new internal::SystemTrayBubble(this, items, detailed);
601 bubble_->set_can_activate(activate); 766 ash::SystemTrayDelegate* delegate =
602 popup_ = views::BubbleDelegateView::CreateBubble(bubble_); 767 ash::Shell::GetInstance()->tray_delegate();
768 bubble_->InitView(container_, can_activate, delegate->GetUserLoginStatus());
603 // If we have focus the shelf should be visible and we need to continue 769 // If we have focus the shelf should be visible and we need to continue
604 // showing the shelf when the popup is shown. 770 // showing the shelf when the popup is shown.
605 if (GetWidget()->IsActive()) 771 if (GetWidget()->IsActive())
606 should_show_launcher_ = true; 772 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 } 773 }
624 774
625 bool SystemTray::PerformAction(const views::Event& event) { 775 bool SystemTray::PerformAction(const views::Event& event) {
626 // If we're already showing the default view, hide it; otherwise, show it 776 // If we're already showing the default view, hide it; otherwise, show it
627 // (and hide any popup that's currently shown). 777 // (and hide any popup that's currently shown).
628 if (popup_ && bubble_ && !bubble_->detailed()) 778 if (bubble_ && !bubble_->detailed())
629 popup_->Hide(); 779 bubble_->Close();
630 else 780 else
631 ShowDefaultView(); 781 ShowDefaultView();
632 return true; 782 return true;
633 } 783 }
634 784
635 void SystemTray::OnMouseEntered(const views::MouseEvent& event) { 785 void SystemTray::OnMouseEntered(const views::MouseEvent& event) {
636 should_show_launcher_ = true; 786 should_show_launcher_ = true;
637 hover_background_animator_.SetPaintsBackground(true, 787 hover_background_animator_.SetPaintsBackground(true,
638 internal::BackgroundAnimator::CHANGE_ANIMATE); 788 internal::BackgroundAnimator::CHANGE_ANIMATE);
639 } 789 }
640 790
641 void SystemTray::OnMouseExited(const views::MouseEvent& event) { 791 void SystemTray::OnMouseExited(const views::MouseEvent& event) {
642 // When the popup closes we'll update |should_show_launcher_|. 792 // When the popup closes we'll update |should_show_launcher_|.
643 if (!popup_) 793 if (!bubble_)
644 should_show_launcher_ = false; 794 should_show_launcher_ = false;
645 hover_background_animator_.SetPaintsBackground(false, 795 hover_background_animator_.SetPaintsBackground(false,
646 internal::BackgroundAnimator::CHANGE_ANIMATE); 796 internal::BackgroundAnimator::CHANGE_ANIMATE);
647 } 797 }
648 798
649 void SystemTray::AboutToRequestFocusFromTabTraversal(bool reverse) { 799 void SystemTray::AboutToRequestFocusFromTabTraversal(bool reverse) {
650 views::View* v = GetNextFocusableView(); 800 views::View* v = GetNextFocusableView();
651 if (v) 801 if (v)
652 v->AboutToRequestFocusFromTabTraversal(reverse); 802 v->AboutToRequestFocusFromTabTraversal(reverse);
653 } 803 }
654 804
655 void SystemTray::GetAccessibleState(ui::AccessibleViewState* state) { 805 void SystemTray::GetAccessibleState(ui::AccessibleViewState* state) {
656 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; 806 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
657 state->name = l10n_util::GetStringUTF16( 807 state->name = l10n_util::GetStringUTF16(
658 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); 808 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
659 } 809 }
660 810
661 void SystemTray::OnPaintFocusBorder(gfx::Canvas* canvas) { 811 void SystemTray::OnPaintFocusBorder(gfx::Canvas* canvas) {
662 // The tray itself expands to the right and bottom edge of the screen to make 812 // 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 813 // sure clicking on the edges brings up the popup. However, the focus border
664 // should be only around the container. 814 // should be only around the container.
665 if (GetWidget() && GetWidget()->IsActive()) 815 if (GetWidget() && GetWidget()->IsActive())
666 canvas->DrawFocusRect(container_->bounds()); 816 canvas->DrawFocusRect(container_->bounds());
667 } 817 }
668 818
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) { 819 void SystemTray::UpdateBackground(int alpha) {
692 background_->set_alpha(hide_background_animator_.alpha() + 820 background_->set_alpha(hide_background_animator_.alpha() +
693 hover_background_animator_.alpha()); 821 hover_background_animator_.alpha());
694 SchedulePaint(); 822 SchedulePaint();
695 } 823 }
696 824
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 825 } // namespace ash
OLDNEW
« ash/system/tray/system_tray.h ('K') | « ash/system/tray/system_tray.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698