diff options
-rw-r--r-- | chrome/browser/views/browser_bubble.cc | 58 | ||||
-rw-r--r-- | chrome/browser/views/browser_bubble.h | 91 | ||||
-rw-r--r-- | chrome/browser/views/browser_bubble_win.cc | 57 | ||||
-rw-r--r-- | chrome/browser/views/browser_views.vcproj | 12 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.cc | 19 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.h | 12 |
6 files changed, 248 insertions, 1 deletions
diff --git a/chrome/browser/views/browser_bubble.cc b/chrome/browser/views/browser_bubble.cc new file mode 100644 index 0000000..cfab7ca --- /dev/null +++ b/chrome/browser/views/browser_bubble.cc @@ -0,0 +1,58 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/views/browser_bubble.h" + +#include "app/l10n_util.h" +#include "views/widget/root_view.h" + +BrowserBubble::BrowserBubble(views::View* view, views::Widget* frame, + const gfx::Point& origin) + : frame_(frame), + view_(view), + visible_(false), + delegate_(NULL) { + gfx::Size size = view->GetPreferredSize(); + bounds_.SetRect(origin.x(), origin.y(), size.width(), size.height()); + InitPopup(); +} + +BrowserBubble::~BrowserBubble() { + DestroyPopup(); +} + +void BrowserBubble::BrowserWindowMoved() { + if (delegate_) + delegate_->BubbleBrowserWindowMoved(this); + else + Hide(); +} + +void BrowserBubble::BrowserWindowClosed() { + if (delegate_) + delegate_->BubbleBrowserWindowClosed(this); + else + Hide(); +} + +void BrowserBubble::SetBounds(int x, int y, int w, int h) { + // If the UI layout is RTL, we need to mirror the position of the bubble + // relative to the parent. + if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) { + gfx::Rect frame_bounds; + frame_->GetBounds(&frame_bounds, false); + x = frame_bounds.width() - x - w; + } + bounds_.SetRect(x, y, w, h); + Reposition(); +} + +void BrowserBubble::Reposition() { + gfx::Point top_left; + views::View::ConvertPointToScreen(frame_->GetRootView(), &top_left); + MovePopup(top_left.x() + bounds_.x(), + top_left.y() + bounds_.y(), + bounds_.width(), + bounds_.height()); +} diff --git a/chrome/browser/views/browser_bubble.h b/chrome/browser/views/browser_bubble.h new file mode 100644 index 0000000..49ce7fe --- /dev/null +++ b/chrome/browser/views/browser_bubble.h @@ -0,0 +1,91 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_VIEWS_BROWSER_BUBBLE_ +#define CHROME_BROWSER_VIEWS_BROWSER_BUBBLE_ + +#include "views/view.h" +#include "views/widget/widget.h" + +// A class for creating a floating window that is "attached" to a particular +// Browser. If you don't install a delegate, the bubble will hide +// automatically when the browser moves. The bubble is only shown manually. +// Users are expected to delete the bubble when finished with it. +class BrowserBubble { + public: + // Delegate to browser bubble events. + class Delegate { + public: + // Called when the Browser Window that this bubble is attached to moves. + virtual void BubbleBrowserWindowMoved(BrowserBubble* bubble) = 0; + virtual void BubbleBrowserWindowClosed(BrowserBubble* bubble) = 0; + }; + + // Note that the bubble will size itself to the preferred size of |view|. + // |view| is the embedded view, |frame| is widget that the bubble is being + // positioned relative to, |origin| is the location that the bubble will + // be positioned relative to |frame|. + BrowserBubble(views::View* view, views::Widget* frame, + const gfx::Point& origin); + virtual ~BrowserBubble(); + + // Get/Set the delegate. + Delegate* delegate() const { return delegate_; } + void set_delegate(Delegate* del) { delegate_ = del; } + + // Notifications from BrowserView. + // With no delegate, both of these default to Hiding the bubble. + virtual void BrowserWindowMoved(); + virtual void BrowserWindowClosed(); + + // Show or hide the bubble. + void Show(); + void Hide(); + bool is_visible() const { return visible_; } + + // The contained view. + views::View* view() const { return view_; } + + // Set the bounds of the bubble relative to the browser window. + void SetBounds(int x, int y, int w, int h); + int width() { return bounds_.width(); } + int height() { return bounds_.height(); } + + // Reposition the bubble - as we are using a WS_POPUP for the bubble, + // we have to manually position it when the browser window moves. + void Reposition(); + + protected: + // Create the popup widget. + virtual void InitPopup(); + + // Destroy the popup widget. + virtual void DestroyPopup(); + + // Move the popup to an absolute position. + void MovePopup(int x, int y, int w, int h); + + private: + // The frame that this bubble is attached to. + views::Widget* frame_; + + // The view that is displayed in this bubble. + views::View* view_; + + // The actual widget that this bubble is in. + scoped_ptr<views::Widget> popup_; + + // The bounds relative to the frame. + gfx::Rect bounds_; + + // Current visibility. + bool visible_; + + // The delegate isn't owned by the bubble. + Delegate* delegate_; + + DISALLOW_COPY_AND_ASSIGN(BrowserBubble); +}; + +#endif // CHROME_BROWSER_VIEWS_BROWSER_BUBBLE_ diff --git a/chrome/browser/views/browser_bubble_win.cc b/chrome/browser/views/browser_bubble_win.cc new file mode 100644 index 0000000..7471baa --- /dev/null +++ b/chrome/browser/views/browser_bubble_win.cc @@ -0,0 +1,57 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/views/browser_bubble.h" + +#include "app/l10n_util_win.h" +#include "chrome/browser/views/frame/browser_view.h" +#include "views/widget/widget_win.h" + +void BrowserBubble::InitPopup() { + gfx::NativeView native_view = frame_->GetNativeView(); + views::WidgetWin* pop = new views::WidgetWin(); + pop->set_delete_on_destroy(false); + pop->set_window_style(WS_POPUP); + pop->set_window_ex_style(WS_EX_LAYERED | + WS_EX_TOOLWINDOW | + l10n_util::GetExtendedTooltipStyles()); + pop->SetLayeredAlpha(0xFF); + pop->Init(native_view, bounds_, false); + pop->SetContentsView(view_); + popup_.reset(pop); + Reposition(); + + BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(native_view); + DCHECK(browser_view); + if (browser_view) + browser_view->AttachBrowserBubble(this); +} + +void BrowserBubble::DestroyPopup() { + gfx::NativeView native_view = frame_->GetNativeView(); + BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(native_view); + if (browser_view) + browser_view->DetachBrowserBubble(this); +} + +void BrowserBubble::MovePopup(int x, int y, int w, int h) { + views::WidgetWin* pop = static_cast<views::WidgetWin*>(popup_.get()); + pop->MoveWindow(x, y, w, h); +} + +void BrowserBubble::Show() { + if (visible_) + return; + views::WidgetWin* pop = static_cast<views::WidgetWin*>(popup_.get()); + pop->Show(); + visible_ = true; +} + +void BrowserBubble::Hide() { + if (!visible_) + return; + views::WidgetWin* pop = static_cast<views::WidgetWin*>(popup_.get()); + pop->Hide(); + visible_ = false; +} diff --git a/chrome/browser/views/browser_views.vcproj b/chrome/browser/views/browser_views.vcproj index 75e2939..3039f3c 100644 --- a/chrome/browser/views/browser_views.vcproj +++ b/chrome/browser/views/browser_views.vcproj @@ -490,6 +490,18 @@ > </File> <File + RelativePath=".\browser_bubble.cc" + > + </File> + <File + RelativePath=".\browser_bubble.h" + > + </File> + <File + RelativePath=".\browser_bubble_win.cc" + > + </File> + <File RelativePath=".\bug_report_view.cc" > </File> diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index e12d4b1..72957ed 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -27,6 +27,7 @@ #include "chrome/browser/views/bookmark_bar_view.h" #include "chrome/browser/views/bookmark_bubble_view.h" #include "chrome/browser/views/bookmark_manager_view.h" +#include "chrome/browser/views/browser_bubble.h" #include "chrome/browser/views/bug_report_view.h" #include "chrome/browser/views/chrome_views_delegate.h" #include "chrome/browser/views/clear_browsing_data.h" @@ -330,6 +331,11 @@ void BrowserView::WindowMoved() { status_bubble_->Reposition(); + BubbleSet::iterator bubble = browser_bubbles_.begin(); + for (; bubble != browser_bubbles_.end(); ++bubble) { + (*bubble)->BrowserWindowMoved(); + } + BookmarkBubbleView::Hide(); // Close the omnibox popup, if any. @@ -507,6 +513,14 @@ void BrowserView::RegisterBrowserViewPrefs(PrefService* prefs) { kDefaultHungPluginDetectFrequency); } +void BrowserView::AttachBrowserBubble(BrowserBubble* bubble) { + browser_bubbles_.insert(bubble); +} + +void BrowserView::DetachBrowserBubble(BrowserBubble* bubble) { + browser_bubbles_.erase(bubble); +} + /////////////////////////////////////////////////////////////////////////////// // BrowserView, BrowserWindow implementation: @@ -540,6 +554,11 @@ void BrowserView::SetBounds(const gfx::Rect& bounds) { void BrowserView::Close() { frame_->Close(); + + BubbleSet::iterator bubble = browser_bubbles_.begin(); + for (; bubble != browser_bubbles_.end(); ++bubble) { + (*bubble)->BrowserWindowClosed(); + } } void BrowserView::Activate() { diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index 74b04c2..a7a5d31 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_H_ #define CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_H_ +#include <set> + #include "chrome/browser/browser.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/hang_monitor/hung_plugin_action.h" @@ -19,6 +21,7 @@ class BookmarkBarView; class Browser; +class BrowserBubble; class BrowserToolbarView; class EncodingMenuControllerDelegate; class ExtensionShelf; @@ -163,6 +166,10 @@ class BrowserView : public BrowserWindow, // Register preferences specific to this view. static void RegisterBrowserViewPrefs(PrefService* prefs); + // Attach/Detach a BrowserBubble to the browser. + void AttachBrowserBubble(BrowserBubble *bubble); + void DetachBrowserBubble(BrowserBubble *bubble); + // Overridden from BrowserWindow: virtual void Show(); virtual void SetBounds(const gfx::Rect& bounds); @@ -280,7 +287,7 @@ class BrowserView : public BrowserWindow, int LayoutDownloadShelf(int bottom); // Layout the Status Bubble. void LayoutStatusBubble(int top); - // Layout the Extension Bottom Bar + // Layout the Extension Shelf int LayoutExtensionShelf(); // Prepare to show the Bookmark Bar for the specified TabContents. Returns @@ -409,6 +416,9 @@ class BrowserView : public BrowserWindow, // A bottom bar for showing extensions. ExtensionShelf* extension_shelf_; + typedef std::set<BrowserBubble*> BubbleSet; + BubbleSet browser_bubbles_; + DISALLOW_COPY_AND_ASSIGN(BrowserView); }; |