Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / website_settings / permission_selector_view.cc
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 }