summaryrefslogtreecommitdiffstats
path: root/chrome/browser
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
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')
-rw-r--r--chrome/browser/extensions/extension_popup_api.cc19
-rw-r--r--chrome/browser/views/browser_actions_container.cc16
-rw-r--r--chrome/browser/views/browser_bubble.cc5
-rw-r--r--chrome/browser/views/browser_bubble.h8
-rw-r--r--chrome/browser/views/browser_bubble_gtk.cc4
-rw-r--r--chrome/browser/views/browser_bubble_win.cc5
-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
-rw-r--r--chrome/browser/views/location_bar_view.cc16
10 files changed, 195 insertions, 69 deletions
diff --git a/chrome/browser/extensions/extension_popup_api.cc b/chrome/browser/extensions/extension_popup_api.cc
index f68553c..48e414c 100644
--- a/chrome/browser/extensions/extension_popup_api.cc
+++ b/chrome/browser/extensions/extension_popup_api.cc
@@ -44,6 +44,10 @@ const wchar_t kTopKey[] = L"top";
const wchar_t kLeftKey[] = L"left";
const wchar_t kGiveFocusKey[] = L"giveFocus";
const wchar_t kDomAnchorKey[] = L"domAnchor";
+const wchar_t kBorderStyleKey[] = L"borderStyle";
+
+// chrome enumeration values
+const char kRectangleChrome[] = "rectangle";
}; // namespace
@@ -111,6 +115,18 @@ bool PopupShowFunction::RunImpl() {
&give_focus));
}
+#if defined(TOOLKIT_VIEWS)
+ // The default behaviour is to provide the bubble-chrome to the popup.
+ ExtensionPopup::PopupChrome chrome = ExtensionPopup::BUBBLE_CHROME;
+ if (show_details->HasKey(kBorderStyleKey)) {
+ std::string chrome_string;
+ EXTENSION_FUNCTION_VALIDATE(show_details->GetString(kBorderStyleKey,
+ &chrome_string));
+ if (chrome_string == kRectangleChrome)
+ chrome = ExtensionPopup::RECTANGLE_CHROME;
+ }
+#endif
+
GURL url = dispatcher()->url().Resolve(url_string);
if (!url.is_valid()) {
error_ = kInvalidURLError;
@@ -144,7 +160,8 @@ bool PopupShowFunction::RunImpl() {
dispatcher()->GetFrameNativeWindow(),
rect,
arrow_location,
- give_focus);
+ give_focus,
+ chrome);
ExtensionPopupHost* popup_host = dispatcher()->GetPopupHost();
DCHECK(popup_host);
diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc
index 5a1ae90..be8cf1b 100644
--- a/chrome/browser/views/browser_actions_container.cc
+++ b/chrome/browser/views/browser_actions_container.cc
@@ -534,13 +534,15 @@ void BrowserActionsContainer::OnBrowserActionExecuted(
BubbleBorder::ArrowLocation arrow_location = UILayoutIsRightToLeft() ?
BubbleBorder::TOP_LEFT : BubbleBorder::TOP_RIGHT;
- popup_ = ExtensionPopup::Show(button->GetPopupUrl(),
- browser_,
- browser_->profile(),
- frame_window,
- rect,
- arrow_location,
- true); // Activate the popup window.
+ popup_ = ExtensionPopup::Show(
+ button->GetPopupUrl(),
+ browser_,
+ browser_->profile(),
+ frame_window,
+ rect,
+ arrow_location,
+ true, // Activate the popup window.
+ ExtensionPopup::BUBBLE_CHROME);
popup_->set_delegate(this);
popup_button_ = button;
popup_button_->SetButtonPushed();
diff --git a/chrome/browser/views/browser_bubble.cc b/chrome/browser/views/browser_bubble.cc
index 26dff82..1b690db 100644
--- a/chrome/browser/views/browser_bubble.cc
+++ b/chrome/browser/views/browser_bubble.cc
@@ -25,12 +25,13 @@ BrowserView* GetBrowserViewFromFrame(views::Widget* frame) {
} // namespace
BrowserBubble::BrowserBubble(views::View* view, views::Widget* frame,
- const gfx::Point& origin)
+ const gfx::Point& origin, bool drop_shadow)
: frame_(frame),
view_(view),
visible_(false),
delegate_(NULL),
- attached_(false) {
+ attached_(false),
+ drop_shadow_enabled_(drop_shadow) {
gfx::Size size = view->GetPreferredSize();
bounds_.SetRect(origin.x(), origin.y(), size.width(), size.height());
InitPopup();
diff --git a/chrome/browser/views/browser_bubble.h b/chrome/browser/views/browser_bubble.h
index 25b91e9..012c552 100644
--- a/chrome/browser/views/browser_bubble.h
+++ b/chrome/browser/views/browser_bubble.h
@@ -38,9 +38,10 @@ class BrowserBubble {
// 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|.
+ // be positioned relative to |frame|. Pass true through |drop_shadow| to
+ // surround the bubble widget with a drop-shadow.
BrowserBubble(views::View* view, views::Widget* frame,
- const gfx::Point& origin);
+ const gfx::Point& origin, bool drop_shadow);
virtual ~BrowserBubble();
// Call manually if you need to detach the bubble from tracking the browser's
@@ -116,6 +117,9 @@ class BrowserBubble {
// Is the bubble attached to a Browser window.
bool attached_;
+ // Does the bubble have a drop-shadow.
+ bool drop_shadow_enabled_;
+
DISALLOW_COPY_AND_ASSIGN(BrowserBubble);
};
diff --git a/chrome/browser/views/browser_bubble_gtk.cc b/chrome/browser/views/browser_bubble_gtk.cc
index ebc343a..66b07c1 100644
--- a/chrome/browser/views/browser_bubble_gtk.cc
+++ b/chrome/browser/views/browser_bubble_gtk.cc
@@ -76,6 +76,10 @@ class BubbleWidget : public views::WidgetGtk {
} // namespace
void BrowserBubble::InitPopup() {
+ // TODO(port)
+ DCHECK(!drop_shadow_enabled_) <<
+ "Drop shadows not supported on GTK browser bubbles.";
+
views::WidgetGtk* pop = new BubbleWidget(this);
pop->SetOpacity(0xFF);
pop->make_transient_to_parent();
diff --git a/chrome/browser/views/browser_bubble_win.cc b/chrome/browser/views/browser_bubble_win.cc
index 2a2a4c2..a74b84a 100644
--- a/chrome/browser/views/browser_bubble_win.cc
+++ b/chrome/browser/views/browser_bubble_win.cc
@@ -79,6 +79,11 @@ void BrowserBubble::InitPopup() {
// popup_ is a Widget, but we need to do some WidgetWin stuff first, then
// we'll assign it into popup_.
views::WidgetWin* pop = new BubbleWidget(this);
+
+ // Enable the drop-shadow through the native windows drop-shadow support.
+ if (drop_shadow_enabled_)
+ pop->set_initial_class_style(CS_DROPSHADOW | pop->initial_class_style());
+
pop->Init(frame_->GetNativeView(), bounds_);
pop->SetContentsView(view_);
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);
}
diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc
index fef451d..18d0f1a 100644
--- a/chrome/browser/views/location_bar_view.cc
+++ b/chrome/browser/views/location_bar_view.cc
@@ -1501,13 +1501,15 @@ void LocationBarView::PageActionImageView::ExecuteAction(int button) {
rect.set_x(origin.x());
rect.set_y(origin.y());
- popup_ = ExtensionPopup::Show(page_action_->GetPopupUrl(current_tab_id_),
- browser,
- browser->profile(),
- browser->window()->GetNativeHandle(),
- rect,
- BubbleBorder::TOP_RIGHT,
- true); // Activate the popup window.
+ popup_ = ExtensionPopup::Show(
+ page_action_->GetPopupUrl(current_tab_id_),
+ browser,
+ browser->profile(),
+ browser->window()->GetNativeHandle(),
+ rect,
+ BubbleBorder::TOP_RIGHT,
+ true, // Activate the popup window.
+ ExtensionPopup::BUBBLE_CHROME);
popup_->set_delegate(this);
} else {
ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(