diff options
author | johnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-08 19:49:56 +0000 |
---|---|---|
committer | johnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-08 19:49:56 +0000 |
commit | d42d02c4a7ea5fd8781af7a67d9ac186d0ee0db5 (patch) | |
tree | 0dea8cb5c6ee1216a0651b2dea603f0042759b06 | |
parent | cad4da4151f41c6203a9fe502fb818bab7e4862a (diff) | |
download | chromium_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
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_; } |