1// Copyright 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.
4
5#include "ui/message_center/views/message_center_button_bar.h"
6
7#include "grit/ui_resources.h"
8#include "grit/ui_strings.h"
9#include "ui/base/l10n/l10n_util.h"
10#include "ui/base/models/simple_menu_model.h"
11#include "ui/base/resource/resource_bundle.h"
12#include "ui/gfx/canvas.h"
13#include "ui/gfx/text_constants.h"
14#include "ui/message_center/message_center.h"
15#include "ui/message_center/message_center_style.h"
16#include "ui/message_center/notifier_settings.h"
17#include "ui/message_center/views/message_center_view.h"
18#include "ui/views/controls/button/button.h"
19#include "ui/views/controls/button/image_button.h"
20#include "ui/views/controls/button/label_button.h"
21#include "ui/views/controls/button/menu_button.h"
22#include "ui/views/controls/button/menu_button_listener.h"
23#include "ui/views/controls/label.h"
24#include "ui/views/controls/menu/menu_runner.h"
25#include "ui/views/layout/box_layout.h"
26#include "ui/views/layout/grid_layout.h"
27
28namespace message_center {
29
30namespace {
31const int kButtonSize = 40;
32const int kChevronWidth = 8;
33const int kFooterLeftMargin = 20;
34const int kFooterRightMargin = 14;
35}  // namespace
36
37// NotificationCenterButton ////////////////////////////////////////////////////
38////////////////////////////////////////////////////////////////////////////////
39class NotificationCenterButton : public views::ToggleImageButton {
40 public:
41  NotificationCenterButton(views::ButtonListener* listener,
42                           int normal_id,
43                           int hover_id,
44                           int pressed_id,
45                           int text_id);
46  void set_size(gfx::Size size) { size_ = size; }
47
48 protected:
49  // Overridden from views::View:
50  virtual gfx::Size GetPreferredSize() OVERRIDE;
51  virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE;
52
53 private:
54  gfx::Size size_;
55
56  DISALLOW_COPY_AND_ASSIGN(NotificationCenterButton);
57};
58
59NotificationCenterButton::NotificationCenterButton(
60    views::ButtonListener* listener,
61    int normal_id,
62    int hover_id,
63    int pressed_id,
64    int text_id)
65    : views::ToggleImageButton(listener), size_(kButtonSize, kButtonSize) {
66  ui::ResourceBundle& resource_bundle = ui::ResourceBundle::GetSharedInstance();
67  SetImage(STATE_NORMAL, resource_bundle.GetImageSkiaNamed(normal_id));
68  SetImage(STATE_HOVERED, resource_bundle.GetImageSkiaNamed(hover_id));
69  SetImage(STATE_PRESSED, resource_bundle.GetImageSkiaNamed(pressed_id));
70  SetImageAlignment(views::ImageButton::ALIGN_CENTER,
71                    views::ImageButton::ALIGN_MIDDLE);
72  if (text_id)
73    SetTooltipText(resource_bundle.GetLocalizedString(text_id));
74
75  set_focusable(true);
76  set_request_focus_on_press(false);
77}
78
79gfx::Size NotificationCenterButton::GetPreferredSize() { return size_; }
80
81void NotificationCenterButton::OnPaintFocusBorder(gfx::Canvas* canvas) {
82  if (HasFocus() && (focusable() || IsAccessibilityFocusable())) {
83    canvas->DrawRect(gfx::Rect(2, 1, width() - 4, height() - 3),
84                     kFocusBorderColor);
85  }
86}
87
88// MessageCenterButtonBar /////////////////////////////////////////////////////
89///////////////////////////////////////////////////////////////////////////////
90MessageCenterButtonBar::MessageCenterButtonBar(
91    MessageCenterView* message_center_view,
92    MessageCenter* message_center,
93    NotifierSettingsProvider* notifier_settings_provider,
94    bool settings_initially_visible)
95    : message_center_view_(message_center_view),
96      message_center_(message_center),
97      title_arrow_(NULL),
98      notification_label_(NULL),
99      button_container_(NULL),
100      close_all_button_(NULL),
101      settings_button_(NULL),
102      quiet_mode_button_(NULL) {
103  if (get_use_acceleration_when_possible())
104    SetPaintToLayer(true);
105  set_background(
106      views::Background::CreateSolidBackground(kMessageCenterBackgroundColor));
107
108  ui::ResourceBundle& resource_bundle = ui::ResourceBundle::GetSharedInstance();
109
110  title_arrow_ = new NotificationCenterButton(this,
111                                              IDR_NOTIFICATION_ARROW,
112                                              IDR_NOTIFICATION_ARROW_HOVER,
113                                              IDR_NOTIFICATION_ARROW_PRESSED,
114                                              0);
115  title_arrow_->set_size(gfx::Size(kChevronWidth, kButtonSize));
116
117  // Keyboardists can use the gear button to switch modes.
118  title_arrow_->set_focusable(false);
119  AddChildView(title_arrow_);
120
121  gfx::Font notification_label_font =
122      ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont);
123  notification_label_ = new views::Label(
124      l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_FOOTER_TITLE),
125      notification_label_font);
126  notification_label_->SetAutoColorReadabilityEnabled(false);
127  notification_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
128  notification_label_->SetEnabledColor(kRegularTextColor);
129  AddChildView(notification_label_);
130
131  button_container_ = new views::View;
132  button_container_->SetLayoutManager(
133      new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
134  quiet_mode_button_ = new NotificationCenterButton(
135      this,
136      IDR_NOTIFICATION_DO_NOT_DISTURB,
137      IDR_NOTIFICATION_DO_NOT_DISTURB_HOVER,
138      IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED,
139      IDS_MESSAGE_CENTER_QUIET_MODE_BUTTON_TOOLTIP);
140  quiet_mode_button_->SetToggledImage(
141      views::Button::STATE_NORMAL,
142      resource_bundle.GetImageSkiaNamed(
143          IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED));
144  quiet_mode_button_->SetToggledImage(
145      views::Button::STATE_HOVERED,
146      resource_bundle.GetImageSkiaNamed(
147          IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED));
148  quiet_mode_button_->SetToggledImage(
149      views::Button::STATE_PRESSED,
150      resource_bundle.GetImageSkiaNamed(
151          IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED));
152  quiet_mode_button_->SetToggled(message_center->IsQuietMode());
153  button_container_->AddChildView(quiet_mode_button_);
154
155  close_all_button_ =
156      new NotificationCenterButton(this,
157                                   IDR_NOTIFICATION_CLEAR_ALL,
158                                   IDR_NOTIFICATION_CLEAR_ALL_HOVER,
159                                   IDR_NOTIFICATION_CLEAR_ALL_PRESSED,
160                                   IDS_MESSAGE_CENTER_CLEAR_ALL);
161  close_all_button_->SetImage(
162      views::Button::STATE_DISABLED,
163      resource_bundle.GetImageSkiaNamed(IDR_NOTIFICATION_CLEAR_ALL_DISABLED));
164  button_container_->AddChildView(close_all_button_);
165
166  settings_button_ =
167      new NotificationCenterButton(this,
168                                   IDR_NOTIFICATION_SETTINGS,
169                                   IDR_NOTIFICATION_SETTINGS_HOVER,
170                                   IDR_NOTIFICATION_SETTINGS_PRESSED,
171                                   IDS_MESSAGE_CENTER_SETTINGS_BUTTON_LABEL);
172  button_container_->AddChildView(settings_button_);
173
174  SetCloseAllButtonEnabled(!settings_initially_visible);
175  SetBackArrowVisible(settings_initially_visible);
176  ViewVisibilityChanged();
177}
178
179void MessageCenterButtonBar::ViewVisibilityChanged() {
180  gfx::ImageSkia* settings_image =
181      ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
182          IDR_NOTIFICATION_SETTINGS);
183  int image_margin = std::max(0, (kButtonSize - settings_image->width()) / 2);
184  views::GridLayout* layout = new views::GridLayout(this);
185  SetLayoutManager(layout);
186  layout->SetInsets(
187      0, kFooterLeftMargin, 0, std::max(0, kFooterRightMargin - image_margin));
188  views::ColumnSet* column = layout->AddColumnSet(0);
189  if (title_arrow_->visible()) {
190    // Column for the left-arrow used to back out of settings.
191    column->AddColumn(views::GridLayout::LEADING,
192                      views::GridLayout::CENTER,
193                      0.0f,
194                      views::GridLayout::USE_PREF,
195                      0,
196                      0);
197
198    column->AddPaddingColumn(0.0f, 10);
199  }
200
201  // Column for the label "Notifications".
202  column->AddColumn(views::GridLayout::LEADING,
203                    views::GridLayout::CENTER,
204                    0.0f,
205                    views::GridLayout::USE_PREF,
206                    0,
207                    0);
208
209  // Fills in the remaining space between "Notifications" and buttons.
210  column->AddPaddingColumn(1.0f, image_margin);
211
212  // The button area column.
213  column->AddColumn(views::GridLayout::LEADING,
214                    views::GridLayout::CENTER,
215                    0.0f,
216                    views::GridLayout::USE_PREF,
217                    0,
218                    0);
219
220  layout->StartRow(0, 0);
221  if (title_arrow_->visible())
222    layout->AddView(title_arrow_);
223  layout->AddView(notification_label_);
224  layout->AddView(button_container_);
225}
226
227MessageCenterButtonBar::~MessageCenterButtonBar() {}
228
229void MessageCenterButtonBar::SetAllButtonsEnabled(bool enabled) {
230  if (close_all_button_)
231    close_all_button_->SetEnabled(enabled);
232  settings_button_->SetEnabled(enabled);
233  quiet_mode_button_->SetEnabled(enabled);
234}
235
236void MessageCenterButtonBar::SetCloseAllButtonEnabled(bool enabled) {
237  if (close_all_button_)
238    close_all_button_->SetEnabled(enabled);
239}
240
241void MessageCenterButtonBar::SetBackArrowVisible(bool visible) {
242  if (title_arrow_)
243    title_arrow_->SetVisible(visible);
244  ViewVisibilityChanged();
245  Layout();
246}
247
248void MessageCenterButtonBar::ChildVisibilityChanged(views::View* child) {
249  InvalidateLayout();
250}
251
252void MessageCenterButtonBar::ButtonPressed(views::Button* sender,
253                                           const ui::Event& event) {
254  if (sender == close_all_button_) {
255    message_center_view()->ClearAllNotifications();
256  } else if (sender == settings_button_ || sender == title_arrow_) {
257    MessageCenterView* center_view = message_center_view();
258    center_view->SetSettingsVisible(!center_view->settings_visible());
259  } else if (sender == quiet_mode_button_) {
260    if (message_center()->IsQuietMode())
261      message_center()->SetQuietMode(false);
262    else
263      message_center()->EnterQuietModeWithExpire(base::TimeDelta::FromDays(1));
264    quiet_mode_button_->SetToggled(message_center()->IsQuietMode());
265  } else {
266    NOTREACHED();
267  }
268}
269
270}  // namespace message_center
271