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

Unified Diff: chrome/browser/ui/views/fullscreen_exit_bubble_views.cc

Issue 12413002: Have FullscreenExitBubbleViews use BubbleDelegateView. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: TESTING Created 7 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ui/views/fullscreen_exit_bubble_views.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/views/fullscreen_exit_bubble_views.cc
diff --git a/chrome/browser/ui/views/fullscreen_exit_bubble_views.cc b/chrome/browser/ui/views/fullscreen_exit_bubble_views.cc
index f0be06d4f394b89f7e7fa57b9f4751335d2d3d63..23ebda358721a038f0f7365271110db47ccaf25c 100644
--- a/chrome/browser/ui/views/fullscreen_exit_bubble_views.cc
+++ b/chrome/browser/ui/views/fullscreen_exit_bubble_views.cc
@@ -7,6 +7,7 @@
#include "base/message_loop.h"
#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
#include "googleurl/src/gurl.h"
#include "grit/generated_resources.h"
#include "grit/ui_strings.h"
@@ -16,14 +17,13 @@
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/screen.h"
-#include "ui/views/bubble/bubble_border.h"
+#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/controls/button/text_button.h"
#include "ui/views/controls/link.h"
#include "ui/views/controls/link_listener.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/grid_layout.h"
-#include "ui/views/view.h"
-#include "ui/views/widget/widget.h"
#if defined(OS_WIN)
#include "ui/base/l10n/l10n_util_win.h"
@@ -73,19 +73,63 @@ gfx::Size ButtonView::GetPreferredSize() {
return visible() ? views::View::GetPreferredSize() : gfx::Size();
}
+// A custom BubbleFrameView that clips its drawing area to a specific display.
+class ClippedBubbleFrameView : public views::BubbleFrameView {
+ public:
+ explicit ClippedBubbleFrameView(const gfx::Insets& margins,
+ const gfx::Rect display);
+ ~ClippedBubbleFrameView();
+
+ // views::BubbleFrameView
+ virtual void Paint(gfx::Canvas* canvas) OVERRIDE;
+
+ private:
+ // The display bounds to which this view is clipped, in screen coordinates.
+ gfx::Rect display_;
+
+ DISALLOW_COPY_AND_ASSIGN(ClippedBubbleFrameView);
+};
+
+ClippedBubbleFrameView::ClippedBubbleFrameView(const gfx::Insets& margins,
+ const gfx::Rect display)
+ : BubbleFrameView(margins),
+ display_(display) {
+}
+
+ClippedBubbleFrameView::~ClippedBubbleFrameView() {}
+
+void ClippedBubbleFrameView::Paint(gfx::Canvas* canvas) {
+ gfx::Point screen_top = display_.origin();
+ ConvertPointToTarget(NULL, this, &screen_top);
+ if (screen_top.y() > 0) {
+ // Clip the canvas to avoid drawing the bubble frame on other displays.
+ canvas->Save();
+ canvas->ClipRect(gfx::Rect(0, screen_top.y(), width(), height()));
+ BubbleFrameView::Paint(canvas);
+ canvas->Restore();
+ } else {
+ BubbleFrameView::Paint(canvas);
+ }
+}
+
} // namespace
class FullscreenExitBubbleViews::FullscreenExitView
- : public views::View,
+ : public views::BubbleDelegateView,
public views::ButtonListener,
public views::LinkListener {
public:
FullscreenExitView(FullscreenExitBubbleViews* bubble,
- const string16& accelerator,
+ views::Widget* frame,
const GURL& url,
FullscreenExitBubbleType bubble_type);
virtual ~FullscreenExitView();
+ // views::BubbleDelegateView
+ virtual views::NonClientFrameView* CreateNonClientFrameView(
+ views::Widget* widget) OVERRIDE;
+ virtual void Paint(gfx::Canvas* canvas) OVERRIDE;
+
// views::ButtonListener
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE;
@@ -95,6 +139,10 @@ class FullscreenExitBubbleViews::FullscreenExitView
void UpdateContent(const GURL& url, FullscreenExitBubbleType bubble_type);
+ // Schedule a paint to update the clip rects and properly clip the bubble view
+ // and bubble frame to the bounds of the fullscreen display.
+ void ScheduleClippedPaint();
+
private:
FullscreenExitBubbleViews* bubble_;
@@ -105,27 +153,26 @@ class FullscreenExitBubbleViews::FullscreenExitView
// Informational label: 'www.foo.com has gone fullscreen'.
views::Label* message_label_;
ButtonView* button_view_;
- const string16 browser_fullscreen_exit_accelerator_;
+ string16 browser_fullscreen_exit_accelerator_;
DISALLOW_COPY_AND_ASSIGN(FullscreenExitView);
};
FullscreenExitBubbleViews::FullscreenExitView::FullscreenExitView(
FullscreenExitBubbleViews* bubble,
- const string16& accelerator,
+ views::Widget* frame,
const GURL& url,
FullscreenExitBubbleType bubble_type)
: bubble_(bubble),
link_(NULL),
mouse_lock_exit_instruction_(NULL),
message_label_(NULL),
- button_view_(NULL),
- browser_fullscreen_exit_accelerator_(accelerator) {
- views::BubbleBorder* bubble_border = new views::BubbleBorder(
- views::BubbleBorder::NONE, views::BubbleBorder::SHADOW, SK_ColorWHITE);
- set_background(new views::BubbleBackground(bubble_border));
- set_border(bubble_border);
- set_focusable(false);
+ button_view_(NULL) {
+ set_parent_window(frame->GetNativeView());
+ set_arrow_location(views::BubbleBorder::NONE);
+ set_shadow(views::BubbleBorder::SHADOW);
+ set_adjust_if_offscreen(false);
+ set_use_focusless(true);
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
message_label_ = new views::Label();
@@ -180,12 +227,41 @@ FullscreenExitBubbleViews::FullscreenExitView::FullscreenExitView(
layout->SetInsets(padding);
SetLayoutManager(layout);
+ ui::Accelerator accelerator;
+ bool got_accelerator = frame->GetAccelerator(IDC_FULLSCREEN, &accelerator);
+ DCHECK(got_accelerator);
+ browser_fullscreen_exit_accelerator_ = accelerator.GetShortcutText();
+
UpdateContent(url, bubble_type);
}
FullscreenExitBubbleViews::FullscreenExitView::~FullscreenExitView() {
}
+views::NonClientFrameView*
+FullscreenExitBubbleViews::FullscreenExitView::CreateNonClientFrameView(
+ views::Widget* widget) {
+ ClippedBubbleFrameView* frame =
+ new ClippedBubbleFrameView(margins(), bubble_->display_bounds());
+ frame->SetBubbleBorder(
+ new views::BubbleBorder(arrow_location(), shadow(), color()));
+ return frame;
+}
+
+void FullscreenExitBubbleViews::FullscreenExitView::Paint(gfx::Canvas* canvas) {
+ gfx::Point screen_top = bubble_->display_bounds().origin();
+ ConvertPointFromScreen(this, &screen_top);
+ if (screen_top.y() > 0) {
+ // Clip the canvas to avoid drawing the bubble contents on other displays.
+ canvas->Save();
+ canvas->ClipRect(gfx::Rect(0, screen_top.y(), width(), height()));
+ BubbleDelegateView::Paint(canvas);
+ canvas->Restore();
+ } else {
+ BubbleDelegateView::Paint(canvas);
+ }
+}
+
void FullscreenExitBubbleViews::FullscreenExitView::ButtonPressed(
views::Button* sender,
const ui::Event& event) {
@@ -239,62 +315,36 @@ void FullscreenExitBubbleViews::FullscreenExitView::UpdateContent(
}
}
+void FullscreenExitBubbleViews::FullscreenExitView::ScheduleClippedPaint() {
+ SchedulePaint();
+ GetBubbleFrameView()->SchedulePaint();
+}
// FullscreenExitBubbleViews ---------------------------------------------------
FullscreenExitBubbleViews::FullscreenExitBubbleViews(
- views::Widget* frame,
- Browser* browser,
+ BrowserView* browser_view,
const GURL& url,
FullscreenExitBubbleType bubble_type)
- : FullscreenExitBubble(browser, url, bubble_type),
- root_view_(frame->GetRootView()),
- popup_(NULL),
- size_animation_(new ui::SlideAnimation(this)) {
- size_animation_->Reset(1);
-
- // Create the contents view.
- ui::Accelerator accelerator(ui::VKEY_UNKNOWN, ui::EF_NONE);
- bool got_accelerator = frame->GetAccelerator(IDC_FULLSCREEN, &accelerator);
- DCHECK(got_accelerator);
+ : FullscreenExitBubble(browser_view->browser(), url, bubble_type),
+ browser_view_(browser_view),
+ animation_(new ui::SlideAnimation(this)) {
+ // Cache the display bounds for popup rect calculations.
+ const gfx::NativeView view = browser_view->GetWidget()->GetNativeView();
+ const gfx::Screen* screen = gfx::Screen::GetScreenFor(view);
+ display_ = screen->GetDisplayNearestWindow(view).bounds();
+
+ animation_->Reset(1);
view_ = new FullscreenExitView(
- this, accelerator.GetShortcutText(), url, bubble_type_);
-
- // TODO(yzshen): Change to use the new views bubble, BubbleDelegateView.
- // Initialize the popup.
- popup_ = new views::Widget;
- views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
- params.transparent = true;
- params.can_activate = false;
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.parent = frame->GetNativeView();
- params.bounds = GetPopupRect(false);
- popup_->Init(params);
- gfx::Size size = GetPopupRect(true).size();
- popup_->SetContentsView(view_);
- // We set layout manager to NULL to prevent the widget from sizing its
- // contents to the same size as itself. This prevents the widget contents from
- // shrinking while we animate the height of the popup to give the impression
- // that it is sliding off the top of the screen.
- popup_->GetRootView()->SetLayoutManager(NULL);
- view_->SetBounds(0, 0, size.width(), size.height());
- popup_->Show(); // This does not activate the popup.
-
+ this, browser_view->GetWidget(), url, bubble_type_);
+ views::Widget* bubble = views::BubbleDelegateView::CreateBubble(view_);
+ bubble->Show();
+ bubble->SetBounds(GetPopupRect(true));
StartWatchingMouseIfNecessary();
}
FullscreenExitBubbleViews::~FullscreenExitBubbleViews() {
- // This is tricky. We may be in an ATL message handler stack, in which case
- // the popup cannot be deleted yet. We also can't set the popup's ownership
- // model to NATIVE_WIDGET_OWNS_WIDGET because if the user closed the last tab
- // while in fullscreen mode, Windows has already destroyed the popup HWND by
- // the time we get here, and thus either the popup will already have been
- // deleted (if we set this in our constructor) or the popup will never get
- // another OnFinalMessage() call (if not, as currently). So instead, we tell
- // the popup to synchronously hide, and then asynchronously close and delete
- // itself.
- popup_->Close();
- MessageLoop::current()->DeleteSoon(FROM_HERE, popup_);
+ view_->GetWidget()->Close();
}
void FullscreenExitBubbleViews::UpdateContent(
@@ -307,10 +357,6 @@ void FullscreenExitBubbleViews::UpdateContent(
url_ = url;
bubble_type_ = bubble_type;
view_->UpdateContent(url_, bubble_type_);
-
- gfx::Size size = GetPopupRect(true).size();
- view_->SetSize(size);
- popup_->SetBounds(GetPopupRect(false));
Show();
StopWatchingMouse();
@@ -319,14 +365,8 @@ void FullscreenExitBubbleViews::UpdateContent(
void FullscreenExitBubbleViews::AnimationProgressed(
const ui::Animation* animation) {
- gfx::Rect popup_rect(GetPopupRect(false));
- if (popup_rect.IsEmpty()) {
- popup_->Hide();
- } else {
- popup_->SetBounds(popup_rect);
- view_->SetY(popup_rect.height() - view_->height());
- popup_->Show();
- }
+ view_->GetWidget()->SetBounds(GetPopupRect(false));
+ view_->ScheduleClippedPaint();
}
void FullscreenExitBubbleViews::AnimationEnded(
@@ -336,54 +376,41 @@ void FullscreenExitBubbleViews::AnimationEnded(
gfx::Rect FullscreenExitBubbleViews::GetPopupRect(
bool ignore_animation_state) const {
- gfx::Size size(view_->GetPreferredSize());
- // NOTE: don't use the bounds of the root_view_. On linux changing window
- // size is async. Instead we use the size of the screen.
- gfx::Screen* screen =
- gfx::Screen::GetScreenFor(root_view_->GetWidget()->GetNativeView());
- gfx::Rect screen_bounds = screen->GetDisplayNearestWindow(
- root_view_->GetWidget()->GetNativeView()).bounds();
- gfx::Point origin(screen_bounds.x() +
- (screen_bounds.width() - size.width()) / 2,
- kPopupTopPx + screen_bounds.y());
- if (!ignore_animation_state) {
- int total_height = size.height() + kPopupTopPx;
- int popup_bottom = size_animation_->CurrentValueBetween(
- static_cast<double>(total_height), 0.0f);
- int y_offset = std::min(popup_bottom, kPopupTopPx);
- size.set_height(size.height() - popup_bottom + y_offset);
- origin.set_y(origin.y() - y_offset);
- }
+ const gfx::Size size(view_->GetWidget()->GetWindowBoundsInScreen().size());
+ const int offset = ignore_animation_state ? 0 :
+ animation_->CurrentValueBetween(size.height() + kPopupTopPx, 0);
+ const gfx::Point origin(display_.x() + (display_.width() - size.width()) / 2,
+ kPopupTopPx + display_.y() - offset);
return gfx::Rect(origin, size);
}
gfx::Point FullscreenExitBubbleViews::GetCursorScreenPoint() {
gfx::Point cursor_pos = gfx::Screen::GetScreenFor(
- root_view_->GetWidget()->GetNativeView())->GetCursorScreenPoint();
- views::View::ConvertPointToTarget(NULL, root_view_, &cursor_pos);
+ browser_view_->GetWidget()->GetNativeView())->GetCursorScreenPoint();
+ views::View::ConvertPointToTarget(NULL, browser_view_, &cursor_pos);
return cursor_pos;
}
bool FullscreenExitBubbleViews::WindowContainsPoint(gfx::Point pos) {
- return root_view_->HitTestPoint(pos);
+ return browser_view_->HitTestPoint(pos);
}
bool FullscreenExitBubbleViews::IsWindowActive() {
- return root_view_->GetWidget()->IsActive();
+ return browser_view_->GetWidget()->IsActive();
}
void FullscreenExitBubbleViews::Hide() {
- size_animation_->SetSlideDuration(kSlideOutDurationMs);
- size_animation_->Hide();
+ animation_->SetSlideDuration(kSlideOutDurationMs);
+ animation_->Hide();
}
void FullscreenExitBubbleViews::Show() {
- size_animation_->SetSlideDuration(kSlideInDurationMs);
- size_animation_->Show();
+ animation_->SetSlideDuration(kSlideInDurationMs);
+ animation_->Show();
}
bool FullscreenExitBubbleViews::IsAnimating() {
- return size_animation_->GetCurrentValue() != 0;
+ return animation_->GetCurrentValue() != 0;
}
void FullscreenExitBubbleViews::StartWatchingMouseIfNecessary() {
« no previous file with comments | « chrome/browser/ui/views/fullscreen_exit_bubble_views.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698