diff options
10 files changed, 119 insertions, 40 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index b7220b6..fbdba53 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -14516,6 +14516,14 @@ Please check your email at <ph name="ACCOUNT_EMAIL">$2<ex>jane.doe@gmail.com</ex <message name="IDS_CHOOSER_BUBBLE_CANCEL_BUTTON_TEXT" desc="The text that is shown on the cancel button in the chooser popup."> Cancel </message> + <!-- Chooser Bubble Footnote Text --> + <message name="IDS_CHOOSER_BUBBLE_FOOTNOTE_TEXT" desc="This text is shown at the bottom of the chooser popup with a link to part of its text."> + Not seeing your device? <ph name="GET_HELP_LINK">$1<ex>Get help</ex></ph> + </message> + <!-- Chooser Bubble Get Help Link Text --> + <message name="IDS_CHOOSER_BUBBLE_GET_HELP_LINK_TEXT" desc="Text of the 'Get help' link at the bottom of the chooser popup."> + Get help + </message> </if> <if expr="is_android"> diff --git a/chrome/browser/ui/bluetooth/bluetooth_chooser_bubble_delegate.cc b/chrome/browser/ui/bluetooth/bluetooth_chooser_bubble_delegate.cc index 7db53f2..10ad62b 100644 --- a/chrome/browser/ui/bluetooth/bluetooth_chooser_bubble_delegate.cc +++ b/chrome/browser/ui/bluetooth/bluetooth_chooser_bubble_delegate.cc @@ -6,7 +6,9 @@ #include "base/stl_util.h" #include "chrome/browser/ui/bluetooth/bluetooth_chooser_desktop.h" +#include "chrome/common/url_constants.h" #include "components/bubble/bubble_controller.h" +#include "url/gurl.h" BluetoothChooserBubbleDelegate::BluetoothChooserBubbleDelegate( content::RenderFrameHost* owner) @@ -56,6 +58,10 @@ void BluetoothChooserBubbleDelegate::Close() { } } +GURL BluetoothChooserBubbleDelegate::GetHelpCenterUrl() const { + return GURL(chrome::kChooserBluetoothOverviewURL); +} + void BluetoothChooserBubbleDelegate::AddDevice( const std::string& device_id, const base::string16& device_name) { diff --git a/chrome/browser/ui/bluetooth/bluetooth_chooser_bubble_delegate.h b/chrome/browser/ui/bluetooth/bluetooth_chooser_bubble_delegate.h index fcebd63..b0af713 100644 --- a/chrome/browser/ui/bluetooth/bluetooth_chooser_bubble_delegate.h +++ b/chrome/browser/ui/bluetooth/bluetooth_chooser_bubble_delegate.h @@ -29,6 +29,7 @@ class BluetoothChooserBubbleDelegate : public ChooserBubbleDelegate { void Select(size_t index) override; void Cancel() override; void Close() override; + GURL GetHelpCenterUrl() const override; // Shows a new device in the chooser. void AddDevice(const std::string& device_id, diff --git a/chrome/browser/ui/views/website_settings/chooser_bubble_ui_view.cc b/chrome/browser/ui/views/website_settings/chooser_bubble_ui_view.cc index 4a412c6..b69e4c9 100644 --- a/chrome/browser/ui/views/website_settings/chooser_bubble_ui_view.cc +++ b/chrome/browser/ui/views/website_settings/chooser_bubble_ui_view.cc @@ -4,8 +4,11 @@ #include "chrome/browser/ui/views/website_settings/chooser_bubble_ui_view.h" +#include <stddef.h> + #include <algorithm> #include <string> +#include <vector> #include "base/macros.h" #include "base/strings/string16.h" @@ -30,10 +33,14 @@ #include "ui/views/bubble/bubble_frame_view.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/button/label_button_border.h" +#include "ui/views/controls/separator.h" +#include "ui/views/controls/styled_label.h" +#include "ui/views/controls/styled_label_listener.h" #include "ui/views/controls/table/table_view.h" #include "ui/views/controls/table/table_view_observer.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/grid_layout.h" +#include "ui/views/layout/layout_constants.h" namespace { @@ -43,16 +50,6 @@ const int kChooserPermissionBubbleWidth = 300; // Chooser permission bubble height const int kChooserPermissionBubbleHeight = 200; -// Spacing constant for outer margin. This is added to the -// bubble margin itself to equalize the margins at 13px. -const int kBubbleOuterMargin = 5; - -// Spacing between major items should be 9px. -const int kItemMajorSpacing = 9; - -// Button border size, draws inside the spacing distance. -const int kButtonBorderSize = 2; - } // namespace scoped_ptr<BubbleUi> ChooserBubbleDelegate::BuildBubbleUi() { @@ -65,6 +62,7 @@ class ChooserTableModel; // View implementation for the chooser bubble. class ChooserBubbleUiViewDelegate : public views::BubbleDelegateView, public views::ButtonListener, + public views::StyledLabelListener, public views::TableViewObserver { public: ChooserBubbleUiViewDelegate(views::View* anchor_view, @@ -75,14 +73,19 @@ class ChooserBubbleUiViewDelegate : public views::BubbleDelegateView, void Close(); - // BubbleDelegateView: + // views::BubbleDelegateView: bool ShouldShowWindowTitle() const override; base::string16 GetWindowTitle() const override; void OnWidgetDestroying(views::Widget* widget) override; - // ButtonListener: + // views::ButtonListener: void ButtonPressed(views::Button* button, const ui::Event& event) override; + // views::StyledLabelListener: + void StyledLabelLinkClicked(views::StyledLabel* label, + const gfx::Range& range, + int event_flags) override; + // views::TableViewObserver: void OnSelectionChanged() override; @@ -98,7 +101,6 @@ class ChooserBubbleUiViewDelegate : public views::BubbleDelegateView, ChooserBubbleDelegate* chooser_bubble_delegate_; views::LabelButton* connect_button_; - views::LabelButton* cancel_button_; views::TableView* table_view_; ChooserTableModel* chooser_table_model_; bool button_pressed_; @@ -146,6 +148,24 @@ ChooserBubbleUiViewDelegate::ChooserBubbleUiViewDelegate( owner_(owner), chooser_bubble_delegate_(chooser_bubble_delegate), button_pressed_(false) { + // TODO(juncai): try using DialogClientView to build the chooser UI view since + // they look similar. + // https://crbug.com/587545 + // ------------------------------------ + // | Chooser bubble title | + // | -------------------------------- | + // | | option 0 | | + // | | option 1 | | + // | | option 2 | | + // | | | | + // | | | | + // | | | | + // | -------------------------------- | + // | [ Connect ] [ Cancel ] | + // |----------------------------------| + // | Not seeing your device? Get help | + // ------------------------------------ + views::GridLayout* layout = new views::GridLayout(this); SetLayoutManager(layout); @@ -153,9 +173,8 @@ ChooserBubbleUiViewDelegate::ChooserBubbleUiViewDelegate( column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, views::GridLayout::USE_PREF, 0, 0); - layout->StartRow(1, 0); - - // Create a table view + // Lay out the table view. + layout->StartRow(0, 0); std::vector<ui::TableColumn> table_columns; table_columns.push_back(ChooserTableColumn( 0, "" /* Empty string makes the column title invisible */)); @@ -165,33 +184,22 @@ ChooserBubbleUiViewDelegate::ChooserBubbleUiViewDelegate( table_view_->set_select_on_remove(false); chooser_table_model_->SetObserver(table_view_); table_view_->SetObserver(this); + table_view_->SetEnabled(chooser_bubble_delegate_->NumOptions() > 0); layout->AddView(table_view_->CreateParentIfNecessary(), 1, 1, views::GridLayout::FILL, views::GridLayout::FILL, kChooserPermissionBubbleWidth, kChooserPermissionBubbleHeight); - if (chooser_bubble_delegate_->NumOptions() == 0) { - table_view_->SetEnabled(false); - } - layout->AddPaddingRow(0, kItemMajorSpacing); + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); + // Lay out the Connect/Cancel buttons. + layout->StartRow(0, 0); views::View* button_row = new views::View(); - views::GridLayout* button_layout = new views::GridLayout(button_row); - views::ColumnSet* button_columns = button_layout->AddColumnSet(0); + views::BoxLayout* button_layout = new views::BoxLayout( + views::BoxLayout::kHorizontal, 0, 0, views::kRelatedButtonHSpacing); + button_layout->set_main_axis_alignment( + views::BoxLayout::MAIN_AXIS_ALIGNMENT_END); button_row->SetLayoutManager(button_layout); - layout->StartRow(1, 0); - layout->AddView(button_row); - - // Lay out the Connect/Cancel buttons. - button_columns->AddColumn(views::GridLayout::TRAILING, - views::GridLayout::FILL, 100, - views::GridLayout::USE_PREF, 0, 0); - button_columns->AddPaddingColumn(0, - kItemMajorSpacing - (2 * kButtonBorderSize)); - button_columns->AddColumn(views::GridLayout::TRAILING, - views::GridLayout::FILL, 0, - views::GridLayout::USE_PREF, 0, 0); - button_layout->StartRow(0, 0); base::string16 connect_text = l10n_util::GetStringUTF16(IDS_CHOOSER_BUBBLE_CONNECT_BUTTON_TEXT); @@ -199,16 +207,35 @@ ChooserBubbleUiViewDelegate::ChooserBubbleUiViewDelegate( connect_button_->SetStyle(views::Button::STYLE_BUTTON); // Disable the connect button at the beginning since no device selected yet. connect_button_->SetEnabled(false); - button_layout->AddView(connect_button_); + button_row->AddChildView(connect_button_); chooser_table_model_->SetConnectButton(connect_button_); base::string16 cancel_text = l10n_util::GetStringUTF16(IDS_CHOOSER_BUBBLE_CANCEL_BUTTON_TEXT); - cancel_button_ = new views::LabelButton(this, cancel_text); - cancel_button_->SetStyle(views::Button::STYLE_BUTTON); - button_layout->AddView(cancel_button_); + views::LabelButton* cancel_button = new views::LabelButton(this, cancel_text); + cancel_button->SetStyle(views::Button::STYLE_BUTTON); + button_row->AddChildView(cancel_button); + layout->AddView(button_row); - button_layout->AddPaddingRow(0, kBubbleOuterMargin); + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); + + // Lay out the separator. + layout->StartRow(0, 0); + layout->AddView(new views::Separator(views::Separator::HORIZONTAL)); + + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); + + // Lay out the styled label. + layout->StartRow(0, 0); + base::string16 link = + l10n_util::GetStringUTF16(IDS_CHOOSER_BUBBLE_GET_HELP_LINK_TEXT); + size_t offset; + base::string16 text = l10n_util::GetStringFUTF16( + IDS_CHOOSER_BUBBLE_FOOTNOTE_TEXT, link, &offset); + views::StyledLabel* label = new views::StyledLabel(text, this); + label->AddStyleRange(gfx::Range(offset, offset + link.length()), + views::StyledLabel::RangeStyleInfo::CreateForLink()); + layout->AddView(label); } ChooserBubbleUiViewDelegate::~ChooserBubbleUiViewDelegate() { @@ -256,6 +283,13 @@ void ChooserBubbleUiViewDelegate::ButtonPressed(views::Button* button, } } +void ChooserBubbleUiViewDelegate::StyledLabelLinkClicked( + views::StyledLabel* label, + const gfx::Range& range, + int event_flags) { + chooser_bubble_delegate_->OpenHelpCenterUrl(); +} + void ChooserBubbleUiViewDelegate::OnSelectionChanged() { connect_button_->SetEnabled(!table_view_->selection_model().empty()); } diff --git a/chrome/browser/ui/website_settings/chooser_bubble_delegate.cc b/chrome/browser/ui/website_settings/chooser_bubble_delegate.cc index 8b20975..7622b5d 100644 --- a/chrome/browser/ui/website_settings/chooser_bubble_delegate.cc +++ b/chrome/browser/ui/website_settings/chooser_bubble_delegate.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/net/referrer.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/website_settings/chooser_bubble_delegate.h" #include "content/public/browser/web_contents.h" @@ -13,6 +14,12 @@ ChooserBubbleDelegate::ChooserBubbleDelegate(content::RenderFrameHost* owner) ChooserBubbleDelegate::~ChooserBubbleDelegate() {} +void ChooserBubbleDelegate::OpenHelpCenterUrl() const { + browser_->OpenURL(content::OpenURLParams( + GetHelpCenterUrl(), content::Referrer(), NEW_FOREGROUND_TAB, + ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false /* is_renderer_initiated */)); +} + std::string ChooserBubbleDelegate::GetName() const { return "ChooserBubble"; } diff --git a/chrome/browser/ui/website_settings/chooser_bubble_delegate.h b/chrome/browser/ui/website_settings/chooser_bubble_delegate.h index 1dd4074..93afa89 100644 --- a/chrome/browser/ui/website_settings/chooser_bubble_delegate.h +++ b/chrome/browser/ui/website_settings/chooser_bubble_delegate.h @@ -12,6 +12,7 @@ #include "components/bubble/bubble_delegate.h" class Browser; +class GURL; // Subclass ChooserBubbleDelegate to implement a chooser bubble, which has // some introductory text and a list of options that users can pick one of. @@ -23,6 +24,10 @@ class Browser; // collecting metrics. // After Select/Cancel/Close is called, this object is destroyed and call back // into it is not allowed. +// TODO(juncai): Change class name ChooserBubbleDelegate to +// ChooserBubbleController since it better reflects its responsibilities and +// clarifies the roles of this class. +// https://crbug.com/588933 class ChooserBubbleDelegate : public BubbleDelegate { public: explicit ChooserBubbleDelegate(content::RenderFrameHost* owner); @@ -52,6 +57,9 @@ class ChooserBubbleDelegate : public BubbleDelegate { virtual ~Observer() {} }; + // Open help center URL. + void OpenHelpCenterUrl() const; + // BubbleDelegate: std::string GetName() const override; scoped_ptr<BubbleUi> BuildBubbleUi() override; @@ -77,6 +85,9 @@ class ChooserBubbleDelegate : public BubbleDelegate { // closes without the user taking an explicit action. virtual void Close() = 0; + // Get help center URL. + virtual GURL GetHelpCenterUrl() const = 0; + // Only one observer may be registered at a time. void set_observer(Observer* observer) { observer_ = observer; } Observer* observer() const { return observer_; } diff --git a/chrome/browser/usb/usb_chooser_bubble_delegate.cc b/chrome/browser/usb/usb_chooser_bubble_delegate.cc index 61549c4..026641d 100644 --- a/chrome/browser/usb/usb_chooser_bubble_delegate.cc +++ b/chrome/browser/usb/usb_chooser_bubble_delegate.cc @@ -13,6 +13,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/usb/usb_chooser_context.h" #include "chrome/browser/usb/usb_chooser_context_factory.h" +#include "chrome/common/url_constants.h" #include "components/bubble/bubble_controller.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" @@ -161,6 +162,10 @@ void UsbChooserBubbleDelegate::OnDeviceAdded( } } +GURL UsbChooserBubbleDelegate::GetHelpCenterUrl() const { + return GURL(chrome::kChooserUsbOverviewURL); +} + void UsbChooserBubbleDelegate::OnDeviceRemoved( scoped_refptr<device::UsbDevice> device) { for (auto it = devices_.begin(); it != devices_.end(); ++it) { diff --git a/chrome/browser/usb/usb_chooser_bubble_delegate.h b/chrome/browser/usb/usb_chooser_bubble_delegate.h index 9d18a97..58cc1a2 100644 --- a/chrome/browser/usb/usb_chooser_bubble_delegate.h +++ b/chrome/browser/usb/usb_chooser_bubble_delegate.h @@ -45,6 +45,7 @@ class UsbChooserBubbleDelegate : public ChooserBubbleDelegate, void Select(size_t index) override; void Cancel() override; void Close() override; + GURL GetHelpCenterUrl() const override; // device::UsbService::Observer: void OnDeviceAdded(scoped_refptr<device::UsbDevice> device) override; diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index 6ed9e2a..53825e3 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc @@ -769,4 +769,7 @@ const char kWindowsXPVistaDeprecationURL[] = const char kChooserBluetoothOverviewURL[] = "https://support.google.com/chrome?p=bluetooth"; +const char kChooserUsbOverviewURL[] = + "https://support.google.com/chrome?p=webusb"; + } // namespace chrome diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h index 3c5b6fd..abca4eb 100644 --- a/chrome/common/url_constants.h +++ b/chrome/common/url_constants.h @@ -578,6 +578,9 @@ extern const char kWindowsXPVistaDeprecationURL[]; // Chooser. extern const char kChooserBluetoothOverviewURL[]; +// The URL for the WebUsb help center article. +extern const char kChooserUsbOverviewURL[]; + } // namespace chrome #endif // CHROME_COMMON_URL_CONSTANTS_H_ |
