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