diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-02 23:47:09 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-02 23:47:09 +0000 |
commit | 83f220770080621463758bce86d195bb60edc178 (patch) | |
tree | 8484a5a144b46c0b4115b694a8854a8bde04c420 | |
parent | ae40ccd86384f6d6246f0d01b6629df16a008402 (diff) | |
download | chromium_src-83f220770080621463758bce86d195bb60edc178.zip chromium_src-83f220770080621463758bce86d195bb60edc178.tar.gz chromium_src-83f220770080621463758bce86d195bb60edc178.tar.bz2 |
Refactoring balloon collection and added chromeos's BalloonCollection.
* Separated BalloonCollection and BalloonCollectionImpl
* Moved BalloonSpaceChangeListener to BalloonCollection from BalloonCollectionImpl as this listener is used by NotificationUIManager.
* Added BalloonCollectionImpl for chromeos. (chromeos/notifications/balloon_collectino_impl.{h,cc})
* Changed NotificationPanel to use ScrollView to show all notifications in the panel.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/660111
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40460 0039d316-1c4b-4281-b951-d872f2087c98
18 files changed, 417 insertions, 175 deletions
diff --git a/chrome/browser/chromeos/notifications/balloon_collection_impl.cc b/chrome/browser/chromeos/notifications/balloon_collection_impl.cc new file mode 100644 index 0000000..c941e56 --- /dev/null +++ b/chrome/browser/chromeos/notifications/balloon_collection_impl.cc @@ -0,0 +1,124 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/notifications/balloon_collection_impl.h" + +#include "base/gfx/rect.h" +#include "base/gfx/size.h" +#include "base/logging.h" +#include "base/stl_util-inl.h" +#include "chrome/browser/chromeos/notifications/balloon_view.h" +#include "chrome/browser/chromeos/notifications/notification_panel.h" +#include "chrome/browser/notifications/balloon.h" +#include "chrome/browser/notifications/notification.h" +#include "chrome/browser/window_sizer.h" + +namespace { + +// Portion of the screen allotted for notifications. When notification balloons +// extend over this, no new notifications are shown until some are closed. +const double kPercentBalloonFillFactor = 0.7; + +// Allow at least this number of balloons on the screen. +const int kMinAllowedBalloonCount = 2; + +// Margin from the edge of the work area +const int kVerticalEdgeMargin = 5; +const int kHorizontalEdgeMargin = 5; + +} // namespace + +namespace chromeos { + +BalloonCollectionImpl::BalloonCollectionImpl() + : panel_(new NotificationPanel()) { +} + +BalloonCollectionImpl::~BalloonCollectionImpl() { + STLDeleteElements(&balloons_); +} + +void BalloonCollectionImpl::Add(const Notification& notification, + Profile* profile) { + Balloon* new_balloon = MakeBalloon(notification, profile); + balloons_.push_back(new_balloon); + new_balloon->Show(); + panel_->Add(new_balloon); + + // There may be no listener in a unit test. + if (space_change_listener_) + space_change_listener_->OnBalloonSpaceChanged(); +} + +bool BalloonCollectionImpl::Remove(const Notification& notification) { + Balloons::iterator iter; + for (iter = balloons_.begin(); iter != balloons_.end(); ++iter) { + if (notification.IsSame((*iter)->notification())) { + // Balloon.CloseByScript() will cause OnBalloonClosed() to be called on + // this object, which will remove it from the collection and free it. + (*iter)->CloseByScript(); + return true; + } + } + return false; +} + +bool BalloonCollectionImpl::HasSpace() const { + return true; +} + +void BalloonCollectionImpl::ResizeBalloon(Balloon* balloon, + const gfx::Size& size) { + // Minimum and maximum size of balloon content. + const int kBalloonMinWidth = 300; + const int kBalloonMaxWidth = 300; + const int kBalloonMinHeight = 24; + const int kBalloonMaxHeight = 120; + + // restrict to the min & max sizes + gfx::Size real_size( + std::max(kBalloonMinWidth, + std::min(kBalloonMaxWidth, size.width())), + std::max(kBalloonMinHeight, + std::min(kBalloonMaxHeight, size.height()))); + balloon->set_content_size(real_size); +} + +void BalloonCollectionImpl::OnBalloonClosed(Balloon* source) { + // We want to free the balloon when finished. + scoped_ptr<Balloon> closed(source); + + panel_->Remove(source); + + for (Balloons::iterator it = balloons_.begin(); it != balloons_.end(); ++it) { + if (*it == source) { + balloons_.erase(it); + break; + } + } + // There may be no listener in a unit test. + if (space_change_listener_) + space_change_listener_->OnBalloonSpaceChanged(); +} + +Balloon* BalloonCollectionImpl::MakeBalloon(const Notification& notification, + Profile* profile) { + // TODO(oshima): Move resize logic to Panel. + const int kInitialBalloonWidth = 300; + const int kInitialBalloonHeight = 60; + + Balloon* balloon = new Balloon(notification, profile, this); + + balloon->set_view(new chromeos::BalloonViewImpl()); + gfx::Size size(kInitialBalloonWidth, kInitialBalloonHeight); + balloon->set_content_size(size); + return balloon; +} + +} // namespace chromeos + +// static +BalloonCollection* BalloonCollection::Create() { + return new chromeos::BalloonCollectionImpl(); +} diff --git a/chrome/browser/chromeos/notifications/balloon_collection_impl.h b/chrome/browser/chromeos/notifications/balloon_collection_impl.h new file mode 100644 index 0000000..319f9e2 --- /dev/null +++ b/chrome/browser/chromeos/notifications/balloon_collection_impl.h @@ -0,0 +1,58 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_NOTIFICATIONS_BALLOON_COLLECTION_IMPL_H_ +#define CHROME_BROWSER_CHROMEOS_NOTIFICATIONS_BALLOON_COLLECTION_IMPL_H_ + +#include <deque> + +#include "base/basictypes.h" +#include "base/gfx/point.h" +#include "base/gfx/rect.h" +#include "base/scoped_ptr.h" +#include "chrome/browser/notifications/balloon_collection.h" + +namespace chromeos { + +class NotificationPanel; + +// A balloon collection represents a set of notification balloons being +// shown in the chromeos notification panel. Unlike other platforms, +// chromeos shows the all notifications in the notification panel, and +// this class does not manage the location of balloons. +class BalloonCollectionImpl : public BalloonCollection { + public: + BalloonCollectionImpl(); + virtual ~BalloonCollectionImpl(); + + // BalloonCollectionInterface overrides + virtual void Add(const Notification& notification, + Profile* profile); + virtual bool Remove(const Notification& notification); + virtual bool HasSpace() const; + virtual void ResizeBalloon(Balloon* balloon, const gfx::Size& size); + virtual void OnBalloonClosed(Balloon* source); + + protected: + // Creates a new balloon. Overridable by unit tests. The caller is + // responsible for freeing the pointer returned. + virtual Balloon* MakeBalloon(const Notification& notification, + Profile* profile); + + private: + // The number of balloons being displayed. + int count() const { return balloons_.size(); } + + // Queue of active balloons. + typedef std::deque<Balloon*> Balloons; + Balloons balloons_; + + scoped_ptr<NotificationPanel> panel_; + + DISALLOW_COPY_AND_ASSIGN(BalloonCollectionImpl); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_NOTIFICATIONS_BALLOON_COLLECTION_H_ diff --git a/chrome/browser/chromeos/notifications/balloon_view.cc b/chrome/browser/chromeos/notifications/balloon_view.cc index f8b5a04..e541cc3 100644 --- a/chrome/browser/chromeos/notifications/balloon_view.cc +++ b/chrome/browser/chromeos/notifications/balloon_view.cc @@ -31,6 +31,8 @@ const int kRevokePermissionCommand = 0; } // namespace +namespace chromeos { + BalloonViewImpl::BalloonViewImpl() : balloon_(NULL), html_contents_(NULL), @@ -94,12 +96,6 @@ void BalloonViewImpl::Show(Balloon* balloon) { balloon_->content_size().width(), balloon_->content_size().height() + close_button_->GetPreferredSize().height()); - - // TODO(oshima): We're not sure if this is the right place to - // add & show in the panel. Revisit the deisgn once we have a collection - // for chromeos. - chromeos::NotificationPanel::Get()->Add(this); - chromeos::NotificationPanel::Get()->Show(); notification_registrar_.Add(this, NotificationType::NOTIFY_BALLOON_DISCONNECTED, Source<Balloon>(balloon)); } @@ -222,8 +218,7 @@ void BalloonViewImpl::CreateOptionsMenu() { void BalloonViewImpl::DelayedClose(bool by_user) { html_contents_->Shutdown(); - // Remove html_contents from panel. - chromeos::NotificationPanel::Get()->Remove(this); - balloon_->OnClose(by_user); } + +} // namespace chromeos diff --git a/chrome/browser/chromeos/notifications/balloon_view.h b/chrome/browser/chromeos/notifications/balloon_view.h index 5b4fcfa..00ef3b0 100644 --- a/chrome/browser/chromeos/notifications/balloon_view.h +++ b/chrome/browser/chromeos/notifications/balloon_view.h @@ -33,6 +33,8 @@ class BalloonViewHost; class NotificationDetails; class NotificationSource; +namespace chromeos { + // A balloon view is the UI component for a notification panel. class BalloonViewImpl : public BalloonView, public views::View, @@ -107,4 +109,6 @@ class BalloonViewImpl : public BalloonView, DISALLOW_COPY_AND_ASSIGN(BalloonViewImpl); }; +} // namespace chromeos + #endif // CHROME_BROWSER_CHROMEOS_NOTIFICATIONS_BALLOON_VIEW_H_ diff --git a/chrome/browser/chromeos/notifications/notification_panel.cc b/chrome/browser/chromeos/notifications/notification_panel.cc index 46c5b81..5d599ed 100644 --- a/chrome/browser/chromeos/notifications/notification_panel.cc +++ b/chrome/browser/chromeos/notifications/notification_panel.cc @@ -9,14 +9,18 @@ #include "app/gfx/canvas.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" -#include "base/singleton.h" #include "chrome/browser/chromeos/notifications/balloon_view.h" #include "grit/generated_resources.h" #include "views/background.h" +#include "views/controls/scroll_view.h" #include "views/widget/widget_gtk.h" namespace chromeos { +// Maximum height of the notification panel. +// TODO(oshima): Get this from system's metrics. +const int kMaxPanelHeight = 400; + class BalloonContainer : public views::View { public: explicit BalloonContainer(int margin) @@ -52,7 +56,8 @@ class BalloonContainer : public views::View { height += c->height() + margin_; max_width = std::max(max_width, c->width()); } - if (height > 0) height -= margin_; + if (height > 0) + height -= margin_; preferred_size_.set_width(max_width); preferred_size_.set_height(height); PreferredSizeChanged(); @@ -62,15 +67,12 @@ class BalloonContainer : public views::View { private: gfx::Size preferred_size_; int margin_; -}; -// static -NotificationPanel* NotificationPanel::Get() { - return Singleton<NotificationPanel>::get(); -} + DISALLOW_COPY_AND_ASSIGN(BalloonContainer); +}; NotificationPanel::NotificationPanel() - : panel_widget_(NULL) { + : balloon_container_(NULL) { Init(); } @@ -79,37 +81,46 @@ NotificationPanel::~NotificationPanel() { gfx::Rect NotificationPanel::GetPanelBounds() { gfx::Size pref_size = balloon_container_->GetPreferredSize(); - int new_height = pref_size.height(); - return gfx::Rect(0, 0, pref_size.width(), new_height); + int new_height = std::min(pref_size.height(), kMaxPanelHeight); + int new_width = pref_size.width(); + if (new_height != pref_size.height()) + new_width += scroll_view_->GetScrollBarWidth(); + return gfx::Rect(0, 0, new_width, new_height); } void NotificationPanel::Init() { DCHECK(!panel_widget_.get()); balloon_container_ = new BalloonContainer(1); - balloon_container_->set_parent_owned(false); balloon_container_->set_background( views::Background::CreateSolidBackground(ResourceBundle::frame_color)); + + scroll_view_.reset(new views::ScrollView()); + scroll_view_->set_parent_owned(false); + scroll_view_->SetContents(balloon_container_); } -void NotificationPanel::Add(BalloonViewImpl* view) { +void NotificationPanel::Add(Balloon* balloon) { + BalloonViewImpl* view = + static_cast<BalloonViewImpl*>(balloon->view()); balloon_container_->AddChildView(view); balloon_container_->UpdateBounds(); - balloon_container_->Layout(); - if (panel_widget_.get()) { + scroll_view_->Layout(); + if (panel_widget_.get()) panel_widget_->SetBounds(GetPanelBounds()); - } + Show(); } -void NotificationPanel::Remove(BalloonViewImpl* view) { +void NotificationPanel::Remove(Balloon* balloon) { + BalloonViewImpl* view = + static_cast<BalloonViewImpl*>(balloon->view()); balloon_container_->RemoveChildView(view); balloon_container_->UpdateBounds(); - balloon_container_->Layout(); + scroll_view_->Layout(); if (panel_widget_.get()) { - if (balloon_container_->GetChildViewCount() == 0) { + if (balloon_container_->GetChildViewCount() == 0) Hide(); - } else { + else panel_widget_->SetBounds(GetPanelBounds()); - } } } @@ -119,7 +130,7 @@ void NotificationPanel::Show() { // when resizing. This needs to be investigated. panel_widget_.reset(new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW)); panel_widget_->Init(NULL, GetPanelBounds()); - panel_widget_->SetContentsView(balloon_container_); + panel_widget_->SetContentsView(scroll_view_.get()); panel_controller_.reset( new PanelController(this, GTK_WINDOW(panel_widget_->GetNativeView()), diff --git a/chrome/browser/chromeos/notifications/notification_panel.h b/chrome/browser/chromeos/notifications/notification_panel.h index 2e6dad5..13062d7 100644 --- a/chrome/browser/chromeos/notifications/notification_panel.h +++ b/chrome/browser/chromeos/notifications/notification_panel.h @@ -9,10 +9,13 @@ #include "base/gfx/rect.h" #include "base/scoped_ptr.h" -#include "base/singleton.h" #include "chrome/browser/chromeos/frame/panel_controller.h" -class BalloonViewImpl; +class Balloon; + +namespace views { +class ScrollView; +} // namespace views namespace chromeos { @@ -20,12 +23,11 @@ class BalloonContainer; class NotificationPanel : PanelController::Delegate { public: - // Returns the Singleton instance of NotificationPanel. - static NotificationPanel* Get(); + NotificationPanel(); + virtual ~NotificationPanel(); - // Adds/Removes a ballon view. - void Add(BalloonViewImpl* view); - void Remove(BalloonViewImpl* view); + void Add(Balloon* balloon); + void Remove(Balloon* ballon); // Shows/Hides the Panel. void Show(); @@ -37,11 +39,6 @@ class NotificationPanel : PanelController::Delegate { virtual void ClosePanel(); private: - friend struct DefaultSingletonTraits<NotificationPanel>; - - NotificationPanel(); - virtual ~NotificationPanel(); - void Init(); // Returns the panel's bounds in the screen's coordinates. // The position will be controlled by window manager so @@ -51,6 +48,9 @@ class NotificationPanel : PanelController::Delegate { BalloonContainer* balloon_container_; scoped_ptr<views::Widget> panel_widget_; scoped_ptr<PanelController> panel_controller_; + scoped_ptr<views::ScrollView> scroll_view_; + + DISALLOW_COPY_AND_ASSIGN(NotificationPanel); }; } // namespace chromeos diff --git a/chrome/browser/notifications/balloon.h b/chrome/browser/notifications/balloon.h index b0ead85..e5767b3 100644 --- a/chrome/browser/notifications/balloon.h +++ b/chrome/browser/notifications/balloon.h @@ -65,6 +65,11 @@ class Balloon { // to this object. void set_view(BalloonView* balloon_view); + // Returns the balloon view associated with the balloon. + BalloonView* view() { + return balloon_view_.get(); + } + // Returns the viewing size for the balloon (content + frame). gfx::Size GetViewSize() const { return balloon_view_->GetSize(); } diff --git a/chrome/browser/notifications/balloon_collection.cc b/chrome/browser/notifications/balloon_collection.cc index d488228..b8b7e9f 100644 --- a/chrome/browser/notifications/balloon_collection.cc +++ b/chrome/browser/notifications/balloon_collection.cc @@ -2,12 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/notifications/balloon_collection.h" +#include "chrome/browser/notifications/balloon_collection_impl.h" #include "base/gfx/rect.h" +#include "base/gfx/size.h" #include "base/logging.h" #include "base/stl_util-inl.h" #include "chrome/browser/notifications/balloon.h" +#include "chrome/browser/notifications/notification.h" #include "chrome/browser/window_sizer.h" namespace { @@ -29,8 +31,7 @@ BalloonCollectionImpl::Layout::Placement BalloonCollectionImpl::Layout::placement_ = Layout::VERTICALLY_FROM_BOTTOM_RIGHT; -BalloonCollectionImpl::BalloonCollectionImpl() - : space_change_listener_(NULL) { +BalloonCollectionImpl::BalloonCollectionImpl() { } BalloonCollectionImpl::~BalloonCollectionImpl() { diff --git a/chrome/browser/notifications/balloon_collection.h b/chrome/browser/notifications/balloon_collection.h index 8bc3132..ff37a12 100644 --- a/chrome/browser/notifications/balloon_collection.h +++ b/chrome/browser/notifications/balloon_collection.h @@ -7,19 +7,31 @@ #ifndef CHROME_BROWSER_NOTIFICATIONS_BALLOON_COLLECTION_H_ #define CHROME_BROWSER_NOTIFICATIONS_BALLOON_COLLECTION_H_ -#include <deque> - -#include "base/gfx/point.h" -#include "base/gfx/rect.h" -#include "base/gfx/size.h" -#include "chrome/browser/notifications/balloon.h" -#include "chrome/browser/notifications/notification.h" - class Balloon; +class Notification; class Profile; +namespace gfx { +class Size; +} // namespace gfx + class BalloonCollection { public: + class BalloonSpaceChangeListener { + public: + virtual ~BalloonSpaceChangeListener() {} + + // Called when there is more or less space for balloons due to + // monitor size changes or balloons disappearing. + virtual void OnBalloonSpaceChanged() = 0; + }; + + static BalloonCollection* Create(); + + BalloonCollection() + : space_change_listener_(NULL) { + } + virtual ~BalloonCollection() {} // Adds a new balloon for the specified notification. @@ -38,25 +50,6 @@ class BalloonCollection { // 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: - class BalloonSpaceChangeListener { - public: - virtual ~BalloonSpaceChangeListener() {} - - // Called when there is more or less space for balloons due to - // monitor size changes or balloons disappearing. - virtual void OnBalloonSpaceChanged() = 0; - }; - - BalloonCollectionImpl(); - virtual ~BalloonCollectionImpl(); BalloonSpaceChangeListener* space_change_listener() { return space_change_listener_; @@ -65,101 +58,9 @@ class BalloonCollectionImpl : public BalloonCollection { space_change_listener_ = listener; } - // BalloonCollectionInterface overrides - virtual void Add(const Notification& notification, - Profile* profile); - virtual bool Remove(const Notification& notification); - virtual bool HasSpace() const; - virtual void ResizeBalloon(Balloon* balloon, const gfx::Size& size); - virtual void OnBalloonClosed(Balloon* source); - protected: - // Calculates layout values for the balloons including - // the scaling, the max/min sizes, and the upper left corner of each. - class Layout { - public: - Layout(); - - // Refresh the work area and balloon placement. - void OnDisplaySettingsChanged(); - - // TODO(johnnyg): Scale the size to account for the system font factor. - static int min_balloon_width() { return kBalloonMinWidth; } - static int max_balloon_width() { return kBalloonMaxWidth; } - static int min_balloon_height() { return kBalloonMinHeight; } - static int max_balloon_height() { return kBalloonMaxHeight; } - - // Returns both the total space available and the maximum - // allowed per balloon. - // - // The size may be a height or length depending on the way that - // balloons are laid out. - void GetMaxLinearSize(int* max_balloon_size, int* total_size) const; - - // Refresh the cached values for work area and drawing metrics. - // The application should call this method to re-acquire metrics after - // any resolution or settings change. - // Returns true if and only if a metric changed. - bool RefreshSystemMetrics(); - - // Returns the origin for the sequence of balloons depending on layout. - // Should not be used to place a balloon -- only to call NextPosition(). - gfx::Point GetLayoutOrigin() const; - - // Compute the position for the next balloon. - // Start with *position_iterator = GetLayoutOrigin() and call repeatedly - // to get a sequence of positions. Return value is the upper-left coordinate - // for each next balloon. - gfx::Point NextPosition(const gfx::Size& balloon_size, - gfx::Point* position_iterator) const; - - private: - enum Placement { - HORIZONTALLY_FROM_BOTTOM_LEFT, - HORIZONTALLY_FROM_BOTTOM_RIGHT, - VERTICALLY_FROM_TOP_RIGHT, - VERTICALLY_FROM_BOTTOM_RIGHT - }; - - // Layout parameters - int VerticalEdgeMargin() const; - int HorizontalEdgeMargin() const; - int InterBalloonMargin() const; - - // Minimum and maximum size of balloon content. - static const int kBalloonMinWidth = 300; - static const int kBalloonMaxWidth = 300; - static const int kBalloonMinHeight = 24; - static const int kBalloonMaxHeight = 120; - - static Placement placement_; - gfx::Rect work_area_; - DISALLOW_COPY_AND_ASSIGN(Layout); - }; - - // Creates a new balloon. Overridable by unit tests. The caller is - // responsible for freeing the pointer returned. - virtual Balloon* MakeBalloon(const Notification& notification, - Profile* profile); - - private: - // The number of balloons being displayed. - int count() const { return balloons_.size(); } - - // Adjusts the positions of the balloons (e.g., when one is closed). - void PositionBalloons(bool is_reposition); - // Non-owned pointer to an object listening for space changes. BalloonSpaceChangeListener* space_change_listener_; - - // Queue of active balloons. - typedef std::deque<Balloon*> Balloons; - Balloons balloons_; - - // The layout parameters for balloons in this collection. - Layout layout_; - - DISALLOW_COPY_AND_ASSIGN(BalloonCollectionImpl); }; #endif // CHROME_BROWSER_NOTIFICATIONS_BALLOON_COLLECTION_H_ diff --git a/chrome/browser/notifications/balloon_collection_impl.h b/chrome/browser/notifications/balloon_collection_impl.h new file mode 100644 index 0000000..c8eef59 --- /dev/null +++ b/chrome/browser/notifications/balloon_collection_impl.h @@ -0,0 +1,120 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Handles the visible notification (or balloons). + +#ifndef CHROME_BROWSER_NOTIFICATIONS_BALLOON_COLLECTION_IMPL_H_ +#define CHROME_BROWSER_NOTIFICATIONS_BALLOON_COLLECTION_IMPL_H_ + +#include <deque> + +#include "base/basictypes.h" +#include "base/gfx/point.h" +#include "base/gfx/rect.h" +#include "chrome/browser/notifications/balloon_collection.h" + +// 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: + BalloonCollectionImpl(); + virtual ~BalloonCollectionImpl(); + + // BalloonCollectionInterface overrides + virtual void Add(const Notification& notification, + Profile* profile); + virtual bool Remove(const Notification& notification); + virtual bool HasSpace() const; + virtual void ResizeBalloon(Balloon* balloon, const gfx::Size& size); + virtual void OnBalloonClosed(Balloon* source); + + protected: + // Calculates layout values for the balloons including + // the scaling, the max/min sizes, and the upper left corner of each. + class Layout { + public: + Layout(); + + // Refresh the work area and balloon placement. + void OnDisplaySettingsChanged(); + + // TODO(johnnyg): Scale the size to account for the system font factor. + static int min_balloon_width() { return kBalloonMinWidth; } + static int max_balloon_width() { return kBalloonMaxWidth; } + static int min_balloon_height() { return kBalloonMinHeight; } + static int max_balloon_height() { return kBalloonMaxHeight; } + + // Returns both the total space available and the maximum + // allowed per balloon. + // + // The size may be a height or length depending on the way that + // balloons are laid out. + void GetMaxLinearSize(int* max_balloon_size, int* total_size) const; + + // Refresh the cached values for work area and drawing metrics. + // The application should call this method to re-acquire metrics after + // any resolution or settings change. + // Returns true if and only if a metric changed. + bool RefreshSystemMetrics(); + + // Returns the origin for the sequence of balloons depending on layout. + // Should not be used to place a balloon -- only to call NextPosition(). + gfx::Point GetLayoutOrigin() const; + + // Compute the position for the next balloon. + // Start with *position_iterator = GetLayoutOrigin() and call repeatedly + // to get a sequence of positions. Return value is the upper-left coordinate + // for each next balloon. + gfx::Point NextPosition(const gfx::Size& balloon_size, + gfx::Point* position_iterator) const; + + private: + enum Placement { + HORIZONTALLY_FROM_BOTTOM_LEFT, + HORIZONTALLY_FROM_BOTTOM_RIGHT, + VERTICALLY_FROM_TOP_RIGHT, + VERTICALLY_FROM_BOTTOM_RIGHT + }; + + // Layout parameters + int VerticalEdgeMargin() const; + int HorizontalEdgeMargin() const; + int InterBalloonMargin() const; + + // Minimum and maximum size of balloon content. + static const int kBalloonMinWidth = 300; + static const int kBalloonMaxWidth = 300; + static const int kBalloonMinHeight = 24; + static const int kBalloonMaxHeight = 120; + + static Placement placement_; + gfx::Rect work_area_; + DISALLOW_COPY_AND_ASSIGN(Layout); + }; + + // Creates a new balloon. Overridable by unit tests. The caller is + // responsible for freeing the pointer returned. + virtual Balloon* MakeBalloon(const Notification& notification, + Profile* profile); + + private: + // The number of balloons being displayed. + int count() const { return balloons_.size(); } + + // Adjusts the positions of the balloons (e.g., when one is closed). + void PositionBalloons(bool is_reposition); + + // Queue of active balloons. + typedef std::deque<Balloon*> Balloons; + Balloons balloons_; + + // The layout parameters for balloons in this collection. + Layout layout_; + + DISALLOW_COPY_AND_ASSIGN(BalloonCollectionImpl); +}; + +#endif // CHROME_BROWSER_NOTIFICATIONS_BALLOON_COLLECTION_IMPL_H_ diff --git a/chrome/browser/notifications/balloon_collection_linux.cc b/chrome/browser/notifications/balloon_collection_linux.cc index e85ed0c..5d0c2b7 100644 --- a/chrome/browser/notifications/balloon_collection_linux.cc +++ b/chrome/browser/notifications/balloon_collection_linux.cc @@ -2,10 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/notifications/balloon_collection.h" +#include "chrome/browser/notifications/balloon_collection_impl.h" #include "base/gfx/size.h" -#include "base/logging.h" #include "chrome/browser/notifications/balloon.h" #include "chrome/browser/views/notifications/balloon_view.h" @@ -30,3 +29,8 @@ int BalloonCollectionImpl::Layout::HorizontalEdgeMargin() const { int BalloonCollectionImpl::Layout::VerticalEdgeMargin() const { return 5; } + +// static +BalloonCollection* BalloonCollection::Create() { + return new BalloonCollectionImpl(); +} diff --git a/chrome/browser/notifications/balloon_collection_mac.mm b/chrome/browser/notifications/balloon_collection_mac.mm index f484fd6..f11fc9d 100644 --- a/chrome/browser/notifications/balloon_collection_mac.mm +++ b/chrome/browser/notifications/balloon_collection_mac.mm @@ -2,10 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/notifications/balloon_collection.h" -#include "chrome/browser/cocoa/notifications/balloon_view_bridge.h" +#include "chrome/browser/notifications/balloon_collection_impl.h" -#include "base/logging.h" +#include "chrome/browser/cocoa/notifications/balloon_view_bridge.h" Balloon* BalloonCollectionImpl::MakeBalloon(const Notification& notification, Profile* profile) { @@ -27,3 +26,8 @@ int BalloonCollectionImpl::Layout::HorizontalEdgeMargin() const { int BalloonCollectionImpl::Layout::VerticalEdgeMargin() const { return 18; } + +// static +BalloonCollection* BalloonCollection::Create() { + return new BalloonCollectionImpl(); +} diff --git a/chrome/browser/notifications/balloon_collection_win.cc b/chrome/browser/notifications/balloon_collection_win.cc index b21923e..405ea04 100644 --- a/chrome/browser/notifications/balloon_collection_win.cc +++ b/chrome/browser/notifications/balloon_collection_win.cc @@ -2,10 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/notifications/balloon_collection.h" +#include "chrome/browser/notifications/balloon_collection_impl.h" #include "base/gfx/rect.h" -#include "base/logging.h" #include "chrome/browser/notifications/balloon.h" #include "chrome/browser/views/notifications/balloon_view.h" @@ -29,3 +28,8 @@ int BalloonCollectionImpl::Layout::HorizontalEdgeMargin() const { int BalloonCollectionImpl::Layout::VerticalEdgeMargin() const { return 5; } + +// static +BalloonCollection* BalloonCollection::Create() { + return new BalloonCollectionImpl(); +} diff --git a/chrome/browser/notifications/desktop_notifications_unittest.h b/chrome/browser/notifications/desktop_notifications_unittest.h index 4297768..927e519 100644 --- a/chrome/browser/notifications/desktop_notifications_unittest.h +++ b/chrome/browser/notifications/desktop_notifications_unittest.h @@ -12,7 +12,7 @@ #include "chrome/browser/browser_list.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/notifications/balloon.h" -#include "chrome/browser/notifications/balloon_collection.h" +#include "chrome/browser/notifications/balloon_collection_impl.h" #include "chrome/browser/notifications/desktop_notification_service.h" #include "chrome/browser/notifications/notification.h" #include "chrome/browser/notifications/notification_object_proxy.h" diff --git a/chrome/browser/notifications/notification_ui_manager.cc b/chrome/browser/notifications/notification_ui_manager.cc index 0330570..e5ae3bd 100644 --- a/chrome/browser/notifications/notification_ui_manager.cc +++ b/chrome/browser/notifications/notification_ui_manager.cc @@ -42,7 +42,7 @@ NotificationUIManager::~NotificationUIManager() { // static NotificationUIManager* NotificationUIManager::Create() { - BalloonCollectionImpl* balloons = new BalloonCollectionImpl(); + BalloonCollection* balloons = BalloonCollection::Create(); NotificationUIManager* instance = new NotificationUIManager(); instance->Initialize(balloons); balloons->set_space_change_listener(instance); diff --git a/chrome/browser/notifications/notification_ui_manager.h b/chrome/browser/notifications/notification_ui_manager.h index 9aff1d4..9e2cf18 100644 --- a/chrome/browser/notifications/notification_ui_manager.h +++ b/chrome/browser/notifications/notification_ui_manager.h @@ -20,7 +20,7 @@ class SiteInstance; // The notification manager manages use of the desktop for notifications. // It maintains a queue of pending notifications when space becomes constrained. class NotificationUIManager - : public BalloonCollectionImpl::BalloonSpaceChangeListener { + : public BalloonCollection::BalloonSpaceChangeListener { public: NotificationUIManager(); virtual ~NotificationUIManager(); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 1b2c93f..a1352ed 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -294,6 +294,8 @@ 'browser/chrome_plugin_host.h', 'browser/chrome_thread.cc', 'browser/chrome_thread.h', + 'browser/chromeos/notifications/balloon_collection_impl.h', + 'browser/chromeos/notifications/balloon_collection_impl.cc', 'browser/chromeos/notifications/balloon_view.h', 'browser/chromeos/notifications/balloon_view.cc', 'browser/chromeos/notifications/notification_panel.h', @@ -1462,6 +1464,7 @@ 'browser/notifications/balloon.h', 'browser/notifications/balloon_collection.cc', 'browser/notifications/balloon_collection.h', + 'browser/notifications/balloon_collection_impl.h', 'browser/notifications/balloon_collection_win.cc', 'browser/notifications/balloon_collection_mac.mm', 'browser/notifications/balloon_collection_linux.cc', @@ -2802,8 +2805,11 @@ ], }], ['OS=="linux" and chromeos==1',{ + 'sources/': [ + ['exclude', '^browser/notifications/balloon_collection_linux.cc'], + ['exclude', '^browser/notifications/balloon_collection_impl.h'], + ], 'dependencies': [ - '../third_party/protobuf2/protobuf.gyp:protobuf_lite', '../third_party/protobuf2/protobuf.gyp:protoc#host', '../third_party/chromeos_login_manager/chromeos_login_manager/chromeos_login_manager.gyp:session', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 3a004ba..533d779 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -978,6 +978,11 @@ ['include', 'browser/views/bookmark_context_menu_test.cc$'], ], }], + ['OS=="linux" and chromeos==1', { + 'sources/': [ + ['exclude', 'browser/notifications/desktop_notifications_unittest\\.cc$'], + ] + }], ['OS=="mac"', { # The test fetches resources which means Mac need the app bundle to # exist on disk so it can pull from it. |