summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/extensions
diff options
context:
space:
mode:
authortwiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-12 20:27:10 +0000
committertwiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-12 20:27:10 +0000
commitc7bf140b32a1a6504e48716b90c6a13fd5c421d3 (patch)
tree876ada1f8ca6320060aab4db3790522989829d31 /chrome/browser/views/extensions
parent1be7eadb032256687abda35ae4b2ba4770757c70 (diff)
downloadchromium_src-c7bf140b32a1a6504e48716b90c6a13fd5c421d3.zip
chromium_src-c7bf140b32a1a6504e48716b90c6a13fd5c421d3.tar.gz
chromium_src-c7bf140b32a1a6504e48716b90c6a13fd5c421d3.tar.bz2
Clone of issue 577015.
See http://codereview.chromium.org/577015 for the review status of this CL. BUG=None TEST=ExtensionApiTest.Popup Review URL: http://codereview.chromium.org/600101 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38927 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views/extensions')
-rw-r--r--chrome/browser/views/extensions/extension_popup.cc157
-rw-r--r--chrome/browser/views/extensions/extension_popup.h31
-rw-r--r--chrome/browser/views/extensions/extension_shelf.cc3
3 files changed, 141 insertions, 50 deletions
diff --git a/chrome/browser/views/extensions/extension_popup.cc b/chrome/browser/views/extensions/extension_popup.cc
index 9fc5ae7..70c9222 100644
--- a/chrome/browser/views/extensions/extension_popup.cc
+++ b/chrome/browser/views/extensions/extension_popup.cc
@@ -14,6 +14,7 @@
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/notification_type.h"
+#include "third_party/skia/include/core/SkColor.h"
#include "views/widget/root_view.h"
#include "views/window/window.h"
@@ -32,17 +33,32 @@ const int ExtensionPopup::kMinHeight = 25;
const int ExtensionPopup::kMaxWidth = 800;
const int ExtensionPopup::kMaxHeight = 600;
+// The width, in pixels, of the black-border on a popup.
+const int kPopupBorderWidth = 1;
+
+const int kPopupBubbleCornerRadius = BubbleBorder::GetCornerRadius() / 2;
+
ExtensionPopup::ExtensionPopup(ExtensionHost* host,
views::Widget* frame,
const gfx::Rect& relative_to,
BubbleBorder::ArrowLocation arrow_location,
- bool activate_on_show)
+ bool activate_on_show,
+ PopupChrome chrome)
: BrowserBubble(host->view(),
frame,
- gfx::Point()),
+ gfx::Point(),
+ RECTANGLE_CHROME == chrome), // If no bubble chrome is to
+ // be displayed, then enable a
+ // drop-shadow on the bubble
+ // widget.
relative_to_(relative_to),
extension_host_(host),
- activate_on_show_(activate_on_show) {
+ activate_on_show_(activate_on_show),
+ border_widget_(NULL),
+ border_(NULL),
+ border_view_(NULL),
+ popup_chrome_(chrome),
+ anchor_position_(arrow_location) {
host->view()->SetContainer(this);
registrar_.Add(this,
NotificationType::EXTENSION_HOST_DID_STOP_LOADING,
@@ -51,45 +67,56 @@ ExtensionPopup::ExtensionPopup(ExtensionHost* host,
// TODO(erikkay) Some of this border code is derived from InfoBubble.
// We should see if we can unify these classes.
- gfx::NativeView native_window = frame->GetNativeView();
+ // The bubble chrome requires a separate window, so construct it here.
+ if (BUBBLE_CHROME == popup_chrome_) {
+ gfx::NativeView native_window = frame->GetNativeView();
#if defined(OS_LINUX)
- border_widget_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
- static_cast<views::WidgetGtk*>(border_widget_)->MakeTransparent();
- static_cast<views::WidgetGtk*>(border_widget_)->make_transient_to_parent();
+ border_widget_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
+ static_cast<views::WidgetGtk*>(border_widget_)->MakeTransparent();
+ static_cast<views::WidgetGtk*>(border_widget_)->make_transient_to_parent();
#else
- border_widget_ = Widget::CreatePopupWidget(Widget::Transparent,
- Widget::NotAcceptEvents,
- Widget::DeleteOnDestroy);
+ border_widget_ = Widget::CreatePopupWidget(Widget::Transparent,
+ Widget::NotAcceptEvents,
+ Widget::DeleteOnDestroy);
#endif
- border_widget_->Init(native_window, bounds());
+ border_widget_->Init(native_window, bounds());
#if defined(OS_LINUX)
- TabOverviewTypes::instance()->SetWindowType(
- border_widget_->GetNativeView(),
- TabOverviewTypes::WINDOW_TYPE_CHROME_INFO_BUBBLE,
- NULL);
+ TabOverviewTypes::instance()->SetWindowType(
+ border_widget_->GetNativeView(),
+ TabOverviewTypes::WINDOW_TYPE_CHROME_INFO_BUBBLE,
+ NULL);
#endif
- border_ = new BubbleBorder;
- border_->set_arrow_location(arrow_location);
+ border_ = new BubbleBorder;
+ border_->set_arrow_location(arrow_location);
- border_view_ = new views::View;
- border_view_->set_background(new BubbleBackground(border_));
- border_view_->set_border(border_);
- border_widget_->SetContentsView(border_view_);
+ border_view_ = new views::View;
+ border_view_->set_background(new BubbleBackground(border_));
- // Ensure that the popup contents are always displayed ontop of the border
- // widget.
- border_widget_->MoveAbove(popup_);
+ border_view_->set_border(border_);
+ border_widget_->SetContentsView(border_view_);
+ // Ensure that the popup contents are always displayed ontop of the border
+ // widget.
+ border_widget_->MoveAbove(popup_);
+ } else {
+ // Otherwise simply set a black-border on the view containing the popup
+ // extension view.
+ views::Border* border = views::Border::CreateSolidBorder(kPopupBorderWidth,
+ SK_ColorBLACK);
+ view()->set_border(border);
+ }
}
ExtensionPopup::~ExtensionPopup() {
// The widget is set to delete on destroy, so no leak here.
- border_widget_->Close();
+ if (border_widget_)
+ border_widget_->Close();
}
void ExtensionPopup::Hide() {
BrowserBubble::Hide();
- border_widget_->Hide();
+ if (border_widget_)
+ border_widget_->Hide();
}
void ExtensionPopup::Show(bool activate) {
@@ -104,7 +131,8 @@ void ExtensionPopup::Show(bool activate) {
ResizeToView();
// Show the border first, then the popup overlaid on top.
- border_widget_->Show();
+ if (border_widget_)
+ border_widget_->Show();
BrowserBubble::Show(activate);
}
@@ -113,27 +141,27 @@ void ExtensionPopup::ResizeToView() {
// know our position to do it.
gfx::Size new_size = view()->size();
- // The rounded corners cut off more of the view than the border insets claim.
- // Since we can't clip the ExtensionView's corners, we need to increase the
- // inset by half the corner radius as well as lying about the size of the
- // contents size to compensate.
- int corner_inset = BubbleBorder::GetCornerRadius() / 2;
- gfx::Size adjusted_size = new_size;
- adjusted_size.Enlarge(2 * corner_inset, 2 * corner_inset);
- gfx::Rect rect = border_->GetBounds(relative_to_, adjusted_size);
- border_widget_->SetBounds(rect);
-
- // Now calculate the inner bounds. This is a bit more convoluted than
- // it should be because BrowserBubble coordinates are in Browser coordinates
- // while |rect| is in screen coordinates.
- gfx::Insets border_insets;
- border_->GetInsets(&border_insets);
+ gfx::Rect rect = GetOuterBounds(relative_to_, new_size);
gfx::Point origin = rect.origin();
views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin);
- origin.set_x(origin.x() + border_insets.left() + corner_inset);
- origin.set_y(origin.y() + border_insets.top() + corner_inset);
+ if (border_widget_) {
+ // Set the bubble-chrome widget according to the outer bounds of the entire
+ // popup.
+ border_widget_->SetBounds(rect);
- SetBounds(origin.x(), origin.y(), new_size.width(), new_size.height());
+ // Now calculate the inner bounds. This is a bit more convoluted than
+ // it should be because BrowserBubble coordinates are in Browser coordinates
+ // while |rect| is in screen coordinates.
+ gfx::Insets border_insets;
+ border_->GetInsets(&border_insets);
+
+ origin.set_x(origin.x() + border_insets.left() + kPopupBubbleCornerRadius);
+ origin.set_y(origin.y() + border_insets.top() + kPopupBubbleCornerRadius);
+
+ SetBounds(origin.x(), origin.y(), new_size.width(), new_size.height());
+ } else {
+ SetBounds(origin.x(), origin.y(), rect.width(), rect.height());
+ }
}
void ExtensionPopup::Observe(NotificationType type,
@@ -159,6 +187,39 @@ void ExtensionPopup::OnExtensionPreferredSizeChanged(ExtensionView* view) {
ResizeToView();
}
+gfx::Rect ExtensionPopup::GetOuterBounds(const gfx::Rect& position_relative_to,
+ const gfx::Size& contents_size) const {
+ gfx::Size adjusted_size = contents_size;
+ // If the popup has a bubble-chrome, then let the BubbleBorder compute
+ // the bounds.
+ if (BUBBLE_CHROME == popup_chrome_) {
+ // The rounded corners cut off more of the view than the border insets
+ // claim. Since we can't clip the ExtensionView's corners, we need to
+ // increase the inset by half the corner radius as well as lying about the
+ // size of the contents size to compensate.
+ adjusted_size.Enlarge(2 * kPopupBubbleCornerRadius,
+ 2 * kPopupBubbleCornerRadius);
+ return border_->GetBounds(position_relative_to, adjusted_size);
+ }
+
+ // Otherwise, enlarge the bounds by the size of the local border.
+ gfx::Insets border_insets;
+ view()->border()->GetInsets(&border_insets);
+ adjusted_size.Enlarge(border_insets.width(), border_insets.height());
+
+ // Position the bounds according to the location of the |anchor_position_|.
+ int y;
+ if ((anchor_position_ == BubbleBorder::TOP_LEFT) ||
+ (anchor_position_ == BubbleBorder::TOP_RIGHT)) {
+ y = position_relative_to.bottom();
+ } else {
+ y = position_relative_to.y() - adjusted_size.height();
+ }
+
+ return gfx::Rect(position_relative_to.x(), y, adjusted_size.width(),
+ adjusted_size.height());
+}
+
// static
ExtensionPopup* ExtensionPopup::Show(
const GURL& url,
@@ -167,7 +228,8 @@ ExtensionPopup* ExtensionPopup::Show(
gfx::NativeWindow frame_window,
const gfx::Rect& relative_to,
BubbleBorder::ArrowLocation arrow_location,
- bool activate_on_show) {
+ bool activate_on_show,
+ PopupChrome chrome) {
DCHECK(profile);
DCHECK(frame_window);
ExtensionProcessManager* manager = profile->GetExtensionProcessManager();
@@ -187,7 +249,8 @@ ExtensionPopup* ExtensionPopup::Show(
ExtensionHost* host = manager->CreatePopup(url, browser);
ExtensionPopup* popup = new ExtensionPopup(host, frame_widget, relative_to,
- arrow_location, activate_on_show);
+ arrow_location, activate_on_show,
+ chrome);
// If the host had somehow finished loading, then we'd miss the notification
// and not show. This seems to happen in single-process mode.
diff --git a/chrome/browser/views/extensions/extension_popup.h b/chrome/browser/views/extensions/extension_popup.h
index 92eab93..72df7b2 100644
--- a/chrome/browser/views/extensions/extension_popup.h
+++ b/chrome/browser/views/extensions/extension_popup.h
@@ -26,6 +26,11 @@ class ExtensionPopup : public BrowserBubble,
public NotificationObserver,
public ExtensionView::Container {
public:
+ enum PopupChrome {
+ BUBBLE_CHROME,
+ RECTANGLE_CHROME
+ };
+
virtual ~ExtensionPopup();
// Create and show a popup with |url| positioned adjacent to |relative_to| in
@@ -42,6 +47,12 @@ class ExtensionPopup : public BrowserBubble,
// If |arrow_location| is BOTTOM_*, then the popup 'pops up', otherwise
// the popup 'drops down'.
// Pass |activate_on_show| as true to activate the popup window.
+ // The |chrome| argument controls the chrome that surrounds the pop-up.
+ // Passing BUBBLE_CHROME will give the pop-up a bubble-like appearance,
+ // including the arrow mentioned above. Passing RECTANGLE_CHROME will give
+ // the popup a rectangular, black border with a drop-shadow with no arrow.
+ // The positioning of the popup is still governed by the arrow-location
+ // parameter.
//
// The actual display of the popup is delayed until the page contents
// finish loading in order to minimize UI flashing and resizing.
@@ -50,7 +61,8 @@ class ExtensionPopup : public BrowserBubble,
gfx::NativeWindow frame_window,
const gfx::Rect& relative_to,
BubbleBorder::ArrowLocation arrow_location,
- bool activate_on_show);
+ bool activate_on_show,
+ PopupChrome chrome);
ExtensionHost* host() const { return extension_host_.get(); }
@@ -80,7 +92,14 @@ class ExtensionPopup : public BrowserBubble,
views::Widget* frame,
const gfx::Rect& relative_to,
BubbleBorder::ArrowLocation arrow_location,
- bool activate_on_show);
+ bool activate_on_show,
+ PopupChrome chrome);
+
+ // Gives the desired bounds (in screen coordinates) given the rect to point
+ // to and the size of the contained contents. Includes all of the
+ // border-chrome surrounding the pop-up as well.
+ gfx::Rect GetOuterBounds(const gfx::Rect& position_relative_to,
+ const gfx::Size& contents_size) const;
// The area on the screen that the popup should be positioned relative to.
gfx::Rect relative_to_;
@@ -101,6 +120,14 @@ class ExtensionPopup : public BrowserBubble,
BubbleBorder* border_;
views::View* border_view_;
+ // The type of chrome associated with the popup window.
+ PopupChrome popup_chrome_;
+
+ // A cached copy of the arrow-position for the bubble chrome.
+ // If a black-border was requested, we still need this value to determine
+ // the position of the pop-up in relation to |relative_to_|.
+ BubbleBorder::ArrowLocation anchor_position_;
+
DISALLOW_COPY_AND_ASSIGN(ExtensionPopup);
};
diff --git a/chrome/browser/views/extensions/extension_shelf.cc b/chrome/browser/views/extensions/extension_shelf.cc
index 69b6dc1..640dfed 100644
--- a/chrome/browser/views/extensions/extension_shelf.cc
+++ b/chrome/browser/views/extensions/extension_shelf.cc
@@ -428,7 +428,8 @@ void ExtensionShelf::Toolstrip::LayoutWindow() {
if (!window_.get()) {
window_.reset(new BrowserBubble(this, shelf_->GetWidget(),
- gfx::Point(0, 0)));
+ gfx::Point(0, 0),
+ false)); // Do not add a drop-shadow.
window_->set_delegate(this);
}