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/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"
25 const int kPermissionIconMarginLeft
= 6;
26 // The width of the column that contains the permissions icons.
27 const int kPermissionIconColumnWidth
= 20;
33 // The |PermissionMenuButton| provides a menu for selecting a setting a
35 class PermissionMenuButton
: public views::MenuButton
,
36 public views::MenuButtonListener
{
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();
48 // Overridden from views::LabelButton.
49 virtual void SetText(const base::string16
& text
) override
;
51 // Overridden from views::View.
52 virtual void GetAccessibleState(ui::AXViewState
* state
) override
;
53 virtual void OnNativeThemeChanged(const ui::NativeTheme
* theme
) override
;
56 // Overridden from views::MenuButtonListener.
57 virtual void OnMenuButtonClicked(View
* source
,
58 const gfx::Point
& point
) override
;
60 PermissionMenuModel
* menu_model_
; // Owned by |PermissionSelectorView|.
61 scoped_ptr
<views::MenuRunner
> menu_runner_
;
63 DISALLOW_COPY_AND_ASSIGN(PermissionMenuButton
);
66 ///////////////////////////////////////////////////////////////////////////////
67 // PermissionMenuButton
68 ///////////////////////////////////////////////////////////////////////////////
70 PermissionMenuButton::PermissionMenuButton(const base::string16
& text
,
71 PermissionMenuModel
* model
,
72 bool show_menu_marker
)
73 : MenuButton(NULL
, text
, this, show_menu_marker
),
77 PermissionMenuButton::~PermissionMenuButton() {
80 void PermissionMenuButton::SetText(const base::string16
& text
) {
81 MenuButton::SetText(text
);
82 SizeToPreferredSize();
85 void PermissionMenuButton::GetAccessibleState(ui::AXViewState
* state
) {
86 MenuButton::GetAccessibleState(state
);
87 state
->value
= GetText();
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
));
99 void PermissionMenuButton::OnMenuButtonClicked(View
* source
,
100 const gfx::Point
& point
) {
102 new views::MenuRunner(menu_model_
, views::MenuRunner::HAS_MNEMONICS
));
105 p
.Offset(-source
->width(), 0);
106 if (menu_runner_
->RunMenuAt(source
->GetWidget()->GetTopLevelWidget(),
108 gfx::Rect(p
, gfx::Size()),
109 views::MENU_ANCHOR_TOPLEFT
,
110 ui::MENU_SOURCE_NONE
) ==
111 views::MenuRunner::MENU_DELETED
) {
116 } // namespace internal
118 ///////////////////////////////////////////////////////////////////////////////
119 // PermissionSelectorView
120 ///////////////////////////////////////////////////////////////////////////////
122 PermissionSelectorView::PermissionSelectorView(
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
,
133 views::GridLayout::FIXED
,
134 kPermissionIconColumnWidth
,
136 column_set
->AddPaddingColumn(0, kPermissionIconMarginLeft
);
137 column_set
->AddColumn(views::GridLayout::FILL
,
138 views::GridLayout::FILL
,
140 views::GridLayout::USE_PREF
,
143 column_set
->AddColumn(views::GridLayout::FILL
,
144 views::GridLayout::FILL
,
146 views::GridLayout::USE_PREF
,
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_
,
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
,
167 views::GridLayout::LEADING
,
168 views::GridLayout::CENTER
);
169 // Create the menu model.
170 menu_model_
.reset(new PermissionMenuModel(
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
),
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_
);
190 void PermissionSelectorView::AddObserver(
191 PermissionSelectorViewObserver
* observer
) {
192 observer_list_
.AddObserver(observer
);
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();
204 PermissionSelectorView::~PermissionSelectorView() {
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());
213 // Update the menu button text to reflect the new setting.
214 menu_button_
->SetText(WebsiteSettingsUI::PermissionActionToUIString(
216 permission
.default_setting
,
217 content_settings::SETTING_SOURCE_USER
));
219 FOR_EACH_OBSERVER(PermissionSelectorViewObserver
,
221 OnPermissionChanged(permission
));