OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/website_settings/permission_selector_row.h" | 5 #include "chrome/browser/ui/views/website_settings/permission_selector_row.h" |
6 | 6 |
7 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
8 #include "base/macros.h" | 8 #include "base/macros.h" |
9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
10 #include "chrome/browser/ui/views/website_settings/non_accessible_image_view.h" | 10 #include "chrome/browser/ui/views/website_settings/non_accessible_image_view.h" |
11 #include "chrome/browser/ui/views/website_settings/website_settings_popup_view.h " | 11 #include "chrome/browser/ui/views/website_settings/website_settings_popup_view.h " |
12 #include "chrome/browser/ui/website_settings/permission_menu_model.h" | 12 #include "chrome/browser/ui/website_settings/permission_menu_model.h" |
13 #include "chrome/browser/ui/website_settings/website_settings_ui.h" | 13 #include "chrome/browser/ui/website_settings/website_settings_ui.h" |
14 #include "chrome/grit/generated_resources.h" | 14 #include "chrome/grit/generated_resources.h" |
15 #include "ui/accessibility/ax_node_data.h" | 15 #include "ui/accessibility/ax_node_data.h" |
16 #include "ui/base/material_design/material_design_controller.h" | 16 #include "ui/base/material_design/material_design_controller.h" |
17 #include "ui/base/models/combobox_model.h" | 17 #include "ui/base/models/combobox_model.h" |
18 #include "ui/gfx/image/image.h" | 18 #include "ui/gfx/image/image.h" |
19 #include "ui/views/controls/button/menu_button.h" | 19 #include "ui/views/controls/button/menu_button.h" |
20 #include "ui/views/controls/combobox/combobox.h" | 20 #include "ui/views/controls/combobox/combobox.h" |
21 #include "ui/views/controls/combobox/combobox_listener.h" | 21 #include "ui/views/controls/combobox/combobox_listener.h" |
22 #include "ui/views/controls/image_view.h" | 22 #include "ui/views/controls/image_view.h" |
23 #include "ui/views/controls/label.h" | 23 #include "ui/views/controls/label.h" |
24 #include "ui/views/controls/menu/menu_runner.h" | 24 #include "ui/views/controls/menu/menu_runner.h" |
25 #include "ui/views/layout/grid_layout.h" | 25 #include "ui/views/layout/grid_layout.h" |
26 #include "ui/views/view.h" | 26 #include "ui/views/view.h" |
27 #include "ui/views/widget/widget.h" | 27 #include "ui/views/widget/widget.h" |
28 | 28 |
29 namespace { | |
30 // Minimum distance between the label and its corresponding menu. | |
31 const int kMinSeparationBetweenLabelAndMenu = 16; | |
32 } // namespace | |
33 | |
34 namespace internal { | 29 namespace internal { |
35 | 30 |
36 // The |PermissionMenuButton| provides a menu for selecting a setting a | 31 // The |PermissionMenuButton| provides a menu for selecting a setting a |
37 // permissions type. | 32 // permissions type. |
38 class PermissionMenuButton : public views::MenuButton, | 33 class PermissionMenuButton : public views::MenuButton, |
39 public views::MenuButtonListener { | 34 public views::MenuButtonListener { |
40 public: | 35 public: |
41 // Creates a new |PermissionMenuButton| with the passed |text|. The ownership | 36 // Creates a new |PermissionMenuButton| with the passed |text|. The ownership |
42 // of the |model| remains with the caller and is not transfered to the | 37 // of the |model| remains with the caller and is not transfered to the |
43 // |PermissionMenuButton|. If the |show_menu_marker| flag is true, then a | 38 // |PermissionMenuButton|. If the |show_menu_marker| flag is true, then a |
(...skipping 23 matching lines...) Expand all Loading... | |
67 }; | 62 }; |
68 | 63 |
69 /////////////////////////////////////////////////////////////////////////////// | 64 /////////////////////////////////////////////////////////////////////////////// |
70 // PermissionMenuButton | 65 // PermissionMenuButton |
71 /////////////////////////////////////////////////////////////////////////////// | 66 /////////////////////////////////////////////////////////////////////////////// |
72 | 67 |
73 PermissionMenuButton::PermissionMenuButton(const base::string16& text, | 68 PermissionMenuButton::PermissionMenuButton(const base::string16& text, |
74 PermissionMenuModel* model, | 69 PermissionMenuModel* model, |
75 bool show_menu_marker) | 70 bool show_menu_marker) |
76 : MenuButton(text, this, show_menu_marker), menu_model_(model) { | 71 : MenuButton(text, this, show_menu_marker), menu_model_(model) { |
72 // Since PermissionMenuButtons are added to a GridLayout, they are not always | |
73 // sized to their preferred size. Disclosure arrows are always right-aligned, | |
74 // so if the text is not right-aligned, awkward space appears between the text | |
75 // and the arrow. | |
76 SetHorizontalAlignment(gfx::ALIGN_RIGHT); | |
77 | |
77 // Update the themed border before the NativeTheme is applied. Usually this | 78 // Update the themed border before the NativeTheme is applied. Usually this |
78 // happens in a call to LabelButton::OnNativeThemeChanged(). However, if | 79 // happens in a call to LabelButton::OnNativeThemeChanged(). However, if |
79 // PermissionMenuButton called that from its override, the NativeTheme would | 80 // PermissionMenuButton called that from its override, the NativeTheme would |
80 // be available, and the button would get native GTK styling on Linux. | 81 // be available, and the button would get native GTK styling on Linux. |
81 UpdateThemedBorder(); | 82 UpdateThemedBorder(); |
82 | 83 |
83 SetFocusForPlatform(); | 84 SetFocusForPlatform(); |
84 set_request_focus_on_press(true); | 85 set_request_focus_on_press(true); |
85 is_rtl_display_ = | 86 is_rtl_display_ = |
86 base::i18n::RIGHT_TO_LEFT == base::i18n::GetStringDirection(text); | 87 base::i18n::RIGHT_TO_LEFT == base::i18n::GetStringDirection(text); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
225 | 226 |
226 } // namespace internal | 227 } // namespace internal |
227 | 228 |
228 /////////////////////////////////////////////////////////////////////////////// | 229 /////////////////////////////////////////////////////////////////////////////// |
229 // PermissionSelectorRow | 230 // PermissionSelectorRow |
230 /////////////////////////////////////////////////////////////////////////////// | 231 /////////////////////////////////////////////////////////////////////////////// |
231 | 232 |
232 PermissionSelectorRow::PermissionSelectorRow( | 233 PermissionSelectorRow::PermissionSelectorRow( |
233 Profile* profile, | 234 Profile* profile, |
234 const GURL& url, | 235 const GURL& url, |
235 const WebsiteSettingsUI::PermissionInfo& permission) | 236 const WebsiteSettingsUI::PermissionInfo& permission, |
237 views::GridLayout* layout) | |
236 : profile_(profile), icon_(NULL), menu_button_(NULL), combobox_(NULL) { | 238 : profile_(profile), icon_(NULL), menu_button_(NULL), combobox_(NULL) { |
237 views::GridLayout* layout = new views::GridLayout(this); | |
238 SetLayoutManager(layout); | |
239 const int column_set_id = 0; | |
240 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); | |
241 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0, | |
242 views::GridLayout::FIXED, kPermissionIconColumnWidth, | |
243 0); | |
244 column_set->AddPaddingColumn(0, kPermissionIconMarginLeft); | |
245 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0, | |
246 views::GridLayout::USE_PREF, 0, 0); | |
247 column_set->AddPaddingColumn(1, kMinSeparationBetweenLabelAndMenu); | |
248 column_set->AddColumn(views::GridLayout::TRAILING, views::GridLayout::FILL, 0, | |
249 views::GridLayout::USE_PREF, 0, 0); | |
250 | |
251 layout->StartRow(1, column_set_id); | |
252 // Create the permission icon. | 239 // Create the permission icon. |
253 icon_ = new NonAccessibleImageView(); | 240 icon_ = new NonAccessibleImageView(); |
254 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(permission); | 241 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(permission); |
255 icon_->SetImage(image.ToImageSkia()); | 242 icon_->SetImage(image.ToImageSkia()); |
256 layout->AddView(icon_, | 243 layout->AddView(icon_, 1, 1, views::GridLayout::CENTER, |
257 1, | |
258 1, | |
259 views::GridLayout::CENTER, | |
260 views::GridLayout::CENTER); | 244 views::GridLayout::CENTER); |
261 // Create the label that displays the permission type. | 245 // Create the label that displays the permission type. |
262 views::Label* label = new views::Label( | 246 label_ = new views::Label( |
263 WebsiteSettingsUI::PermissionTypeToUIString(permission.type)); | 247 WebsiteSettingsUI::PermissionTypeToUIString(permission.type)); |
264 layout->AddView(label, | 248 layout->AddView(label_, 1, 1, views::GridLayout::LEADING, |
265 1, | |
266 1, | |
267 views::GridLayout::LEADING, | |
268 views::GridLayout::CENTER); | 249 views::GridLayout::CENTER); |
269 // Create the menu model. | 250 // Create the menu model. |
270 menu_model_.reset(new PermissionMenuModel( | 251 menu_model_.reset(new PermissionMenuModel( |
271 profile, url, permission, | 252 profile, url, permission, |
272 base::Bind(&PermissionSelectorRow::PermissionChanged, | 253 base::Bind(&PermissionSelectorRow::PermissionChanged, |
273 base::Unretained(this)))); | 254 base::Unretained(this)))); |
274 | 255 |
275 // Create the permission menu button. | 256 // Create the permission menu button. |
276 #if defined(OS_MACOSX) | 257 #if defined(OS_MACOSX) |
277 bool use_real_combobox = true; | 258 bool use_real_combobox = true; |
278 #else | 259 #else |
279 bool use_real_combobox = | 260 bool use_real_combobox = |
280 ui::MaterialDesignController::IsSecondaryUiMaterial(); | 261 ui::MaterialDesignController::IsSecondaryUiMaterial(); |
281 #endif | 262 #endif |
282 if (use_real_combobox) | 263 if (use_real_combobox) |
283 InitializeComboboxView(layout, permission); | 264 InitializeComboboxView(layout, permission); |
284 else | 265 else |
285 InitializeMenuButtonView(layout, permission); | 266 InitializeMenuButtonView(layout, permission); |
286 } | 267 } |
287 | 268 |
288 void PermissionSelectorRow::AddObserver( | 269 void PermissionSelectorRow::AddObserver( |
289 PermissionSelectorRowObserver* observer) { | 270 PermissionSelectorRowObserver* observer) { |
290 observer_list_.AddObserver(observer); | 271 observer_list_.AddObserver(observer); |
291 } | 272 } |
292 | 273 |
293 void PermissionSelectorRow::ChildPreferredSizeChanged(View* child) { | |
294 Layout(); | |
295 } | |
296 | |
297 PermissionSelectorRow::~PermissionSelectorRow() { | 274 PermissionSelectorRow::~PermissionSelectorRow() { |
298 // Gross. On paper the Combobox and the ComboboxModelAdapter are both owned by | 275 // Gross. On paper the Combobox and the ComboboxModelAdapter are both owned by |
299 // this class, but actually, the Combobox is owned by View and will be | 276 // this class, but actually, the Combobox is owned by View and will be |
300 // destroyed in ~View(), which runs *after* ~PermissionSelectorRow() is done, | 277 // destroyed in ~View(), which runs *after* ~PermissionSelectorRow() is done, |
301 // which means the Combobox gets destroyed after its ComboboxModel, which | 278 // which means the Combobox gets destroyed after its ComboboxModel, which |
302 // causes an explosion when the Combobox attempts to stop observing the | 279 // causes an explosion when the Combobox attempts to stop observing the |
303 // ComboboxModel. This hack ensures the Combobox is deleted before its | 280 // ComboboxModel. This hack ensures the Combobox is deleted before its |
304 // ComboboxModel. | 281 // ComboboxModel. |
305 // | 282 // |
306 // Technically, the MenuButton has the same problem, but MenuButton doesn't | 283 // Technically, the MenuButton has the same problem, but MenuButton doesn't |
307 // use its model in its destructor. | 284 // use its model in its destructor. |
308 if (combobox_) | 285 if (combobox_) |
309 RemoveChildView(combobox_); | 286 combobox_->parent()->RemoveChildView(combobox_); |
310 } | 287 } |
311 | 288 |
312 void PermissionSelectorRow::InitializeMenuButtonView( | 289 void PermissionSelectorRow::InitializeMenuButtonView( |
313 views::GridLayout* layout, | 290 views::GridLayout* layout, |
314 const WebsiteSettingsUI::PermissionInfo& permission) { | 291 const WebsiteSettingsUI::PermissionInfo& permission) { |
315 bool button_enabled = | 292 bool button_enabled = |
316 permission.source == content_settings::SETTING_SOURCE_USER; | 293 permission.source == content_settings::SETTING_SOURCE_USER; |
317 menu_button_ = new internal::PermissionMenuButton( | 294 menu_button_ = new internal::PermissionMenuButton( |
318 WebsiteSettingsUI::PermissionActionToUIString( | 295 WebsiteSettingsUI::PermissionActionToUIString( |
319 profile_, permission.type, permission.setting, | 296 profile_, permission.type, permission.setting, |
(...skipping 25 matching lines...) Expand all Loading... | |
345 // Change the permission icon to reflect the selected setting. | 322 // Change the permission icon to reflect the selected setting. |
346 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(permission); | 323 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(permission); |
347 icon_->SetImage(image.ToImageSkia()); | 324 icon_->SetImage(image.ToImageSkia()); |
348 | 325 |
349 // Update the menu button text to reflect the new setting. | 326 // Update the menu button text to reflect the new setting. |
350 if (menu_button_) { | 327 if (menu_button_) { |
351 menu_button_->SetText(WebsiteSettingsUI::PermissionActionToUIString( | 328 menu_button_->SetText(WebsiteSettingsUI::PermissionActionToUIString( |
352 profile_, permission.type, permission.setting, | 329 profile_, permission.type, permission.setting, |
353 permission.default_setting, content_settings::SETTING_SOURCE_USER)); | 330 permission.default_setting, content_settings::SETTING_SOURCE_USER)); |
354 menu_button_->SizeToPreferredSize(); | 331 menu_button_->SizeToPreferredSize(); |
332 // Re-layout will be done at the |WebsiteSettingsPopupView| level, since | |
333 // that view may need to resize itself to accomodate the new sizes of its | |
334 // contents. | |
335 menu_button_->InvalidateLayout(); | |
355 } else if (combobox_) { | 336 } else if (combobox_) { |
356 bool use_default = permission.setting == CONTENT_SETTING_DEFAULT; | 337 bool use_default = permission.setting == CONTENT_SETTING_DEFAULT; |
357 combobox_->UpdateSelectedIndex(use_default); | 338 combobox_->UpdateSelectedIndex(use_default); |
358 } | 339 } |
359 | 340 |
360 for (PermissionSelectorRowObserver& observer : observer_list_) | 341 for (PermissionSelectorRowObserver& observer : observer_list_) |
361 observer.OnPermissionChanged(permission); | 342 observer.OnPermissionChanged(permission); |
362 } | 343 } |
344 | |
345 views::View* PermissionSelectorRow::button() { | |
346 return menu_button_ ? static_cast<views::View*>(menu_button_) | |
sky
2017/03/07 22:03:40
I'm surprised you need a cast here.
Elly Fong-Jones
2017/03/08 18:41:09
You can't have different types on the arms of a ?:
| |
347 : static_cast<views::View*>(combobox_); | |
348 } | |
OLD | NEW |