diff options
-rw-r--r-- | chrome/browser/chromeos/frame/browser_view.cc | 2 | ||||
-rw-r--r-- | chrome/browser/views/app_launcher.cc | 30 | ||||
-rw-r--r-- | chrome/browser/views/app_launcher.h | 16 | ||||
-rw-r--r-- | chrome/browser/views/bubble_border.cc | 12 | ||||
-rw-r--r-- | chrome/browser/views/bubble_border.h | 13 | ||||
-rw-r--r-- | chrome/browser/views/info_bubble.cc | 72 | ||||
-rw-r--r-- | chrome/browser/views/info_bubble.h | 77 | ||||
-rw-r--r-- | chrome/browser/views/pinned_contents_info_bubble.cc | 74 | ||||
-rw-r--r-- | chrome/browser/views/pinned_contents_info_bubble.h | 89 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 4 |
10 files changed, 300 insertions, 89 deletions
diff --git a/chrome/browser/chromeos/frame/browser_view.cc b/chrome/browser/chromeos/frame/browser_view.cc index bf822aa..63804a0 100644 --- a/chrome/browser/chromeos/frame/browser_view.cc +++ b/chrome/browser/chromeos/frame/browser_view.cc @@ -450,7 +450,7 @@ void BrowserView::ButtonPressed(views::Button* sender, origin.Offset(kAppLauncherLeftPadding, 0); views::RootView::ConvertPointToScreen(this, &origin); bounds.set_origin(origin); - ::AppLauncher::Show(browser(), bounds); + ::AppLauncher::Show(browser(), bounds, gfx::Point()); } // views::ContextMenuController overrides. diff --git a/chrome/browser/views/app_launcher.cc b/chrome/browser/views/app_launcher.cc index 489a8e6..a074f84 100644 --- a/chrome/browser/views/app_launcher.cc +++ b/chrome/browser/views/app_launcher.cc @@ -18,9 +18,11 @@ #include "chrome/browser/browser_window.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/view_ids.h" #include "chrome/browser/views/dom_view.h" #include "chrome/browser/views/info_bubble.h" #include "chrome/browser/views/frame/browser_view.h" +#include "chrome/browser/views/toolbar_view.h" #include "chrome/common/url_constants.h" #include "views/widget/root_view.h" #include "views/widget/widget.h" @@ -45,10 +47,10 @@ const int kNavigationEntryYMargin = 1; const int kNavigationBarBottomPadding = 3; // NavigationBar constants. -const int kNavigationBarHeight = 25; +const int kNavigationBarHeight = 23; const int kNavigationBarBorderThickness = 1; -// The delta applied to the default font size for the omnibox. +// The delta applied to the default font size for the Omnibox. const int kAutocompleteEditFontDelta = 3; // Command line switch for specifying url of the page. @@ -237,6 +239,7 @@ InfoBubbleContentsView::InfoBubbleContentsView(AppLauncher* app_launcher) : app_launcher_(app_launcher), navigation_bar_(NULL), dom_view_(NULL) { + DCHECK(app_launcher); } InfoBubbleContentsView::~InfoBubbleContentsView() { @@ -299,6 +302,7 @@ void InfoBubbleContentsView::Layout() { AppLauncher::AppLauncher(Browser* browser) : browser_(browser), info_bubble_(NULL) { + DCHECK(browser); info_bubble_content_ = new InfoBubbleContentsView(this); } @@ -306,12 +310,15 @@ AppLauncher::~AppLauncher() { } // static -AppLauncher* AppLauncher::Show(Browser* browser, const gfx::Rect& bounds) { +AppLauncher* AppLauncher::Show(Browser* browser, + const gfx::Rect& bounds, + const gfx::Point& bubble_anchor) { AppLauncher* app_launcher = new AppLauncher(browser); BrowserView* browser_view = static_cast<BrowserView*>(browser->window()); app_launcher->info_bubble_ = - InfoBubble::Show(browser_view->frame()->GetWindow(), bounds, - app_launcher->info_bubble_content_, app_launcher); + PinnedContentsInfoBubble::Show(browser_view->frame()->GetWindow(), + bounds, bubble_anchor, app_launcher->info_bubble_content_, + app_launcher); app_launcher->info_bubble_content_->BubbleShown(); return app_launcher; } @@ -326,7 +333,17 @@ AppLauncher* AppLauncher::ShowForNewTab(Browser* browser) { gfx::Point origin = bounds.origin(); views::RootView::ConvertPointToScreen(tabstrip, &origin); bounds.set_origin(origin); - return Show(browser, bounds); + + // Figure out where the location bar is, so we can pin the bubble to + // make our url bar appear exactly over it. + views::RootView* root_view = views::Widget::GetWidgetFromNativeWindow( + browser_view->GetNativeHandle())->GetRootView(); + views::View* location_bar = root_view->GetViewByID(VIEW_ID_LOCATION_BAR); + gfx::Point location_bar_origin = location_bar->bounds().origin(); + views::RootView::ConvertPointToScreen(location_bar->GetParent(), + &location_bar_origin); + + return Show(browser, bounds, location_bar_origin); } void AppLauncher::Hide() { @@ -352,7 +369,6 @@ void AppLauncher::InfoBubbleClosing(InfoBubble* info_bubble, new DeleteTask<AppLauncher>(this)); } - void AppLauncher::AddTabWithURL(const GURL& url, PageTransition::Type transition) { #if defined(OS_CHROMEOS) diff --git a/chrome/browser/views/app_launcher.h b/chrome/browser/views/app_launcher.h index 229f265..fa5cc03 100644 --- a/chrome/browser/views/app_launcher.h +++ b/chrome/browser/views/app_launcher.h @@ -7,7 +7,7 @@ #include "base/scoped_ptr.h" #include "chrome/browser/tab_contents/tab_contents_delegate.h" -#include "chrome/browser/views/info_bubble.h" +#include "chrome/browser/views/pinned_contents_info_bubble.h" #include "views/view.h" class Browser; @@ -49,13 +49,17 @@ class TabContentsDelegateImpl; // When a new url is opened, or the user clicks outsides the bounds of the // widget the app launcher is closed. class AppLauncher : public InfoBubbleDelegate, - public TabContentsDelegate { + public TabContentsDelegate { public: // Shows an application launcher bubble pointing to the |bounds| (which should - // be in screen coordinates). + // be in screen coordinates). |bubble_anchor| specifies at which coordinates + // the bubble contents should appear (in screen coordinates). The bubble will + // be moved accordingly. // The caller DOES NOT OWN the AppLauncher returned. It is deleted // automatically when the AppLauncher is closed. - static AppLauncher* Show(Browser* browser, const gfx::Rect& bounds); + static AppLauncher* Show(Browser* browser, + const gfx::Rect& bounds, + const gfx::Point& bubble_anchor); // Shows an application launcher bubble pointing to the new tab button. // The caller DOES NOT OWN the AppLauncher returned. It is deleted @@ -107,8 +111,8 @@ class AppLauncher : public InfoBubbleDelegate, // The currently active browser. We use this to open urls. Browser* browser_; - // The InfoBubble displaying the omnibox and app contents. - InfoBubble* info_bubble_; + // The InfoBubble displaying the Omnibox and app contents. + PinnedContentsInfoBubble* info_bubble_; // The view with the navigation bar and render view, shown in the info-bubble. InfoBubbleContentsView* info_bubble_content_; diff --git a/chrome/browser/views/bubble_border.cc b/chrome/browser/views/bubble_border.cc index d7bd07f..3548286 100644 --- a/chrome/browser/views/bubble_border.cc +++ b/chrome/browser/views/bubble_border.cc @@ -44,12 +44,14 @@ gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to, // of padding. const int kArrowOverlap = 3; int x = position_relative_to.x() + (position_relative_to.width() / 2); + int arrow_offset = override_arrow_x_offset_ ? override_arrow_x_offset_ : + arrow_x_offset_; if (arrow_is_left()) - x -= arrow_x_offset_; + x -= arrow_offset; else if (arrow_location_ == NONE) x -= ((contents_size.width() / 2) + insets.left()); else - x += (arrow_x_offset_ - border_size.width() + 1); + x += (arrow_offset - border_size.width() + 1); int y = position_relative_to.y(); if (arrow_is_bottom()) y += (kArrowOverlap - border_size.height()); @@ -103,7 +105,7 @@ void BubbleBorder::InitClass() { } void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { - // Convenience shorthand variables + // Convenience shorthand variables. int width = view.width(); int tl_width = top_left_->width(); int tl_height = top_left_->height(); @@ -223,9 +225,11 @@ void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { border_y = SkIntToScalar(top); tip_y = SkIntToScalar(top - kArrowInteriorHeight); } + int arrow_offset = override_arrow_x_offset_ ? override_arrow_x_offset_ : + arrow_x_offset_; int arrow_width = arrow->width(); int arrow_center = arrow_is_left() ? - arrow_x_offset_ : width - arrow_x_offset_ - 1; + arrow_offset : width - arrow_offset - 1; int arrow_x = arrow_center - (arrow_width / 2); SkScalar arrow_interior_x = SkIntToScalar(arrow_center - kArrowInteriorHeight); diff --git a/chrome/browser/views/bubble_border.h b/chrome/browser/views/bubble_border.h index e2d5de3..3670503 100644 --- a/chrome/browser/views/bubble_border.h +++ b/chrome/browser/views/bubble_border.h @@ -27,7 +27,9 @@ class BubbleBorder : public views::Border { BOTTOM_RIGHT }; - BubbleBorder() : arrow_location_(NONE), background_color_(SK_ColorWHITE) { + BubbleBorder() : override_arrow_x_offset_(0), + arrow_location_(NONE), + background_color_(SK_ColorWHITE) { InitClass(); } @@ -45,6 +47,12 @@ class BubbleBorder : public views::Border { arrow_location_ = arrow_location; } + // Sets a fixed x offset for the arrow. The arrow will still point to the + // same location but the bubble will shift horizontally to make that happen. + void set_arrow_offset(int offset) { + override_arrow_x_offset_ = offset; + } + // Sets the background color for the arrow body. This is irrelevant if you do // not also set the arrow location to something other than NONE. void set_background_color(SkColor background_color) { @@ -99,6 +107,9 @@ class BubbleBorder : public views::Border { static int arrow_x_offset_; + // If specified, overrides the pre-calculated |arrow_x_offset_| of the arrow. + int override_arrow_x_offset_; + ArrowLocation arrow_location_; SkColor background_color_; diff --git a/chrome/browser/views/info_bubble.cc b/chrome/browser/views/info_bubble.cc index 218decd..8150db9 100644 --- a/chrome/browser/views/info_bubble.cc +++ b/chrome/browser/views/info_bubble.cc @@ -29,55 +29,17 @@ const SkColor InfoBubble::kBackgroundColor = const SkColor InfoBubble::kBackgroundColor = SK_ColorWHITE; #endif -// BorderContents ------------------------------------------------------------- - -// This is used to paint the border of the InfoBubble. Windows uses this via -// BorderWidget (see below), while others can use it directly in the bubble. -class BorderContents : public views::View { - public: - BorderContents() { } - - // Given the size of the contents and the rect to point at, initializes the - // bubble and returns the bounds of both the border - // and the contents inside the bubble. - // |prefer_arrow_on_right| specifies the preferred location for the arrow - // anchor. If the bubble does not fit on the monitor, the arrow location may - // changed so it can. - // - // TODO(pkasting): Maybe this should use mirroring transformations instead, - // which would hopefully simplify this code. - void InitAndGetBounds( - const gfx::Rect& position_relative_to, // In screen coordinates - const gfx::Size& contents_size, - bool prefer_arrow_on_right, - gfx::Rect* contents_bounds, // Returned in window coordinates - gfx::Rect* window_bounds); // Returned in screen coordinates - - private: - virtual ~BorderContents() { } - - // Overridden from View: - virtual void Paint(gfx::Canvas* canvas); - - DISALLOW_COPY_AND_ASSIGN(BorderContents); -}; - void BorderContents::InitAndGetBounds( const gfx::Rect& position_relative_to, const gfx::Size& contents_size, bool prefer_arrow_on_right, gfx::Rect* contents_bounds, gfx::Rect* window_bounds) { - // Margins between the contents and the inside of the border, in pixels. - const int kLeftMargin = 6; - const int kTopMargin = 6; - const int kRightMargin = 6; - const int kBottomMargin = 9; - // Set the border. - BubbleBorder* bubble_border = new BubbleBorder; - set_border(bubble_border); - bubble_border->set_background_color(InfoBubble::kBackgroundColor); + if (!bubble_border_) + bubble_border_ = new BubbleBorder; + set_border(bubble_border_); + bubble_border_->set_background_color(InfoBubble::kBackgroundColor); // Give the contents a margin. gfx::Size local_contents_size(contents_size); @@ -88,9 +50,9 @@ void BorderContents::InitAndGetBounds( // bounds. BubbleBorder::ArrowLocation arrow_location(prefer_arrow_on_right ? BubbleBorder::TOP_RIGHT : BubbleBorder::TOP_LEFT); - bubble_border->set_arrow_location(arrow_location); + bubble_border_->set_arrow_location(arrow_location); *window_bounds = - bubble_border->GetBounds(position_relative_to, local_contents_size); + bubble_border_->GetBounds(position_relative_to, local_contents_size); // See if those bounds will fit on the monitor. scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_provider( @@ -109,10 +71,10 @@ void BorderContents::InitAndGetBounds( arrow_location = arrow_on_left ? BubbleBorder::TOP_LEFT : BubbleBorder::TOP_RIGHT; } - bubble_border->set_arrow_location(arrow_location); + bubble_border_->set_arrow_location(arrow_location); // Now get the recalculated bounds. - *window_bounds = bubble_border->GetBounds(position_relative_to, + *window_bounds = bubble_border_->GetBounds(position_relative_to, local_contents_size); } @@ -120,7 +82,7 @@ void BorderContents::InitAndGetBounds( // subtracting the border dimensions and margin amounts. *contents_bounds = gfx::Rect(gfx::Point(), window_bounds->size()); gfx::Insets insets; - bubble_border->GetInsets(&insets); + bubble_border_->GetInsets(&insets); contents_bounds->Inset(insets.left() + kLeftMargin, insets.top() + kTopMargin, insets.right() + kRightMargin, insets.bottom() + kBottomMargin); } @@ -152,7 +114,7 @@ void BorderContents::Paint(gfx::Canvas* canvas) { #if defined(OS_WIN) // BorderWidget --------------------------------------------------------------- -BorderWidget::BorderWidget() { +BorderWidget::BorderWidget() : border_contents_(NULL) { set_delete_on_destroy(false); // Our owner will free us manually. set_window_style(WS_POPUP); set_window_ex_style(WS_EX_TOOLWINDOW | WS_EX_LAYERED); @@ -165,15 +127,16 @@ gfx::Rect BorderWidget::InitAndGetBounds( bool prefer_arrow_on_right) { // Set up the border view and ask it to calculate our bounds (and our // contents'). - BorderContents* border_contents = new BorderContents; + if (!border_contents_) + border_contents_ = new BorderContents; gfx::Rect contents_bounds, window_bounds; - border_contents->InitAndGetBounds(position_relative_to, contents_size, - prefer_arrow_on_right, &contents_bounds, - &window_bounds); + border_contents_->InitAndGetBounds(position_relative_to, contents_size, + prefer_arrow_on_right, &contents_bounds, + &window_bounds); // Initialize ourselves. WidgetWin::Init(GetAncestor(owner, GA_ROOT), window_bounds); - SetContentsView(border_contents); + SetContentsView(border_contents_); SetWindowPos(owner, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW); @@ -270,7 +233,8 @@ void InfoBubble::Init(views::Window* parent, (contents->UILayoutIsRightToLeft() == delegate->PreferOriginSideAnchor()); #if defined(OS_WIN) - border_.reset(new BorderWidget); + if (!border_.get()) + border_.reset(new BorderWidget); // Initialize and position the border window. window_bounds = border_->InitAndGetBounds(GetNativeView(), position_relative_to, contents->GetPreferredSize(), diff --git a/chrome/browser/views/info_bubble.h b/chrome/browser/views/info_bubble.h index 90911b5..ea80b0f 100644 --- a/chrome/browser/views/info_bubble.h +++ b/chrome/browser/views/info_bubble.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -7,6 +7,7 @@ #include "third_party/skia/include/core/SkColor.h" #include "views/accelerator.h" +#include "views/view.h" #if defined(OS_WIN) #include "views/widget/widget_win.h" #elif defined(OS_LINUX) @@ -23,6 +24,7 @@ // have any additional margins. class BorderWidget; +class BubbleBorder; class InfoBubble; namespace views { @@ -33,6 +35,46 @@ namespace gfx { class Path; } +// This is used to paint the border of the InfoBubble. Windows uses this via +// BorderWidget (see below), while others can use it directly in the bubble. +class BorderContents : public views::View { + public: + BorderContents() : bubble_border_(NULL) { } + + // Given the size of the contents and the rect to point at, initializes the + // bubble and returns the bounds of both the border + // and the contents inside the bubble. + // |prefer_arrow_on_right| specifies the preferred location for the arrow + // anchor. If the bubble does not fit on the monitor, the arrow location may + // changed so it can. + // + // TODO(pkasting): Maybe this should use mirroring transformations instead, + // which would hopefully simplify this code. + virtual void InitAndGetBounds( + const gfx::Rect& position_relative_to, // In screen coordinates + const gfx::Size& contents_size, + bool prefer_arrow_on_right, + gfx::Rect* contents_bounds, // Returned in window coordinates + gfx::Rect* window_bounds); // Returned in screen coordinates + + protected: + virtual ~BorderContents() { } + + // Margins between the contents and the inside of the border, in pixels. + static const int kLeftMargin = 6; + static const int kTopMargin = 6; + static const int kRightMargin = 6; + static const int kBottomMargin = 9; + + BubbleBorder* bubble_border_; + + private: + // Overridden from View: + virtual void Paint(gfx::Canvas* canvas); + + DISALLOW_COPY_AND_ASSIGN(BorderContents); +}; + #if defined(OS_WIN) // This is a window that surrounds the info bubble and paints the margin and // border. It is a separate window so that it can be a layered window, so that @@ -47,12 +89,15 @@ class BorderWidget : public views::WidgetWin { // Given the owning (parent) window, the size of the contained contents // (without margins), and the rect (in screen coordinates) to point to, // initializes the window and returns the bounds (in screen coordinates) the - // contents should use. |is_rtl| is supplied to + // contents should use. |is_rtl| is supplied to // BorderContents::InitAndGetBounds(), see its declaration for details. - gfx::Rect InitAndGetBounds(HWND owner, - const gfx::Rect& position_relative_to, - const gfx::Size& contents_size, - bool is_rtl); + virtual gfx::Rect InitAndGetBounds(HWND owner, + const gfx::Rect& position_relative_to, + const gfx::Size& contents_size, + bool is_rtl); + + protected: + BorderContents* border_contents_; private: // Overridden from WidgetWin: @@ -82,7 +127,7 @@ class InfoBubbleDelegate { virtual bool PreferOriginSideAnchor() { return true; } }; -// TODO: this code is ifdef-tastic. It might be cleaner to refactor the +// TODO(sky): this code is ifdef-tastic. It might be cleaner to refactor the // WidgetFoo subclass into a separate class that calls into InfoBubble. // That way InfoBubble has no (or very few) ifdefs. class InfoBubble @@ -120,10 +165,10 @@ class InfoBubble virtual ~InfoBubble() {} // Creates the InfoBubble. - void Init(views::Window* parent, - const gfx::Rect& position_relative_to, - views::View* contents, - InfoBubbleDelegate* delegate); + virtual void Init(views::Window* parent, + const gfx::Rect& position_relative_to, + views::View* contents, + InfoBubbleDelegate* delegate); #if defined(OS_WIN) // Overridden from WidgetWin: @@ -133,6 +178,11 @@ class InfoBubble virtual void IsActiveChanged(); #endif +#if defined(OS_WIN) + // The window used to render the padding, border and arrow. + scoped_ptr<BorderWidget> border_; +#endif + private: // Closes the window notifying the delegate. |closed_by_escape| is true if // the close is the result of pressing escape. @@ -147,11 +197,6 @@ class InfoBubble // The window that this InfoBubble is parented to. views::Window* parent_; -#if defined(OS_WIN) - // The window used to render the padding, border and arrow. - scoped_ptr<BorderWidget> border_; -#endif - // Have we been closed? bool closed_; diff --git a/chrome/browser/views/pinned_contents_info_bubble.cc b/chrome/browser/views/pinned_contents_info_bubble.cc new file mode 100644 index 0000000..8331db1 --- /dev/null +++ b/chrome/browser/views/pinned_contents_info_bubble.cc @@ -0,0 +1,74 @@ +// Copyright (c) 2010 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/pinned_contents_info_bubble.h" + +#include "chrome/browser/views/bubble_border.h" + +#if defined(OS_WIN) +// BorderWidget --------------------------------------------------------------- + +void PinnedContentsBorderContents::InitAndGetBounds( + const gfx::Rect& position_relative_to, + const gfx::Size& contents_size, + bool prefer_arrow_on_right, + gfx::Rect* contents_bounds, + gfx::Rect* window_bounds) { + bubble_border_ = new BubbleBorder; + + // Arrow offset is calculated from the middle of the |position_relative_to|. + int offset = position_relative_to.x() + (position_relative_to.width() / 2); + offset -= bubble_anchor_.x(); + + gfx::Insets insets; + bubble_border_->GetInsets(&insets); + offset += kLeftMargin + insets.left() + 1; + bubble_border_->set_arrow_offset(offset); + + BorderContents::InitAndGetBounds( + position_relative_to, contents_size, prefer_arrow_on_right, + contents_bounds, window_bounds); + + // Now move the y position to make sure the bubble contents overlap the view. + window_bounds->Offset(0, -(kTopMargin + 1)); +} + +gfx::Rect PinnedContentsBorderWidget::InitAndGetBounds( + HWND owner, + const gfx::Rect& position_relative_to, + const gfx::Size& contents_size, + bool prefer_arrow_on_right) { + border_contents_ = new PinnedContentsBorderContents(bubble_anchor_); + return BorderWidget::InitAndGetBounds( + owner, position_relative_to, contents_size, + prefer_arrow_on_right); +} +#endif + +// InfoBubble ----------------------------------------------------------------- + +// static +PinnedContentsInfoBubble* PinnedContentsInfoBubble::Show( + views::Window* parent, + const gfx::Rect& position_relative_to, + const gfx::Point& bubble_anchor, + views::View* contents, + InfoBubbleDelegate* delegate) { + PinnedContentsInfoBubble* window = + new PinnedContentsInfoBubble(bubble_anchor); + window->Init(parent, position_relative_to, contents, delegate); + return window; +} + +void PinnedContentsInfoBubble::Init(views::Window* parent, + const gfx::Rect& position_relative_to, + views::View* contents, + InfoBubbleDelegate* delegate) { +// TODO(finnur): This needs to be implemented for other platforms once we +// decide this is the way to go. +#if defined(OS_WIN) + border_.reset(new PinnedContentsBorderWidget(bubble_anchor_)); +#endif + InfoBubble::Init(parent, position_relative_to, contents, delegate); +} diff --git a/chrome/browser/views/pinned_contents_info_bubble.h b/chrome/browser/views/pinned_contents_info_bubble.h new file mode 100644 index 0000000..92477c0 --- /dev/null +++ b/chrome/browser/views/pinned_contents_info_bubble.h @@ -0,0 +1,89 @@ +// Copyright (c) 2010 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_PINNED_CONTENTS_INFO_BUBBLE_H_ +#define CHROME_BROWSER_VIEWS_PINNED_CONTENTS_INFO_BUBBLE_H_ + +#include "chrome/browser/views/info_bubble.h" + +// This is a specialization of BorderContents, used to draw a border around +// an InfoBubble that has its contents pinned to a specific location. See +// base class for details. +class PinnedContentsBorderContents : public BorderContents { + public: + explicit PinnedContentsBorderContents(const gfx::Point& bubble_anchor) + : bubble_anchor_(bubble_anchor) {} + + // BorderContents overrides: + virtual void InitAndGetBounds( + const gfx::Rect& position_relative_to, // In screen coordinates + const gfx::Size& contents_size, + bool prefer_arrow_on_right, + gfx::Rect* contents_bounds, // Returned in window coordinates + gfx::Rect* window_bounds); // Returned in screen coordinates + + private: + // The location of the pinned contents (in screen coordinates). + const gfx::Point bubble_anchor_; + + DISALLOW_COPY_AND_ASSIGN(PinnedContentsBorderContents); +}; + +#if defined(OS_WIN) +// The window that surrounds the info bubble. See base class for details. +class PinnedContentsBorderWidget : public BorderWidget { + public: + explicit PinnedContentsBorderWidget(const gfx::Point& bubble_anchor) + : bubble_anchor_(bubble_anchor) {} + virtual ~PinnedContentsBorderWidget() {} + + // BorderWidget overrides: + virtual gfx::Rect InitAndGetBounds(HWND owner, + const gfx::Rect& position_relative_to, + const gfx::Size& contents_size, + bool is_rtl); + + private: + // The location of the pinned contents (in screen coordinates). + const gfx::Point bubble_anchor_; + + DISALLOW_COPY_AND_ASSIGN(PinnedContentsBorderWidget); +}; +#endif + +// A specialization of the InfoBubble. Used to draw an InfoBubble which, in +// addition to having an arrow pointing to where the user clicked, also shifts +// the bubble horizontally to fix it to a specific location. See base class +// for details. +class PinnedContentsInfoBubble : public InfoBubble { + public: + // Shows the InfoBubble (see base class function for details). + // |bubble_anchor| specifies how far horizontally to shift the bubble in + // order to anchor its contents. Once the InfoBubble has been anchored its + // arrow may be pointing to a slightly different |y| location than specified + // in |position_relative_to|. + static PinnedContentsInfoBubble* Show(views::Window* parent, + const gfx::Rect& position_relative_to, + const gfx::Point& bubble_anchor_, + views::View* contents, + InfoBubbleDelegate* delegate); + + private: + explicit PinnedContentsInfoBubble(const gfx::Point& bubble_anchor) + : bubble_anchor_(bubble_anchor) {} + virtual ~PinnedContentsInfoBubble() {} + + // InfoBubble overrides: + virtual void Init(views::Window* parent, + const gfx::Rect& position_relative_to, + views::View* contents, + InfoBubbleDelegate* delegate); + + // The location of the pinned contents (in screen coordinates). + const gfx::Point bubble_anchor_; + + DISALLOW_COPY_AND_ASSIGN(PinnedContentsInfoBubble); +}; + +#endif // CHROME_BROWSER_VIEWS_PINNED_CONTENTS_INFO_BUBBLE_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 3f84b65..55a856a 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2353,6 +2353,8 @@ 'browser/views/options/plugin_filter_page_view.cc', 'browser/views/options/plugin_filter_page_view.h', 'browser/views/page_info_window_view.cc', + 'browser/views/pinned_contents_info_bubble.cc', + 'browser/views/pinned_contents_info_bubble.h', 'browser/views/repost_form_warning_view.cc', 'browser/views/repost_form_warning_view.h', 'browser/views/restart_message_box.cc', @@ -2912,6 +2914,8 @@ #['include', '^browser/views/panels/panel_scroller_container.h'], #['include', '^browser/views/panels/panel_scroller_header.cc'], #['include', '^browser/views/panels/panel_scroller_header.h'], + ['include', '^browser/views/pinned_contents_info_bubble.cc'], + ['include', '^browser/views/pinned_contents_info_bubble.h'], ['include', '^browser/views/restart_message_box.cc'], ['include', '^browser/views/restart_message_box.h'], ['include', '^browser/views/sad_tab_view.cc'], |