Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "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 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 203 } | 203 } |
| 204 } | 204 } |
| 205 | 205 |
| 206 views::View* owner_; | 206 views::View* owner_; |
| 207 | 207 |
| 208 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleBackground); | 208 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleBackground); |
| 209 }; | 209 }; |
| 210 | 210 |
| 211 class SystemTrayBubbleBorder : public views::BubbleBorder { | 211 class SystemTrayBubbleBorder : public views::BubbleBorder { |
| 212 public: | 212 public: |
| 213 explicit SystemTrayBubbleBorder(views::View* owner) | 213 enum ArrowType { |
| 214 ARROW_TYPE_NONE, | |
| 215 ARROW_TYPE_BOTTOM, | |
| 216 }; | |
| 217 | |
| 218 SystemTrayBubbleBorder(views::View* owner, ArrowType arrow_type) | |
| 214 : views::BubbleBorder(views::BubbleBorder::BOTTOM_RIGHT, | 219 : views::BubbleBorder(views::BubbleBorder::BOTTOM_RIGHT, |
| 215 views::BubbleBorder::NO_SHADOW), | 220 views::BubbleBorder::NO_SHADOW), |
| 216 owner_(owner) { | 221 owner_(owner), |
| 222 arrow_type_(arrow_type) { | |
| 217 set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); | 223 set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); |
| 218 } | 224 } |
| 219 | 225 |
| 220 virtual ~SystemTrayBubbleBorder() {} | 226 virtual ~SystemTrayBubbleBorder() {} |
| 221 | 227 |
| 222 private: | 228 private: |
| 223 // Overridden from views::Border. | 229 // Overridden from views::Border. |
| 224 virtual void Paint(const views::View& view, | 230 virtual void Paint(const views::View& view, |
| 225 gfx::Canvas* canvas) const OVERRIDE { | 231 gfx::Canvas* canvas) const OVERRIDE { |
| 226 views::View* first = NULL, *last = NULL; | 232 views::View* first = NULL, *last = NULL; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 249 | 255 |
| 250 // Draw the bottom line. | 256 // Draw the bottom line. |
| 251 int y = owner_->height() + 1; | 257 int y = owner_->height() + 1; |
| 252 canvas->FillRect(gfx::Rect(kLeftPadding, y, owner_->width(), | 258 canvas->FillRect(gfx::Rect(kLeftPadding, y, owner_->width(), |
| 253 kBottomLineHeight), kBorderDarkColor); | 259 kBottomLineHeight), kBorderDarkColor); |
| 254 | 260 |
| 255 if (!Shell::GetInstance()->shelf()->IsVisible()) | 261 if (!Shell::GetInstance()->shelf()->IsVisible()) |
| 256 return; | 262 return; |
| 257 | 263 |
| 258 // Draw the arrow. | 264 // Draw the arrow. |
| 259 int left_base_x = base::i18n::IsRTL() ? kArrowWidth : | 265 if (arrow_type_ == ARROW_TYPE_BOTTOM) { |
| 260 owner_->width() - kArrowPaddingFromRight - kArrowWidth; | 266 int left_base_x = base::i18n::IsRTL() ? kArrowWidth : |
| 261 int left_base_y = y; | 267 owner_->width() - kArrowPaddingFromRight - kArrowWidth; |
| 262 int tip_x = left_base_x + kArrowWidth / 2; | 268 int left_base_y = y; |
| 263 int tip_y = left_base_y + kArrowHeight; | 269 int tip_x = left_base_x + kArrowWidth / 2; |
| 264 SkPath path; | 270 int tip_y = left_base_y + kArrowHeight; |
| 265 path.incReserve(4); | 271 SkPath path; |
| 266 path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y)); | 272 path.incReserve(4); |
| 267 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); | 273 path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y)); |
| 268 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth), | 274 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); |
| 269 SkIntToScalar(left_base_y)); | 275 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth), |
| 276 SkIntToScalar(left_base_y)); | |
| 270 | 277 |
| 271 SkPaint paint; | 278 SkPaint paint; |
| 272 paint.setStyle(SkPaint::kFill_Style); | 279 paint.setStyle(SkPaint::kFill_Style); |
| 273 paint.setColor(kBackgroundColor); | 280 paint.setColor(kBackgroundColor); |
| 274 canvas->DrawPath(path, paint); | 281 canvas->DrawPath(path, paint); |
| 275 | 282 |
| 276 // Now draw the arrow border. | 283 // Now draw the arrow border. |
| 277 paint.setStyle(SkPaint::kStroke_Style); | 284 paint.setStyle(SkPaint::kStroke_Style); |
| 278 paint.setColor(kBorderDarkColor); | 285 paint.setColor(kBorderDarkColor); |
| 279 canvas->DrawPath(path, paint); | 286 canvas->DrawPath(path, paint); |
| 287 } | |
| 280 } | 288 } |
| 281 | 289 |
| 282 views::View* owner_; | 290 views::View* owner_; |
| 291 ArrowType arrow_type_; | |
| 283 | 292 |
| 284 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleBorder); | 293 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleBorder); |
| 285 }; | 294 }; |
| 286 | 295 |
| 287 } // namespace | 296 } // namespace |
| 288 | 297 |
| 289 namespace internal { | 298 namespace internal { |
| 290 | 299 |
| 291 class SystemTrayBackground : public views::Background { | 300 class SystemTrayBackground : public views::Background { |
| 292 public: | 301 public: |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 320 public: | 329 public: |
| 321 SystemTrayBubbleView(views::View* anchor, | 330 SystemTrayBubbleView(views::View* anchor, |
| 322 SystemTrayBubble* host, | 331 SystemTrayBubble* host, |
| 323 bool can_activate); | 332 bool can_activate); |
| 324 virtual ~SystemTrayBubbleView(); | 333 virtual ~SystemTrayBubbleView(); |
| 325 | 334 |
| 326 void SetBubbleBorder(views::BubbleBorder* border) { | 335 void SetBubbleBorder(views::BubbleBorder* border) { |
| 327 GetBubbleFrameView()->SetBubbleBorder(border); | 336 GetBubbleFrameView()->SetBubbleBorder(border); |
| 328 } | 337 } |
| 329 | 338 |
| 339 void UpdateAnchor() { | |
| 340 SizeToContents(); | |
| 341 GetWidget()->GetRootView()->SchedulePaint(); | |
| 342 } | |
| 343 | |
| 330 // Called when the host is destroyed. | 344 // Called when the host is destroyed. |
| 331 void reset_host() { host_ = NULL; } | 345 void reset_host() { host_ = NULL; } |
| 332 | 346 |
| 333 private: | 347 private: |
| 334 // Overridden from views::BubbleDelegateView. | 348 // Overridden from views::BubbleDelegateView. |
| 335 virtual void Init() OVERRIDE; | 349 virtual void Init() OVERRIDE; |
| 336 virtual gfx::Rect GetAnchorRect() OVERRIDE; | 350 virtual gfx::Rect GetAnchorRect() OVERRIDE; |
| 337 // Overridden from views::View. | 351 // Overridden from views::View. |
| 338 virtual void ChildPreferredSizeChanged(View* child) OVERRIDE; | 352 virtual void ChildPreferredSizeChanged(View* child) OVERRIDE; |
| 339 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; | 353 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; |
| 340 virtual bool CanActivate() const OVERRIDE; | 354 virtual bool CanActivate() const OVERRIDE; |
| 341 virtual gfx::Size GetPreferredSize() OVERRIDE; | 355 virtual gfx::Size GetPreferredSize() OVERRIDE; |
| 342 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE; | 356 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE; |
| 343 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE; | 357 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE; |
| 344 | 358 |
| 345 SystemTrayBubble* host_; | 359 SystemTrayBubble* host_; |
| 346 bool can_activate_; | 360 bool can_activate_; |
| 347 | 361 |
| 348 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleView); | 362 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleView); |
| 349 }; | 363 }; |
| 350 | 364 |
| 351 class SystemTrayBubble : public base::MessagePumpObserver, | 365 class SystemTrayBubble : public base::MessagePumpObserver, |
| 352 public views::Widget::Observer { | 366 public views::Widget::Observer { |
| 353 public: | 367 public: |
| 368 enum BubbleType { | |
| 369 BUBBLE_TYPE_DEFAULT, | |
| 370 BUBBLE_TYPE_DETAILED, | |
| 371 BUBBLE_TYPE_NOTIFICATION | |
| 372 }; | |
| 373 | |
| 374 enum AnchorType { | |
| 375 ANCHOR_TYPE_TRAY, | |
| 376 ANCHOR_TYPE_BUBBLE | |
| 377 }; | |
| 378 | |
| 354 SystemTrayBubble(ash::SystemTray* tray, | 379 SystemTrayBubble(ash::SystemTray* tray, |
| 355 const std::vector<ash::SystemTrayItem*>& items, | 380 const std::vector<ash::SystemTrayItem*>& items, |
| 356 bool detailed); | 381 BubbleType bubble_type); |
| 357 virtual ~SystemTrayBubble(); | 382 virtual ~SystemTrayBubble(); |
| 358 | 383 |
| 359 // Creates |bubble_view_| and a child views for each member of |items_|. | 384 // Creates |bubble_view_| and a child views for each member of |items_|. |
| 360 // Also creates |bubble_widget_| and sets up animations. | 385 // Also creates |bubble_widget_| and sets up animations. |
| 361 void InitView(views::View* anchor, | 386 void InitView(views::View* anchor, |
| 387 AnchorType anchor_type, | |
| 362 bool can_activate, | 388 bool can_activate, |
| 363 ash::user::LoginStatus login_status); | 389 ash::user::LoginStatus login_status); |
| 364 | 390 |
| 365 bool detailed() const { return detailed_; } | 391 gfx::Rect GetAnchorRect() const; |
| 392 | |
| 393 BubbleType bubble_type() const { return bubble_type_; } | |
| 394 SystemTrayBubbleView* bubble_view() const { return bubble_view_; } | |
| 366 | 395 |
| 367 void DestroyItemViews(); | 396 void DestroyItemViews(); |
| 368 views::Widget* GetTrayWidget() const; | |
| 369 void StartAutoCloseTimer(int seconds); | 397 void StartAutoCloseTimer(int seconds); |
| 370 void StopAutoCloseTimer(); | 398 void StopAutoCloseTimer(); |
| 371 void RestartAutoCloseTimer(); | 399 void RestartAutoCloseTimer(); |
| 372 void Close(); | 400 void Close(); |
| 373 | 401 |
| 374 private: | 402 private: |
| 375 // Overridden from base::MessagePumpObserver. | 403 // Overridden from base::MessagePumpObserver. |
| 376 virtual base::EventStatus WillProcessEvent( | 404 virtual base::EventStatus WillProcessEvent( |
| 377 const base::NativeEvent& event) OVERRIDE; | 405 const base::NativeEvent& event) OVERRIDE; |
| 378 virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE; | 406 virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE; |
| 379 // Overridden from views::Widget::Observer. | 407 // Overridden from views::Widget::Observer. |
| 380 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE; | 408 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE; |
| 381 virtual void OnWidgetVisibilityChanged(views::Widget* widget, | 409 virtual void OnWidgetVisibilityChanged(views::Widget* widget, |
| 382 bool visible) OVERRIDE; | 410 bool visible) OVERRIDE; |
| 383 | 411 |
| 384 ash::SystemTray* tray_; | 412 ash::SystemTray* tray_; |
| 385 SystemTrayBubbleView* bubble_view_; | 413 SystemTrayBubbleView* bubble_view_; |
| 386 views::Widget* bubble_widget_; | 414 views::Widget* bubble_widget_; |
| 387 std::vector<ash::SystemTrayItem*> items_; | 415 std::vector<ash::SystemTrayItem*> items_; |
| 388 bool detailed_; | 416 BubbleType bubble_type_; |
| 417 AnchorType anchor_type_; | |
| 418 views::View* anchor_; | |
| 389 | 419 |
| 390 int autoclose_delay_; | 420 int autoclose_delay_; |
| 391 base::OneShotTimer<SystemTrayBubble> autoclose_; | 421 base::OneShotTimer<SystemTrayBubble> autoclose_; |
| 392 | 422 |
| 393 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubble); | 423 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubble); |
| 394 }; | 424 }; |
| 395 | 425 |
| 396 // SystemTrayBubbleView | 426 // SystemTrayBubbleView |
| 397 | 427 |
| 398 SystemTrayBubbleView::SystemTrayBubbleView(views::View* anchor, | 428 SystemTrayBubbleView::SystemTrayBubbleView(views::View* anchor, |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 412 if (host_) | 442 if (host_) |
| 413 host_->DestroyItemViews(); | 443 host_->DestroyItemViews(); |
| 414 } | 444 } |
| 415 | 445 |
| 416 void SystemTrayBubbleView::Init() { | 446 void SystemTrayBubbleView::Init() { |
| 417 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 1, 1, 1)); | 447 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 1, 1, 1)); |
| 418 set_background(new SystemTrayBubbleBackground(this)); | 448 set_background(new SystemTrayBubbleBackground(this)); |
| 419 } | 449 } |
| 420 | 450 |
| 421 gfx::Rect SystemTrayBubbleView::GetAnchorRect() { | 451 gfx::Rect SystemTrayBubbleView::GetAnchorRect() { |
| 422 if (host_) { | 452 gfx::Rect rect; |
| 423 views::Widget* widget = host_->GetTrayWidget(); | 453 if (host_) |
| 424 if (widget->IsVisible()) { | 454 rect = host_->GetAnchorRect(); |
| 425 gfx::Rect rect = widget->GetWindowScreenBounds(); | 455 if (rect.IsEmpty()) { |
| 426 rect.Inset( | 456 rect = gfx::Screen::GetPrimaryMonitor().bounds(); |
| 427 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 0, 0, | 457 rect = gfx::Rect(base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : |
| 428 base::i18n::IsRTL() ? 0 : kPaddingFromRightEdgeOfScreen, | 458 rect.width() - kPaddingFromRightEdgeOfScreen, |
| 429 kPaddingFromBottomOfScreen); | 459 rect.height() - kPaddingFromBottomOfScreen, |
| 430 return rect; | 460 0, 0); |
| 431 } | |
| 432 } | 461 } |
| 433 gfx::Rect rect = gfx::Screen::GetPrimaryMonitor().bounds(); | 462 return rect; |
| 434 return gfx::Rect(base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : | |
| 435 rect.width() - kPaddingFromRightEdgeOfScreen, | |
| 436 rect.height() - kPaddingFromBottomOfScreen, | |
| 437 0, 0); | |
| 438 } | 463 } |
| 439 | 464 |
| 440 void SystemTrayBubbleView::ChildPreferredSizeChanged(View* child) { | 465 void SystemTrayBubbleView::ChildPreferredSizeChanged(View* child) { |
| 441 SizeToContents(); | 466 SizeToContents(); |
| 442 } | 467 } |
| 443 | 468 |
| 444 void SystemTrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) { | 469 void SystemTrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) { |
| 445 if (can_activate_) { | 470 if (can_activate_) { |
| 446 state->role = ui::AccessibilityTypes::ROLE_WINDOW; | 471 state->role = ui::AccessibilityTypes::ROLE_WINDOW; |
| 447 state->name = l10n_util::GetStringUTF16( | 472 state->name = l10n_util::GetStringUTF16( |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 466 void SystemTrayBubbleView::OnMouseExited(const views::MouseEvent& event) { | 491 void SystemTrayBubbleView::OnMouseExited(const views::MouseEvent& event) { |
| 467 if (host_) | 492 if (host_) |
| 468 host_->RestartAutoCloseTimer(); | 493 host_->RestartAutoCloseTimer(); |
| 469 } | 494 } |
| 470 | 495 |
| 471 // SystemTrayBubble | 496 // SystemTrayBubble |
| 472 | 497 |
| 473 SystemTrayBubble::SystemTrayBubble( | 498 SystemTrayBubble::SystemTrayBubble( |
| 474 ash::SystemTray* tray, | 499 ash::SystemTray* tray, |
| 475 const std::vector<ash::SystemTrayItem*>& items, | 500 const std::vector<ash::SystemTrayItem*>& items, |
| 476 bool detailed) | 501 BubbleType bubble_type) |
| 477 : tray_(tray), | 502 : tray_(tray), |
| 478 bubble_view_(NULL), | 503 bubble_view_(NULL), |
| 479 bubble_widget_(NULL), | 504 bubble_widget_(NULL), |
| 480 items_(items), | 505 items_(items), |
| 481 detailed_(detailed), | 506 bubble_type_(bubble_type), |
| 507 anchor_type_(ANCHOR_TYPE_TRAY), | |
| 508 anchor_(NULL), | |
| 482 autoclose_delay_(0) { | 509 autoclose_delay_(0) { |
| 483 } | 510 } |
| 484 | 511 |
| 485 SystemTrayBubble::~SystemTrayBubble() { | 512 SystemTrayBubble::~SystemTrayBubble() { |
| 486 // The bubble may be closing without having been hidden first. So it may still | 513 // The bubble may be closing without having been hidden first. So it may still |
| 487 // be in the message-loop's observer list. | 514 // be in the message-loop's observer list. |
| 488 MessageLoopForUI::current()->RemoveObserver(this); | 515 MessageLoopForUI::current()->RemoveObserver(this); |
| 489 | 516 |
| 490 DestroyItemViews(); | 517 DestroyItemViews(); |
| 491 // Reset the host pointer in bubble_view_ in case its destruction is deferred. | 518 // Reset the host pointer in bubble_view_ in case its destruction is deferred. |
| 492 if (bubble_view_) | 519 if (bubble_view_) |
| 493 bubble_view_->reset_host(); | 520 bubble_view_->reset_host(); |
| 494 if (bubble_widget_) { | 521 if (bubble_widget_) { |
| 495 bubble_widget_->RemoveObserver(this); | 522 bubble_widget_->RemoveObserver(this); |
| 496 // This triggers the destruction of bubble_view_. | 523 // This triggers the destruction of bubble_view_. |
| 497 bubble_widget_->Close(); | 524 bubble_widget_->Close(); |
| 498 } | 525 } |
| 499 } | 526 } |
| 500 | 527 |
| 501 void SystemTrayBubble::InitView(views::View* anchor, | 528 void SystemTrayBubble::InitView(views::View* anchor, |
| 529 AnchorType anchor_type, | |
| 502 bool can_activate, | 530 bool can_activate, |
| 503 ash::user::LoginStatus login_status) { | 531 ash::user::LoginStatus login_status) { |
| 504 DCHECK(bubble_view_ == NULL); | 532 DCHECK(bubble_view_ == NULL); |
| 533 anchor_type_ = anchor_type; | |
| 534 anchor_ = anchor; | |
| 505 bubble_view_ = new SystemTrayBubbleView(anchor, this, can_activate); | 535 bubble_view_ = new SystemTrayBubbleView(anchor, this, can_activate); |
| 506 | 536 |
| 507 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin(); | 537 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin(); |
| 508 it != items_.end(); | 538 it != items_.end(); |
| 509 ++it) { | 539 ++it) { |
| 510 views::View* view = detailed_ ? | 540 views::View* view = NULL; |
| 511 (*it)->CreateDetailedView(login_status) : | 541 switch (bubble_type_) { |
| 512 (*it)->CreateDefaultView(login_status); | 542 case BUBBLE_TYPE_DEFAULT: |
| 543 view = (*it)->CreateDefaultView(login_status); | |
| 544 break; | |
| 545 case BUBBLE_TYPE_DETAILED: | |
| 546 view = (*it)->CreateDetailedView(login_status); | |
| 547 break; | |
| 548 case BUBBLE_TYPE_NOTIFICATION: | |
| 549 view = (*it)->CreateNotificationView(login_status); | |
| 550 break; | |
| 551 } | |
| 513 if (view) | 552 if (view) |
| 514 bubble_view_->AddChildView(new TrayPopupItemContainer(view)); | 553 bubble_view_->AddChildView(new TrayPopupItemContainer(view)); |
| 515 } | 554 } |
| 516 | 555 |
| 517 DCHECK(bubble_widget_ == NULL); | 556 DCHECK(bubble_widget_ == NULL); |
| 518 bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_); | 557 bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_); |
| 519 | 558 |
| 520 // Must occur after call to CreateBubble() | 559 // Must occur after call to CreateBubble() |
| 521 bubble_view_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); | 560 bubble_view_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); |
| 522 bubble_widget_->non_client_view()->frame_view()->set_background(NULL); | 561 bubble_widget_->non_client_view()->frame_view()->set_background(NULL); |
| 523 bubble_view_->SetBubbleBorder(new SystemTrayBubbleBorder(bubble_view_)); | 562 SystemTrayBubbleBorder::ArrowType arrow_type; |
| 563 if (anchor_type_ == ANCHOR_TYPE_TRAY) | |
| 564 arrow_type = SystemTrayBubbleBorder::ARROW_TYPE_BOTTOM; | |
| 565 else | |
| 566 arrow_type = SystemTrayBubbleBorder::ARROW_TYPE_NONE; | |
| 567 bubble_view_->SetBubbleBorder( | |
| 568 new SystemTrayBubbleBorder(bubble_view_, arrow_type)); | |
| 524 | 569 |
| 525 bubble_widget_->AddObserver(this); | 570 bubble_widget_->AddObserver(this); |
| 526 | 571 |
| 527 // Setup animation. | 572 // Setup animation. |
| 528 ash::SetWindowVisibilityAnimationType( | 573 ash::SetWindowVisibilityAnimationType( |
| 529 bubble_widget_->GetNativeWindow(), | 574 bubble_widget_->GetNativeWindow(), |
| 530 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); | 575 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); |
| 531 ash::SetWindowVisibilityAnimationTransition( | 576 ash::SetWindowVisibilityAnimationTransition( |
| 532 bubble_widget_->GetNativeWindow(), | 577 bubble_widget_->GetNativeWindow(), |
| 533 ash::ANIMATE_BOTH); | 578 ash::ANIMATE_BOTH); |
| 534 ash::SetWindowVisibilityAnimationDuration( | 579 ash::SetWindowVisibilityAnimationDuration( |
| 535 bubble_widget_->GetNativeWindow(), | 580 bubble_widget_->GetNativeWindow(), |
| 536 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS)); | 581 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS)); |
| 537 | 582 |
| 538 bubble_view_->Show(); | 583 bubble_view_->Show(); |
| 539 } | 584 } |
| 540 | 585 |
| 586 gfx::Rect SystemTrayBubble::GetAnchorRect() const { | |
| 587 gfx::Rect rect; | |
| 588 views::Widget* widget = anchor_->GetWidget(); | |
|
sadrul
2012/05/08 19:40:17
I think instead of keeping anchor_ around, you can
stevenjb
2012/05/08 22:49:20
Good call. Done.
| |
| 589 if (widget->IsVisible()) { | |
| 590 rect = widget->GetWindowScreenBounds(); | |
| 591 if (anchor_type_ == ANCHOR_TYPE_TRAY) { | |
| 592 rect.Inset( | |
| 593 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 0, | |
| 594 0, | |
| 595 base::i18n::IsRTL() ? 0 : kPaddingFromRightEdgeOfScreen, | |
| 596 kPaddingFromBottomOfScreen); | |
| 597 } else if (anchor_type_ == ANCHOR_TYPE_BUBBLE) { | |
| 598 rect.Inset( | |
| 599 base::i18n::IsRTL() ? kShadowThickness - 1 : 0, | |
| 600 0, | |
| 601 base::i18n::IsRTL() ? 0 : kShadowThickness - 1, | |
| 602 0); | |
| 603 } | |
| 604 } | |
| 605 return rect; | |
| 606 } | |
| 607 | |
| 541 void SystemTrayBubble::DestroyItemViews() { | 608 void SystemTrayBubble::DestroyItemViews() { |
| 542 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin(); | 609 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin(); |
| 543 it != items_.end(); | 610 it != items_.end(); |
| 544 ++it) { | 611 ++it) { |
| 545 if (detailed_) | 612 switch (bubble_type_) { |
| 546 (*it)->DestroyDetailedView(); | 613 case BUBBLE_TYPE_DEFAULT: |
| 547 else | 614 (*it)->DestroyDefaultView(); |
| 548 (*it)->DestroyDefaultView(); | 615 break; |
| 616 case BUBBLE_TYPE_DETAILED: | |
| 617 (*it)->DestroyDetailedView(); | |
| 618 break; | |
| 619 case BUBBLE_TYPE_NOTIFICATION: | |
| 620 (*it)->DestroyNotificationView(); | |
| 621 break; | |
| 622 } | |
| 549 } | 623 } |
| 550 } | 624 } |
| 551 | 625 |
| 552 views::Widget* SystemTrayBubble::GetTrayWidget() const { | |
| 553 return tray_->GetWidget(); | |
| 554 } | |
| 555 | |
| 556 void SystemTrayBubble::StartAutoCloseTimer(int seconds) { | 626 void SystemTrayBubble::StartAutoCloseTimer(int seconds) { |
| 557 autoclose_.Stop(); | 627 autoclose_.Stop(); |
| 558 autoclose_delay_ = seconds; | 628 autoclose_delay_ = seconds; |
| 559 if (autoclose_delay_) { | 629 if (autoclose_delay_) { |
| 560 autoclose_.Start(FROM_HERE, | 630 autoclose_.Start(FROM_HERE, |
| 561 base::TimeDelta::FromSeconds(autoclose_delay_), | 631 base::TimeDelta::FromSeconds(autoclose_delay_), |
| 562 this, &SystemTrayBubble::Close); | 632 this, &SystemTrayBubble::Close); |
| 563 } | 633 } |
| 564 } | 634 } |
| 565 | 635 |
| 566 void SystemTrayBubble::StopAutoCloseTimer() { | 636 void SystemTrayBubble::StopAutoCloseTimer() { |
| 567 autoclose_.Stop(); | 637 autoclose_.Stop(); |
| 568 } | 638 } |
| 569 | 639 |
| 570 void SystemTrayBubble::RestartAutoCloseTimer() { | 640 void SystemTrayBubble::RestartAutoCloseTimer() { |
| 571 if (autoclose_delay_) | 641 if (autoclose_delay_) |
| 572 StartAutoCloseTimer(autoclose_delay_); | 642 StartAutoCloseTimer(autoclose_delay_); |
| 573 } | 643 } |
| 574 | 644 |
| 575 void SystemTrayBubble::Close() { | 645 void SystemTrayBubble::Close() { |
| 576 if (bubble_widget_) | 646 if (bubble_widget_) |
| 577 bubble_widget_->Close(); | 647 bubble_widget_->Close(); |
| 578 } | 648 } |
| 579 | 649 |
| 580 base::EventStatus SystemTrayBubble::WillProcessEvent( | 650 base::EventStatus SystemTrayBubble::WillProcessEvent( |
| 581 const base::NativeEvent& event) { | 651 const base::NativeEvent& event) { |
| 582 // Check if the user clicked outside of the bubble and close it if they did. | 652 // Check if the user clicked outside of the bubble and close it if they did. |
| 583 if (ui::EventTypeFromNative(event) == ui::ET_MOUSE_PRESSED) { | 653 if (bubble_type_ != BUBBLE_TYPE_NOTIFICATION && |
| 654 ui::EventTypeFromNative(event) == ui::ET_MOUSE_PRESSED) { | |
| 584 gfx::Point cursor_in_view = ui::EventLocationFromNative(event); | 655 gfx::Point cursor_in_view = ui::EventLocationFromNative(event); |
| 585 views::View::ConvertPointFromScreen(bubble_view_, &cursor_in_view); | 656 views::View::ConvertPointFromScreen(bubble_view_, &cursor_in_view); |
| 586 if (!bubble_view_->HitTest(cursor_in_view)) { | 657 if (!bubble_view_->HitTest(cursor_in_view)) { |
| 587 bubble_widget_->Close(); | 658 bubble_widget_->Close(); |
| 588 } | 659 } |
| 589 } | 660 } |
| 590 return base::EVENT_CONTINUE; | 661 return base::EVENT_CONTINUE; |
| 591 } | 662 } |
| 592 | 663 |
| 593 void SystemTrayBubble::DidProcessEvent(const base::NativeEvent& event) { | 664 void SystemTrayBubble::DidProcessEvent(const base::NativeEvent& event) { |
| 594 } | 665 } |
| 595 | 666 |
| 596 void SystemTrayBubble::OnWidgetClosing(views::Widget* widget) { | 667 void SystemTrayBubble::OnWidgetClosing(views::Widget* widget) { |
| 597 CHECK_EQ(bubble_widget_, widget); | 668 CHECK_EQ(bubble_widget_, widget); |
| 598 MessageLoopForUI::current()->RemoveObserver(this); | 669 MessageLoopForUI::current()->RemoveObserver(this); |
| 599 bubble_widget_ = NULL; | 670 bubble_widget_ = NULL; |
| 600 tray_->RemoveBubble(this); | 671 tray_->RemoveBubble(this); |
| 601 } | 672 } |
| 602 | 673 |
| 603 void SystemTrayBubble::OnWidgetVisibilityChanged(views::Widget* widget, | 674 void SystemTrayBubble::OnWidgetVisibilityChanged(views::Widget* widget, |
| 604 bool visible) { | 675 bool visible) { |
| 605 if (!visible) | 676 if (!visible) |
| 606 MessageLoopForUI::current()->RemoveObserver(this); | 677 MessageLoopForUI::current()->RemoveObserver(this); |
| 607 else | 678 else |
| 608 MessageLoopForUI::current()->AddObserver(this); | 679 MessageLoopForUI::current()->AddObserver(this); |
| 609 } | 680 } |
| 610 | 681 |
| 682 // Observe the tray layer animation and update the anchor when it changes. | |
| 683 // TODO(stevenjb): Observe or mirror the actual animation, not just the start | |
| 684 // and end points. | |
| 685 class SystemTrayLayerAnimationObserver : public ui::LayerAnimationObserver { | |
| 686 public: | |
| 687 explicit SystemTrayLayerAnimationObserver(SystemTray* host) : host_(host) {} | |
| 688 | |
| 689 virtual void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) { | |
| 690 host_->UpdateNotificationAnchor(); | |
| 691 } | |
| 692 | |
| 693 virtual void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) { | |
| 694 host_->UpdateNotificationAnchor(); | |
| 695 } | |
| 696 | |
| 697 virtual void OnLayerAnimationScheduled(ui::LayerAnimationSequence* sequence) { | |
| 698 host_->UpdateNotificationAnchor(); | |
| 699 } | |
| 700 | |
| 701 private: | |
| 702 SystemTray* host_; | |
|
sadrul
2012/05/08 19:40:17
DISALLOW_COPY_AND_ASSIGN
stevenjb
2012/05/08 22:49:20
Done.
| |
| 703 }; | |
| 704 | |
| 611 } // namespace internal | 705 } // namespace internal |
| 612 | 706 |
| 613 // SystemTray | 707 // SystemTray |
| 614 | 708 |
| 709 using internal::SystemTrayBubble; | |
| 710 using internal::SystemTrayLayerAnimationObserver; | |
| 711 | |
| 615 SystemTray::SystemTray() | 712 SystemTray::SystemTray() |
| 616 : items_(), | 713 : items_(), |
| 617 accessibility_observer_(NULL), | 714 accessibility_observer_(NULL), |
| 618 audio_observer_(NULL), | 715 audio_observer_(NULL), |
| 619 bluetooth_observer_(NULL), | 716 bluetooth_observer_(NULL), |
| 620 brightness_observer_(NULL), | 717 brightness_observer_(NULL), |
| 621 caps_lock_observer_(NULL), | 718 caps_lock_observer_(NULL), |
| 622 clock_observer_(NULL), | 719 clock_observer_(NULL), |
| 623 drive_observer_(NULL), | 720 drive_observer_(NULL), |
| 624 ime_observer_(NULL), | 721 ime_observer_(NULL), |
| 625 network_observer_(NULL), | 722 network_observer_(NULL), |
| 626 power_status_observer_(NULL), | 723 power_status_observer_(NULL), |
| 627 update_observer_(NULL), | 724 update_observer_(NULL), |
| 628 user_observer_(NULL), | 725 user_observer_(NULL), |
| 629 widget_(NULL), | 726 widget_(NULL), |
| 630 background_(new internal::SystemTrayBackground), | 727 background_(new internal::SystemTrayBackground), |
| 631 should_show_launcher_(false), | 728 should_show_launcher_(false), |
| 632 ALLOW_THIS_IN_INITIALIZER_LIST(hide_background_animator_(this, | 729 ALLOW_THIS_IN_INITIALIZER_LIST(hide_background_animator_(this, |
| 633 0, kTrayBackgroundAlpha)), | 730 0, kTrayBackgroundAlpha)), |
| 634 ALLOW_THIS_IN_INITIALIZER_LIST(hover_background_animator_(this, | 731 ALLOW_THIS_IN_INITIALIZER_LIST(hover_background_animator_(this, |
| 635 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha)) { | 732 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha)) { |
| 636 container_ = new views::View; | 733 tray_container_ = new views::View; |
| 637 container_->SetLayoutManager(new views::BoxLayout( | 734 tray_container_->SetLayoutManager(new views::BoxLayout( |
| 638 views::BoxLayout::kHorizontal, 0, 0, 0)); | 735 views::BoxLayout::kHorizontal, 0, 0, 0)); |
| 639 container_->set_background(background_); | 736 tray_container_->set_background(background_); |
| 640 container_->set_border( | 737 tray_container_->set_border( |
| 641 views::Border::CreateEmptyBorder(1, 1, 1, 1)); | 738 views::Border::CreateEmptyBorder(1, 1, 1, 1)); |
| 642 set_border(views::Border::CreateEmptyBorder(0, 0, | 739 set_border(views::Border::CreateEmptyBorder(0, 0, |
| 643 kPaddingFromBottomOfScreen, kPaddingFromRightEdgeOfScreen)); | 740 kPaddingFromBottomOfScreen, kPaddingFromRightEdgeOfScreen)); |
| 644 set_notify_enter_exit_on_child(true); | 741 set_notify_enter_exit_on_child(true); |
| 645 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); | 742 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); |
| 646 AddChildView(container_); | 743 AddChildView(tray_container_); |
| 647 | 744 |
| 648 // Initially we want to paint the background, but without the hover effect. | 745 // Initially we want to paint the background, but without the hover effect. |
| 649 SetPaintsBackground(true, internal::BackgroundAnimator::CHANGE_IMMEDIATE); | 746 SetPaintsBackground(true, internal::BackgroundAnimator::CHANGE_IMMEDIATE); |
| 650 hover_background_animator_.SetPaintsBackground(false, | 747 hover_background_animator_.SetPaintsBackground(false, |
| 651 internal::BackgroundAnimator::CHANGE_IMMEDIATE); | 748 internal::BackgroundAnimator::CHANGE_IMMEDIATE); |
| 652 } | 749 } |
| 653 | 750 |
| 654 SystemTray::~SystemTray() { | 751 SystemTray::~SystemTray() { |
| 655 bubble_.reset(); | 752 bubble_.reset(); |
| 656 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); | 753 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 718 params.delegate = status_area_view; | 815 params.delegate = status_area_view; |
| 719 params.parent = Shell::GetInstance()->GetContainer( | 816 params.parent = Shell::GetInstance()->GetContainer( |
| 720 ash::internal::kShellWindowId_StatusContainer); | 817 ash::internal::kShellWindowId_StatusContainer); |
| 721 params.transparent = true; | 818 params.transparent = true; |
| 722 widget_->Init(params); | 819 widget_->Init(params); |
| 723 widget_->set_focus_on_creation(false); | 820 widget_->set_focus_on_creation(false); |
| 724 status_area_view->AddChildView(this); | 821 status_area_view->AddChildView(this); |
| 725 widget_->SetContentsView(status_area_view); | 822 widget_->SetContentsView(status_area_view); |
| 726 widget_->Show(); | 823 widget_->Show(); |
| 727 widget_->GetNativeView()->SetName("StatusTrayWidget"); | 824 widget_->GetNativeView()->SetName("StatusTrayWidget"); |
| 825 | |
| 826 layer_animation_observer_.reset(new SystemTrayLayerAnimationObserver(this)); | |
| 827 widget_->GetNativeView()->layer()->GetAnimator()->AddObserver( | |
| 828 layer_animation_observer_.get()); | |
| 728 } | 829 } |
| 729 | 830 |
| 730 void SystemTray::AddTrayItem(SystemTrayItem* item) { | 831 void SystemTray::AddTrayItem(SystemTrayItem* item) { |
| 731 items_.push_back(item); | 832 items_.push_back(item); |
| 732 | 833 |
| 733 SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate(); | 834 SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate(); |
| 734 views::View* tray_item = item->CreateTrayView(delegate->GetUserLoginStatus()); | 835 views::View* tray_item = item->CreateTrayView(delegate->GetUserLoginStatus()); |
| 735 if (tray_item) { | 836 if (tray_item) { |
| 736 container_->AddChildViewAt(tray_item, 0); | 837 tray_container_->AddChildViewAt(tray_item, 0); |
| 737 PreferredSizeChanged(); | 838 PreferredSizeChanged(); |
| 738 } | 839 } |
| 739 } | 840 } |
| 740 | 841 |
| 741 void SystemTray::RemoveTrayItem(SystemTrayItem* item) { | 842 void SystemTray::RemoveTrayItem(SystemTrayItem* item) { |
| 742 NOTIMPLEMENTED(); | 843 NOTIMPLEMENTED(); |
| 743 } | 844 } |
| 744 | 845 |
| 745 void SystemTray::ShowDefaultView() { | 846 void SystemTray::ShowDefaultView() { |
| 746 ShowItems(items_.get(), false, true); | 847 ShowItems(items_.get(), false, true); |
| 747 } | 848 } |
| 748 | 849 |
| 749 void SystemTray::ShowDetailedView(SystemTrayItem* item, | 850 void SystemTray::ShowDetailedView(SystemTrayItem* item, |
| 750 int close_delay, | 851 int close_delay, |
| 751 bool activate) { | 852 bool activate) { |
| 752 std::vector<SystemTrayItem*> items; | 853 std::vector<SystemTrayItem*> items; |
| 753 items.push_back(item); | 854 items.push_back(item); |
| 754 ShowItems(items, true, activate); | 855 ShowItems(items, true, activate); |
| 755 bubble_->StartAutoCloseTimer(close_delay); | 856 bubble_->StartAutoCloseTimer(close_delay); |
| 756 } | 857 } |
| 757 | 858 |
| 859 void SystemTray::ShowNotificationView(SystemTrayItem* item) { | |
| 860 if (std::find(notification_items_.begin(), notification_items_.end(), item) | |
| 861 != notification_items_.end()) | |
| 862 return; | |
| 863 notification_items_.push_back(item); | |
| 864 ShowNotifications(); | |
| 865 } | |
| 866 | |
| 867 void SystemTray::HideNotificationView(SystemTrayItem* item) { | |
| 868 std::vector<SystemTrayItem*>::iterator found_iter = | |
| 869 std::find(notification_items_.begin(), notification_items_.end(), item); | |
| 870 if (found_iter == notification_items_.end()) | |
| 871 return; | |
| 872 notification_items_.erase(found_iter); | |
| 873 ShowNotifications(); | |
| 874 } | |
| 875 | |
| 758 void SystemTray::SetDetailedViewCloseDelay(int close_delay) { | 876 void SystemTray::SetDetailedViewCloseDelay(int close_delay) { |
| 759 if (bubble_.get() && bubble_->detailed()) | 877 if (bubble_.get() && |
| 878 bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DETAILED) | |
| 760 bubble_->StartAutoCloseTimer(close_delay); | 879 bubble_->StartAutoCloseTimer(close_delay); |
| 761 } | 880 } |
| 762 | 881 |
| 763 void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) { | 882 void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) { |
| 764 bubble_.reset(); | 883 bubble_.reset(); |
| 765 | 884 |
| 766 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); | 885 for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); |
| 767 it != items_.end(); | 886 it != items_.end(); |
| 768 ++it) { | 887 ++it) { |
| 769 (*it)->UpdateAfterLoginStatusChange(login_status); | 888 (*it)->UpdateAfterLoginStatusChange(login_status); |
| 770 } | 889 } |
| 771 | 890 |
| 772 SetVisible(true); | 891 SetVisible(true); |
| 773 PreferredSizeChanged(); | 892 PreferredSizeChanged(); |
| 774 } | 893 } |
| 775 | 894 |
| 776 bool SystemTray::CloseBubbleForTest() const { | 895 bool SystemTray::CloseBubbleForTest() const { |
| 777 if (!bubble_.get()) | 896 if (!bubble_.get()) |
| 778 return false; | 897 return false; |
| 779 bubble_->Close(); | 898 bubble_->Close(); |
| 780 return true; | 899 return true; |
| 781 } | 900 } |
| 782 | 901 |
| 783 // Private methods. | 902 // Private methods. |
| 784 | 903 |
| 785 void SystemTray::RemoveBubble(internal::SystemTrayBubble* bubble) { | 904 void SystemTray::RemoveBubble(SystemTrayBubble* bubble) { |
| 786 CHECK_EQ(bubble_.get(), bubble); | 905 if (bubble == bubble_.get()) { |
| 787 bubble_.reset(); | 906 bubble_.reset(); |
| 788 | 907 ShowNotifications(); // State changed, re-create notifications. |
| 789 if (should_show_launcher_) { | 908 if (should_show_launcher_) { |
| 790 // No need to show the launcher if the mouse isn't over the status area | 909 // No need to show the launcher if the mouse isn't over the status area |
| 791 // anymore. | 910 // anymore. |
| 792 aura::RootWindow* root = GetWidget()->GetNativeView()->GetRootWindow(); | 911 aura::RootWindow* root = GetWidget()->GetNativeView()->GetRootWindow(); |
| 793 should_show_launcher_ = GetWidget()->GetWindowScreenBounds().Contains( | 912 should_show_launcher_ = GetWidget()->GetWindowScreenBounds().Contains( |
| 794 root->last_mouse_location()); | 913 root->last_mouse_location()); |
| 795 if (!should_show_launcher_) | 914 if (!should_show_launcher_) |
| 796 Shell::GetInstance()->shelf()->UpdateAutoHideState(); | 915 Shell::GetInstance()->shelf()->UpdateAutoHideState(); |
| 916 } | |
| 917 } else if (bubble == notification_bubble_) { | |
| 918 notification_bubble_.reset(); | |
| 919 } else { | |
| 920 NOTREACHED(); | |
| 797 } | 921 } |
| 798 } | 922 } |
| 799 | 923 |
| 800 void SystemTray::SetPaintsBackground( | 924 void SystemTray::SetPaintsBackground( |
| 801 bool value, | 925 bool value, |
| 802 internal::BackgroundAnimator::ChangeType change_type) { | 926 internal::BackgroundAnimator::ChangeType change_type) { |
| 803 hide_background_animator_.SetPaintsBackground(value, change_type); | 927 hide_background_animator_.SetPaintsBackground(value, change_type); |
| 804 } | 928 } |
| 805 | 929 |
| 806 void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items, | 930 void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items, |
| 807 bool detailed, | 931 bool detailed, |
| 808 bool can_activate) { | 932 bool can_activate) { |
| 809 // Destroy any existing bubble and create a new one. | 933 // Destroy any existing bubble and create a new one. |
| 810 bubble_.reset(new internal::SystemTrayBubble(this, items, detailed)); | 934 SystemTrayBubble::BubbleType bubble_type = detailed ? |
| 935 SystemTrayBubble::BUBBLE_TYPE_DETAILED : | |
| 936 SystemTrayBubble::BUBBLE_TYPE_DEFAULT; | |
| 937 bubble_.reset(new SystemTrayBubble(this, items, bubble_type)); | |
| 811 ash::SystemTrayDelegate* delegate = | 938 ash::SystemTrayDelegate* delegate = |
| 812 ash::Shell::GetInstance()->tray_delegate(); | 939 ash::Shell::GetInstance()->tray_delegate(); |
| 813 bubble_->InitView(container_, can_activate, delegate->GetUserLoginStatus()); | 940 views::View* anchor = tray_container_; |
| 941 bubble_->InitView(anchor, SystemTrayBubble::ANCHOR_TYPE_TRAY, | |
| 942 can_activate, delegate->GetUserLoginStatus()); | |
| 814 // If we have focus the shelf should be visible and we need to continue | 943 // If we have focus the shelf should be visible and we need to continue |
| 815 // showing the shelf when the popup is shown. | 944 // showing the shelf when the popup is shown. |
| 816 if (GetWidget()->IsActive()) | 945 if (GetWidget()->IsActive()) |
| 817 should_show_launcher_ = true; | 946 should_show_launcher_ = true; |
| 947 ShowNotifications(); // State changed, re-create notifications. | |
| 948 } | |
| 949 | |
| 950 void SystemTray::ShowNotifications() { | |
|
sadrul
2012/05/08 19:40:17
Since this can hide the notifications in some case
stevenjb
2012/05/08 22:49:20
Done.
| |
| 951 // Only show the notification buble if we have notifications and we are not | |
| 952 // showing the default bubble. | |
| 953 if (notification_items_.empty() || | |
| 954 (bubble_.get() && | |
| 955 bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DEFAULT)) { | |
| 956 notification_bubble_.reset(); | |
| 957 return; | |
| 958 } | |
| 959 notification_bubble_.reset( | |
| 960 new SystemTrayBubble(this, notification_items_, | |
| 961 SystemTrayBubble::BUBBLE_TYPE_NOTIFICATION)); | |
| 962 views::View* anchor; | |
| 963 SystemTrayBubble::AnchorType anchor_type; | |
| 964 if (bubble_.get()) { | |
| 965 anchor = bubble_->bubble_view(); | |
| 966 anchor_type = SystemTrayBubble::ANCHOR_TYPE_BUBBLE; | |
| 967 } else { | |
| 968 anchor = tray_container_; | |
| 969 anchor_type = SystemTrayBubble::ANCHOR_TYPE_TRAY; | |
| 970 } | |
| 971 notification_bubble_->InitView( | |
| 972 anchor, anchor_type, | |
| 973 false /* can_activate */, | |
| 974 ash::Shell::GetInstance()->tray_delegate()->GetUserLoginStatus()); | |
| 975 } | |
| 976 | |
| 977 void SystemTray::UpdateNotificationAnchor() { | |
| 978 if (!notification_bubble_.get()) | |
| 979 return; | |
| 980 notification_bubble_->bubble_view()->UpdateAnchor(); | |
| 981 // Ensure that the notification buble is above the launcher/status area. | |
| 982 notification_bubble_->bubble_view()->GetWidget()->StackAtTop(); | |
| 818 } | 983 } |
| 819 | 984 |
| 820 bool SystemTray::PerformAction(const views::Event& event) { | 985 bool SystemTray::PerformAction(const views::Event& event) { |
| 821 // If we're already showing the default view, hide it; otherwise, show it | 986 // If we're already showing the default view, hide it; otherwise, show it |
| 822 // (and hide any popup that's currently shown). | 987 // (and hide any popup that's currently shown). |
| 823 if (bubble_.get() && !bubble_->detailed()) | 988 if (bubble_.get() && |
| 989 bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DEFAULT) { | |
| 824 bubble_->Close(); | 990 bubble_->Close(); |
| 825 else | 991 } else { |
| 826 ShowDefaultView(); | 992 ShowDefaultView(); |
| 993 } | |
| 827 return true; | 994 return true; |
| 828 } | 995 } |
| 829 | 996 |
| 830 void SystemTray::OnMouseEntered(const views::MouseEvent& event) { | 997 void SystemTray::OnMouseEntered(const views::MouseEvent& event) { |
| 831 should_show_launcher_ = true; | 998 should_show_launcher_ = true; |
| 832 hover_background_animator_.SetPaintsBackground(true, | 999 hover_background_animator_.SetPaintsBackground(true, |
| 833 internal::BackgroundAnimator::CHANGE_ANIMATE); | 1000 internal::BackgroundAnimator::CHANGE_ANIMATE); |
| 834 } | 1001 } |
| 835 | 1002 |
| 836 void SystemTray::OnMouseExited(const views::MouseEvent& event) { | 1003 void SystemTray::OnMouseExited(const views::MouseEvent& event) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 851 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; | 1018 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; |
| 852 state->name = l10n_util::GetStringUTF16( | 1019 state->name = l10n_util::GetStringUTF16( |
| 853 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); | 1020 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); |
| 854 } | 1021 } |
| 855 | 1022 |
| 856 void SystemTray::OnPaintFocusBorder(gfx::Canvas* canvas) { | 1023 void SystemTray::OnPaintFocusBorder(gfx::Canvas* canvas) { |
| 857 // The tray itself expands to the right and bottom edge of the screen to make | 1024 // The tray itself expands to the right and bottom edge of the screen to make |
| 858 // sure clicking on the edges brings up the popup. However, the focus border | 1025 // sure clicking on the edges brings up the popup. However, the focus border |
| 859 // should be only around the container. | 1026 // should be only around the container. |
| 860 if (GetWidget() && GetWidget()->IsActive()) | 1027 if (GetWidget() && GetWidget()->IsActive()) |
| 861 canvas->DrawFocusRect(container_->bounds()); | 1028 canvas->DrawFocusRect(tray_container_->bounds()); |
| 862 } | 1029 } |
| 863 | 1030 |
| 864 void SystemTray::UpdateBackground(int alpha) { | 1031 void SystemTray::UpdateBackground(int alpha) { |
| 865 background_->set_alpha(hide_background_animator_.alpha() + | 1032 background_->set_alpha(hide_background_animator_.alpha() + |
| 866 hover_background_animator_.alpha()); | 1033 hover_background_animator_.alpha()); |
| 867 SchedulePaint(); | 1034 SchedulePaint(); |
| 868 } | 1035 } |
| 869 | 1036 |
| 870 } // namespace ash | 1037 } // namespace ash |
| OLD | NEW |