permission_selector_view.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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 "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 22namespace { 23 24// Left icon margin. 25const int kPermissionIconMarginLeft = 6; 26// The width of the column that contains the permissions icons. 27const int kPermissionIconColumnWidth = 20; 28 29} // namespace 30 31namespace internal { 32 33// The |PermissionMenuButton| provides a menu for selecting a setting a 34// permissions type. 35class 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::MenuButton. 49 virtual gfx::Size GetPreferredSize() const OVERRIDE; 50 51 // Overridden from views::TextButton. 52 virtual void SetText(const base::string16& text) OVERRIDE; 53 54 // Overridden from views::View. 55 virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE; 56 57 private: 58 // Overridden from views::MenuButtonListener. 59 virtual void OnMenuButtonClicked(View* source, 60 const gfx::Point& point) OVERRIDE; 61 62 PermissionMenuModel* menu_model_; // Owned by |PermissionSelectorView|. 63 scoped_ptr<views::MenuRunner> menu_runner_; 64 65 DISALLOW_COPY_AND_ASSIGN(PermissionMenuButton); 66}; 67 68/////////////////////////////////////////////////////////////////////////////// 69// PermissionMenuButton 70/////////////////////////////////////////////////////////////////////////////// 71 72PermissionMenuButton::PermissionMenuButton(const base::string16& text, 73 PermissionMenuModel* model, 74 bool show_menu_marker) 75 : MenuButton(NULL, text, this, show_menu_marker), 76 menu_model_(model) { 77 SetEnabledColor(GetNativeTheme()->GetSystemColor( 78 ui::NativeTheme::kColorId_LabelEnabledColor)); 79 SetHoverColor(GetNativeTheme()->GetSystemColor( 80 ui::NativeTheme::kColorId_LabelEnabledColor)); 81 SetDisabledColor(GetNativeTheme()->GetSystemColor( 82 ui::NativeTheme::kColorId_LabelDisabledColor)); 83} 84 85PermissionMenuButton::~PermissionMenuButton() { 86} 87 88gfx::Size PermissionMenuButton::GetPreferredSize() const { 89 gfx::Insets insets = GetInsets(); 90 // Scale the button to the current text size. 91 gfx::Size prefsize(text_size_.width() + insets.width(), 92 text_size_.height() + insets.height()); 93 if (max_width_ > 0) 94 prefsize.set_width(std::min(max_width_, prefsize.width())); 95 if (show_menu_marker()) { 96 prefsize.Enlarge(menu_marker()->width() + 97 views::MenuButton::kMenuMarkerPaddingLeft + 98 views::MenuButton::kMenuMarkerPaddingRight, 99 0); 100 } 101 return prefsize; 102} 103 104void PermissionMenuButton::SetText(const base::string16& text) { 105 MenuButton::SetText(text); 106 SizeToPreferredSize(); 107} 108 109void PermissionMenuButton::GetAccessibleState(ui::AXViewState* state) { 110 MenuButton::GetAccessibleState(state); 111 state->value = text(); 112} 113 114void PermissionMenuButton::OnMenuButtonClicked(View* source, 115 const gfx::Point& point) { 116 menu_runner_.reset(new views::MenuRunner(menu_model_)); 117 118 gfx::Point p(point); 119 p.Offset(-source->width(), 0); 120 if (menu_runner_->RunMenuAt(source->GetWidget()->GetTopLevelWidget(), 121 this, 122 gfx::Rect(p, gfx::Size()), 123 views::MENU_ANCHOR_TOPLEFT, 124 ui::MENU_SOURCE_NONE, 125 views::MenuRunner::HAS_MNEMONICS) == 126 views::MenuRunner::MENU_DELETED) { 127 return; 128 } 129} 130 131} // namespace internal 132 133/////////////////////////////////////////////////////////////////////////////// 134// PermissionSelectorView 135/////////////////////////////////////////////////////////////////////////////// 136 137PermissionSelectorView::PermissionSelectorView( 138 const GURL& url, 139 const WebsiteSettingsUI::PermissionInfo& permission) 140 : icon_(NULL), menu_button_(NULL) { 141 views::GridLayout* layout = new views::GridLayout(this); 142 SetLayoutManager(layout); 143 const int column_set_id = 0; 144 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); 145 column_set->AddColumn(views::GridLayout::FILL, 146 views::GridLayout::FILL, 147 1, 148 views::GridLayout::FIXED, 149 kPermissionIconColumnWidth, 150 0); 151 column_set->AddPaddingColumn(0, kPermissionIconMarginLeft); 152 column_set->AddColumn(views::GridLayout::FILL, 153 views::GridLayout::FILL, 154 1, 155 views::GridLayout::USE_PREF, 156 0, 157 0); 158 column_set->AddColumn(views::GridLayout::FILL, 159 views::GridLayout::FILL, 160 1, 161 views::GridLayout::USE_PREF, 162 0, 163 0); 164 165 layout->StartRow(1, column_set_id); 166 // Create the permission icon. 167 icon_ = new views::ImageView(); 168 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(permission); 169 icon_->SetImage(image.ToImageSkia()); 170 layout->AddView(icon_, 171 1, 172 1, 173 views::GridLayout::CENTER, 174 views::GridLayout::CENTER); 175 // Create the label that displays the permission type. 176 views::Label* label = new views::Label(l10n_util::GetStringFUTF16( 177 IDS_WEBSITE_SETTINGS_PERMISSION_TYPE, 178 WebsiteSettingsUI::PermissionTypeToUIString(permission.type))); 179 layout->AddView(label, 180 1, 181 1, 182 views::GridLayout::LEADING, 183 views::GridLayout::CENTER); 184 // Create the menu model. 185 menu_model_.reset(new PermissionMenuModel( 186 url, 187 permission, 188 base::Bind(&PermissionSelectorView::PermissionChanged, 189 base::Unretained(this)))); 190 // Create the permission menu button. 191 bool button_enabled = 192 permission.source == content_settings::SETTING_SOURCE_USER; 193 menu_button_ = new internal::PermissionMenuButton( 194 WebsiteSettingsUI::PermissionActionToUIString( 195 permission.setting, permission.default_setting, permission.source), 196 menu_model_.get(), 197 button_enabled); 198 menu_button_->SetEnabled(button_enabled); 199 menu_button_->SetFocusable(button_enabled); 200 menu_button_->SetAccessibleName( 201 WebsiteSettingsUI::PermissionTypeToUIString(permission.type)); 202 layout->AddView(menu_button_); 203} 204 205void PermissionSelectorView::AddObserver( 206 PermissionSelectorViewObserver* observer) { 207 observer_list_.AddObserver(observer); 208} 209 210void PermissionSelectorView::ChildPreferredSizeChanged(View* child) { 211 SizeToPreferredSize(); 212 // FIXME: The parent is only a plain |View| that is used as a 213 // container/box/panel. The SizeToPreferredSize method of the parent is 214 // called here directly in order not to implement a custom |View| class with 215 // its own implementation of the ChildPreferredSizeChanged method. 216 parent()->SizeToPreferredSize(); 217} 218 219PermissionSelectorView::~PermissionSelectorView() { 220} 221 222void PermissionSelectorView::PermissionChanged( 223 const WebsiteSettingsUI::PermissionInfo& permission) { 224 // Change the permission icon to reflect the selected setting. 225 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(permission); 226 icon_->SetImage(image.ToImageSkia()); 227 228 // Update the menu button text to reflect the new setting. 229 menu_button_->SetText(WebsiteSettingsUI::PermissionActionToUIString( 230 permission.setting, 231 permission.default_setting, 232 content_settings::SETTING_SOURCE_USER)); 233 234 FOR_EACH_OBSERVER(PermissionSelectorViewObserver, 235 observer_list_, 236 OnPermissionChanged(permission)); 237} 238