Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / ui / views / extensions / bookmark_app_bubble_view.cc
blob0b3fede7c23e1f9edf95de65abbd7c3ec8a8b214
1 // Copyright 2014 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/extensions/bookmark_app_bubble_view.h"
7 #include "base/numerics/safe_conversions.h"
8 #include "base/strings/string16.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/ui/host_desktop.h"
12 #include "chrome/grit/generated_resources.h"
13 #include "content/public/browser/web_contents.h"
14 #include "extensions/common/constants.h"
15 #include "ui/accessibility/ax_view_state.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/events/keycodes/keyboard_codes.h"
19 #include "ui/gfx/image/image_skia.h"
20 #include "ui/gfx/image/image_skia_source.h"
21 #include "ui/views/controls/button/checkbox.h"
22 #include "ui/views/controls/button/label_button.h"
23 #include "ui/views/controls/image_view.h"
24 #include "ui/views/controls/label.h"
25 #include "ui/views/controls/textfield/textfield.h"
26 #include "ui/views/layout/grid_layout.h"
27 #include "ui/views/layout/layout_constants.h"
28 #include "ui/views/widget/widget.h"
30 using views::ColumnSet;
31 using views::GridLayout;
33 namespace {
35 // Minimum width of the the bubble.
36 const int kMinBubbleWidth = 300;
37 // Minimum width of the the textfield.
38 const int kMinTextfieldWidth = 200;
39 // Size of the icon.
40 const int kIconSize = extension_misc::EXTENSION_ICON_MEDIUM;
42 class WebAppInfoImageSource : public gfx::ImageSkiaSource {
43 public:
44 WebAppInfoImageSource(int dip_size, const WebApplicationInfo& info)
45 : dip_size_(dip_size), info_(info) {}
46 ~WebAppInfoImageSource() override {}
48 private:
49 gfx::ImageSkiaRep GetImageForScale(float scale) override {
50 int size = base::saturated_cast<int>(dip_size_ * scale);
51 for (const auto& icon_info : info_.icons) {
52 if (icon_info.width == size) {
53 return gfx::ImageSkiaRep(icon_info.data, scale);
56 return gfx::ImageSkiaRep();
59 int dip_size_;
60 WebApplicationInfo info_;
63 } // namespace
65 BookmarkAppBubbleView::~BookmarkAppBubbleView() {
68 // static
69 void BookmarkAppBubbleView::ShowBubble(
70 views::View* anchor_view,
71 const WebApplicationInfo& web_app_info,
72 const BrowserWindow::ShowBookmarkAppBubbleCallback& callback) {
73 // |bookmark_app_bubble| becomes owned by the BubbleDelegateView through the
74 // views system, and is freed when the BubbleDelegateView is closed and
75 // subsequently destroyed.
76 BookmarkAppBubbleView* bookmark_app_bubble =
77 new BookmarkAppBubbleView(anchor_view, web_app_info, callback);
78 views::BubbleDelegateView::CreateBubble(bookmark_app_bubble)->Show();
79 // Select the entire title textfield contents when the bubble is first shown.
80 bookmark_app_bubble->title_tf_->SelectAll(true);
81 bookmark_app_bubble->SetArrowPaintType(views::BubbleBorder::PAINT_NONE);
84 BookmarkAppBubbleView::BookmarkAppBubbleView(
85 views::View* anchor_view,
86 const WebApplicationInfo& web_app_info,
87 const BrowserWindow::ShowBookmarkAppBubbleCallback& callback)
88 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
89 web_app_info_(web_app_info),
90 user_accepted_(false),
91 callback_(callback),
92 add_button_(NULL),
93 cancel_button_(NULL),
94 open_as_window_checkbox_(NULL),
95 title_tf_(NULL) {
96 const SkColor background_color = GetNativeTheme()->GetSystemColor(
97 ui::NativeTheme::kColorId_DialogBackground);
98 set_arrow(views::BubbleBorder::TOP_CENTER);
99 set_color(background_color);
100 set_background(views::Background::CreateSolidBackground(background_color));
101 set_margins(gfx::Insets(views::kPanelVertMargin, 0, 0, 0));
104 void BookmarkAppBubbleView::Init() {
105 views::Label* title_label = new views::Label(
106 l10n_util::GetStringUTF16(TitleStringId()));
107 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
108 title_label->SetFontList(rb->GetFontList(ui::ResourceBundle::MediumFont));
109 title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
111 add_button_ =
112 new views::LabelButton(this, l10n_util::GetStringUTF16(IDS_ADD));
113 add_button_->SetStyle(views::Button::STYLE_BUTTON);
114 add_button_->SetIsDefault(true);
116 cancel_button_ =
117 new views::LabelButton(this, l10n_util::GetStringUTF16(IDS_CANCEL));
118 cancel_button_->SetStyle(views::Button::STYLE_BUTTON);
120 GridLayout* layout = new GridLayout(this);
121 SetLayoutManager(layout);
123 // Column sets used in the layout of the bubble.
124 enum ColumnSetID {
125 TITLE_COLUMN_SET_ID,
126 TITLE_TEXT_COLUMN_SET_ID,
127 CONTENT_COLUMN_SET_ID
130 // The column layout used for the title and checkbox.
131 ColumnSet* cs = layout->AddColumnSet(TITLE_COLUMN_SET_ID);
132 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
133 cs->AddColumn(
134 GridLayout::LEADING, GridLayout::CENTER, 0, GridLayout::USE_PREF, 0, 0);
135 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
137 // The column layout used for the icon and text box.
138 cs = layout->AddColumnSet(TITLE_TEXT_COLUMN_SET_ID);
139 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
140 cs->AddColumn(GridLayout::LEADING,
141 GridLayout::CENTER,
143 GridLayout::USE_PREF,
146 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
147 cs->AddColumn(GridLayout::FILL,
148 GridLayout::CENTER,
150 GridLayout::USE_PREF,
152 kMinTextfieldWidth);
153 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
155 // The column layout used for the row with buttons.
156 cs = layout->AddColumnSet(CONTENT_COLUMN_SET_ID);
157 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
158 cs->AddColumn(
159 GridLayout::LEADING, GridLayout::CENTER, 0, GridLayout::USE_PREF, 0, 0);
160 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
161 cs->AddColumn(
162 GridLayout::LEADING, GridLayout::CENTER, 0, GridLayout::USE_PREF, 0, 0);
163 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
164 cs->AddColumn(
165 GridLayout::LEADING, GridLayout::CENTER, 0, GridLayout::USE_PREF, 0, 0);
166 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
168 layout->StartRow(0, TITLE_COLUMN_SET_ID);
169 layout->AddView(title_label);
170 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
172 layout->StartRow(0, TITLE_TEXT_COLUMN_SET_ID);
173 icon_image_view_ = new views::ImageView();
175 gfx::Size image_size(kIconSize, kIconSize);
176 gfx::ImageSkia image(new WebAppInfoImageSource(kIconSize, web_app_info_),
177 image_size);
178 icon_image_view_->SetImageSize(image_size);
179 icon_image_view_->SetImage(image);
180 layout->AddView(icon_image_view_);
182 title_tf_ = new views::Textfield();
183 title_tf_->SetText(web_app_info_.title);
184 title_tf_->SetAccessibleName(l10n_util::GetStringUTF16(
185 IDS_BOOKMARK_APP_AX_BUBBLE_NAME_LABEL));
186 title_tf_->set_controller(this);
187 layout->AddView(title_tf_);
188 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
190 layout->StartRow(0, CONTENT_COLUMN_SET_ID);
191 open_as_window_checkbox_ = new views::Checkbox(
192 l10n_util::GetStringUTF16(IDS_BOOKMARK_APP_BUBBLE_OPEN_AS_WINDOW));
193 open_as_window_checkbox_->SetChecked(web_app_info_.open_as_window);
194 layout->AddView(open_as_window_checkbox_);
195 layout->AddView(add_button_);
196 layout->AddView(cancel_button_);
197 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
199 AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE));
200 UpdateAddButtonState();
203 views::View* BookmarkAppBubbleView::GetInitiallyFocusedView() {
204 return title_tf_;
207 void BookmarkAppBubbleView::WindowClosing() {
208 callback_.Run(user_accepted_, web_app_info_);
211 bool BookmarkAppBubbleView::AcceleratorPressed(
212 const ui::Accelerator& accelerator) {
213 if (accelerator.key_code() == ui::VKEY_RETURN) {
214 HandleButtonPressed(add_button_);
217 return BubbleDelegateView::AcceleratorPressed(accelerator);
220 void BookmarkAppBubbleView::GetAccessibleState(ui::AXViewState* state) {
221 views::BubbleDelegateView::GetAccessibleState(state);
222 state->name = l10n_util::GetStringUTF16(TitleStringId());
225 gfx::Size BookmarkAppBubbleView::GetMinimumSize() const {
226 gfx::Size size(views::BubbleDelegateView::GetPreferredSize());
227 size.SetToMax(gfx::Size(kMinBubbleWidth, 0));
228 return size;
231 void BookmarkAppBubbleView::ButtonPressed(views::Button* sender,
232 const ui::Event& event) {
233 HandleButtonPressed(sender);
236 void BookmarkAppBubbleView::ContentsChanged(
237 views::Textfield* sender,
238 const base::string16& new_contents) {
239 DCHECK_EQ(title_tf_, sender);
240 UpdateAddButtonState();
243 void BookmarkAppBubbleView::HandleButtonPressed(views::Button* sender) {
244 if (sender == add_button_) {
245 user_accepted_ = true;
246 web_app_info_.title = GetTrimmedTitle();
247 web_app_info_.open_as_window = open_as_window_checkbox_->checked();
250 GetWidget()->Close();
253 void BookmarkAppBubbleView::UpdateAddButtonState() {
254 add_button_->SetEnabled(!GetTrimmedTitle().empty());
257 int BookmarkAppBubbleView::TitleStringId() {
258 #if defined(OS_WIN)
259 int string_id = IDS_ADD_TO_TASKBAR_BUBBLE_TITLE;
260 #else
261 int string_id = IDS_ADD_TO_DESKTOP_BUBBLE_TITLE;
262 #endif
263 #if defined(USE_ASH)
264 if (chrome::GetHostDesktopTypeForNativeWindow(
265 anchor_widget()->GetNativeWindow()) ==
266 chrome::HOST_DESKTOP_TYPE_ASH) {
267 string_id = IDS_ADD_TO_SHELF_BUBBLE_TITLE;
269 #endif
270 return string_id;
273 base::string16 BookmarkAppBubbleView::GetTrimmedTitle() {
274 base::string16 title(title_tf_->text());
275 base::TrimWhitespace(title, base::TRIM_ALL, &title);
276 return title;