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"
10 #include "base/strings/string16.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "grit/ui_resources.h"
13 #include "grit/ui_strings.h"
14 #include "skia/ext/image_operations.h"
15 #include "third_party/skia/include/core/SkColor.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/models/simple_menu_model.h"
18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/events/keycodes/keyboard_codes.h"
20 #include "ui/gfx/canvas.h"
21 #include "ui/gfx/image/image.h"
22 #include "ui/gfx/size.h"
23 #include "ui/message_center/message_center_style.h"
24 #include "ui/message_center/views/message_center_view.h"
25 #include "ui/views/background.h"
26 #include "ui/views/border.h"
27 #include "ui/views/controls/button/checkbox.h"
28 #include "ui/views/controls/button/custom_button.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
{
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
72 // The amount of built-in padding for the notifier group switcher.
73 const int kButtonPainterInsets
= 5;
75 // Menu button metrics to make the text line up.
76 const int kMenuButtonInnateMargin
= 2;
77 const int kMenuButtonLeftPadding
= 12;
78 const int kMenuButtonRightPadding
= 13;
79 const int kMenuButtonVerticalPadding
= 9;
81 // Used to place the context menu correctly.
82 const int kMenuWhitespaceOffset
= 2;
84 // The innate vertical blank space in the label for the title of the settings
86 const int kInnateTitleBottomMargin
= 1;
87 const int kInnateTitleTopMargin
= 7;
89 // The innate top blank space in the label for the description of the settings
91 const int kInnateDescriptionTopMargin
= 2;
93 // Checkboxes have some built-in right padding blank space.
94 const int kInnateCheckboxRightPadding
= 2;
96 // Spec defines the checkbox size; the innate padding throws this measurement
97 // off so we need to compute a slightly different area for the checkbox to
99 const int kComputedCheckboxSize
=
100 settings::kCheckboxSizeWithPadding
- kInnateCheckboxRightPadding
;
102 // The menubutton has innate margin, so we need to compensate for that when
103 // figuring the margin of the title area.
104 const int kComputedContentsTitleMargin
= 0 - kMenuButtonInnateMargin
;
106 // The spec doesn't include the bottom blank area of the title bar or the innate
107 // blank area in the description label, so we'll use this as the space between
108 // the title and description.
109 const int kComputedTitleBottomMargin
= settings::kDescriptionToSwitcherSpace
-
110 kInnateTitleBottomMargin
-
111 kInnateDescriptionTopMargin
;
113 // The blank space above the title needs to be adjusted by the amount of blank
114 // space included in the title label.
115 const int kComputedTitleTopMargin
=
116 settings::kTopMargin
- kInnateTitleTopMargin
;
118 // The switcher has a lot of blank space built in so we should include that when
119 // spacing the title area vertically.
120 const int kComputedTitleElementSpacing
=
121 settings::kDescriptionToSwitcherSpace
- kButtonPainterInsets
- 1;
123 // A function to create a focus border.
124 scoped_ptr
<views::Painter
> CreateFocusPainter() {
125 return views::Painter::CreateSolidFocusPainter(kFocusBorderColor
,
126 gfx::Insets(1, 2, 3, 2));
129 // EntryView ------------------------------------------------------------------
131 // The view to guarantee the 48px height and place the contents at the
132 // middle. It also guarantee the left margin.
133 class EntryView
: public views::View
{
135 explicit EntryView(views::View
* contents
);
136 virtual ~EntryView();
139 virtual void Layout() OVERRIDE
;
140 virtual gfx::Size
GetPreferredSize() const OVERRIDE
;
141 virtual void GetAccessibleState(ui::AXViewState
* state
) OVERRIDE
;
142 virtual void OnFocus() OVERRIDE
;
143 virtual bool OnKeyPressed(const ui::KeyEvent
& event
) OVERRIDE
;
144 virtual bool OnKeyReleased(const ui::KeyEvent
& event
) OVERRIDE
;
145 virtual void OnPaint(gfx::Canvas
* canvas
) OVERRIDE
;
146 virtual void OnBlur() OVERRIDE
;
149 scoped_ptr
<views::Painter
> focus_painter_
;
151 DISALLOW_COPY_AND_ASSIGN(EntryView
);
154 EntryView::EntryView(views::View
* contents
)
155 : focus_painter_(CreateFocusPainter()) {
156 AddChildView(contents
);
159 EntryView::~EntryView() {}
161 void EntryView::Layout() {
162 DCHECK_EQ(1, child_count());
163 views::View
* content
= child_at(0);
164 int content_width
= width();
165 int content_height
= content
->GetHeightForWidth(content_width
);
166 int y
= std::max((height() - content_height
) / 2, 0);
167 content
->SetBounds(0, y
, content_width
, content_height
);
170 gfx::Size
EntryView::GetPreferredSize() const {
171 DCHECK_EQ(1, child_count());
172 gfx::Size size
= child_at(0)->GetPreferredSize();
173 size
.SetToMax(gfx::Size(settings::kWidth
, settings::kEntryHeight
));
177 void EntryView::GetAccessibleState(ui::AXViewState
* state
) {
178 DCHECK_EQ(1, child_count());
179 child_at(0)->GetAccessibleState(state
);
182 void EntryView::OnFocus() {
183 views::View::OnFocus();
184 ScrollRectToVisible(GetLocalBounds());
185 // We render differently when focused.
189 bool EntryView::OnKeyPressed(const ui::KeyEvent
& event
) {
190 return child_at(0)->OnKeyPressed(event
);
193 bool EntryView::OnKeyReleased(const ui::KeyEvent
& event
) {
194 return child_at(0)->OnKeyReleased(event
);
197 void EntryView::OnPaint(gfx::Canvas
* canvas
) {
198 View::OnPaint(canvas
);
199 views::Painter::PaintFocusPainter(this, canvas
, focus_painter_
.get());
202 void EntryView::OnBlur() {
204 // We render differently when focused.
211 // NotifierGroupMenuModel -----------------------------------------------------
213 class NotifierGroupMenuModel
: public ui::SimpleMenuModel
,
214 public ui::SimpleMenuModel::Delegate
{
216 NotifierGroupMenuModel(NotifierSettingsProvider
* notifier_settings_provider
);
217 virtual ~NotifierGroupMenuModel();
219 // ui::SimpleMenuModel::Delegate:
220 virtual bool IsCommandIdChecked(int command_id
) const OVERRIDE
;
221 virtual bool IsCommandIdEnabled(int command_id
) const OVERRIDE
;
222 virtual bool GetAcceleratorForCommandId(
224 ui::Accelerator
* accelerator
) OVERRIDE
;
225 virtual void ExecuteCommand(int command_id
, int event_flags
) OVERRIDE
;
228 NotifierSettingsProvider
* notifier_settings_provider_
;
230 DISALLOW_COPY_AND_ASSIGN(NotifierGroupMenuModel
);
233 NotifierGroupMenuModel::NotifierGroupMenuModel(
234 NotifierSettingsProvider
* notifier_settings_provider
)
235 : ui::SimpleMenuModel(this),
236 notifier_settings_provider_(notifier_settings_provider
) {
237 if (!notifier_settings_provider_
)
240 size_t num_menu_items
= notifier_settings_provider_
->GetNotifierGroupCount();
241 for (size_t i
= 0; i
< num_menu_items
; ++i
) {
242 const NotifierGroup
& group
=
243 notifier_settings_provider_
->GetNotifierGroupAt(i
);
245 AddCheckItem(i
, group
.login_info
.empty() ? group
.name
: group
.login_info
);
249 NotifierGroupMenuModel::~NotifierGroupMenuModel() {}
251 bool NotifierGroupMenuModel::IsCommandIdChecked(int command_id
) const {
252 // If there's no provider, assume only one notifier group - the active one.
253 return !notifier_settings_provider_
||
254 notifier_settings_provider_
->IsNotifierGroupActiveAt(command_id
);
257 bool NotifierGroupMenuModel::IsCommandIdEnabled(int command_id
) const {
261 bool NotifierGroupMenuModel::GetAcceleratorForCommandId(
263 ui::Accelerator
* accelerator
) {
267 void NotifierGroupMenuModel::ExecuteCommand(int command_id
, int event_flags
) {
268 if (!notifier_settings_provider_
)
271 size_t notifier_group_index
= static_cast<size_t>(command_id
);
272 size_t num_notifier_groups
=
273 notifier_settings_provider_
->GetNotifierGroupCount();
274 if (notifier_group_index
>= num_notifier_groups
)
277 notifier_settings_provider_
->SwitchToNotifierGroup(notifier_group_index
);
281 // NotifierSettingsView::NotifierButton ---------------------------------------
283 // We do not use views::Checkbox class directly because it doesn't support
285 NotifierSettingsView::NotifierButton::NotifierButton(
286 NotifierSettingsProvider
* provider
,
288 views::ButtonListener
* listener
)
289 : views::CustomButton(listener
),
292 icon_view_(new views::ImageView()),
293 name_view_(new views::Label(notifier_
->name
)),
294 checkbox_(new views::Checkbox(base::string16())),
299 // Since there may never be an icon (but that could change at a later time),
300 // we own the icon view here.
301 icon_view_
->set_owned_by_client();
303 checkbox_
->SetChecked(notifier_
->enabled
);
304 checkbox_
->set_listener(this);
305 checkbox_
->SetFocusable(false);
306 checkbox_
->SetAccessibleName(notifier_
->name
);
308 if (ShouldHaveLearnMoreButton()) {
309 // Create a more-info button that will be right-aligned.
310 learn_more_
= new views::ImageButton(this);
311 learn_more_
->SetFocusPainter(CreateFocusPainter());
312 learn_more_
->set_request_focus_on_press(false);
313 learn_more_
->SetFocusable(true);
315 ui::ResourceBundle
& rb
= ResourceBundle::GetSharedInstance();
316 learn_more_
->SetImage(
317 views::Button::STATE_NORMAL
,
318 rb
.GetImageSkiaNamed(IDR_NOTIFICATION_ADVANCED_SETTINGS
));
319 learn_more_
->SetImage(
320 views::Button::STATE_HOVERED
,
321 rb
.GetImageSkiaNamed(IDR_NOTIFICATION_ADVANCED_SETTINGS_HOVER
));
322 learn_more_
->SetImage(
323 views::Button::STATE_PRESSED
,
324 rb
.GetImageSkiaNamed(IDR_NOTIFICATION_ADVANCED_SETTINGS_PRESSED
));
325 learn_more_
->SetState(views::Button::STATE_NORMAL
);
326 int learn_more_border_width
=
327 (settings::kLearnMoreTargetWidth
- settings::kLearnMoreSize
) / 2;
328 int learn_more_border_height
=
329 (settings::kLearnMoreTargetHeight
- settings::kLearnMoreSize
) / 2;
330 // The image itself is quite small, this large invisible border creates a
331 // much bigger click target.
332 learn_more_
->SetBorder(
333 views::Border::CreateEmptyBorder(learn_more_border_height
,
334 learn_more_border_width
,
335 learn_more_border_height
,
336 learn_more_border_width
));
337 learn_more_
->SetImageAlignment(views::ImageButton::ALIGN_CENTER
,
338 views::ImageButton::ALIGN_MIDDLE
);
341 UpdateIconImage(notifier_
->icon
);
344 NotifierSettingsView::NotifierButton::~NotifierButton() {
347 void NotifierSettingsView::NotifierButton::UpdateIconImage(
348 const gfx::Image
& icon
) {
349 bool has_icon_view
= false;
351 notifier_
->icon
= icon
;
352 if (!icon
.IsEmpty()) {
353 icon_view_
->SetImage(icon
.ToImageSkia());
354 icon_view_
->SetImageSize(
355 gfx::Size(settings::kEntryIconSize
, settings::kEntryIconSize
));
356 has_icon_view
= true;
358 GridChanged(ShouldHaveLearnMoreButton(), has_icon_view
);
361 void NotifierSettingsView::NotifierButton::SetChecked(bool checked
) {
362 checkbox_
->SetChecked(checked
);
363 notifier_
->enabled
= checked
;
366 bool NotifierSettingsView::NotifierButton::checked() const {
367 return checkbox_
->checked();
370 bool NotifierSettingsView::NotifierButton::has_learn_more() const {
371 return learn_more_
!= NULL
;
374 const Notifier
& NotifierSettingsView::NotifierButton::notifier() const {
375 return *notifier_
.get();
378 void NotifierSettingsView::NotifierButton::SendLearnMorePressedForTest() {
379 if (learn_more_
== NULL
)
381 gfx::Point
point(110, 120);
382 ui::MouseEvent
pressed(
383 ui::ET_MOUSE_PRESSED
, point
, point
, ui::EF_LEFT_MOUSE_BUTTON
,
384 ui::EF_LEFT_MOUSE_BUTTON
);
385 ButtonPressed(learn_more_
, pressed
);
388 void NotifierSettingsView::NotifierButton::ButtonPressed(
389 views::Button
* button
,
390 const ui::Event
& event
) {
391 if (button
== checkbox_
) {
392 // The checkbox state has already changed at this point, but we'll update
393 // the state on NotifierSettingsView::ButtonPressed() too, so here change
394 // back to the previous state.
395 checkbox_
->SetChecked(!checkbox_
->checked());
396 CustomButton::NotifyClick(event
);
397 } else if (button
== learn_more_
) {
399 provider_
->OnNotifierAdvancedSettingsRequested(notifier_
->notifier_id
,
404 void NotifierSettingsView::NotifierButton::GetAccessibleState(
405 ui::AXViewState
* state
) {
406 static_cast<views::View
*>(checkbox_
)->GetAccessibleState(state
);
409 bool NotifierSettingsView::NotifierButton::ShouldHaveLearnMoreButton() const {
413 return provider_
->NotifierHasAdvancedSettings(notifier_
->notifier_id
);
416 void NotifierSettingsView::NotifierButton::GridChanged(bool has_learn_more
,
417 bool has_icon_view
) {
418 using views::ColumnSet
;
419 using views::GridLayout
;
421 GridLayout
* layout
= new GridLayout(this);
422 SetLayoutManager(layout
);
423 ColumnSet
* cs
= layout
->AddColumnSet(0);
424 // Add a column for the checkbox.
425 cs
->AddPaddingColumn(0, kInnateCheckboxRightPadding
);
426 cs
->AddColumn(GridLayout::CENTER
,
430 kComputedCheckboxSize
,
432 cs
->AddPaddingColumn(0, settings::kInternalHorizontalSpacing
);
435 // Add a column for the icon.
436 cs
->AddColumn(GridLayout::CENTER
,
440 settings::kEntryIconSize
,
442 cs
->AddPaddingColumn(0, settings::kInternalHorizontalSpacing
);
445 // Add a column for the name.
447 GridLayout::LEADING
, GridLayout::CENTER
, 0, GridLayout::USE_PREF
, 0, 0);
449 // Add a padding column which contains expandable blank space.
450 cs
->AddPaddingColumn(1, 0);
452 // Add a column for the learn more button if necessary.
453 if (has_learn_more
) {
454 cs
->AddPaddingColumn(0, settings::kInternalHorizontalSpacing
);
456 GridLayout::CENTER
, GridLayout::CENTER
, 0, GridLayout::USE_PREF
, 0, 0);
459 layout
->StartRow(0, 0);
460 layout
->AddView(checkbox_
);
462 layout
->AddView(icon_view_
.get());
463 layout
->AddView(name_view_
);
465 layout
->AddView(learn_more_
);
471 // NotifierSettingsView -------------------------------------------------------
473 NotifierSettingsView::NotifierSettingsView(NotifierSettingsProvider
* provider
)
474 : title_arrow_(NULL
),
476 notifier_group_selector_(NULL
),
478 provider_(provider
) {
479 // |provider_| may be NULL in tests.
481 provider_
->AddObserver(this);
485 views::Background::CreateSolidBackground(kMessageCenterBackgroundColor
));
486 SetPaintToLayer(true);
488 title_label_
= new views::Label(
489 l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS_BUTTON_LABEL
),
490 ui::ResourceBundle::GetSharedInstance().GetFontList(
491 ui::ResourceBundle::MediumFont
));
492 title_label_
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
493 title_label_
->SetMultiLine(true);
494 title_label_
->SetBorder(
495 views::Border::CreateEmptyBorder(kComputedTitleTopMargin
,
496 settings::kTitleMargin
,
497 kComputedTitleBottomMargin
,
498 settings::kTitleMargin
));
500 AddChildView(title_label_
);
502 scroller_
= new views::ScrollView();
503 scroller_
->SetVerticalScrollBar(new views::OverlayScrollBar(false));
504 AddChildView(scroller_
);
506 std::vector
<Notifier
*> notifiers
;
508 provider_
->GetNotifierList(¬ifiers
);
510 UpdateContentsView(notifiers
);
513 NotifierSettingsView::~NotifierSettingsView() {
514 // |provider_| may be NULL in tests.
516 provider_
->RemoveObserver(this);
519 bool NotifierSettingsView::IsScrollable() {
520 return scroller_
->height() < scroller_
->contents()->height();
523 void NotifierSettingsView::UpdateIconImage(const NotifierId
& notifier_id
,
524 const gfx::Image
& icon
) {
525 for (std::set
<NotifierButton
*>::iterator iter
= buttons_
.begin();
526 iter
!= buttons_
.end();
528 if ((*iter
)->notifier().notifier_id
== notifier_id
) {
529 (*iter
)->UpdateIconImage(icon
);
535 void NotifierSettingsView::NotifierGroupChanged() {
536 std::vector
<Notifier
*> notifiers
;
538 provider_
->GetNotifierList(¬ifiers
);
540 UpdateContentsView(notifiers
);
543 void NotifierSettingsView::NotifierEnabledChanged(const NotifierId
& notifier_id
,
546 void NotifierSettingsView::UpdateContentsView(
547 const std::vector
<Notifier
*>& notifiers
) {
550 views::View
* contents_view
= new views::View();
551 contents_view
->SetLayoutManager(new views::BoxLayout(
552 views::BoxLayout::kVertical
, settings::kHorizontalMargin
, 0, 0));
554 views::View
* contents_title_view
= new views::View();
555 contents_title_view
->SetLayoutManager(
556 new views::BoxLayout(views::BoxLayout::kVertical
,
557 kComputedContentsTitleMargin
,
559 kComputedTitleElementSpacing
));
561 bool need_account_switcher
=
562 provider_
&& provider_
->GetNotifierGroupCount() > 1;
563 int top_label_resource_id
=
564 need_account_switcher
? IDS_MESSAGE_CENTER_SETTINGS_DESCRIPTION_MULTIUSER
565 : IDS_MESSAGE_CENTER_SETTINGS_DIALOG_DESCRIPTION
;
567 views::Label
* top_label
=
568 new views::Label(l10n_util::GetStringUTF16(top_label_resource_id
));
570 top_label
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
571 top_label
->SetMultiLine(true);
572 top_label
->SetBorder(views::Border::CreateEmptyBorder(
574 settings::kTitleMargin
+ kMenuButtonInnateMargin
,
576 settings::kTitleMargin
+ kMenuButtonInnateMargin
));
577 contents_title_view
->AddChildView(top_label
);
579 if (need_account_switcher
) {
580 const NotifierGroup
& active_group
= provider_
->GetActiveNotifierGroup();
581 base::string16 notifier_group_text
= active_group
.login_info
.empty() ?
582 active_group
.name
: active_group
.login_info
;
583 notifier_group_selector_
=
584 new views::MenuButton(NULL
, notifier_group_text
, this, true);
585 scoped_ptr
<views::TextButtonDefaultBorder
> selector_border(
586 new views::TextButtonDefaultBorder());
587 ui::ResourceBundle
* rb
= &ResourceBundle::GetSharedInstance();
588 gfx::Insets
painter_insets(kButtonPainterInsets
, kButtonPainterInsets
,
589 kButtonPainterInsets
, kButtonPainterInsets
);
590 selector_border
->set_normal_painter(views::Painter::CreateImagePainter(
591 *rb
->GetImageSkiaNamed(IDR_BUTTON_NORMAL
), painter_insets
));
592 selector_border
->set_hot_painter(views::Painter::CreateImagePainter(
593 *rb
->GetImageSkiaNamed(IDR_BUTTON_HOVER
), painter_insets
));
594 selector_border
->set_pushed_painter(views::Painter::CreateImagePainter(
595 *rb
->GetImageSkiaNamed(IDR_BUTTON_PRESSED
), painter_insets
));
596 selector_border
->SetInsets(gfx::Insets(
597 kMenuButtonVerticalPadding
, kMenuButtonLeftPadding
,
598 kMenuButtonVerticalPadding
, kMenuButtonRightPadding
));
599 notifier_group_selector_
->SetBorder(
600 selector_border
.PassAs
<views::Border
>());
601 notifier_group_selector_
->SetFocusPainter(scoped_ptr
<views::Painter
>());
602 notifier_group_selector_
->set_animate_on_state_change(false);
603 notifier_group_selector_
->SetFocusable(true);
604 contents_title_view
->AddChildView(notifier_group_selector_
);
607 contents_view
->AddChildView(contents_title_view
);
609 size_t notifier_count
= notifiers
.size();
610 for (size_t i
= 0; i
< notifier_count
; ++i
) {
611 NotifierButton
* button
= new NotifierButton(provider_
, notifiers
[i
], this);
612 EntryView
* entry
= new EntryView(button
);
614 // This code emulates separators using borders. We will create an invisible
615 // border on the last notifier, as the spec leaves a space for it.
616 scoped_ptr
<views::Border
> entry_border
;
617 if (i
== notifier_count
- 1) {
618 entry_border
= views::Border::CreateEmptyBorder(
619 0, 0, settings::kEntrySeparatorHeight
, 0);
622 views::Border::CreateSolidSidedBorder(0,
624 settings::kEntrySeparatorHeight
,
626 settings::kEntrySeparatorColor
);
628 entry
->SetBorder(entry_border
.Pass());
629 entry
->SetFocusable(true);
630 contents_view
->AddChildView(entry
);
631 buttons_
.insert(button
);
634 scroller_
->SetContents(contents_view
);
636 contents_view
->SetBoundsRect(gfx::Rect(contents_view
->GetPreferredSize()));
640 void NotifierSettingsView::Layout() {
641 int title_height
= title_label_
->GetHeightForWidth(width());
642 title_label_
->SetBounds(settings::kTitleMargin
,
644 width() - settings::kTitleMargin
* 2,
647 views::View
* contents_view
= scroller_
->contents();
648 int content_width
= width();
649 int content_height
= contents_view
->GetHeightForWidth(content_width
);
650 if (title_height
+ content_height
> height()) {
651 content_width
-= scroller_
->GetScrollBarWidth();
652 content_height
= contents_view
->GetHeightForWidth(content_width
);
654 contents_view
->SetBounds(0, 0, content_width
, content_height
);
655 scroller_
->SetBounds(0, title_height
, width(), height() - title_height
);
658 gfx::Size
NotifierSettingsView::GetMinimumSize() const {
659 gfx::Size
size(settings::kWidth
, settings::kMinimumHeight
);
660 int total_height
= title_label_
->GetPreferredSize().height() +
661 scroller_
->contents()->GetPreferredSize().height();
662 if (total_height
> settings::kMinimumHeight
)
663 size
.Enlarge(scroller_
->GetScrollBarWidth(), 0);
667 gfx::Size
NotifierSettingsView::GetPreferredSize() const {
668 gfx::Size preferred_size
;
669 gfx::Size title_size
= title_label_
->GetPreferredSize();
670 gfx::Size content_size
= scroller_
->contents()->GetPreferredSize();
671 return gfx::Size(std::max(title_size
.width(), content_size
.width()),
672 title_size
.height() + content_size
.height());
675 bool NotifierSettingsView::OnKeyPressed(const ui::KeyEvent
& event
) {
676 if (event
.key_code() == ui::VKEY_ESCAPE
) {
677 GetWidget()->Close();
681 return scroller_
->OnKeyPressed(event
);
684 bool NotifierSettingsView::OnMouseWheel(const ui::MouseWheelEvent
& event
) {
685 return scroller_
->OnMouseWheel(event
);
688 void NotifierSettingsView::ButtonPressed(views::Button
* sender
,
689 const ui::Event
& event
) {
690 if (sender
== title_arrow_
) {
691 MessageCenterView
* center_view
= static_cast<MessageCenterView
*>(parent());
692 center_view
->SetSettingsVisible(!center_view
->settings_visible());
696 std::set
<NotifierButton
*>::iterator iter
=
697 buttons_
.find(static_cast<NotifierButton
*>(sender
));
699 if (iter
== buttons_
.end())
702 (*iter
)->SetChecked(!(*iter
)->checked());
704 provider_
->SetNotifierEnabled((*iter
)->notifier(), (*iter
)->checked());
707 void NotifierSettingsView::OnMenuButtonClicked(views::View
* source
,
708 const gfx::Point
& point
) {
709 notifier_group_menu_model_
.reset(new NotifierGroupMenuModel(provider_
));
710 notifier_group_menu_runner_
.reset(
711 new views::MenuRunner(notifier_group_menu_model_
.get()));
712 gfx::Rect menu_anchor
= source
->GetBoundsInScreen();
714 gfx::Insets(0, kMenuWhitespaceOffset
, 0, kMenuWhitespaceOffset
));
715 if (views::MenuRunner::MENU_DELETED
==
716 notifier_group_menu_runner_
->RunMenuAt(GetWidget(),
717 notifier_group_selector_
,
719 views::MENU_ANCHOR_BUBBLE_ABOVE
,
720 ui::MENU_SOURCE_MOUSE
,
721 views::MenuRunner::CONTEXT_MENU
))
723 MessageCenterView
* center_view
= static_cast<MessageCenterView
*>(parent());
724 center_view
->OnSettingsChanged();
727 } // namespace message_center