Home | History | Annotate | Download | only in views
      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