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