Add ICU message format support
[chromium-blink-merge.git] / ui / message_center / views / notifier_settings_view.cc
blob645e97115b58c1512e804f0cae1fcaf49e6eefe6
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/message_center/views/notifier_settings_view.h"
7 #include <set>
8 #include <string>
10 #include "base/strings/string16.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "skia/ext/image_operations.h"
13 #include "third_party/skia/include/core/SkColor.h"
14 #include "ui/base/l10n/l10n_util.h"
15 #include "ui/base/models/simple_menu_model.h"
16 #include "ui/base/resource/resource_bundle.h"
17 #include "ui/events/event_utils.h"
18 #include "ui/events/keycodes/keyboard_codes.h"
19 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/geometry/size.h"
21 #include "ui/gfx/image/image.h"
22 #include "ui/message_center/message_center_style.h"
23 #include "ui/message_center/views/message_center_view.h"
24 #include "ui/resources/grit/ui_resources.h"
25 #include "ui/strings/grit/ui_strings.h"
26 #include "ui/views/background.h"
27 #include "ui/views/border.h"
28 #include "ui/views/controls/button/checkbox.h"
29 #include "ui/views/controls/button/label_button_border.h"
30 #include "ui/views/controls/button/menu_button.h"
31 #include "ui/views/controls/image_view.h"
32 #include "ui/views/controls/label.h"
33 #include "ui/views/controls/link.h"
34 #include "ui/views/controls/link_listener.h"
35 #include "ui/views/controls/menu/menu_runner.h"
36 #include "ui/views/controls/scroll_view.h"
37 #include "ui/views/controls/scrollbar/overlay_scroll_bar.h"
38 #include "ui/views/layout/box_layout.h"
39 #include "ui/views/layout/fill_layout.h"
40 #include "ui/views/layout/grid_layout.h"
41 #include "ui/views/painter.h"
42 #include "ui/views/widget/widget.h"
44 namespace message_center {
45 namespace settings {
47 // Additional views-specific parameters.
49 // The width of the settings pane in pixels.
50 const int kWidth = 360;
52 // The width of the learn more icon in pixels.
53 const int kLearnMoreSize = 12;
55 // The width of the click target that contains the learn more button in pixels.
56 const int kLearnMoreTargetWidth = 28;
58 // The height of the click target that contains the learn more button in pixels.
59 const int kLearnMoreTargetHeight = 40;
61 // The minimum height of the settings pane in pixels.
62 const int kMinimumHeight = 480;
64 // The horizontal margin of the title area of the settings pane in addition to
65 // the standard margin from settings::kHorizontalMargin.
66 const int kTitleMargin = 10;
68 } // namespace settings
70 namespace {
72 // Menu button metrics to make the text line up.
73 const int kMenuButtonInnateMargin = 2;
75 // Used to place the context menu correctly.
76 const int kMenuWhitespaceOffset = 2;
78 // The innate vertical blank space in the label for the title of the settings
79 // pane.
80 const int kInnateTitleBottomMargin = 1;
81 const int kInnateTitleTopMargin = 7;
83 // The innate top blank space in the label for the description of the settings
84 // pane.
85 const int kInnateDescriptionTopMargin = 2;
87 // Checkboxes have some built-in right padding blank space.
88 const int kInnateCheckboxRightPadding = 2;
90 // Spec defines the checkbox size; the innate padding throws this measurement
91 // off so we need to compute a slightly different area for the checkbox to
92 // inhabit.
93 const int kComputedCheckboxSize =
94 settings::kCheckboxSizeWithPadding - kInnateCheckboxRightPadding;
96 // The menubutton has innate margin, so we need to compensate for that when
97 // figuring the margin of the title area.
98 const int kComputedContentsTitleMargin = 0 - kMenuButtonInnateMargin;
100 // The spec doesn't include the bottom blank area of the title bar or the innate
101 // blank area in the description label, so we'll use this as the space between
102 // the title and description.
103 const int kComputedTitleBottomMargin = settings::kDescriptionToSwitcherSpace -
104 kInnateTitleBottomMargin -
105 kInnateDescriptionTopMargin;
107 // The blank space above the title needs to be adjusted by the amount of blank
108 // space included in the title label.
109 const int kComputedTitleTopMargin =
110 settings::kTopMargin - kInnateTitleTopMargin;
112 // The switcher has a lot of blank space built in so we should include that when
113 // spacing the title area vertically.
114 const int kComputedTitleElementSpacing =
115 settings::kDescriptionToSwitcherSpace - 6;
117 // A function to create a focus border.
118 scoped_ptr<views::Painter> CreateFocusPainter() {
119 return views::Painter::CreateSolidFocusPainter(kFocusBorderColor,
120 gfx::Insets(1, 2, 3, 2));
123 // EntryView ------------------------------------------------------------------
125 // The view to guarantee the 48px height and place the contents at the
126 // middle. It also guarantee the left margin.
127 class EntryView : public views::View {
128 public:
129 explicit EntryView(views::View* contents);
130 ~EntryView() override;
132 // views::View:
133 void Layout() override;
134 gfx::Size GetPreferredSize() const override;
135 void GetAccessibleState(ui::AXViewState* state) override;
136 void OnFocus() override;
137 bool OnKeyPressed(const ui::KeyEvent& event) override;
138 bool OnKeyReleased(const ui::KeyEvent& event) override;
139 void OnPaint(gfx::Canvas* canvas) override;
140 void OnBlur() override;
142 private:
143 scoped_ptr<views::Painter> focus_painter_;
145 DISALLOW_COPY_AND_ASSIGN(EntryView);
148 EntryView::EntryView(views::View* contents)
149 : focus_painter_(CreateFocusPainter()) {
150 AddChildView(contents);
153 EntryView::~EntryView() {}
155 void EntryView::Layout() {
156 DCHECK_EQ(1, child_count());
157 views::View* content = child_at(0);
158 int content_width = width();
159 int content_height = content->GetHeightForWidth(content_width);
160 int y = std::max((height() - content_height) / 2, 0);
161 content->SetBounds(0, y, content_width, content_height);
164 gfx::Size EntryView::GetPreferredSize() const {
165 DCHECK_EQ(1, child_count());
166 gfx::Size size = child_at(0)->GetPreferredSize();
167 size.SetToMax(gfx::Size(settings::kWidth, settings::kEntryHeight));
168 return size;
171 void EntryView::GetAccessibleState(ui::AXViewState* state) {
172 DCHECK_EQ(1, child_count());
173 child_at(0)->GetAccessibleState(state);
176 void EntryView::OnFocus() {
177 views::View::OnFocus();
178 ScrollRectToVisible(GetLocalBounds());
179 // We render differently when focused.
180 SchedulePaint();
183 bool EntryView::OnKeyPressed(const ui::KeyEvent& event) {
184 return child_at(0)->OnKeyPressed(event);
187 bool EntryView::OnKeyReleased(const ui::KeyEvent& event) {
188 return child_at(0)->OnKeyReleased(event);
191 void EntryView::OnPaint(gfx::Canvas* canvas) {
192 View::OnPaint(canvas);
193 views::Painter::PaintFocusPainter(this, canvas, focus_painter_.get());
196 void EntryView::OnBlur() {
197 View::OnBlur();
198 // We render differently when focused.
199 SchedulePaint();
202 } // namespace
205 // NotifierGroupMenuModel -----------------------------------------------------
207 class NotifierGroupMenuModel : public ui::SimpleMenuModel,
208 public ui::SimpleMenuModel::Delegate {
209 public:
210 NotifierGroupMenuModel(NotifierSettingsProvider* notifier_settings_provider);
211 ~NotifierGroupMenuModel() override;
213 // ui::SimpleMenuModel::Delegate:
214 bool IsCommandIdChecked(int command_id) const override;
215 bool IsCommandIdEnabled(int command_id) const override;
216 bool GetAcceleratorForCommandId(int command_id,
217 ui::Accelerator* accelerator) override;
218 void ExecuteCommand(int command_id, int event_flags) override;
220 private:
221 NotifierSettingsProvider* notifier_settings_provider_;
223 DISALLOW_COPY_AND_ASSIGN(NotifierGroupMenuModel);
226 NotifierGroupMenuModel::NotifierGroupMenuModel(
227 NotifierSettingsProvider* notifier_settings_provider)
228 : ui::SimpleMenuModel(this),
229 notifier_settings_provider_(notifier_settings_provider) {
230 if (!notifier_settings_provider_)
231 return;
233 size_t num_menu_items = notifier_settings_provider_->GetNotifierGroupCount();
234 for (size_t i = 0; i < num_menu_items; ++i) {
235 const NotifierGroup& group =
236 notifier_settings_provider_->GetNotifierGroupAt(i);
238 AddCheckItem(i, group.login_info.empty() ? group.name : group.login_info);
242 NotifierGroupMenuModel::~NotifierGroupMenuModel() {}
244 bool NotifierGroupMenuModel::IsCommandIdChecked(int command_id) const {
245 // If there's no provider, assume only one notifier group - the active one.
246 return !notifier_settings_provider_ ||
247 notifier_settings_provider_->IsNotifierGroupActiveAt(command_id);
250 bool NotifierGroupMenuModel::IsCommandIdEnabled(int command_id) const {
251 return true;
254 bool NotifierGroupMenuModel::GetAcceleratorForCommandId(
255 int command_id,
256 ui::Accelerator* accelerator) {
257 return false;
260 void NotifierGroupMenuModel::ExecuteCommand(int command_id, int event_flags) {
261 if (!notifier_settings_provider_)
262 return;
264 size_t notifier_group_index = static_cast<size_t>(command_id);
265 size_t num_notifier_groups =
266 notifier_settings_provider_->GetNotifierGroupCount();
267 if (notifier_group_index >= num_notifier_groups)
268 return;
270 notifier_settings_provider_->SwitchToNotifierGroup(notifier_group_index);
274 // NotifierSettingsView::NotifierButton ---------------------------------------
276 // We do not use views::Checkbox class directly because it doesn't support
277 // showing 'icon'.
278 NotifierSettingsView::NotifierButton::NotifierButton(
279 NotifierSettingsProvider* provider,
280 Notifier* notifier,
281 views::ButtonListener* listener)
282 : views::CustomButton(listener),
283 provider_(provider),
284 notifier_(notifier),
285 icon_view_(new views::ImageView()),
286 name_view_(new views::Label(notifier_->name)),
287 checkbox_(new views::Checkbox(base::string16())),
288 learn_more_(NULL) {
289 DCHECK(provider);
290 DCHECK(notifier);
292 // Since there may never be an icon (but that could change at a later time),
293 // we own the icon view here.
294 icon_view_->set_owned_by_client();
296 checkbox_->SetChecked(notifier_->enabled);
297 checkbox_->set_listener(this);
298 checkbox_->SetFocusable(false);
299 checkbox_->SetAccessibleName(notifier_->name);
301 if (ShouldHaveLearnMoreButton()) {
302 // Create a more-info button that will be right-aligned.
303 learn_more_ = new views::ImageButton(this);
304 learn_more_->SetFocusPainter(CreateFocusPainter());
305 learn_more_->set_request_focus_on_press(false);
306 learn_more_->SetFocusable(true);
308 ui::ResourceBundle& rb = ResourceBundle::GetSharedInstance();
309 learn_more_->SetImage(
310 views::Button::STATE_NORMAL,
311 rb.GetImageSkiaNamed(IDR_NOTIFICATION_ADVANCED_SETTINGS));
312 learn_more_->SetImage(
313 views::Button::STATE_HOVERED,
314 rb.GetImageSkiaNamed(IDR_NOTIFICATION_ADVANCED_SETTINGS_HOVER));
315 learn_more_->SetImage(
316 views::Button::STATE_PRESSED,
317 rb.GetImageSkiaNamed(IDR_NOTIFICATION_ADVANCED_SETTINGS_PRESSED));
318 learn_more_->SetState(views::Button::STATE_NORMAL);
319 int learn_more_border_width =
320 (settings::kLearnMoreTargetWidth - settings::kLearnMoreSize) / 2;
321 int learn_more_border_height =
322 (settings::kLearnMoreTargetHeight - settings::kLearnMoreSize) / 2;
323 // The image itself is quite small, this large invisible border creates a
324 // much bigger click target.
325 learn_more_->SetBorder(
326 views::Border::CreateEmptyBorder(learn_more_border_height,
327 learn_more_border_width,
328 learn_more_border_height,
329 learn_more_border_width));
330 learn_more_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
331 views::ImageButton::ALIGN_MIDDLE);
334 UpdateIconImage(notifier_->icon);
337 NotifierSettingsView::NotifierButton::~NotifierButton() {
340 void NotifierSettingsView::NotifierButton::UpdateIconImage(
341 const gfx::Image& icon) {
342 bool has_icon_view = false;
344 notifier_->icon = icon;
345 if (!icon.IsEmpty()) {
346 icon_view_->SetImage(icon.ToImageSkia());
347 icon_view_->SetImageSize(
348 gfx::Size(settings::kEntryIconSize, settings::kEntryIconSize));
349 has_icon_view = true;
351 GridChanged(ShouldHaveLearnMoreButton(), has_icon_view);
354 void NotifierSettingsView::NotifierButton::SetChecked(bool checked) {
355 checkbox_->SetChecked(checked);
356 notifier_->enabled = checked;
359 bool NotifierSettingsView::NotifierButton::checked() const {
360 return checkbox_->checked();
363 bool NotifierSettingsView::NotifierButton::has_learn_more() const {
364 return learn_more_ != NULL;
367 const Notifier& NotifierSettingsView::NotifierButton::notifier() const {
368 return *notifier_.get();
371 void NotifierSettingsView::NotifierButton::SendLearnMorePressedForTest() {
372 if (learn_more_ == NULL)
373 return;
374 gfx::Point point(110, 120);
375 ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, point, point,
376 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
377 ui::EF_LEFT_MOUSE_BUTTON);
378 ButtonPressed(learn_more_, pressed);
381 void NotifierSettingsView::NotifierButton::ButtonPressed(
382 views::Button* button,
383 const ui::Event& event) {
384 if (button == checkbox_) {
385 // The checkbox state has already changed at this point, but we'll update
386 // the state on NotifierSettingsView::ButtonPressed() too, so here change
387 // back to the previous state.
388 checkbox_->SetChecked(!checkbox_->checked());
389 CustomButton::NotifyClick(event);
390 } else if (button == learn_more_) {
391 DCHECK(provider_);
392 provider_->OnNotifierAdvancedSettingsRequested(notifier_->notifier_id,
393 NULL);
397 void NotifierSettingsView::NotifierButton::GetAccessibleState(
398 ui::AXViewState* state) {
399 static_cast<views::View*>(checkbox_)->GetAccessibleState(state);
402 bool NotifierSettingsView::NotifierButton::ShouldHaveLearnMoreButton() const {
403 if (!provider_)
404 return false;
406 return provider_->NotifierHasAdvancedSettings(notifier_->notifier_id);
409 void NotifierSettingsView::NotifierButton::GridChanged(bool has_learn_more,
410 bool has_icon_view) {
411 using views::ColumnSet;
412 using views::GridLayout;
414 GridLayout* layout = new GridLayout(this);
415 SetLayoutManager(layout);
416 ColumnSet* cs = layout->AddColumnSet(0);
417 // Add a column for the checkbox.
418 cs->AddPaddingColumn(0, kInnateCheckboxRightPadding);
419 cs->AddColumn(GridLayout::CENTER,
420 GridLayout::CENTER,
422 GridLayout::FIXED,
423 kComputedCheckboxSize,
425 cs->AddPaddingColumn(0, settings::kInternalHorizontalSpacing);
427 if (has_icon_view) {
428 // Add a column for the icon.
429 cs->AddColumn(GridLayout::CENTER,
430 GridLayout::CENTER,
432 GridLayout::FIXED,
433 settings::kEntryIconSize,
435 cs->AddPaddingColumn(0, settings::kInternalHorizontalSpacing);
438 // Add a column for the name.
439 cs->AddColumn(
440 GridLayout::LEADING, GridLayout::CENTER, 0, GridLayout::USE_PREF, 0, 0);
442 // Add a padding column which contains expandable blank space.
443 cs->AddPaddingColumn(1, 0);
445 // Add a column for the learn more button if necessary.
446 if (has_learn_more) {
447 cs->AddPaddingColumn(0, settings::kInternalHorizontalSpacing);
448 cs->AddColumn(
449 GridLayout::CENTER, GridLayout::CENTER, 0, GridLayout::USE_PREF, 0, 0);
452 layout->StartRow(0, 0);
453 layout->AddView(checkbox_);
454 if (has_icon_view)
455 layout->AddView(icon_view_.get());
456 layout->AddView(name_view_);
457 if (has_learn_more)
458 layout->AddView(learn_more_);
460 Layout();
464 // NotifierSettingsView -------------------------------------------------------
466 NotifierSettingsView::NotifierSettingsView(NotifierSettingsProvider* provider)
467 : title_arrow_(NULL),
468 title_label_(NULL),
469 notifier_group_selector_(NULL),
470 scroller_(NULL),
471 provider_(provider) {
472 // |provider_| may be NULL in tests.
473 if (provider_)
474 provider_->AddObserver(this);
476 SetFocusable(true);
477 set_background(
478 views::Background::CreateSolidBackground(kMessageCenterBackgroundColor));
479 SetPaintToLayer(true);
481 title_label_ = new views::Label(
482 l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS_BUTTON_LABEL),
483 ui::ResourceBundle::GetSharedInstance().GetFontList(
484 ui::ResourceBundle::MediumFont));
485 title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
486 title_label_->SetMultiLine(true);
487 title_label_->SetBorder(
488 views::Border::CreateEmptyBorder(kComputedTitleTopMargin,
489 settings::kTitleMargin,
490 kComputedTitleBottomMargin,
491 settings::kTitleMargin));
493 AddChildView(title_label_);
495 scroller_ = new views::ScrollView();
496 scroller_->SetVerticalScrollBar(new views::OverlayScrollBar(false));
497 AddChildView(scroller_);
499 std::vector<Notifier*> notifiers;
500 if (provider_)
501 provider_->GetNotifierList(&notifiers);
503 UpdateContentsView(notifiers);
506 NotifierSettingsView::~NotifierSettingsView() {
507 // |provider_| may be NULL in tests.
508 if (provider_)
509 provider_->RemoveObserver(this);
512 bool NotifierSettingsView::IsScrollable() {
513 return scroller_->height() < scroller_->contents()->height();
516 void NotifierSettingsView::UpdateIconImage(const NotifierId& notifier_id,
517 const gfx::Image& icon) {
518 for (std::set<NotifierButton*>::iterator iter = buttons_.begin();
519 iter != buttons_.end();
520 ++iter) {
521 if ((*iter)->notifier().notifier_id == notifier_id) {
522 (*iter)->UpdateIconImage(icon);
523 return;
528 void NotifierSettingsView::NotifierGroupChanged() {
529 std::vector<Notifier*> notifiers;
530 if (provider_)
531 provider_->GetNotifierList(&notifiers);
533 UpdateContentsView(notifiers);
536 void NotifierSettingsView::NotifierEnabledChanged(const NotifierId& notifier_id,
537 bool enabled) {}
539 void NotifierSettingsView::UpdateContentsView(
540 const std::vector<Notifier*>& notifiers) {
541 buttons_.clear();
543 views::View* contents_view = new views::View();
544 contents_view->SetLayoutManager(new views::BoxLayout(
545 views::BoxLayout::kVertical, settings::kHorizontalMargin, 0, 0));
547 views::View* contents_title_view = new views::View();
548 contents_title_view->SetLayoutManager(
549 new views::BoxLayout(views::BoxLayout::kVertical,
550 kComputedContentsTitleMargin,
552 kComputedTitleElementSpacing));
554 bool need_account_switcher =
555 provider_ && provider_->GetNotifierGroupCount() > 1;
556 int top_label_resource_id =
557 need_account_switcher ? IDS_MESSAGE_CENTER_SETTINGS_DESCRIPTION_MULTIUSER
558 : IDS_MESSAGE_CENTER_SETTINGS_DIALOG_DESCRIPTION;
560 views::Label* top_label =
561 new views::Label(l10n_util::GetStringUTF16(top_label_resource_id));
563 top_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
564 top_label->SetMultiLine(true);
565 top_label->SetBorder(views::Border::CreateEmptyBorder(
567 settings::kTitleMargin + kMenuButtonInnateMargin,
569 settings::kTitleMargin + kMenuButtonInnateMargin));
570 contents_title_view->AddChildView(top_label);
572 if (need_account_switcher) {
573 const NotifierGroup& active_group = provider_->GetActiveNotifierGroup();
574 base::string16 notifier_group_text = active_group.login_info.empty() ?
575 active_group.name : active_group.login_info;
576 notifier_group_selector_ =
577 new views::MenuButton(NULL, notifier_group_text, this, true);
578 notifier_group_selector_->SetBorder(scoped_ptr<views::Border>(
579 new views::LabelButtonAssetBorder(views::Button::STYLE_BUTTON)));
580 notifier_group_selector_->SetFocusPainter(nullptr);
581 notifier_group_selector_->set_animate_on_state_change(false);
582 notifier_group_selector_->SetFocusable(true);
583 contents_title_view->AddChildView(notifier_group_selector_);
586 contents_view->AddChildView(contents_title_view);
588 size_t notifier_count = notifiers.size();
589 for (size_t i = 0; i < notifier_count; ++i) {
590 NotifierButton* button = new NotifierButton(provider_, notifiers[i], this);
591 EntryView* entry = new EntryView(button);
593 // This code emulates separators using borders. We will create an invisible
594 // border on the last notifier, as the spec leaves a space for it.
595 scoped_ptr<views::Border> entry_border;
596 if (i == notifier_count - 1) {
597 entry_border = views::Border::CreateEmptyBorder(
598 0, 0, settings::kEntrySeparatorHeight, 0);
599 } else {
600 entry_border =
601 views::Border::CreateSolidSidedBorder(0,
603 settings::kEntrySeparatorHeight,
605 settings::kEntrySeparatorColor);
607 entry->SetBorder(entry_border.Pass());
608 entry->SetFocusable(true);
609 contents_view->AddChildView(entry);
610 buttons_.insert(button);
613 scroller_->SetContents(contents_view);
615 contents_view->SetBoundsRect(gfx::Rect(contents_view->GetPreferredSize()));
616 InvalidateLayout();
619 void NotifierSettingsView::Layout() {
620 int title_height = title_label_->GetHeightForWidth(width());
621 title_label_->SetBounds(settings::kTitleMargin,
623 width() - settings::kTitleMargin * 2,
624 title_height);
626 views::View* contents_view = scroller_->contents();
627 int content_width = width();
628 int content_height = contents_view->GetHeightForWidth(content_width);
629 if (title_height + content_height > height()) {
630 content_width -= scroller_->GetScrollBarWidth();
631 content_height = contents_view->GetHeightForWidth(content_width);
633 contents_view->SetBounds(0, 0, content_width, content_height);
634 scroller_->SetBounds(0, title_height, width(), height() - title_height);
637 gfx::Size NotifierSettingsView::GetMinimumSize() const {
638 gfx::Size size(settings::kWidth, settings::kMinimumHeight);
639 int total_height = title_label_->GetPreferredSize().height() +
640 scroller_->contents()->GetPreferredSize().height();
641 if (total_height > settings::kMinimumHeight)
642 size.Enlarge(scroller_->GetScrollBarWidth(), 0);
643 return size;
646 gfx::Size NotifierSettingsView::GetPreferredSize() const {
647 gfx::Size preferred_size;
648 gfx::Size title_size = title_label_->GetPreferredSize();
649 gfx::Size content_size = scroller_->contents()->GetPreferredSize();
650 return gfx::Size(std::max(title_size.width(), content_size.width()),
651 title_size.height() + content_size.height());
654 bool NotifierSettingsView::OnKeyPressed(const ui::KeyEvent& event) {
655 if (event.key_code() == ui::VKEY_ESCAPE) {
656 GetWidget()->Close();
657 return true;
660 return scroller_->OnKeyPressed(event);
663 bool NotifierSettingsView::OnMouseWheel(const ui::MouseWheelEvent& event) {
664 return scroller_->OnMouseWheel(event);
667 void NotifierSettingsView::ButtonPressed(views::Button* sender,
668 const ui::Event& event) {
669 if (sender == title_arrow_) {
670 MessageCenterView* center_view = static_cast<MessageCenterView*>(parent());
671 center_view->SetSettingsVisible(!center_view->settings_visible());
672 return;
675 std::set<NotifierButton*>::iterator iter =
676 buttons_.find(static_cast<NotifierButton*>(sender));
678 if (iter == buttons_.end())
679 return;
681 (*iter)->SetChecked(!(*iter)->checked());
682 if (provider_)
683 provider_->SetNotifierEnabled((*iter)->notifier(), (*iter)->checked());
686 void NotifierSettingsView::OnMenuButtonClicked(views::View* source,
687 const gfx::Point& point) {
688 notifier_group_menu_model_.reset(new NotifierGroupMenuModel(provider_));
689 notifier_group_menu_runner_.reset(new views::MenuRunner(
690 notifier_group_menu_model_.get(), views::MenuRunner::CONTEXT_MENU));
691 gfx::Rect menu_anchor = source->GetBoundsInScreen();
692 menu_anchor.Inset(
693 gfx::Insets(0, kMenuWhitespaceOffset, 0, kMenuWhitespaceOffset));
694 if (views::MenuRunner::MENU_DELETED ==
695 notifier_group_menu_runner_->RunMenuAt(GetWidget(),
696 notifier_group_selector_,
697 menu_anchor,
698 views::MENU_ANCHOR_BUBBLE_ABOVE,
699 ui::MENU_SOURCE_MOUSE))
700 return;
701 MessageCenterView* center_view = static_cast<MessageCenterView*>(parent());
702 center_view->OnSettingsChanged();
705 } // namespace message_center