OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/browser/views/status_bubble_views.h" | 5 #include "chrome/browser/views/status_bubble_views.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "app/gfx/canvas.h" | 9 #include "app/gfx/canvas.h" |
10 #include "app/gfx/text_elider.h" | 10 #include "app/gfx/text_elider.h" |
11 #include "app/l10n_util.h" | 11 #include "app/l10n_util.h" |
12 #if defined(OS_WIN) | |
13 #include "app/l10n_util_win.h" | |
14 #endif | |
15 #include "app/animation.h" | 12 #include "app/animation.h" |
16 #include "app/resource_bundle.h" | 13 #include "app/resource_bundle.h" |
17 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
18 #include "base/string_util.h" | 15 #include "base/string_util.h" |
19 #include "chrome/browser/browser_theme_provider.h" | 16 #include "chrome/browser/browser_theme_provider.h" |
20 #include "googleurl/src/gurl.h" | 17 #include "googleurl/src/gurl.h" |
21 #include "grit/generated_resources.h" | 18 #include "grit/generated_resources.h" |
22 #include "grit/theme_resources.h" | 19 #include "grit/theme_resources.h" |
23 #include "net/base/net_util.h" | 20 #include "net/base/net_util.h" |
24 #include "third_party/skia/include/core/SkPaint.h" | 21 #include "third_party/skia/include/core/SkPaint.h" |
25 #include "third_party/skia/include/core/SkPath.h" | 22 #include "third_party/skia/include/core/SkPath.h" |
26 #include "third_party/skia/include/core/SkRect.h" | 23 #include "third_party/skia/include/core/SkRect.h" |
27 #include "views/controls/label.h" | 24 #include "views/controls/label.h" |
| 25 #include "views/screen.h" |
28 #include "views/widget/root_view.h" | 26 #include "views/widget/root_view.h" |
29 #include "views/widget/widget.h" | 27 #include "views/widget/widget.h" |
30 #if defined(OS_WIN) | 28 #include "views/window/window.h" |
31 #include "views/widget/widget_win.h" | |
32 #endif | |
33 | 29 |
34 // The alpha and color of the bubble's shadow. | 30 // The alpha and color of the bubble's shadow. |
35 static const SkColor kShadowColor = SkColorSetARGB(30, 0, 0, 0); | 31 static const SkColor kShadowColor = SkColorSetARGB(30, 0, 0, 0); |
36 | 32 |
37 // The roundedness of the edges of our bubble. | 33 // The roundedness of the edges of our bubble. |
38 static const int kBubbleCornerRadius = 4; | 34 static const int kBubbleCornerRadius = 4; |
39 | 35 |
40 // How close the mouse can get to the infobubble before it starts sliding | 36 // How close the mouse can get to the infobubble before it starts sliding |
41 // off-screen. | 37 // off-screen. |
42 static const int kMousePadding = 20; | 38 static const int kMousePadding = 20; |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 download_shelf_is_visible_(false) { | 455 download_shelf_is_visible_(false) { |
460 } | 456 } |
461 | 457 |
462 StatusBubbleViews::~StatusBubbleViews() { | 458 StatusBubbleViews::~StatusBubbleViews() { |
463 if (popup_.get()) | 459 if (popup_.get()) |
464 popup_->CloseNow(); | 460 popup_->CloseNow(); |
465 } | 461 } |
466 | 462 |
467 void StatusBubbleViews::Init() { | 463 void StatusBubbleViews::Init() { |
468 if (!popup_.get()) { | 464 if (!popup_.get()) { |
469 #if defined(OS_WIN) | 465 popup_.reset(views::Widget::CreateTransparentPopupWidget(false)); |
470 views::WidgetWin* popup = new views::WidgetWin; | |
471 popup->set_delete_on_destroy(false); | |
472 | |
473 if (!view_) | 466 if (!view_) |
474 view_ = new StatusView(this, popup, frame_->GetThemeProvider()); | 467 view_ = new StatusView(this, popup_.get(), frame_->GetThemeProvider()); |
475 | 468 popup_->SetOpacity(0x00); |
476 popup->set_window_style(WS_POPUP); | 469 popup_->Init(frame_->GetNativeView(), gfx::Rect()); |
477 popup->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW | | 470 popup_->SetContentsView(view_); |
478 WS_EX_TRANSPARENT | | |
479 l10n_util::GetExtendedTooltipStyles()); | |
480 popup->SetOpacity(0x00); | |
481 popup->Init(frame_->GetNativeView(), gfx::Rect()); | |
482 popup->SetContentsView(view_); | |
483 Reposition(); | 471 Reposition(); |
484 popup->Show(); | 472 popup_->Show(); |
485 popup_.reset(popup); | |
486 #else | |
487 NOTIMPLEMENTED(); | |
488 #endif | |
489 } | 473 } |
490 } | 474 } |
491 | 475 |
492 void StatusBubbleViews::Reposition() { | 476 void StatusBubbleViews::Reposition() { |
493 if (popup_.get()) { | 477 if (popup_.get()) { |
494 gfx::Point top_left; | 478 gfx::Point top_left; |
495 views::View::ConvertPointToScreen(frame_->GetRootView(), &top_left); | 479 views::View::ConvertPointToScreen(frame_->GetRootView(), &top_left); |
496 | 480 |
497 popup_->SetBounds(gfx::Rect(top_left.x() + position_.x(), | 481 popup_->SetBounds(gfx::Rect(top_left.x() + position_.x(), |
498 top_left.y() + position_.y(), | 482 top_left.y() + position_.y(), |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 AvoidMouse(); | 566 AvoidMouse(); |
583 } | 567 } |
584 } | 568 } |
585 } | 569 } |
586 | 570 |
587 void StatusBubbleViews::UpdateDownloadShelfVisibility(bool visible) { | 571 void StatusBubbleViews::UpdateDownloadShelfVisibility(bool visible) { |
588 download_shelf_is_visible_ = visible; | 572 download_shelf_is_visible_ = visible; |
589 } | 573 } |
590 | 574 |
591 void StatusBubbleViews::AvoidMouse() { | 575 void StatusBubbleViews::AvoidMouse() { |
592 // Our status bubble is located in screen coordinates, so we should get | |
593 // those rather than attempting to reverse decode the web contents | |
594 // coordinates. | |
595 gfx::Point cursor_location; | |
596 #if defined(OS_WIN) | |
597 POINT tmp = { 0, 0 }; | |
598 GetCursorPos(&tmp); | |
599 cursor_location = tmp; | |
600 #else | |
601 NOTIMPLEMENTED(); | |
602 #endif | |
603 | |
604 // Get the position of the frame. | 576 // Get the position of the frame. |
605 gfx::Point top_left; | 577 gfx::Point top_left; |
606 views::RootView* root = frame_->GetRootView(); | 578 views::RootView* root = frame_->GetRootView(); |
607 views::View::ConvertPointToScreen(root, &top_left); | 579 views::View::ConvertPointToScreen(root, &top_left); |
608 int window_width = root->GetLocalBounds(true).width(); // border included. | 580 int window_width = root->GetLocalBounds(true).width(); // border included. |
609 | 581 |
| 582 // Our status bubble is located in screen coordinates, so we should get |
| 583 // those rather than attempting to reverse decode the web contents |
| 584 // coordinates. |
| 585 gfx::Point cursor_location = views::Screen::GetCursorScreenPoint(); |
| 586 |
610 // Get the cursor position relative to the popup. | 587 // Get the cursor position relative to the popup. |
611 if (view_->UILayoutIsRightToLeft()) { | 588 if (view_->UILayoutIsRightToLeft()) { |
612 int top_right_x = top_left.x() + window_width; | 589 int top_right_x = top_left.x() + window_width; |
613 cursor_location.set_x(top_right_x - cursor_location.x()); | 590 cursor_location.set_x(top_right_x - cursor_location.x()); |
614 } else { | 591 } else { |
615 cursor_location.set_x(cursor_location.x() - (top_left.x() + position_.x())); | 592 cursor_location.set_x(cursor_location.x() - (top_left.x() + position_.x())); |
616 } | 593 } |
617 cursor_location.set_y(cursor_location.y() - (top_left.y() + position_.y())); | 594 cursor_location.set_y(cursor_location.y() - (top_left.y() + position_.y())); |
618 | 595 |
619 // If the mouse is in a position where we think it would move the | 596 // If the mouse is in a position where we think it would move the |
(...skipping 21 matching lines...) Expand all Loading... |
641 offset = size_.height() - kShadowThickness * 2; | 618 offset = size_.height() - kShadowThickness * 2; |
642 view_->SetStyle(StatusView::STYLE_BOTTOM); | 619 view_->SetStyle(StatusView::STYLE_BOTTOM); |
643 } else if (offset > kBubbleCornerRadius / 2 - kShadowThickness) { | 620 } else if (offset > kBubbleCornerRadius / 2 - kShadowThickness) { |
644 view_->SetStyle(StatusView::STYLE_FLOATING); | 621 view_->SetStyle(StatusView::STYLE_FLOATING); |
645 } else { | 622 } else { |
646 view_->SetStyle(StatusView::STYLE_STANDARD); | 623 view_->SetStyle(StatusView::STYLE_STANDARD); |
647 } | 624 } |
648 | 625 |
649 // Check if the bubble sticks out from the monitor or will obscure | 626 // Check if the bubble sticks out from the monitor or will obscure |
650 // download shelf. | 627 // download shelf. |
651 #if defined(OS_WIN) | 628 gfx::NativeWindow window = frame_->GetWindow()->GetNativeWindow(); |
652 MONITORINFO monitor_info; | 629 gfx::Rect monitor_rect = |
653 monitor_info.cbSize = sizeof(monitor_info); | 630 views::Screen::GetMonitorWorkAreaNearestWindow(window); |
654 GetMonitorInfo(MonitorFromWindow(frame_->GetNativeView(), | |
655 MONITOR_DEFAULTTONEAREST), &monitor_info); | |
656 gfx::Rect monitor_rect(monitor_info.rcWork); | |
657 #else | |
658 gfx::Rect monitor_rect; | |
659 NOTIMPLEMENTED(); | |
660 #endif | |
661 const int bubble_bottom_y = top_left.y() + position_.y() + size_.height(); | 631 const int bubble_bottom_y = top_left.y() + position_.y() + size_.height(); |
662 | 632 |
663 if (bubble_bottom_y + offset > monitor_rect.height() || | 633 if (bubble_bottom_y + offset > monitor_rect.height() || |
664 (download_shelf_is_visible_ && | 634 (download_shelf_is_visible_ && |
665 view_->GetStyle() == StatusView::STYLE_FLOATING)) { | 635 view_->GetStyle() == StatusView::STYLE_FLOATING)) { |
666 // The offset is still too large. Move the bubble to the right and reset | 636 // The offset is still too large. Move the bubble to the right and reset |
667 // Y offset_ to zero. | 637 // Y offset_ to zero. |
668 view_->SetStyle(StatusView::STYLE_STANDARD_RIGHT); | 638 view_->SetStyle(StatusView::STYLE_STANDARD_RIGHT); |
669 offset_ = 0; | 639 offset_ = 0; |
670 | 640 |
(...skipping 10 matching lines...) Expand all Loading... |
681 } | 651 } |
682 } else if (offset_ != 0 || | 652 } else if (offset_ != 0 || |
683 view_->GetStyle() == StatusView::STYLE_STANDARD_RIGHT) { | 653 view_->GetStyle() == StatusView::STYLE_STANDARD_RIGHT) { |
684 offset_ = 0; | 654 offset_ = 0; |
685 view_->SetStyle(StatusView::STYLE_STANDARD); | 655 view_->SetStyle(StatusView::STYLE_STANDARD); |
686 popup_->SetBounds(gfx::Rect(top_left.x() + position_.x(), | 656 popup_->SetBounds(gfx::Rect(top_left.x() + position_.x(), |
687 top_left.y() + position_.y(), | 657 top_left.y() + position_.y(), |
688 size_.width(), size_.height())); | 658 size_.width(), size_.height())); |
689 } | 659 } |
690 } | 660 } |
OLD | NEW |