summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjohnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-08 19:49:56 +0000
committerjohnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-08 19:49:56 +0000
commitd42d02c4a7ea5fd8781af7a67d9ac186d0ee0db5 (patch)
tree0dea8cb5c6ee1216a0651b2dea603f0042759b06
parentcad4da4151f41c6203a9fe502fb818bab7e4862a (diff)
downloadchromium_src-d42d02c4a7ea5fd8781af7a67d9ac186d0ee0db5.zip
chromium_src-d42d02c4a7ea5fd8781af7a67d9ac186d0ee0db5.tar.gz
chromium_src-d42d02c4a7ea5fd8781af7a67d9ac186d0ee0db5.tar.bz2
Notifications should resize themselves to the content within min-max bounds, rather than being all the same size.
CL hooks into RenderView callbacks to detect the size of the content, and contains some refactoring so that conceptually balloon size = content size + frame, rather than content size = balloon size - frame as it has been. BUG=26691 TEST=included Review URL: http://codereview.chromium.org/460131 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34076 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/notifications/balloon.cc11
-rw-r--r--chrome/browser/notifications/balloon.h33
-rw-r--r--chrome/browser/notifications/balloon_collection.cc15
-rw-r--r--chrome/browser/notifications/balloon_collection.h16
-rw-r--r--chrome/browser/notifications/balloon_collection_win.cc2
-rw-r--r--chrome/browser/notifications/desktop_notifications_unittest.cc39
-rw-r--r--chrome/browser/notifications/desktop_notifications_unittest.h4
-rw-r--r--chrome/browser/views/notifications/balloon_view.cc153
-rw-r--r--chrome/browser/views/notifications/balloon_view.h12
-rw-r--r--chrome/browser/views/notifications/balloon_view_host.cc18
-rw-r--r--chrome/browser/views/notifications/balloon_view_host.h7
11 files changed, 218 insertions, 92 deletions
diff --git a/chrome/browser/notifications/balloon.cc b/chrome/browser/notifications/balloon.cc
index d9d4c1f..da49395 100644
--- a/chrome/browser/notifications/balloon.cc
+++ b/chrome/browser/notifications/balloon.cc
@@ -10,10 +10,10 @@
#include "chrome/browser/renderer_host/site_instance.h"
Balloon::Balloon(const Notification& notification, Profile* profile,
- BalloonCloseListener* listener)
+ BalloonCollection* collection)
: profile_(profile),
notification_(notification),
- close_listener_(listener) {
+ collection_(collection) {
}
Balloon::~Balloon() {
@@ -25,6 +25,10 @@ void Balloon::SetPosition(const gfx::Point& upper_left, bool reposition) {
balloon_view_->RepositionToBalloon();
}
+void Balloon::SetContentPreferredSize(const gfx::Size& size) {
+ collection_->ResizeBalloon(this, size);
+}
+
void Balloon::set_view(BalloonView* balloon_view) {
balloon_view_.reset(balloon_view);
}
@@ -38,8 +42,7 @@ void Balloon::Show() {
void Balloon::OnClose(bool by_user) {
notification_.Close(by_user);
- if (close_listener_)
- close_listener_->OnBalloonClosed(this);
+ collection_->OnBalloonClosed(this);
}
void Balloon::CloseByScript() {
diff --git a/chrome/browser/notifications/balloon.h b/chrome/browser/notifications/balloon.h
index b0f49b4..b0ead85 100644
--- a/chrome/browser/notifications/balloon.h
+++ b/chrome/browser/notifications/balloon.h
@@ -17,6 +17,7 @@
#include "chrome/browser/notifications/notification.h"
class Balloon;
+class BalloonCollection;
class Profile;
class SiteInstance;
@@ -33,23 +34,17 @@ class BalloonView {
// Close the view.
virtual void Close(bool by_user) = 0;
+
+ // The total size of the view.
+ virtual gfx::Size GetSize() const = 0;
};
// Represents a Notification on the screen.
class Balloon {
public:
- class BalloonCloseListener {
- public:
- virtual ~BalloonCloseListener() {}
-
- // Called when a balloon is closed.
- virtual void OnBalloonClosed(Balloon* source) = 0;
- };
-
- // |listener| may be null in unit tests w/o actual UI.
Balloon(const Notification& notification,
Profile* profile,
- BalloonCloseListener* listener);
+ BalloonCollection* collection);
virtual ~Balloon();
const Notification& notification() const { return notification_; }
@@ -58,13 +53,21 @@ class Balloon {
const gfx::Point& position() const { return position_; }
void SetPosition(const gfx::Point& upper_left, bool reposition);
- const gfx::Size& size() const { return size_; }
- void set_size(const gfx::Size& size) { size_ = size; }
+ const gfx::Size& content_size() const { return content_size_; }
+ void set_content_size(const gfx::Size& size) { content_size_ = size; }
+
+ // Request a new content size for this balloon. This will get passed
+ // to the balloon collection for checking against available space and
+ // min/max restrictions.
+ void SetContentPreferredSize(const gfx::Size& size);
// Provides a view for this balloon. Ownership transfers
// to this object.
void set_view(BalloonView* balloon_view);
+ // Returns the viewing size for the balloon (content + frame).
+ gfx::Size GetViewSize() const { return balloon_view_->GetSize(); }
+
// Shows the balloon.
virtual void Show();
@@ -82,15 +85,15 @@ class Balloon {
// The notification being shown in this balloon.
Notification notification_;
- // A listener to be called when the balloon closes.
- BalloonCloseListener* close_listener_;
+ // The collection that this balloon belongs to. Non-owned pointer.
+ BalloonCollection* collection_;
// The actual UI element for the balloon.
scoped_ptr<BalloonView> balloon_view_;
// Position and size of the balloon on the screen.
gfx::Point position_;
- gfx::Size size_;
+ gfx::Size content_size_;
DISALLOW_COPY_AND_ASSIGN(Balloon);
};
diff --git a/chrome/browser/notifications/balloon_collection.cc b/chrome/browser/notifications/balloon_collection.cc
index 194ebdd..b6760d5 100644
--- a/chrome/browser/notifications/balloon_collection.cc
+++ b/chrome/browser/notifications/balloon_collection.cc
@@ -76,6 +76,19 @@ bool BalloonCollectionImpl::HasSpace() const {
return current_max_size < max_allowed_size - max_balloon_size;
}
+void BalloonCollectionImpl::ResizeBalloon(Balloon* balloon,
+ const gfx::Size& size) {
+ // restrict to the min & max sizes
+ gfx::Size real_size(
+ std::max(Layout::min_balloon_width(),
+ std::min(Layout::max_balloon_width(), size.width())),
+ std::max(Layout::min_balloon_height(),
+ std::min(Layout::max_balloon_height(), size.height())));
+
+ balloon->set_content_size(real_size);
+ PositionBalloons(true);
+}
+
void BalloonCollectionImpl::OnBalloonClosed(Balloon* source) {
// We want to free the balloon when finished.
scoped_ptr<Balloon> closed(source);
@@ -95,7 +108,7 @@ void BalloonCollectionImpl::OnBalloonClosed(Balloon* source) {
void BalloonCollectionImpl::PositionBalloons(bool reposition) {
gfx::Point origin = layout_.GetLayoutOrigin();
for (Balloons::iterator it = balloons_.begin(); it != balloons_.end(); ++it) {
- gfx::Point upper_left = layout_.NextPosition((*it)->size(), &origin);
+ gfx::Point upper_left = layout_.NextPosition((*it)->GetViewSize(), &origin);
(*it)->SetPosition(upper_left, reposition);
}
}
diff --git a/chrome/browser/notifications/balloon_collection.h b/chrome/browser/notifications/balloon_collection.h
index 918f993..8810b18 100644
--- a/chrome/browser/notifications/balloon_collection.h
+++ b/chrome/browser/notifications/balloon_collection.h
@@ -32,14 +32,19 @@ class BalloonCollection {
// Is there room to add another notification?
virtual bool HasSpace() const = 0;
+
+ // Request the resizing of a balloon.
+ virtual void ResizeBalloon(Balloon* balloon, const gfx::Size& size) = 0;
+
+ // Inform the collection that a balloon was closed.
+ virtual void OnBalloonClosed(Balloon* source) = 0;
};
// A balloon collection represents a set of notification balloons being
// shown on the screen. It positions new notifications according to
// a layout, and monitors for balloons being closed, which it reports
// up to its parent, the notification UI manager.
-class BalloonCollectionImpl : public BalloonCollection,
- public Balloon::BalloonCloseListener {
+class BalloonCollectionImpl : public BalloonCollection {
public:
class BalloonSpaceChangeListener {
public:
@@ -65,8 +70,7 @@ class BalloonCollectionImpl : public BalloonCollection,
Profile* profile);
virtual bool Remove(const Notification& notification);
virtual bool HasSpace() const;
-
- // Balloon::BalloonCloseListener interface
+ virtual void ResizeBalloon(Balloon* balloon, const gfx::Size& size);
virtual void OnBalloonClosed(Balloon* source);
protected:
@@ -117,10 +121,10 @@ class BalloonCollectionImpl : public BalloonCollection,
VERTICALLY_FROM_BOTTOM_RIGHT
};
- // Minimum and maximum size of balloon
+ // Minimum and maximum size of balloon content.
static const int kBalloonMinWidth = 300;
static const int kBalloonMaxWidth = 300;
- static const int kBalloonMinHeight = 90;
+ static const int kBalloonMinHeight = 48;
static const int kBalloonMaxHeight = 120;
static Placement placement_;
diff --git a/chrome/browser/notifications/balloon_collection_win.cc b/chrome/browser/notifications/balloon_collection_win.cc
index 45f7921..53d9808 100644
--- a/chrome/browser/notifications/balloon_collection_win.cc
+++ b/chrome/browser/notifications/balloon_collection_win.cc
@@ -34,7 +34,7 @@ Balloon* BalloonCollectionImpl::MakeBalloon(const Notification& notification,
Balloon* balloon = new Balloon(notification, profile, this);
balloon->set_view(new BalloonViewImpl());
gfx::Size size(layout_.min_balloon_width(), layout_.min_balloon_height());
- balloon->set_size(size);
+ balloon->set_content_size(size);
return balloon;
}
diff --git a/chrome/browser/notifications/desktop_notifications_unittest.cc b/chrome/browser/notifications/desktop_notifications_unittest.cc
index 8d0bcf6..32bda04 100644
--- a/chrome/browser/notifications/desktop_notifications_unittest.cc
+++ b/chrome/browser/notifications/desktop_notifications_unittest.cc
@@ -70,8 +70,8 @@ int MockBalloonCollection::UppermostVerticalPosition() {
return min;
}
-DesktopNotificationsTest::DesktopNotificationsTest() :
- ui_thread_(ChromeThread::UI, &message_loop_) {
+DesktopNotificationsTest::DesktopNotificationsTest()
+ : ui_thread_(ChromeThread::UI, &message_loop_) {
}
DesktopNotificationsTest::~DesktopNotificationsTest() {
@@ -183,6 +183,41 @@ TEST_F(DesktopNotificationsTest, TestPositioning) {
EXPECT_EQ(expected_log, log_output_);
}
+
+TEST_F(DesktopNotificationsTest, TestVariableSize) {
+ std::string expected_log;
+ // Create some toasts. After each but the first, make sure there
+ // is a minimum separation between the toasts.
+ int last_top = 0;
+ EXPECT_TRUE(service_->ShowDesktopNotificationText(
+ GURL("http://long.google.com"), GURL("/icon.png"),
+ ASCIIToUTF16("Really Really Really Really Really Really "
+ "Really Really Really Really Really Really "
+ "Really Really Really Really Really Really Really Long Title"),
+ ASCIIToUTF16("Text"),
+ 0, 0, DesktopNotificationService::PageNotification, 0));
+ expected_log.append("notification displayed\n");
+ EXPECT_TRUE(service_->ShowDesktopNotificationText(
+ GURL("http://short.google.com"), GURL("/icon.png"),
+ ASCIIToUTF16("Short title"), ASCIIToUTF16("Text"),
+ 0, 0, DesktopNotificationService::PageNotification, 1));
+ expected_log.append("notification displayed\n");
+
+ std::set<Balloon*>& balloons = balloon_collection_->balloons();
+ std::set<Balloon*>::iterator iter;
+ for (iter = balloons.begin(); iter != balloons.end(); ++iter) {
+ if ((*iter)->notification().origin_url().host() == "long.google.com") {
+ EXPECT_GE((*iter)->GetViewSize().height(),
+ balloon_collection_->MinHeight());
+ EXPECT_LE((*iter)->GetViewSize().height(),
+ balloon_collection_->MaxHeight());
+ } else {
+ EXPECT_EQ((*iter)->GetViewSize().height(),
+ balloon_collection_->MinHeight());
+ }
+ }
+ EXPECT_EQ(expected_log, log_output_);
+}
#endif
TEST_F(DesktopNotificationsTest, TestQueueing) {
diff --git a/chrome/browser/notifications/desktop_notifications_unittest.h b/chrome/browser/notifications/desktop_notifications_unittest.h
index b06aa6e..4297768 100644
--- a/chrome/browser/notifications/desktop_notifications_unittest.h
+++ b/chrome/browser/notifications/desktop_notifications_unittest.h
@@ -45,6 +45,7 @@ class MockBalloonView : public BalloonView {
void Show(Balloon* balloon) {}
void RepositionToBalloon() {}
void Close(bool by_user) { balloon_->OnClose(by_user); }
+ gfx::Size GetSize() const { return balloon_->content_size(); }
private:
// Non-owned pointer.
@@ -79,8 +80,9 @@ class MockBalloonCollection : public BalloonCollectionImpl {
// Returns the highest y-coordinate of all the balloons in the collection.
int UppermostVerticalPosition();
- // Returns the minimum height of a balloon.
+ // Returns the height bounds of a balloon.
int MinHeight() { return Layout::min_balloon_height(); }
+ int MaxHeight() { return Layout::max_balloon_height(); }
private:
std::set<Balloon*> balloons_;
diff --git a/chrome/browser/views/notifications/balloon_view.cc b/chrome/browser/views/notifications/balloon_view.cc
index b6dffd5..8bd8800 100644
--- a/chrome/browser/views/notifications/balloon_view.cc
+++ b/chrome/browser/views/notifications/balloon_view.cc
@@ -18,6 +18,8 @@
#include "chrome/browser/notifications/balloon.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/profile.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/views/notifications/balloon_view_host.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_source.h"
@@ -26,7 +28,6 @@
#include "grit/theme_resources.h"
#include "views/controls/button/button.h"
#include "views/controls/button/text_button.h"
-#include "views/controls/label.h"
#include "views/controls/menu/menu_2.h"
#include "views/controls/native/native_view_host.h"
#include "views/painter.h"
@@ -129,6 +130,15 @@ void BalloonViewImpl::Close(bool by_user) {
&BalloonViewImpl::DelayedClose, by_user));
}
+gfx::Size BalloonViewImpl::GetSize() const {
+ // BalloonView has no size if it hasn't been shown yet (which is when
+ // balloon_ is set).
+ if (!balloon_)
+ return gfx::Size(0, 0);
+
+ return gfx::Size(GetTotalWidth(), GetTotalHeight());
+}
+
void BalloonViewImpl::RunMenu(views::View* source, const gfx::Point& pt) {
RunOptionsMenu(pt);
}
@@ -156,6 +166,10 @@ void BalloonViewImpl::SizeContentsWindow() {
gfx::Path path;
GetContentsMask(contents_rect, &path);
html_container_->SetShape(path.CreateNativeRegion());
+
+ close_button_->SetBounds(GetCloseButtonBounds());
+ options_menu_button_->SetBounds(GetOptionsMenuBounds());
+ source_label_->SetBounds(GetLabelBounds());
}
void BalloonViewImpl::RepositionToBalloon() {
@@ -165,16 +179,20 @@ void BalloonViewImpl::RepositionToBalloon() {
if (!kAnimateEnabled) {
frame_container_->SetBounds(
- gfx::Rect(balloon_->position(), balloon_->size()));
+ gfx::Rect(balloon_->position().x(), balloon_->position().y(),
+ GetTotalWidth(), GetTotalHeight()));
gfx::Rect contents_rect = GetContentsRectangle();
html_container_->SetBounds(contents_rect);
+ html_contents_->SetPreferredSize(contents_rect.size());
+ RenderWidgetHostView* view = html_contents_->render_view_host()->view();
+ if (view)
+ view->SetSize(contents_rect.size());
return;
}
- anim_frame_end_ = gfx::Rect(balloon_->position().x(),
- balloon_->position().y(),
- balloon_->size().width(),
- balloon_->size().height());
+ anim_frame_end_ = gfx::Rect(
+ balloon_->position().x(), balloon_->position().y(),
+ GetTotalWidth(), GetTotalHeight());
frame_container_->GetBounds(&anim_frame_start_, false);
animation_.reset(new SlideAnimation(this));
animation_->Show();
@@ -196,19 +214,68 @@ void BalloonViewImpl::AnimationProgressed(const Animation* animation) {
e * anim_frame_end_.width()),
static_cast<int>(s * anim_frame_start_.height() +
e * anim_frame_end_.height()));
-
frame_container_->SetBounds(frame_position);
- html_container_->SetBounds(GetContentsRectangle());
+
+ gfx::Path path;
+ gfx::Rect contents_rect = GetContentsRectangle();
+ html_container_->SetBounds(contents_rect);
+ GetContentsMask(contents_rect, &path);
+ html_container_->SetShape(path.CreateNativeRegion());
+
+ html_contents_->SetPreferredSize(contents_rect.size());
+ RenderWidgetHostView* view = html_contents_->render_view_host()->view();
+ if (view)
+ view->SetSize(contents_rect.size());
+}
+
+gfx::Rect BalloonViewImpl::GetCloseButtonBounds() const {
+ return gfx::Rect(
+ width() - kDismissButtonWidth - kRightMargin,
+ height() - kDismissButtonHeight - kShelfBorderTopOverlap - kBottomMargin,
+ kDismissButtonWidth,
+ kDismissButtonHeight);
+}
+
+gfx::Rect BalloonViewImpl::GetOptionsMenuBounds() const {
+ return gfx::Rect(
+ width() - kDismissButtonWidth - kOptionsMenuWidth - kRightMargin,
+ height() - kOptionsMenuHeight - kShelfBorderTopOverlap - kBottomMargin,
+ kOptionsMenuWidth,
+ kOptionsMenuHeight);
+}
+
+gfx::Rect BalloonViewImpl::GetLabelBounds() const {
+ return gfx::Rect(
+ kLeftLabelMargin,
+ height() - kDismissButtonHeight - kShelfBorderTopOverlap - kBottomMargin,
+ width() - kDismissButtonWidth - kOptionsMenuWidth - kRightMargin,
+ kDismissButtonHeight);
}
void BalloonViewImpl::Show(Balloon* balloon) {
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+
+ const std::wstring source_label_text = l10n_util::GetStringF(
+ IDS_NOTIFICATION_BALLOON_SOURCE_LABEL,
+ balloon_->notification().display_source());
+ const std::wstring options_text =
+ l10n_util::GetString(IDS_NOTIFICATION_OPTIONS_MENU_LABEL);
+ const std::wstring dismiss_text =
+ l10n_util::GetString(IDS_NOTIFICATION_BALLOON_DISMISS_LABEL);
+
balloon_ = balloon;
close_button_listener_.reset(new BalloonCloseButtonListener(this));
SetBounds(balloon_->position().x(), balloon_->position().y(),
- balloon_->size().width(), balloon_->size().height());
+ GetTotalWidth(), GetTotalHeight());
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ source_label_ = new views::Label(source_label_text);
+ AddChildView(source_label_);
+ options_menu_button_ = new views::MenuButton(NULL, options_text, this, false);
+ AddChildView(options_menu_button_);
+ close_button_ = new views::TextButton(close_button_listener_.get(),
+ dismiss_text);
+ AddChildView(close_button_);
// We have to create two windows: one for the contents and one for the
// frame. Why?
@@ -241,29 +308,15 @@ void BalloonViewImpl::Show(Balloon* balloon) {
frame_container_->Init(NULL, balloon_rect);
frame_container_->SetContentsView(this);
- const std::wstring dismiss_text =
- l10n_util::GetString(IDS_NOTIFICATION_BALLOON_DISMISS_LABEL);
- close_button_ = new views::TextButton(close_button_listener_.get(),
- dismiss_text);
- close_button_->SetFont(rb.GetFont(ResourceBundle::SmallFont));
close_button_->SetIcon(*rb.GetBitmapNamed(IDR_BALLOON_CLOSE));
close_button_->SetHoverIcon(*rb.GetBitmapNamed(IDR_BALLOON_CLOSE_HOVER));
+ close_button_->SetFont(rb.GetFont(ResourceBundle::SmallFont));
close_button_->SetEnabledColor(SK_ColorWHITE);
close_button_->SetHoverColor(SK_ColorDKGRAY);
close_button_->set_alignment(views::TextButton::ALIGN_CENTER);
close_button_->set_icon_placement(views::TextButton::ICON_ON_RIGHT);
- close_button_->SetBounds(width() - kDismissButtonWidth
- - kRightMargin,
- height() - kDismissButtonHeight
- - kShelfBorderTopOverlap
- - kBottomMargin,
- kDismissButtonWidth,
- kDismissButtonHeight);
- AddChildView(close_button_);
+ close_button_->SetBounds(GetCloseButtonBounds());
- const std::wstring options_text =
- l10n_util::GetString(IDS_NOTIFICATION_OPTIONS_MENU_LABEL);
- options_menu_button_ = new views::MenuButton(NULL, options_text, this, false);
options_menu_button_->SetFont(rb.GetFont(ResourceBundle::SmallFont));
options_menu_button_->SetIcon(*rb.GetBitmapNamed(IDR_BALLOON_OPTIONS_ARROW));
options_menu_button_->SetHoverIcon(
@@ -272,34 +325,12 @@ void BalloonViewImpl::Show(Balloon* balloon) {
options_menu_button_->set_icon_placement(views::TextButton::ICON_ON_RIGHT);
options_menu_button_->SetEnabledColor(SK_ColorWHITE);
options_menu_button_->SetHoverColor(SK_ColorDKGRAY);
- options_menu_button_->SetBounds(width() - kDismissButtonWidth
- - kOptionsMenuWidth
- - kRightMargin,
- height() - kOptionsMenuHeight
- - kShelfBorderTopOverlap
- - kBottomMargin,
- kOptionsMenuWidth,
- kOptionsMenuHeight);
- AddChildView(options_menu_button_);
+ options_menu_button_->SetBounds(GetOptionsMenuBounds());
- const std::wstring source_label_text = l10n_util::GetStringF(
- IDS_NOTIFICATION_BALLOON_SOURCE_LABEL,
- this->balloon_->notification().display_source());
-
- views::Label* source_label = new views::Label(source_label_text);
- source_label->SetFont(ResourceBundle::GetSharedInstance().GetFont(
- ResourceBundle::SmallFont));
- source_label->SetColor(SK_ColorWHITE);
- source_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- source_label->SetBounds(kLeftLabelMargin,
- height() - kDismissButtonHeight
- - kShelfBorderTopOverlap
- - kBottomMargin,
- width() - kDismissButtonWidth
- - kOptionsMenuWidth
- - kRightMargin,
- kDismissButtonHeight);
- AddChildView(source_label);
+ source_label_->SetFont(rb.GetFont(ResourceBundle::SmallFont));
+ source_label_->SetColor(SK_ColorWHITE);
+ source_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ source_label_->SetBounds(GetLabelBounds());
SizeContentsWindow();
html_container_->Show();
@@ -373,17 +404,27 @@ int BalloonViewImpl::GetBalloonFrameHeight() const {
return GetTotalFrameHeight() - GetShelfHeight();
}
+int BalloonViewImpl::GetTotalWidth() const {
+ return balloon_->content_size().width()
+ + kLeftMargin + kRightMargin + kLeftShadowWidth + kRightShadowWidth;
+}
+
+int BalloonViewImpl::GetTotalHeight() const {
+ return balloon_->content_size().height()
+ + kTopMargin + kBottomMargin + kTopShadowWidth + kBottomShadowWidth
+ + GetShelfHeight();
+}
+
gfx::Rect BalloonViewImpl::GetContentsRectangle() const {
if (!frame_container_)
return gfx::Rect();
- int contents_width = GetFrameWidth() - kLeftMargin - kRightMargin;
- int contents_height = GetBalloonFrameHeight() - kTopMargin - kBottomMargin;
+ gfx::Size content_size = balloon_->content_size();
gfx::Point offset = GetContentsOffset();
gfx::Rect frame_rect;
frame_container_->GetBounds(&frame_rect, true);
return gfx::Rect(frame_rect.x() + offset.x(), frame_rect.y() + offset.y(),
- contents_width, contents_height);
+ content_size.width(), content_size.height());
}
void BalloonViewImpl::Paint(gfx::Canvas* canvas) {
diff --git a/chrome/browser/views/notifications/balloon_view.h b/chrome/browser/views/notifications/balloon_view.h
index bc313ba..84147ad 100644
--- a/chrome/browser/views/notifications/balloon_view.h
+++ b/chrome/browser/views/notifications/balloon_view.h
@@ -20,6 +20,7 @@
#include "chrome/common/notification_registrar.h"
#include "chrome/common/notification_service.h"
#include "views/controls/button/menu_button.h"
+#include "views/controls/label.h"
#include "views/controls/menu/view_menu_delegate.h"
#include "views/view.h"
@@ -52,6 +53,7 @@ class BalloonViewImpl : public BalloonView,
void Show(Balloon* balloon);
void RepositionToBalloon();
void Close(bool by_user);
+ gfx::Size GetSize() const;
private:
// views::View interface.
@@ -109,6 +111,13 @@ class BalloonViewImpl : public BalloonView,
// The height of the part of the frame around the balloon.
int GetBalloonFrameHeight() const;
+ int GetTotalWidth() const;
+ int GetTotalHeight() const;
+
+ gfx::Rect GetCloseButtonBounds() const;
+ gfx::Rect GetOptionsMenuBounds() const;
+ gfx::Rect GetLabelBounds() const;
+
// Where the balloon contents should be placed with respect to the top left
// of the frame.
gfx::Point GetContentsOffset() const;
@@ -140,6 +149,9 @@ class BalloonViewImpl : public BalloonView,
// Pointer to sub-view is owned by the View sub-class.
views::TextButton* close_button_;
+ // Pointer to sub-view is owned by View class.
+ views::Label* source_label_;
+
// Listener for clicks on the close button.
scoped_ptr<views::ButtonListener> close_button_listener_;
diff --git a/chrome/browser/views/notifications/balloon_view_host.cc b/chrome/browser/views/notifications/balloon_view_host.cc
index 1c467e0..e825399 100644
--- a/chrome/browser/views/notifications/balloon_view_host.cc
+++ b/chrome/browser/views/notifications/balloon_view_host.cc
@@ -17,6 +17,7 @@
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
+#include "chrome/common/render_messages.h"
#include "chrome/common/renderer_preferences.h"
#include "views/widget/widget.h"
#include "views/widget/widget_win.h"
@@ -47,6 +48,11 @@ void BalloonViewHost::Close(RenderViewHost* render_view_host) {
balloon_->CloseByScript();
}
+void BalloonViewHost::RenderViewCreated(RenderViewHost* render_view_host) {
+ render_view_host->Send(new ViewMsg_EnablePreferredSizeChangedMode(
+ render_view_host->routing_id()));
+}
+
void BalloonViewHost::RendererReady(RenderViewHost* /* render_view_host */) {
should_notify_on_disconnect_ = true;
NotificationService::current()->Notify(
@@ -73,10 +79,10 @@ void BalloonViewHost::CreateNewWindow(int route_id) {
}
void BalloonViewHost::ShowCreatedWindow(int route_id,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_pos,
- bool user_gesture,
- const GURL& creator_url) {
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture,
+ const GURL& creator_url) {
// Don't allow pop-ups from notifications.
if (disposition == NEW_POPUP)
return;
@@ -88,6 +94,10 @@ void BalloonViewHost::ShowCreatedWindow(int route_id,
}
}
+void BalloonViewHost::UpdatePreferredSize(const gfx::Size& new_size) {
+ balloon_->SetContentPreferredSize(new_size);
+}
+
void BalloonViewHost::Init(gfx::NativeView parent_hwnd) {
DCHECK(!render_view_host_) << "BalloonViewHost already initialized.";
RenderViewHost* rvh = new RenderViewHost(site_instance_.get(),
diff --git a/chrome/browser/views/notifications/balloon_view_host.h b/chrome/browser/views/notifications/balloon_view_host.h
index b9e5a0c..6e18dc3 100644
--- a/chrome/browser/views/notifications/balloon_view_host.h
+++ b/chrome/browser/views/notifications/balloon_view_host.h
@@ -43,6 +43,7 @@ class BalloonViewHost : public views::NativeViewHost,
return balloon_->notification().content_url();
}
virtual void Close(RenderViewHost* render_view_host);
+ virtual void RenderViewCreated(RenderViewHost* render_view_host);
virtual void RendererReady(RenderViewHost* render_view_host);
virtual void RendererGone(RenderViewHost* render_view_host);
virtual void UpdateTitle(RenderViewHost* /* render_view_host */,
@@ -82,8 +83,10 @@ class BalloonViewHost : public views::NativeViewHost,
}
virtual void HandleMouseEvent() {}
virtual void HandleMouseLeave() {}
- virtual void UpdatePreferredSize(const gfx::Size& pref_size) {}
- virtual RendererPreferences GetRendererPrefs() const { return RendererPreferences(); }
+ virtual void UpdatePreferredSize(const gfx::Size& pref_size);
+ virtual RendererPreferences GetRendererPrefs() const {
+ return RendererPreferences();
+ }
// Accessors.
RenderViewHost* render_view_host() const { return render_view_host_; }