Home | History | Annotate | Download | only in website_settings
      1 // Copyright (c) 2012 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 "chrome/browser/ui/views/website_settings/permission_selector_view.h"
      6 
      7 #include "base/strings/utf_string_conversions.h"
      8 #include "chrome/browser/ui/website_settings/permission_menu_model.h"
      9 #include "chrome/browser/ui/website_settings/website_settings_ui.h"
     10 #include "chrome/grit/generated_resources.h"
     11 #include "ui/accessibility/ax_view_state.h"
     12 #include "ui/base/l10n/l10n_util.h"
     13 #include "ui/gfx/image/image.h"
     14 #include "ui/views/controls/button/menu_button.h"
     15 #include "ui/views/controls/image_view.h"
     16 #include "ui/views/controls/label.h"
     17 #include "ui/views/controls/menu/menu_runner.h"
     18 #include "ui/views/layout/grid_layout.h"
     19 #include "ui/views/view.h"
     20 #include "ui/views/widget/widget.h"
     21 
     22 namespace {
     23 
     24 // Left icon margin.
     25 const int kPermissionIconMarginLeft = 6;
     26 // The width of the column that contains the permissions icons.
     27 const int kPermissionIconColumnWidth = 20;
     28 
     29 }  // namespace
     30 
     31 namespace internal {
     32 
     33 // The |PermissionMenuButton| provides a menu for selecting a setting a
     34 // permissions type.
     35 class PermissionMenuButton : public views::MenuButton,
     36                              public views::MenuButtonListener {
     37  public:
     38   // Creates a new |PermissionMenuButton| with the passed |text|. The ownership
     39   // of the |model| remains with the caller and is not transfered to the
     40   // |PermissionMenuButton|. If the |show_menu_marker| flag is true, then a
     41   // small icon is be displayed next to the button |text|, indicating that the
     42   // button opens a drop down menu.
     43   PermissionMenuButton(const base::string16& text,
     44                        PermissionMenuModel* model,
     45                        bool show_menu_marker);
     46   virtual ~PermissionMenuButton();
     47 
     48   // Overridden from views::LabelButton.
     49   virtual void SetText(const base::string16& text) OVERRIDE;
     50 
     51   // Overridden from views::View.
     52   virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
     53   virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) OVERRIDE;
     54 
     55  private:
     56   // Overridden from views::MenuButtonListener.
     57   virtual void OnMenuButtonClicked(View* source,
     58                                    const gfx::Point& point) OVERRIDE;
     59 
     60   PermissionMenuModel* menu_model_;  // Owned by |PermissionSelectorView|.
     61   scoped_ptr<views::MenuRunner> menu_runner_;
     62 
     63   DISALLOW_COPY_AND_ASSIGN(PermissionMenuButton);
     64 };
     65 
     66 ///////////////////////////////////////////////////////////////////////////////
     67 // PermissionMenuButton
     68 ///////////////////////////////////////////////////////////////////////////////
     69 
     70 PermissionMenuButton::PermissionMenuButton(const base::string16& text,
     71                                            PermissionMenuModel* model,
     72                                            bool show_menu_marker)
     73     : MenuButton(NULL, text, this, show_menu_marker),
     74       menu_model_(model) {
     75 }
     76 
     77 PermissionMenuButton::~PermissionMenuButton() {
     78 }
     79 
     80 void PermissionMenuButton::SetText(const base::string16& text) {
     81   MenuButton::SetText(text);
     82   SizeToPreferredSize();
     83 }
     84 
     85 void PermissionMenuButton::GetAccessibleState(ui::AXViewState* state) {
     86   MenuButton::GetAccessibleState(state);
     87   state->value = GetText();
     88 }
     89 
     90 void PermissionMenuButton::OnNativeThemeChanged(const ui::NativeTheme* theme) {
     91   SetTextColor(views::Button::STATE_NORMAL, GetNativeTheme()->GetSystemColor(
     92       ui::NativeTheme::kColorId_LabelEnabledColor));
     93   SetTextColor(views::Button::STATE_HOVERED, GetNativeTheme()->GetSystemColor(
     94       ui::NativeTheme::kColorId_LabelEnabledColor));
     95   SetTextColor(views::Button::STATE_DISABLED, GetNativeTheme()->GetSystemColor(
     96       ui::NativeTheme::kColorId_LabelDisabledColor));
     97 }
     98 
     99 void PermissionMenuButton::OnMenuButtonClicked(View* source,
    100                                                const gfx::Point& point) {
    101   menu_runner_.reset(
    102       new views::MenuRunner(menu_model_, views::MenuRunner::HAS_MNEMONICS));
    103 
    104   gfx::Point p(point);
    105   p.Offset(-source->width(), 0);
    106   if (menu_runner_->RunMenuAt(source->GetWidget()->GetTopLevelWidget(),
    107                               this,
    108                               gfx::Rect(p, gfx::Size()),
    109                               views::MENU_ANCHOR_TOPLEFT,
    110                               ui::MENU_SOURCE_NONE) ==
    111       views::MenuRunner::MENU_DELETED) {
    112     return;
    113   }
    114 }
    115 
    116 }  // namespace internal
    117 
    118 ///////////////////////////////////////////////////////////////////////////////
    119 // PermissionSelectorView
    120 ///////////////////////////////////////////////////////////////////////////////
    121 
    122 PermissionSelectorView::PermissionSelectorView(
    123     const GURL& url,
    124     const WebsiteSettingsUI::PermissionInfo& permission)
    125     : icon_(NULL), menu_button_(NULL) {
    126   views::GridLayout* layout = new views::GridLayout(this);
    127   SetLayoutManager(layout);
    128   const int column_set_id = 0;
    129   views::ColumnSet* column_set = layout->AddColumnSet(column_set_id);
    130   column_set->AddColumn(views::GridLayout::FILL,
    131                         views::GridLayout::FILL,
    132                         1,
    133                         views::GridLayout::FIXED,
    134                         kPermissionIconColumnWidth,
    135                         0);
    136   column_set->AddPaddingColumn(0, kPermissionIconMarginLeft);
    137   column_set->AddColumn(views::GridLayout::FILL,
    138                         views::GridLayout::FILL,
    139                         1,
    140                         views::GridLayout::USE_PREF,
    141                         0,
    142                         0);
    143   column_set->AddColumn(views::GridLayout::FILL,
    144                         views::GridLayout::FILL,
    145                         1,
    146                         views::GridLayout::USE_PREF,
    147                         0,
    148                         0);
    149 
    150   layout->StartRow(1, column_set_id);
    151   // Create the permission icon.
    152   icon_ = new views::ImageView();
    153   const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(permission);
    154   icon_->SetImage(image.ToImageSkia());
    155   layout->AddView(icon_,
    156                   1,
    157                   1,
    158                   views::GridLayout::CENTER,
    159                   views::GridLayout::CENTER);
    160   // Create the label that displays the permission type.
    161   views::Label* label = new views::Label(l10n_util::GetStringFUTF16(
    162       IDS_WEBSITE_SETTINGS_PERMISSION_TYPE,
    163       WebsiteSettingsUI::PermissionTypeToUIString(permission.type)));
    164   layout->AddView(label,
    165                   1,
    166                   1,
    167                   views::GridLayout::LEADING,
    168                   views::GridLayout::CENTER);
    169   // Create the menu model.
    170   menu_model_.reset(new PermissionMenuModel(
    171       url,
    172       permission,
    173       base::Bind(&PermissionSelectorView::PermissionChanged,
    174                  base::Unretained(this))));
    175   // Create the permission menu button.
    176   bool button_enabled =
    177       permission.source == content_settings::SETTING_SOURCE_USER;
    178   menu_button_ = new internal::PermissionMenuButton(
    179       WebsiteSettingsUI::PermissionActionToUIString(
    180           permission.setting, permission.default_setting, permission.source),
    181       menu_model_.get(),
    182       button_enabled);
    183   menu_button_->SetEnabled(button_enabled);
    184   menu_button_->SetFocusable(button_enabled);
    185   menu_button_->SetAccessibleName(
    186       WebsiteSettingsUI::PermissionTypeToUIString(permission.type));
    187   layout->AddView(menu_button_);
    188 }
    189 
    190 void PermissionSelectorView::AddObserver(
    191     PermissionSelectorViewObserver* observer) {
    192   observer_list_.AddObserver(observer);
    193 }
    194 
    195 void PermissionSelectorView::ChildPreferredSizeChanged(View* child) {
    196   SizeToPreferredSize();
    197   // FIXME: The parent is only a plain |View| that is used as a
    198   // container/box/panel. The SizeToPreferredSize method of the parent is
    199   // called here directly in order not to implement a custom |View| class with
    200   // its own implementation of the ChildPreferredSizeChanged method.
    201   parent()->SizeToPreferredSize();
    202 }
    203 
    204 PermissionSelectorView::~PermissionSelectorView() {
    205 }
    206 
    207 void PermissionSelectorView::PermissionChanged(
    208     const WebsiteSettingsUI::PermissionInfo& permission) {
    209   // Change the permission icon to reflect the selected setting.
    210   const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(permission);
    211   icon_->SetImage(image.ToImageSkia());
    212 
    213   // Update the menu button text to reflect the new setting.
    214   menu_button_->SetText(WebsiteSettingsUI::PermissionActionToUIString(
    215       permission.setting,
    216       permission.default_setting,
    217       content_settings::SETTING_SOURCE_USER));
    218 
    219   FOR_EACH_OBSERVER(PermissionSelectorViewObserver,
    220                     observer_list_,
    221                     OnPermissionChanged(permission));
    222 }
    223