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