- add sources.
[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/website_settings_ui.h"
9 #include "grit/generated_resources.h"
10 #include "ui/base/accessibility/accessible_view_state.h"
11 #include "ui/base/l10n/l10n_util.h"
12 #include "ui/base/models/simple_menu_model.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 ContentSetting CommandIdToContentSetting(int command_id) {
30   switch (command_id) {
31     case PermissionMenuModel::COMMAND_SET_TO_DEFAULT:
32       return CONTENT_SETTING_DEFAULT;
33     case PermissionMenuModel::COMMAND_SET_TO_ALLOW:
34       return CONTENT_SETTING_ALLOW;
35     case PermissionMenuModel::COMMAND_SET_TO_BLOCK:
36       return CONTENT_SETTING_BLOCK;
37     default:
38       NOTREACHED();
39       return CONTENT_SETTING_DEFAULT;
40   }
41 }
42
43 }  // namespace
44
45 namespace internal {
46
47 // The |PermissionMenuButton| provides a menu for selecting a setting a
48 // permissions type.
49 class PermissionMenuButton : public views::MenuButton,
50                              public views::MenuButtonListener {
51  public:
52   // Creates a new |PermissionMenuButton| with the passed |text|. The ownership
53   // of the |model| remains with the caller and is not transfered to the
54   // |PermissionMenuButton|. If the |show_menu_marker| flag is true, then a
55   // small icon is be displayed next to the button |text|, indicating that the
56   // button opens a drop down menu.
57   PermissionMenuButton(const string16& text,
58                        PermissionMenuModel* model,
59                        bool show_menu_marker);
60   virtual ~PermissionMenuButton();
61
62   // Overridden from views::MenuButton.
63   virtual gfx::Size GetPreferredSize() OVERRIDE;
64
65   // Overridden from views::TextButton.
66   virtual void SetText(const string16& text) OVERRIDE;
67
68   // Overridden from views::View.
69   virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
70
71  private:
72   // Overridden from views::MenuButtonListener.
73   virtual void OnMenuButtonClicked(View* source,
74                                    const gfx::Point& point) OVERRIDE;
75
76   PermissionMenuModel* menu_model_;  // Owned by |PermissionSelectorView|.
77   scoped_ptr<views::MenuRunner> menu_runner_;
78
79   DISALLOW_COPY_AND_ASSIGN(PermissionMenuButton);
80 };
81
82 ///////////////////////////////////////////////////////////////////////////////
83 // PermissionMenuButton
84 ///////////////////////////////////////////////////////////////////////////////
85
86 PermissionMenuButton::PermissionMenuButton(const string16& text,
87                                            PermissionMenuModel* model,
88                                            bool show_menu_marker)
89     : MenuButton(NULL, text, this, show_menu_marker),
90       menu_model_(model) {
91   SetEnabledColor(GetNativeTheme()->GetSystemColor(
92       ui::NativeTheme::kColorId_LabelEnabledColor));
93   SetHoverColor(GetNativeTheme()->GetSystemColor(
94       ui::NativeTheme::kColorId_LabelEnabledColor));
95   SetDisabledColor(GetNativeTheme()->GetSystemColor(
96       ui::NativeTheme::kColorId_LabelDisabledColor));
97 }
98
99 PermissionMenuButton::~PermissionMenuButton() {
100 }
101
102 gfx::Size PermissionMenuButton::GetPreferredSize() {
103   gfx::Insets insets = GetInsets();
104   // Scale the button to the current text size.
105   gfx::Size prefsize(text_size_.width() + insets.width(),
106                      text_size_.height() + insets.height());
107   if (max_width_ > 0)
108     prefsize.set_width(std::min(max_width_, prefsize.width()));
109   if (show_menu_marker()) {
110     prefsize.Enlarge(menu_marker()->width() +
111                          views::MenuButton::kMenuMarkerPaddingLeft +
112                          views::MenuButton::kMenuMarkerPaddingRight,
113                      0);
114   }
115   return prefsize;
116 }
117
118 void PermissionMenuButton::SetText(const string16& text) {
119   MenuButton::SetText(text);
120   SizeToPreferredSize();
121 }
122
123 void PermissionMenuButton::GetAccessibleState(ui::AccessibleViewState* state) {
124   MenuButton::GetAccessibleState(state);
125   state->value = text();
126 }
127
128 void PermissionMenuButton::OnMenuButtonClicked(View* source,
129                                                const gfx::Point& point) {
130   menu_runner_.reset(new views::MenuRunner(menu_model_));
131
132   gfx::Point p(point);
133   p.Offset(-source->width(), 0);
134   if (menu_runner_->RunMenuAt(
135           source->GetWidget()->GetTopLevelWidget(),
136           this,
137           gfx::Rect(p, gfx::Size()),
138           views::MenuItemView::TOPLEFT,
139           ui::MENU_SOURCE_NONE,
140           views::MenuRunner::HAS_MNEMONICS) == views::MenuRunner::MENU_DELETED)
141     return;
142 }
143
144 }  // namespace internal
145
146 ///////////////////////////////////////////////////////////////////////////////
147 // PermissionSelectorView
148 ///////////////////////////////////////////////////////////////////////////////
149
150 PermissionSelectorView::PermissionSelectorView(
151     const GURL& url,
152     ContentSettingsType type,
153     ContentSetting default_setting,
154     ContentSetting current_setting,
155     content_settings::SettingSource source)
156     : icon_(NULL),
157       menu_button_(NULL),
158       type_(type),
159       default_setting_(default_setting),
160       current_setting_(current_setting) {
161   views::GridLayout* layout = new views::GridLayout(this);
162   SetLayoutManager(layout);
163   const int column_set_id = 0;
164   views::ColumnSet* column_set = layout->AddColumnSet(column_set_id);
165   column_set->AddColumn(views::GridLayout::FILL,
166                         views::GridLayout::FILL,
167                         1,
168                         views::GridLayout::FIXED,
169                         kPermissionIconColumnWidth,
170                         0);
171   column_set->AddPaddingColumn(0, kPermissionIconMarginLeft);
172   column_set->AddColumn(views::GridLayout::FILL,
173                         views::GridLayout::FILL,
174                         1,
175                         views::GridLayout::USE_PREF,
176                         0,
177                         0);
178   column_set->AddColumn(views::GridLayout::FILL,
179                         views::GridLayout::FILL,
180                         1,
181                         views::GridLayout::USE_PREF,
182                         0,
183                         0);
184
185   layout->StartRow(1, column_set_id);
186   // Create the permission icon.
187   icon_ = new views::ImageView();
188   ContentSetting setting = current_setting;
189   if (setting == CONTENT_SETTING_DEFAULT)
190     setting = default_setting;
191   const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(type, setting);
192   icon_->SetImage(image.ToImageSkia());
193   layout->AddView(icon_,
194                   1,
195                   1,
196                   views::GridLayout::CENTER,
197                   views::GridLayout::CENTER);
198   // Create the label that displays the permission type.
199   views::Label* label = new views::Label(
200       l10n_util::GetStringFUTF16(
201           IDS_WEBSITE_SETTINGS_PERMISSION_TYPE,
202           WebsiteSettingsUI::PermissionTypeToUIString(type)));
203   layout->AddView(label,
204                   1,
205                   1,
206                   views::GridLayout::LEADING,
207                   views::GridLayout::CENTER);
208   // Create the permission menu button.
209   menu_button_model_.reset(new PermissionMenuModel(
210       this, url, type, default_setting, current_setting));
211   bool button_enabled = source == content_settings::SETTING_SOURCE_USER;
212   menu_button_ = new internal::PermissionMenuButton(
213       WebsiteSettingsUI::PermissionActionToUIString(current_setting,
214                                                     default_setting,
215                                                     source),
216       menu_button_model_.get(),
217       button_enabled);
218   menu_button_->SetEnabled(button_enabled);
219   menu_button_->set_focusable(button_enabled);
220   menu_button_->SetAccessibleName(
221       WebsiteSettingsUI::PermissionTypeToUIString(type));
222   layout->AddView(menu_button_);
223 }
224
225 void PermissionSelectorView::AddObserver(
226     PermissionSelectorViewObserver* observer) {
227   observer_list_.AddObserver(observer);
228 }
229
230 void PermissionSelectorView::ChildPreferredSizeChanged(View* child) {
231   SizeToPreferredSize();
232   // FIXME: The parent is only a plain |View| that is used as a
233   // container/box/panel. The SizeToPreferredSize method of the parent is
234   // called here directly in order not to implement a custom |View| class with
235   // its own implementation of the ChildPreferredSizeChanged method.
236   parent()->SizeToPreferredSize();
237 }
238
239 PermissionSelectorView::~PermissionSelectorView() {
240 }
241
242 void PermissionSelectorView::ExecuteCommand(int command_id) {
243   current_setting_ = CommandIdToContentSetting(command_id);
244
245   // Change the permission icon to reflect the selected setting.
246   ContentSetting effective_setting = current_setting_;
247   if (effective_setting == CONTENT_SETTING_DEFAULT)
248     effective_setting = default_setting_;
249   const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(
250       type_, effective_setting);
251   icon_->SetImage(image.ToImageSkia());
252
253   // Update the menu button text to reflect the new setting.
254   menu_button_->SetText(WebsiteSettingsUI::PermissionActionToUIString(
255       current_setting_,
256       default_setting_,
257       content_settings::SETTING_SOURCE_USER));
258
259   FOR_EACH_OBSERVER(PermissionSelectorViewObserver,
260                     observer_list_,
261                     OnPermissionChanged(this));
262 }
263
264 bool PermissionSelectorView::IsCommandIdChecked(int command_id) {
265   return current_setting_ == CommandIdToContentSetting(command_id);
266 }