diff options
author | dewittj@chromium.org <dewittj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-07 14:29:52 +0000 |
---|---|---|
committer | dewittj@chromium.org <dewittj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-07 14:29:52 +0000 |
commit | 76c589d605ed841dbecdab98ab2560a821b539d7 (patch) | |
tree | ad8464a75b844fd0886b34ae1cff240030d5d53b /ui | |
parent | 58e7f9bede489a70939ccc69bd24ba986d679b0e (diff) | |
download | chromium_src-76c589d605ed841dbecdab98ab2560a821b539d7.zip chromium_src-76c589d605ed841dbecdab98ab2560a821b539d7.tar.gz chromium_src-76c589d605ed841dbecdab98ab2560a821b539d7.tar.bz2 |
Update notification settings to allow for multiprofile situations.
This introduces the NotifierGroup concept to ui/message_center, which will
correspond directly to Profiles. The user will be able to select a
NotifierGroup and then update the notification settings relevant to that
group/profile.
TBR=sky@chromium.org
R=jianli@chromium.org
BUG=254511,256415,218402
Review URL: https://chromiumcodereview.appspot.com/20066003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216186 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/base/strings/ui_strings.grd | 13 | ||||
-rw-r--r-- | ui/message_center/cocoa/settings_controller.h | 1 | ||||
-rw-r--r-- | ui/message_center/cocoa/settings_controller.mm | 2 | ||||
-rw-r--r-- | ui/message_center/fake_notifier_settings_provider.cc | 24 | ||||
-rw-r--r-- | ui/message_center/fake_notifier_settings_provider.h | 10 | ||||
-rw-r--r-- | ui/message_center/message_center.gyp | 2 | ||||
-rw-r--r-- | ui/message_center/notifier_settings.cc | 11 | ||||
-rw-r--r-- | ui/message_center/notifier_settings.h | 44 | ||||
-rw-r--r-- | ui/message_center/views/message_center_button_bar.cc | 210 | ||||
-rw-r--r-- | ui/message_center/views/message_center_button_bar.h | 68 | ||||
-rw-r--r-- | ui/message_center/views/message_center_view.cc | 313 | ||||
-rw-r--r-- | ui/message_center/views/message_center_view.h | 15 | ||||
-rw-r--r-- | ui/message_center/views/notifier_settings_view.cc | 171 | ||||
-rw-r--r-- | ui/message_center/views/notifier_settings_view.h | 20 |
14 files changed, 609 insertions, 295 deletions
diff --git a/ui/base/strings/ui_strings.grd b/ui/base/strings/ui_strings.grd index 21d7001..94b99d2 100644 --- a/ui/base/strings/ui_strings.grd +++ b/ui/base/strings/ui_strings.grd @@ -464,9 +464,16 @@ need to be translated for each locale.--> <message name="IDS_MESSAGE_CENTER_SETTINGS_GO_BACK_BUTTON_TOOLTIP" desc="The tooltip on back button that returns from settings to the notification list."> Go back to notifications </message> - <message name="IDS_MESSAGE_CENTER_SETTINGS_DIALOG_DESCRIPTION" desc="The label to describe the settings dialog."> - Allow notifications from the following: - </message> + <if expr="is_macosx"> + <message name="IDS_MESSAGE_CENTER_SETTINGS_DIALOG_DESCRIPTION" desc="The label to describe the settings dialog."> + Allow notifications from the following: + </message> + </if> + <if expr="not is_macosx"> + <message name="IDS_MESSAGE_CENTER_SETTINGS_DIALOG_DESCRIPTION" desc="The label to describe the settings dialog."> + Manage notifications per profile: + </message> + </if> <message name="IDS_MESSAGE_CENTER_SETTINGS" desc="The menu entry or button for visiting the appropriate settings page."> Settings... </message> diff --git a/ui/message_center/cocoa/settings_controller.h b/ui/message_center/cocoa/settings_controller.h index d81b99b..380ae14 100644 --- a/ui/message_center/cocoa/settings_controller.h +++ b/ui/message_center/cocoa/settings_controller.h @@ -26,6 +26,7 @@ class NotifierSettingsObserverMac : public NotifierSettingsObserver { // Overridden from NotifierSettingsObserver: virtual void UpdateIconImage(const NotifierId& notifier_id, const gfx::Image& icon) OVERRIDE; + virtual void NotifierGroupChanged() OVERRIDE; private: MCSettingsController* settings_controller_; // weak, owns this diff --git a/ui/message_center/cocoa/settings_controller.mm b/ui/message_center/cocoa/settings_controller.mm index 45c66ea..f34f9f0 100644 --- a/ui/message_center/cocoa/settings_controller.mm +++ b/ui/message_center/cocoa/settings_controller.mm @@ -110,6 +110,8 @@ void NotifierSettingsObserverMac::UpdateIconImage(const NotifierId& notifier_id, [settings_controller_ setIcon:icon.AsNSImage() forNotifierId:notifier_id]; } +void NotifierSettingsObserverMac::NotifierGroupChanged() {} + } // namespace message_center @implementation MCSettingsController diff --git a/ui/message_center/fake_notifier_settings_provider.cc b/ui/message_center/fake_notifier_settings_provider.cc index 0695d08..66b193b 100644 --- a/ui/message_center/fake_notifier_settings_provider.cc +++ b/ui/message_center/fake_notifier_settings_provider.cc @@ -4,14 +4,36 @@ #include "ui/message_center/fake_notifier_settings_provider.h" +#include "base/strings/utf_string_conversions.h" +#include "ui/gfx/image/image.h" + namespace message_center { FakeNotifierSettingsProvider::FakeNotifierSettingsProvider( const std::vector<Notifier*>& notifiers) - : notifiers_(notifiers), closed_called_count_(0) {} + : notifiers_(notifiers), + notifier_group_(gfx::Image(), + UTF8ToUTF16("Fake name"), + UTF8ToUTF16("fake@email.com"), + true), + closed_called_count_(0) {} FakeNotifierSettingsProvider::~FakeNotifierSettingsProvider() {} +size_t FakeNotifierSettingsProvider::GetNotifierGroupCount() const { return 1; } + +const message_center::NotifierGroup& +FakeNotifierSettingsProvider::GetNotifierGroupAt(size_t index) const { + return notifier_group_; +} + +void FakeNotifierSettingsProvider::SwitchToNotifierGroup(size_t index) {} + +const message_center::NotifierGroup& +FakeNotifierSettingsProvider::GetActiveNotifierGroup() const { + return notifier_group_; +} + void FakeNotifierSettingsProvider::GetNotifierList( std::vector<Notifier*>* notifiers) { notifiers->clear(); diff --git a/ui/message_center/fake_notifier_settings_provider.h b/ui/message_center/fake_notifier_settings_provider.h index 47a3549..f2c5cd7 100644 --- a/ui/message_center/fake_notifier_settings_provider.h +++ b/ui/message_center/fake_notifier_settings_provider.h @@ -14,7 +14,14 @@ namespace message_center { class FakeNotifierSettingsProvider : public NotifierSettingsProvider { public: FakeNotifierSettingsProvider(const std::vector<Notifier*>& notifiers); - ~FakeNotifierSettingsProvider(); + virtual ~FakeNotifierSettingsProvider(); + + virtual size_t GetNotifierGroupCount() const OVERRIDE; + virtual const message_center::NotifierGroup& GetNotifierGroupAt( + size_t index) const OVERRIDE; + virtual void SwitchToNotifierGroup(size_t index) OVERRIDE; + virtual const message_center::NotifierGroup& GetActiveNotifierGroup() const + OVERRIDE; virtual void GetNotifierList(std::vector<Notifier*>* notifiers) OVERRIDE; @@ -31,6 +38,7 @@ class FakeNotifierSettingsProvider : public NotifierSettingsProvider { private: std::vector<Notifier*> notifiers_; std::map<const Notifier*, bool> enabled_; + const NotifierGroup notifier_group_; int closed_called_count_; }; diff --git a/ui/message_center/message_center.gyp b/ui/message_center/message_center.gyp index eac6938..dc1f1ab 100644 --- a/ui/message_center/message_center.gyp +++ b/ui/message_center/message_center.gyp @@ -70,6 +70,8 @@ 'views/message_bubble_base.h', 'views/message_center_bubble.cc', 'views/message_center_bubble.h', + 'views/message_center_button_bar.cc', + 'views/message_center_button_bar.h', 'views/message_center_view.cc', 'views/message_center_view.h', 'views/message_popup_collection.cc', diff --git a/ui/message_center/notifier_settings.cc b/ui/message_center/notifier_settings.cc index 85c6097..4355b94 100644 --- a/ui/message_center/notifier_settings.cc +++ b/ui/message_center/notifier_settings.cc @@ -50,8 +50,15 @@ Notifier::Notifier(const NotifierId& notifier_id, Notifier::~Notifier() { } -std::string ToString( - NotifierId::SystemComponentNotifierType type) { +NotifierGroup::NotifierGroup(const gfx::Image& icon, + const string16& name, + const string16& login_info, + size_t index) + : icon(icon), name(name), login_info(login_info), index(index) {} + +NotifierGroup::~NotifierGroup() {} + +std::string ToString(NotifierId::SystemComponentNotifierType type) { switch (type) { case NotifierId::SCREENSHOT: return "screenshot"; diff --git a/ui/message_center/notifier_settings.h b/ui/message_center/notifier_settings.h index c494048..05fc7fe 100644 --- a/ui/message_center/notifier_settings.h +++ b/ui/message_center/notifier_settings.h @@ -84,6 +84,30 @@ struct MESSAGE_CENTER_EXPORT Notifier { DISALLOW_COPY_AND_ASSIGN(Notifier); }; +struct MESSAGE_CENTER_EXPORT NotifierGroup { + NotifierGroup(const gfx::Image& icon, + const string16& name, + const string16& login_info, + size_t index); + ~NotifierGroup(); + + // Icon of a notifier group. + const gfx::Image icon; + + // Display name of a notifier group. + const string16 name; + + // More display information about the notifier group. + string16 login_info; + + // Unique identifier for the notifier group so that they can be selected in + // the UI. + const size_t index; + + private: + DISALLOW_COPY_AND_ASSIGN(NotifierGroup); +}; + MESSAGE_CENTER_EXPORT std::string ToString( NotifierId::SystemComponentNotifierType type); MESSAGE_CENTER_EXPORT NotifierId::SystemComponentNotifierType @@ -96,16 +120,36 @@ class MESSAGE_CENTER_EXPORT NotifierSettingsObserver { // Called when an icon in the controller has been updated. virtual void UpdateIconImage(const NotifierId& notifier_id, const gfx::Image& icon) = 0; + + // Called when any change happens to the set of notifier groups. + virtual void NotifierGroupChanged() = 0; }; // A class used by NotifierSettingsView to integrate with a setting system // for the clients of this module. class MESSAGE_CENTER_EXPORT NotifierSettingsProvider { public: + virtual ~NotifierSettingsProvider() {}; + // Sets the delegate. virtual void AddObserver(NotifierSettingsObserver* observer) = 0; virtual void RemoveObserver(NotifierSettingsObserver* observer) = 0; + // Returns the number of notifier groups available. + virtual size_t GetNotifierGroupCount() const = 0; + + // Requests the model for a particular notifier group. + virtual const message_center::NotifierGroup& GetNotifierGroupAt( + size_t index) const = 0; + + // Informs the settings provider that further requests to GetNotifierList + // should return notifiers for the specified notifier group. + virtual void SwitchToNotifierGroup(size_t index) = 0; + + // Requests the currently active notifier group. + virtual const message_center::NotifierGroup& GetActiveNotifierGroup() + const = 0; + // Collects the current notifier list and fills to |notifiers|. Caller takes // the ownership of the elements of |notifiers|. virtual void GetNotifierList(std::vector<Notifier*>* notifiers) = 0; diff --git a/ui/message_center/views/message_center_button_bar.cc b/ui/message_center/views/message_center_button_bar.cc new file mode 100644 index 0000000..b436bf3 --- /dev/null +++ b/ui/message_center/views/message_center_button_bar.cc @@ -0,0 +1,210 @@ +// Copyright 2013 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 "ui/message_center/views/message_center_button_bar.h" + +#include "grit/ui_resources.h" +#include "grit/ui_strings.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/models/simple_menu_model.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/text_constants.h" +#include "ui/message_center/message_center.h" +#include "ui/message_center/message_center_style.h" +#include "ui/message_center/notifier_settings.h" +#include "ui/message_center/views/message_center_view.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/controls/button/image_button.h" +#include "ui/views/controls/button/label_button.h" +#include "ui/views/controls/button/menu_button.h" +#include "ui/views/controls/button/menu_button_listener.h" +#include "ui/views/controls/label.h" +#include "ui/views/controls/menu/menu_runner.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/layout/grid_layout.h" + +namespace message_center { + +namespace { +const int kButtonSize = 40; +const int kChevronMargin = 4; +const int kFooterLeftMargin = 17; +const int kFooterRightMargin = 14; +} // namespace + +// NotificationCenterButton //////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +class NotificationCenterButton : public views::ToggleImageButton { + public: + NotificationCenterButton(views::ButtonListener* listener, + int normal_id, + int hover_id, + int pressed_id, + int text_id); + + protected: + // Overridden from views::View: + virtual gfx::Size GetPreferredSize() OVERRIDE; + virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(NotificationCenterButton); +}; + +NotificationCenterButton::NotificationCenterButton( + views::ButtonListener* listener, + int normal_id, + int hover_id, + int pressed_id, + int text_id) + : views::ToggleImageButton(listener) { + ui::ResourceBundle& resource_bundle = ui::ResourceBundle::GetSharedInstance(); + SetImage(STATE_NORMAL, resource_bundle.GetImageSkiaNamed(normal_id)); + SetImage(STATE_HOVERED, resource_bundle.GetImageSkiaNamed(hover_id)); + SetImage(STATE_PRESSED, resource_bundle.GetImageSkiaNamed(pressed_id)); + SetImageAlignment(views::ImageButton::ALIGN_CENTER, + views::ImageButton::ALIGN_MIDDLE); + SetTooltipText(resource_bundle.GetLocalizedString(text_id)); + set_focusable(true); + set_request_focus_on_press(false); +} + +gfx::Size NotificationCenterButton::GetPreferredSize() { + return gfx::Size(kButtonSize, kButtonSize); +} + +void NotificationCenterButton::OnPaintFocusBorder(gfx::Canvas* canvas) { + if (HasFocus() && (focusable() || IsAccessibilityFocusable())) { + canvas->DrawRect(gfx::Rect(2, 1, width() - 4, height() - 3), + kFocusBorderColor); + } +} + +// MessageCenterButtonBar ///////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +MessageCenterButtonBar::MessageCenterButtonBar( + MessageCenterView* message_center_view, + MessageCenter* message_center, + NotifierSettingsProvider* notifier_settings_provider, + bool settings_initially_visible) + : message_center_view_(message_center_view), + message_center_(message_center), + close_all_button_(NULL), + quiet_mode_button_(NULL) { + if (get_use_acceleration_when_possible()) + SetPaintToLayer(true); + set_background( + views::Background::CreateSolidBackground(kMessageCenterBackgroundColor)); + + views::Label* notification_label = new views::Label( + l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_FOOTER_TITLE)); + notification_label->SetAutoColorReadabilityEnabled(false); + notification_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + notification_label->SetEnabledColor(kRegularTextColor); + AddChildView(notification_label); + + views::View* button_container = new views::View; + button_container->SetLayoutManager( + new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0)); + quiet_mode_button_ = new NotificationCenterButton( + this, + IDR_NOTIFICATION_DO_NOT_DISTURB, + IDR_NOTIFICATION_DO_NOT_DISTURB_HOVER, + IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED, + IDS_MESSAGE_CENTER_QUIET_MODE_BUTTON_TOOLTIP); + ui::ResourceBundle& resource_bundle = ui::ResourceBundle::GetSharedInstance(); + quiet_mode_button_->SetToggledImage( + views::Button::STATE_NORMAL, + resource_bundle.GetImageSkiaNamed( + IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED)); + quiet_mode_button_->SetToggledImage( + views::Button::STATE_HOVERED, + resource_bundle.GetImageSkiaNamed( + IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED)); + quiet_mode_button_->SetToggledImage( + views::Button::STATE_PRESSED, + resource_bundle.GetImageSkiaNamed( + IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED)); + quiet_mode_button_->SetToggled(message_center->IsQuietMode()); + button_container->AddChildView(quiet_mode_button_); + + close_all_button_ = + new NotificationCenterButton(this, + IDR_NOTIFICATION_CLEAR_ALL, + IDR_NOTIFICATION_CLEAR_ALL_HOVER, + IDR_NOTIFICATION_CLEAR_ALL_PRESSED, + IDS_MESSAGE_CENTER_CLEAR_ALL); + button_container->AddChildView(close_all_button_); + settings_button_ = + new NotificationCenterButton(this, + IDR_NOTIFICATION_SETTINGS, + IDR_NOTIFICATION_SETTINGS_HOVER, + IDR_NOTIFICATION_SETTINGS_PRESSED, + IDS_MESSAGE_CENTER_SETTINGS_BUTTON_LABEL); + button_container->AddChildView(settings_button_); + + gfx::ImageSkia* settings_image = + ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( + IDR_NOTIFICATION_SETTINGS); + int image_margin = std::max(0, (kButtonSize - settings_image->width()) / 2); + views::GridLayout* layout = new views::GridLayout(this); + SetLayoutManager(layout); + layout->SetInsets( + 0, kFooterLeftMargin, 0, std::max(0, kFooterRightMargin - image_margin)); + views::ColumnSet* column = layout->AddColumnSet(0); + column->AddColumn(views::GridLayout::FILL, + views::GridLayout::FILL, + 1.0f, + views::GridLayout::USE_PREF, + 0, + 0); + column->AddColumn(views::GridLayout::LEADING, + views::GridLayout::FILL, + 0, + views::GridLayout::USE_PREF, + 0, + 0); + layout->StartRow(0, 0); + layout->AddView(notification_label); + layout->AddView(button_container); +} + +MessageCenterButtonBar::~MessageCenterButtonBar() {} + +void MessageCenterButtonBar::SetAllButtonsEnabled(bool enabled) { + if (close_all_button_) + close_all_button_->SetEnabled(enabled); + settings_button_->SetEnabled(enabled); + quiet_mode_button_->SetEnabled(enabled); +} + +void MessageCenterButtonBar::SetCloseAllButtonVisible(bool visible) { + if (close_all_button_) + close_all_button_->SetVisible(visible); +} + +void MessageCenterButtonBar::ChildVisibilityChanged(views::View* child) { + InvalidateLayout(); +} + +void MessageCenterButtonBar::ButtonPressed(views::Button* sender, + const ui::Event& event) { + if (sender == close_all_button_) { + message_center_view()->ClearAllNotifications(); + } else if (sender == settings_button_) { + MessageCenterView* center_view = message_center_view(); + center_view->SetSettingsVisible(!center_view->settings_visible()); + } else if (sender == quiet_mode_button_) { + if (message_center()->IsQuietMode()) + message_center()->SetQuietMode(false); + else + message_center()->EnterQuietModeWithExpire(base::TimeDelta::FromDays(1)); + quiet_mode_button_->SetToggled(message_center()->IsQuietMode()); + } else { + NOTREACHED(); + } +} + +} // namespace message_center diff --git a/ui/message_center/views/message_center_button_bar.h b/ui/message_center/views/message_center_button_bar.h new file mode 100644 index 0000000..72b30c9 --- /dev/null +++ b/ui/message_center/views/message_center_button_bar.h @@ -0,0 +1,68 @@ +// Copyright 2013 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 UI_MESSAGE_CENTER_VIEWS_MESSAGE_CENTER_BUTTON_BAR_H_ +#define UI_MESSAGE_CENTER_VIEWS_MESSAGE_CENTER_BUTTON_BAR_H_ + +#include "ui/views/controls/button/button.h" +#include "ui/views/view.h" + +namespace views { +class Label; +} + +namespace message_center { + +class ButtonBarSettingsLabel; +class MessageCenter; +class MessageCenterTray; +class MessageCenterView; +class NotificationCenterButton; +class NotifierSettingsProvider; + +// MessageCenterButtonBar is the class that shows the content outside the main +// notification area - the label (or NotifierGroup switcher) and the buttons. +class MessageCenterButtonBar : public views::View, + public views::ButtonListener { + public: + MessageCenterButtonBar(MessageCenterView* message_center_view, + MessageCenter* message_center, + NotifierSettingsProvider* notifier_settings_provider, + bool settings_initially_visible); + virtual ~MessageCenterButtonBar(); + + // Enables or disables all of the buttons in the center. This is used to + // prevent user clicks during the close-all animation. + virtual void SetAllButtonsEnabled(bool enabled); + + // Sometimes we shouldn't see the close-all button. + void SetCloseAllButtonVisible(bool visible); + + private: + // Overridden from views::View: + virtual void ChildVisibilityChanged(views::View* child) OVERRIDE; + + // Overridden from views::ButtonListener: + virtual void ButtonPressed(views::Button* sender, + const ui::Event& event) OVERRIDE; + + MessageCenterView* message_center_view() const { + return message_center_view_; + } + MessageCenter* message_center() const { return message_center_; } + + MessageCenterView* message_center_view_; // Weak reference. + MessageCenter* message_center_; // Weak reference. + + // Sub-views of the button bar. + views::Button* close_all_button_; + NotificationCenterButton* settings_button_; + NotificationCenterButton* quiet_mode_button_; + + DISALLOW_COPY_AND_ASSIGN(MessageCenterButtonBar); +}; + +} // namespace message_center + +#endif // UI_MESSAGE_CENTER_VIEWS_MESSAGE_CENTER_BUTTON_BAR_H_ diff --git a/ui/message_center/views/message_center_view.cc b/ui/message_center/views/message_center_view.cc index ee7ac74..9f0d2fd 100644 --- a/ui/message_center/views/message_center_view.cc +++ b/ui/message_center/views/message_center_view.cc @@ -10,22 +10,17 @@ #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/stl_util.h" -#include "grit/ui_resources.h" #include "grit/ui_strings.h" #include "ui/base/animation/multi_animation.h" #include "ui/base/animation/slide_animation.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" #include "ui/gfx/insets.h" -#include "ui/gfx/point.h" #include "ui/gfx/rect.h" #include "ui/gfx/size.h" -#include "ui/gfx/text_constants.h" #include "ui/message_center/message_center.h" #include "ui/message_center/message_center_style.h" -#include "ui/message_center/message_center_tray.h" -#include "ui/message_center/message_center_util.h" +#include "ui/message_center/views/message_center_button_bar.h" #include "ui/message_center/views/message_view.h" #include "ui/message_center/views/notification_view.h" #include "ui/message_center/views/notifier_settings_view.h" @@ -34,238 +29,30 @@ #include "ui/views/background.h" #include "ui/views/border.h" #include "ui/views/controls/button/button.h" -#include "ui/views/controls/button/label_button.h" #include "ui/views/controls/label.h" #include "ui/views/controls/scroll_view.h" #include "ui/views/controls/scrollbar/overlay_scroll_bar.h" #include "ui/views/layout/box_layout.h" -#include "ui/views/layout/grid_layout.h" -#include "ui/views/painter.h" #include "ui/views/widget/widget.h" namespace message_center { namespace { -const int kMinScrollViewHeight = 100; -const int kFooterLeftMargin = 17; -const int kFooterRightMargin = 14; -const int kButtonSize = 40; -const SkColor kNoNotificationsTextColor = SkColorSetRGB(0xb4, 0xb4, 0xb4); const SkColor kBorderDarkColor = SkColorSetRGB(0xaa, 0xaa, 0xaa); -const SkColor kTransparentColor = SkColorSetARGB(0, 0, 0, 0); const SkColor kButtonTextHighlightColor = SkColorSetRGB(0x2a, 0x2a, 0x2a); const SkColor kButtonTextHoverColor = SkColorSetRGB(0x2a, 0x2a, 0x2a); +const SkColor kNoNotificationsTextColor = SkColorSetRGB(0xb4, 0xb4, 0xb4); +const SkColor kTransparentColor = SkColorSetARGB(0, 0, 0, 0); const int kAnimateClearingNextNotificationDelayMS = 40; +const int kButtonBarBorderThickness = 1; +const int kMinScrollViewHeight = 100; -static const int kDefaultFrameRateHz = 60; static const int kDefaultAnimationDurationMs = 120; +static const int kDefaultFrameRateHz = 60; } // namespace -// NotificationCenterButton //////////////////////////////////////////////////// - -class NotificationCenterButton : public views::ToggleImageButton { - public: - NotificationCenterButton(views::ButtonListener* listener, - int normal_id, - int hover_id, - int pressed_id, - int text_id); - - protected: - // Overridden from views::View: - virtual gfx::Size GetPreferredSize() OVERRIDE; - virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(NotificationCenterButton); -}; - -NotificationCenterButton::NotificationCenterButton( - views::ButtonListener* listener, - int normal_id, - int hover_id, - int pressed_id, - int text_id) - : views::ToggleImageButton(listener) { - ui::ResourceBundle& resource_bundle = ui::ResourceBundle::GetSharedInstance(); - SetImage(STATE_NORMAL, resource_bundle.GetImageSkiaNamed(normal_id)); - SetImage(STATE_HOVERED, resource_bundle.GetImageSkiaNamed(hover_id)); - SetImage(STATE_PRESSED, resource_bundle.GetImageSkiaNamed(pressed_id)); - SetImageAlignment(views::ImageButton::ALIGN_CENTER, - views::ImageButton::ALIGN_MIDDLE); - SetTooltipText(resource_bundle.GetLocalizedString(text_id)); - set_focusable(true); - set_request_focus_on_press(false); -} - -gfx::Size NotificationCenterButton::GetPreferredSize() { - return gfx::Size(kButtonSize, kButtonSize); -} - -void NotificationCenterButton::OnPaintFocusBorder(gfx::Canvas* canvas) { - if (HasFocus() && (focusable() || IsAccessibilityFocusable())) { - canvas->DrawRect(gfx::Rect(2, 1, width() - 4, height() - 3), - kFocusBorderColor); - } -} - -// MessageCenterButtonBar ////////////////////////////////////////////////// - -class MessageCenterButtonBar : public views::View, - public views::ButtonListener { - public: - MessageCenterButtonBar(MessageCenterView* message_center_view, - MessageCenter* message_center); - virtual ~MessageCenterButtonBar(); - - virtual void SetAllButtonsEnabled(bool enabled); - void SetCloseAllVisible(bool visible); - - private: - // Overridden from views::View: - virtual void ChildVisibilityChanged(views::View* child) OVERRIDE; - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender, const ui::Event& event) - OVERRIDE; - - MessageCenterView* message_center_view() const { - return message_center_view_; - } - MessageCenter* message_center() const { return message_center_; } - MessageCenterTray* tray() const { return tray_; } - views::Button* close_all_button() const { return close_all_button_; } - void set_close_all_button(views::Button* button) { - close_all_button_ = button; - } - - MessageCenterView* message_center_view_; // Weak reference. - MessageCenter* message_center_; // Weak reference. - MessageCenterTray* tray_; // Weak reference. - views::Button* close_all_button_; - NotificationCenterButton* settings_button_; - NotificationCenterButton* quiet_mode_button_; - - DISALLOW_COPY_AND_ASSIGN(MessageCenterButtonBar); -}; - -MessageCenterButtonBar::MessageCenterButtonBar( - MessageCenterView* message_center_view, - MessageCenter* message_center) - : message_center_view_(message_center_view), - message_center_(message_center), - close_all_button_(NULL) { - if (get_use_acceleration_when_possible()) - SetPaintToLayer(true); - set_background(views::Background::CreateSolidBackground( - kMessageCenterBackgroundColor)); - - views::Label* notification_label = new views::Label(l10n_util::GetStringUTF16( - IDS_MESSAGE_CENTER_FOOTER_TITLE)); - notification_label->SetAutoColorReadabilityEnabled(false); - notification_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - notification_label->SetEnabledColor(kRegularTextColor); - AddChildView(notification_label); - - views::View* button_container = new views::View; - button_container->SetLayoutManager( - new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0)); - quiet_mode_button_ = new NotificationCenterButton( - this, - IDR_NOTIFICATION_DO_NOT_DISTURB, - IDR_NOTIFICATION_DO_NOT_DISTURB_HOVER, - IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED, - IDS_MESSAGE_CENTER_QUIET_MODE_BUTTON_TOOLTIP); - ui::ResourceBundle& resource_bundle = ui::ResourceBundle::GetSharedInstance(); - quiet_mode_button_->SetToggledImage( - views::Button::STATE_NORMAL, - resource_bundle.GetImageSkiaNamed( - IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED)); - quiet_mode_button_->SetToggledImage( - views::Button::STATE_HOVERED, - resource_bundle.GetImageSkiaNamed( - IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED)); - quiet_mode_button_->SetToggledImage( - views::Button::STATE_PRESSED, - resource_bundle.GetImageSkiaNamed( - IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED)); - quiet_mode_button_->SetToggled(message_center->IsQuietMode()); - button_container->AddChildView(quiet_mode_button_); - - NotificationCenterButton* close_all_button = new NotificationCenterButton( - this, - IDR_NOTIFICATION_CLEAR_ALL, - IDR_NOTIFICATION_CLEAR_ALL_HOVER, - IDR_NOTIFICATION_CLEAR_ALL_PRESSED, - IDS_MESSAGE_CENTER_CLEAR_ALL); - button_container->AddChildView(close_all_button); - set_close_all_button(close_all_button); - settings_button_ = new NotificationCenterButton( - this, - IDR_NOTIFICATION_SETTINGS, - IDR_NOTIFICATION_SETTINGS_HOVER, - IDR_NOTIFICATION_SETTINGS_PRESSED, - IDS_MESSAGE_CENTER_SETTINGS_BUTTON_LABEL); - button_container->AddChildView(settings_button_); - - gfx::ImageSkia* settings_image = - ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - IDR_NOTIFICATION_SETTINGS); - int image_margin = std::max(0, (kButtonSize - settings_image->width()) / 2); - views::GridLayout* layout = new views::GridLayout(this); - SetLayoutManager(layout); - layout->SetInsets( - 0, kFooterLeftMargin, 0, std::max(0, kFooterRightMargin - image_margin)); - views::ColumnSet* column = layout->AddColumnSet(0); - column->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, - 1.0f, views::GridLayout::USE_PREF, 0, 0); - column->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, - 0, views::GridLayout::USE_PREF, 0, 0); - layout->StartRow(0, 0); - layout->AddView(notification_label); - layout->AddView(button_container); -} - -MessageCenterButtonBar::~MessageCenterButtonBar() {} - -void MessageCenterButtonBar::SetAllButtonsEnabled(bool enabled) { - if (close_all_button_) - close_all_button_->SetEnabled(enabled); - settings_button_->SetEnabled(enabled); - quiet_mode_button_->SetEnabled(enabled); -} - -void MessageCenterButtonBar::SetCloseAllVisible(bool visible) { - if (close_all_button_) - close_all_button_->SetVisible(visible); -} - -// Overridden from views::View: -void MessageCenterButtonBar::ChildVisibilityChanged(views::View* child) { - InvalidateLayout(); -} - -// Overridden from views::ButtonListener: -void MessageCenterButtonBar::ButtonPressed(views::Button* sender, - const ui::Event& event) { - if (sender == close_all_button()) { - message_center_view()->ClearAllNotifications(); - } else if (sender == settings_button_) { - MessageCenterView* center_view = static_cast<MessageCenterView*>(parent()); - center_view->SetSettingsVisible(!center_view->settings_visible()); - } else if (sender == quiet_mode_button_) { - if (message_center()->IsQuietMode()) - message_center()->SetQuietMode(false); - else - message_center()->EnterQuietModeWithExpire(base::TimeDelta::FromDays(1)); - quiet_mode_button_->SetToggled(message_center()->IsQuietMode()); - } else { - NOTREACHED(); - } -} - // BoundedScrollView /////////////////////////////////////////////////////////// // A custom scroll view whose height has a minimum and maximum value and whose @@ -806,17 +593,33 @@ MessageCenterView::MessageCenterView(MessageCenter* message_center, tray_(tray), top_down_(top_down), settings_visible_(initially_settings_visible), + source_view_(NULL), + source_height_(0), + target_view_(NULL), + target_height_(0), is_closing_(false) { message_center_->AddObserver(this); set_notify_enter_exit_on_child(true); set_background(views::Background::CreateSolidBackground( kMessageCenterBackgroundColor)); - button_bar_ = new MessageCenterButtonBar(this, message_center); + NotifierSettingsProvider* notifier_settings_provider = + message_center_->GetNotifierSettingsProvider(); + button_bar_ = new MessageCenterButtonBar(this, + message_center, + notifier_settings_provider, + initially_settings_visible); const int button_height = button_bar_->GetPreferredSize().height(); - scroller_ = new BoundedScrollView(kMinScrollViewHeight, - max_height - button_height); + button_bar_->set_border(views::Border::CreateSolidSidedBorder( + top_down_ ? 0 : kButtonBarBorderThickness, + 0, + top_down_ ? kButtonBarBorderThickness : 0, + 0, + kFooterDelimiterColor)); + + scroller_ = + new BoundedScrollView(kMinScrollViewHeight, max_height - button_height); if (get_use_acceleration_when_possible()) { scroller_->SetPaintToLayer(true); @@ -832,8 +635,7 @@ MessageCenterView::MessageCenterView(MessageCenter* message_center, message_list_view_->AddChildView(no_notifications_message_view_); scroller_->SetContents(message_list_view_); - settings_view_ = new NotifierSettingsView( - message_center_->GetNotifierSettingsProvider()); + settings_view_ = new NotifierSettingsView(notifier_settings_provider); if (initially_settings_visible) scroller_->SetVisible(false); @@ -915,13 +717,6 @@ void MessageCenterView::SetSettingsVisible(bool visible) { settings_transition_animation_->Start(); } -void MessageCenterView::SetIsClosing(bool is_closing) { - is_closing_ = is_closing; - if (is_closing) - message_center_->RemoveObserver(this); - else - message_center_->AddObserver(this); -} void MessageCenterView::ClearAllNotifications() { if (is_closing_) @@ -942,11 +737,26 @@ size_t MessageCenterView::NumMessageViewsForTest() const { return message_list_view_->child_count(); } +void MessageCenterView::OnSettingsChanged() { + scroller_->InvalidateLayout(); + PreferredSizeChanged(); + Layout(); +} + +void MessageCenterView::SetIsClosing(bool is_closing) { + is_closing_ = is_closing; + if (is_closing) + message_center_->RemoveObserver(this); + else + message_center_->AddObserver(this); +} + void MessageCenterView::Layout() { if (is_closing_) return; - int button_height = button_bar_->GetHeightForWidth(width()); + int button_height = button_bar_->GetHeightForWidth(width()) + + button_bar_->GetInsets().height(); // Skip unnecessary re-layout of contents during the resize animation. if (settings_transition_animation_ && settings_transition_animation_->is_animating() && @@ -966,27 +776,6 @@ void MessageCenterView::Layout() { width(), height() - button_height); - bool is_scrollable = false; - if (scroller_->visible()) - is_scrollable = scroller_->height() < message_list_view_->height(); - else - is_scrollable = settings_view_->IsScrollable(); - - if (is_scrollable && !button_bar_->border()) { - // Draw separator line on the top of the button bar if it is on the bottom - // or draw it at the bottom if the bar is on the top. - button_bar_->set_border(views::Border::CreateSolidSidedBorder( - top_down_ ? 0 : 1, - 0, - top_down_ ? 1 : 0, - 0, - kFooterDelimiterColor)); - button_bar_->SchedulePaint(); - } else if (!is_scrollable && button_bar_->border()) { - button_bar_->set_border(NULL); - button_bar_->SchedulePaint(); - } - button_bar_->SetBounds(0, top_down_ ? 0 : height() - button_height, width(), @@ -1030,7 +819,8 @@ int MessageCenterView::GetHeightForWidth(int width) { content_height += scroller_->GetHeightForWidth(width); else content_height += settings_view_->GetHeightForWidth(width); - return button_bar_->GetHeightForWidth(width) + content_height; + return button_bar_->GetHeightForWidth(width) + + button_bar_->GetInsets().height() + content_height; } bool MessageCenterView::OnMouseWheel(const ui::MouseWheelEvent& event) { @@ -1178,15 +968,12 @@ void MessageCenterView::AddNotificationAt(const Notification& notification, } void MessageCenterView::NotificationsChanged() { - if (!message_views_.empty()) { - no_notifications_message_view_->SetVisible(false); - button_bar_->SetCloseAllVisible(true); - scroller_->set_focusable(true); - } else { - no_notifications_message_view_->SetVisible(true); - button_bar_->SetCloseAllVisible(false); - scroller_->set_focusable(false); - } + bool no_message_views = message_views_.empty(); + + no_notifications_message_view_->SetVisible(no_message_views); + button_bar_->SetCloseAllButtonVisible(!no_message_views); + scroller_->set_focusable(!no_message_views); + scroller_->InvalidateLayout(); PreferredSizeChanged(); Layout(); diff --git a/ui/message_center/views/message_center_view.h b/ui/message_center/views/message_center_view.h index 506a3a4..d53910c 100644 --- a/ui/message_center/views/message_center_view.h +++ b/ui/message_center/views/message_center_view.h @@ -54,6 +54,7 @@ class MESSAGE_CENTER_EXPORT MessageCenterView : public views::View, size_t NumMessageViewsForTest() const; void SetSettingsVisible(bool visible); + void OnSettingsChanged(); bool settings_visible() const { return settings_visible_; } void SetIsClosing(bool is_closing); @@ -86,7 +87,9 @@ class MESSAGE_CENTER_EXPORT MessageCenterView : public views::View, MessageCenter* message_center_; // Weak reference. MessageCenterTray* tray_; // Weak reference. - std::vector<MessageView*> message_views_; + std::vector<MessageView*> message_views_; // Weak references. + + // Child views. views::ScrollView* scroller_; MessageListView* message_list_view_; NotifierSettingsView* settings_view_; @@ -96,11 +99,17 @@ class MESSAGE_CENTER_EXPORT MessageCenterView : public views::View, // Data for transition animation between settings view and message list. bool settings_visible_; + + // Animation managing transition between message center and settings (and vice + // versa). + scoped_ptr<ui::MultiAnimation> settings_transition_animation_; + + // Helper data to keep track of the transition between settings and + // message center views. views::View* source_view_; - views::View* target_view_; int source_height_; + views::View* target_view_; int target_height_; - scoped_ptr<ui::MultiAnimation> settings_transition_animation_; // True when the widget is closing so that further operations should be // ignored. diff --git a/ui/message_center/views/notifier_settings_view.cc b/ui/message_center/views/notifier_settings_view.cc index 5673070..b97bc84 100644 --- a/ui/message_center/views/notifier_settings_view.cc +++ b/ui/message_center/views/notifier_settings_view.cc @@ -8,14 +8,18 @@ #include <string> #include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" #include "grit/ui_resources.h" #include "grit/ui_strings.h" +#include "skia/ext/image_operations.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/models/simple_menu_model.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" #include "ui/gfx/image/image.h" +#include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/size.h" #include "ui/message_center/message_center_style.h" #include "ui/message_center/views/message_center_view.h" @@ -23,8 +27,10 @@ #include "ui/views/border.h" #include "ui/views/controls/button/checkbox.h" #include "ui/views/controls/button/custom_button.h" +#include "ui/views/controls/button/menu_button.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" +#include "ui/views/controls/menu/menu_runner.h" #include "ui/views/controls/scroll_view.h" #include "ui/views/controls/scrollbar/overlay_scroll_bar.h" #include "ui/views/layout/box_layout.h" @@ -114,6 +120,78 @@ bool EntryView::OnKeyReleased(const ui::KeyEvent& event) { } // namespace +// NotifierGroupMenuModel ////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +class NotifierGroupMenuModel : public ui::SimpleMenuModel, + public ui::SimpleMenuModel::Delegate { + public: + NotifierGroupMenuModel(NotifierSettingsProvider* notifier_settings_provider); + virtual ~NotifierGroupMenuModel(); + + // Overridden from ui::SimpleMenuModel::Delegate: + virtual bool IsCommandIdChecked(int command_id) const OVERRIDE; + virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE; + virtual bool GetAcceleratorForCommandId( + int command_id, + ui::Accelerator* accelerator) OVERRIDE; + virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE; + + private: + NotifierSettingsProvider* notifier_settings_provider_; +}; + +NotifierGroupMenuModel::NotifierGroupMenuModel( + NotifierSettingsProvider* notifier_settings_provider) + : ui::SimpleMenuModel(this), + notifier_settings_provider_(notifier_settings_provider) { + if (!notifier_settings_provider_) + return; + + size_t num_menu_items = notifier_settings_provider_->GetNotifierGroupCount(); + for (size_t i = 0; i < num_menu_items; ++i) { + const NotifierGroup& group = + notifier_settings_provider_->GetNotifierGroupAt(i); + + AddItem(i, group.login_info.empty() ? group.name : group.login_info); + + gfx::ImageSkia resized_icon = gfx::ImageSkiaOperations::CreateResizedImage( + *group.icon.ToImageSkia(), + skia::ImageOperations::RESIZE_BETTER, + gfx::Size(kSettingsIconSize, kSettingsIconSize)); + + SetIcon(i, gfx::Image(resized_icon)); + } +} + +NotifierGroupMenuModel::~NotifierGroupMenuModel() {} + +bool NotifierGroupMenuModel::IsCommandIdChecked(int command_id) const { + return false; +} + +bool NotifierGroupMenuModel::IsCommandIdEnabled(int command_id) const { + return true; +} + +bool NotifierGroupMenuModel::GetAcceleratorForCommandId( + int command_id, + ui::Accelerator* accelerator) { + return false; +} + +void NotifierGroupMenuModel::ExecuteCommand(int command_id, int event_flags) { + if (!notifier_settings_provider_) + return; + + size_t notifier_group_index = static_cast<size_t>(command_id); + size_t num_notifier_groups = + notifier_settings_provider_->GetNotifierGroupCount(); + if (notifier_group_index >= num_notifier_groups) + return; + + notifier_settings_provider_->SwitchToNotifierGroup(notifier_group_index); +} + // We do not use views::Checkbox class directly because it doesn't support // showing 'icon'. class NotifierSettingsView::NotifierButton : public views::CustomButton, @@ -240,30 +318,11 @@ NotifierSettingsView::NotifierSettingsView(NotifierSettingsProvider* provider) scroller_->SetVerticalScrollBar(new views::OverlayScrollBar(false)); AddChildView(scroller_); - views::View* contents_view = new views::View(); - contents_view->SetLayoutManager(new views::BoxLayout( - views::BoxLayout::kVertical, 0, 0, 0)); - - views::Label* top_label = new views::Label(l10n_util::GetStringUTF16( - IDS_MESSAGE_CENTER_SETTINGS_DIALOG_DESCRIPTION)); - top_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - top_label->SetMultiLine(true); - top_label->SizeToFit(kMinimumWindowWidth - kMarginWidth * 2); - contents_view->AddChildView(new EntryView(top_label)); - std::vector<Notifier*> notifiers; if (provider_) provider_->GetNotifierList(¬ifiers); - for (size_t i = 0; i < notifiers.size(); ++i) { - NotifierButton* button = new NotifierButton(notifiers[i], this); - EntryView* entry = new EntryView(button); - entry->set_focusable(true); - contents_view->AddChildView(entry); - buttons_.insert(button); - } - scroller_->SetContents(contents_view); - contents_view->SetBoundsRect(gfx::Rect(contents_view->GetPreferredSize())); + UpdateContentsView(notifiers); } NotifierSettingsView::~NotifierSettingsView() { @@ -287,6 +346,57 @@ void NotifierSettingsView::UpdateIconImage(const NotifierId& notifier_id, } } +void NotifierSettingsView::NotifierGroupChanged() { + std::vector<Notifier*> notifiers; + if (provider_) + provider_->GetNotifierList(¬ifiers); + + UpdateContentsView(notifiers); +} + +void NotifierSettingsView::UpdateContentsView( + const std::vector<Notifier*>& notifiers) { + buttons_.clear(); + + views::View* contents_view = new views::View(); + contents_view->SetLayoutManager( + new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); + + views::View* contents_title_view = new views::View(); + contents_title_view->SetLayoutManager( + new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 5)); + views::Label* top_label = new views::Label(l10n_util::GetStringUTF16( + IDS_MESSAGE_CENTER_SETTINGS_DIALOG_DESCRIPTION)); + top_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + top_label->SetMultiLine(true); + contents_title_view->AddChildView(top_label); + + string16 notifier_group_text; + if (provider_) { + const NotifierGroup& active_group = provider_->GetActiveNotifierGroup(); + notifier_group_text = active_group.login_info.empty() + ? active_group.name + : active_group.login_info; + } + + views::View* notifier_group_selector = + new views::MenuButton(NULL, notifier_group_text, this, true); + contents_title_view->AddChildView(notifier_group_selector); + contents_view->AddChildView(new EntryView(contents_title_view)); + + for (size_t i = 0; i < notifiers.size(); ++i) { + NotifierButton* button = new NotifierButton(notifiers[i], this); + EntryView* entry = new EntryView(button); + entry->set_focusable(true); + contents_view->AddChildView(entry); + buttons_.insert(button); + } + scroller_->SetContents(contents_view); + + contents_view->SetBoundsRect(gfx::Rect(contents_view->GetPreferredSize())); + InvalidateLayout(); +} + void NotifierSettingsView::Layout() { int title_height = title_entry_->GetHeightForWidth(width()); title_entry_->SetBounds(0, 0, width(), title_height); @@ -343,11 +453,30 @@ void NotifierSettingsView::ButtonPressed(views::Button* sender, std::set<NotifierButton*>::iterator iter = buttons_.find( static_cast<NotifierButton*>(sender)); - DCHECK(iter != buttons_.end()); + + if (iter == buttons_.end()) + return; (*iter)->SetChecked(!(*iter)->checked()); if (provider_) provider_->SetNotifierEnabled((*iter)->notifier(), (*iter)->checked()); } +void NotifierSettingsView::OnMenuButtonClicked(views::View* source, + const gfx::Point& point) { + notifier_group_menu_model_.reset(new NotifierGroupMenuModel(provider_)); + notifier_group_menu_runner_.reset( + new views::MenuRunner(notifier_group_menu_model_.get())); + if (views::MenuRunner::MENU_DELETED == + notifier_group_menu_runner_->RunMenuAt(GetWidget(), + NULL, + source->GetBoundsInScreen(), + views::MenuItemView::BUBBLE_ABOVE, + ui::MENU_SOURCE_MOUSE, + views::MenuRunner::CONTEXT_MENU)) + return; + MessageCenterView* center_view = static_cast<MessageCenterView*>(parent()); + center_view->OnSettingsChanged(); +} + } // namespace message_center diff --git a/ui/message_center/views/notifier_settings_view.h b/ui/message_center/views/notifier_settings_view.h index 303eff4..6fc5b58 100644 --- a/ui/message_center/views/notifier_settings_view.h +++ b/ui/message_center/views/notifier_settings_view.h @@ -5,20 +5,30 @@ #ifndef UI_MESSAGE_CENTER_VIEWS_NOTIFIER_SETTINGS_VIEW_H_ #define UI_MESSAGE_CENTER_VIEWS_NOTIFIER_SETTINGS_VIEW_H_ +#include <set> + +#include "base/memory/scoped_ptr.h" #include "ui/message_center/message_center_export.h" #include "ui/message_center/notifier_settings.h" #include "ui/message_center/views/message_bubble_base.h" #include "ui/views/controls/button/image_button.h" +#include "ui/views/controls/button/menu_button_listener.h" #include "ui/views/view.h" +namespace views { +class MenuRunner; +} + namespace message_center { +class NotifierGroupMenuModel; // A class to show the list of notifier extensions / URL patterns and allow // users to customize the settings. class MESSAGE_CENTER_EXPORT NotifierSettingsView : public NotifierSettingsObserver, public views::View, - public views::ButtonListener { + public views::ButtonListener, + public views::MenuButtonListener { public: explicit NotifierSettingsView(NotifierSettingsProvider* provider); virtual ~NotifierSettingsView(); @@ -28,6 +38,7 @@ class MESSAGE_CENTER_EXPORT NotifierSettingsView // Overridden from NotifierSettingsDelegate: virtual void UpdateIconImage(const NotifierId& notifier_id, const gfx::Image& icon) OVERRIDE; + virtual void NotifierGroupChanged() OVERRIDE; void set_provider(NotifierSettingsProvider* new_provider) { provider_ = new_provider; @@ -36,6 +47,9 @@ class MESSAGE_CENTER_EXPORT NotifierSettingsView private: class NotifierButton; + // Given a new list of notifiers, updates the view to reflect it. + void UpdateContentsView(const std::vector<Notifier*>& notifiers); + // Overridden from views::View: virtual void Layout() OVERRIDE; virtual gfx::Size GetMinimumSize() OVERRIDE; @@ -46,12 +60,16 @@ class MESSAGE_CENTER_EXPORT NotifierSettingsView // Overridden from views::ButtonListener: virtual void ButtonPressed(views::Button* sender, const ui::Event& event) OVERRIDE; + virtual void OnMenuButtonClicked(views::View* source, + const gfx::Point& point) OVERRIDE; views::ImageButton* title_arrow_; views::View* title_entry_; views::ScrollView* scroller_; NotifierSettingsProvider* provider_; std::set<NotifierButton*> buttons_; + scoped_ptr<NotifierGroupMenuModel> notifier_group_menu_model_; + scoped_ptr<views::MenuRunner> notifier_group_menu_runner_; DISALLOW_COPY_AND_ASSIGN(NotifierSettingsView); }; |