summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/notifications
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 /chrome/browser/views/notifications
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
Diffstat (limited to 'chrome/browser/views/notifications')
-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
4 files changed, 128 insertions, 62 deletions
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_; }