Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: chrome/browser/ui/views/toolbar/site_chip_view.cc

Issue 92073003: [SiteChip] Draw site chip icon and site title. Drag support. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/toolbar/site_chip_view.h" 5 #include "chrome/browser/ui/views/toolbar/site_chip_view.h"
6 6
7 #include "base/files/file_path.h"
7 #include "base/prefs/pref_service.h" 8 #include "base/prefs/pref_service.h"
8 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/extensions/extension_icon_image.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/extension_system.h"
15 #include "chrome/browser/favicon/favicon_tab_helper.h"
10 #include "chrome/browser/profiles/profile.h" 16 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/search/search.h" 17 #include "chrome/browser/search/search.h"
12 #include "chrome/browser/themes/theme_properties.h" 18 #include "chrome/browser/themes/theme_properties.h"
13 #include "chrome/browser/ui/browser.h" 19 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/omnibox/omnibox_view.h" 20 #include "chrome/browser/ui/omnibox/omnibox_view.h"
15 #include "chrome/browser/ui/toolbar/toolbar_model.h" 21 #include "chrome/browser/ui/toolbar/toolbar_model.h"
16 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" 22 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
17 #include "chrome/browser/ui/views/toolbar/toolbar_view.h" 23 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
24 #include "chrome/common/extensions/extension_constants.h"
25 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
18 #include "chrome/common/pref_names.h" 26 #include "chrome/common/pref_names.h"
19 #include "content/public/browser/web_contents.h" 27 #include "content/public/browser/web_contents.h"
28 #include "extensions/common/constants.h"
29 #include "grit/generated_resources.h"
20 #include "grit/theme_resources.h" 30 #include "grit/theme_resources.h"
21 #include "net/base/net_util.h" 31 #include "net/base/net_util.h"
32 #include "ui/base/l10n/l10n_util.h"
22 #include "ui/base/resource/resource_bundle.h" 33 #include "ui/base/resource/resource_bundle.h"
23 #include "ui/base/theme_provider.h" 34 #include "ui/base/theme_provider.h"
24 #include "ui/views/background.h" 35 #include "ui/views/background.h"
36 #include "ui/views/button_drag_utils.h"
25 #include "ui/views/controls/button/label_button.h" 37 #include "ui/views/controls/button/label_button.h"
26 #include "ui/views/controls/button/label_button_border.h" 38 #include "ui/views/controls/button/label_button_border.h"
27 #include "ui/views/controls/label.h" 39 #include "ui/views/controls/label.h"
28 #include "ui/views/painter.h" 40 #include "ui/views/painter.h"
29 41
30 const int kEdgeThickness = 4; 42
31 const int kIconTextSpacing = 4; 43 // SiteChipExtensionIcon ------------------------------------------------------
32 const int kTrailingLabelMargin = 2; 44
45 class SiteChipExtensionIcon : public extensions::IconImage::Observer {
46 public:
47 SiteChipExtensionIcon(LocationIconView* icon_view,
48 Profile* profile,
49 const extensions::Extension* extension);
50 ~SiteChipExtensionIcon();
msw 2013/12/11 00:16:19 Error from http://build.chromium.org/p/tryserver.c
Greg Billock 2013/12/11 04:53:38 Thanks, just saw this on the bot. Re-CQ-ing.
51
52 // IconImage::Observer:
53 virtual void OnExtensionIconImageChanged(
54 extensions::IconImage* image) OVERRIDE;
55
56 private:
57 LocationIconView* icon_view_;
58 scoped_ptr<extensions::IconImage> icon_image_;
59
60 DISALLOW_COPY_AND_ASSIGN(SiteChipExtensionIcon);
61 };
62
63 SiteChipExtensionIcon::SiteChipExtensionIcon(
64 LocationIconView* icon_view,
65 Profile* profile,
66 const extensions::Extension* extension)
67 : icon_view_(icon_view),
68 icon_image_(new extensions::IconImage(
69 profile,
70 extension,
71 extensions::IconsInfo::GetIcons(extension),
72 extension_misc::EXTENSION_ICON_BITTY,
73 extensions::IconsInfo::GetDefaultAppIcon(),
74 this)) {
75 // Forces load of the image.
76 icon_image_->image_skia().GetRepresentation(1.0f);
77
78 if (!icon_image_->image_skia().image_reps().empty())
79 OnExtensionIconImageChanged(icon_image_.get());
80 }
81
82 SiteChipExtensionIcon::~SiteChipExtensionIcon() {
83 }
84
85 void SiteChipExtensionIcon::OnExtensionIconImageChanged(
86 extensions::IconImage* image) {
87 if (icon_view_)
88 icon_view_->SetImage(&icon_image_->image_skia());
89 }
90
91
92 // SiteChipView ---------------------------------------------------------------
93
94 namespace {
95
96 const int kEdgeThickness = 5;
97 const int k16x16IconExtraSpacing = 3;
98 const int k16x16IconLeadingSpacing = 3;
99 const int k16x16IconTrailingSpacing = 3;
100 const int kIconTextSpacing = 3;
101 const int kTrailingLabelMargin = 0;
102
103 } // namespace
104
105 string16 SiteChipView::SiteLabelFromURL(const GURL& url) {
106 // The NTP.
107 if (!url.is_valid())
108 return string16(UTF8ToUTF16("Chrome"));
109
110 // TODO(gbillock): for kChromeUIScheme and kAboutScheme, return the title of
111 // the page.
112 // See url_constants.cc for hosts. ?? Or just show "Chrome"?
113 if (url.SchemeIs(chrome::kChromeUIScheme) ||
114 url.SchemeIs(chrome::kAboutScheme)) {
115 return string16(UTF8ToUTF16("Chrome"));
116 }
117
118 // For file: urls, return the full URL.
119 if (url.SchemeIsFile())
120 return base::UTF8ToUTF16(url.spec());
121
122 // TODO(gbillock): Handle filesystem urls the same way?
123 // Also: should handle interstitials differently?
124
125 // TODO(gbillock): think about view-source?
126
127 Profile* profile = toolbar_view_->browser()->profile();
128
129 // For chrome-extension urls, return the extension name.
130 if (url.SchemeIs(extensions::kExtensionScheme)) {
131 ExtensionService* service =
132 extensions::ExtensionSystem::Get(profile)->extension_service();
133 const extensions::Extension* extension =
134 service->extensions()->GetExtensionOrAppByURL(url);
135 return extension ?
136 base::UTF8ToUTF16(extension->name()) : UTF8ToUTF16(url.host());
137 }
138
139 if (url.SchemeIsHTTPOrHTTPS()) {
140 // See ToolbarModelImpl::GetText(). Does not pay attention to any user
141 // edits, and uses GetURL/net::FormatUrl -- We don't really care about
142 // length or the autocomplete parser.
143 // TODO(gbillock): This uses an algorithm very similar to GetText, which
144 // is probably too conservative. Try out just using a simpler mechanism of
145 // StripWWW() and IDNToUnicode().
146 std::string languages;
147 if (profile)
148 languages = profile->GetPrefs()->GetString(prefs::kAcceptLanguages);
149
150 base::string16 formatted = net::FormatUrl(url.GetOrigin(), languages,
151 net::kFormatUrlOmitAll, net::UnescapeRule::NORMAL, NULL, NULL, NULL);
152 // Remove scheme, "www.", and trailing "/".
153 if (StartsWith(formatted, ASCIIToUTF16("http://"), false))
154 formatted = formatted.substr(7);
155 if (StartsWith(formatted, ASCIIToUTF16("https://"), false))
156 formatted = formatted.substr(8);
157 if (StartsWith(formatted, ASCIIToUTF16("www."), false))
158 formatted = formatted.substr(4);
159 if (EndsWith(formatted, ASCIIToUTF16("/"), false))
160 formatted = formatted.substr(0, formatted.size()-1);
161 return formatted;
162 }
163
164 // For FTP, prepend "ftp:" to hostname.
165 if (url.SchemeIs(content::kFtpScheme)) {
166 return string16(UTF8ToUTF16(std::string("ftp:") + url.host()));
167 }
168
169 // If all else fails, return hostname.
170 return string16(UTF8ToUTF16(url.host()));
171 }
33 172
34 SiteChipView::SiteChipView(ToolbarView* toolbar_view) 173 SiteChipView::SiteChipView(ToolbarView* toolbar_view)
35 : ToolbarButton(this, NULL), 174 : ToolbarButton(this, NULL),
36 toolbar_view_(toolbar_view) { 175 toolbar_view_(toolbar_view),
176 painter_(NULL),
177 showing_16x16_icon_(false) {
178 set_drag_controller(this);
37 } 179 }
38 180
39 SiteChipView::~SiteChipView() { 181 SiteChipView::~SiteChipView() {
40 } 182 }
41 183
42 void SiteChipView::Init() { 184 void SiteChipView::Init() {
43 ToolbarButton::Init(); 185 ToolbarButton::Init();
44 186
45 // TODO(gbillock): Would be nice to just use stock LabelButton stuff here. 187 // TODO(gbillock): Would be nice to just use stock LabelButton stuff here.
46 location_icon_view_ = new LocationIconView(toolbar_view_->location_bar()); 188 location_icon_view_ = new LocationIconView(toolbar_view_->location_bar());
47 host_label_ = new views::Label(); 189 host_label_ = new views::Label();
48 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 190 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
49 host_label_->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont)); 191 host_label_->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont));
50 192
51 AddChildView(location_icon_view_); 193 AddChildView(location_icon_view_);
52 AddChildView(host_label_); 194 AddChildView(host_label_);
53 195
54 // temporary background painter
55 const int kBackgroundImages[] = IMAGE_GRID(IDR_SITE_CHIP_EV);
56 background_painter_.reset(
57 views::Painter::CreateImageGridPainter(kBackgroundImages));
58
59 // temporary icon filler
60 location_icon_view_->SetImage(GetThemeProvider()->GetImageSkiaNamed( 196 location_icon_view_->SetImage(GetThemeProvider()->GetImageSkiaNamed(
61 IDR_OMNIBOX_HTTPS_VALID)); 197 IDR_LOCATION_BAR_HTTP));
62 location_icon_view_->ShowTooltip(true); 198 location_icon_view_->ShowTooltip(true);
63 199
64 // temporary filler text. 200 const int kEVBackgroundImages[] = IMAGE_GRID(IDR_SITE_CHIP_EV);
65 host_label_->SetText(ASCIIToUTF16("site.chip")); 201 ev_background_painter_.reset(
202 views::Painter::CreateImageGridPainter(kEVBackgroundImages));
203 const int kBrokenSSLBackgroundImages[] = IMAGE_GRID(IDR_SITE_CHIP_BROKENSSL);
204 broken_ssl_background_painter_.reset(
205 views::Painter::CreateImageGridPainter(kBrokenSSLBackgroundImages));
66 } 206 }
67 207
68 bool SiteChipView::ShouldShow() { 208 bool SiteChipView::ShouldShow() {
69 return chrome::ShouldDisplayOriginChip(); 209 return chrome::ShouldDisplayOriginChip();
70 } 210 }
71 211
72 void SiteChipView::Update(content::WebContents* tab) { 212 void SiteChipView::Update(content::WebContents* web_contents) {
213 if (!web_contents)
214 return;
215
216 // Note: security level can change async as the connection is made.
217 GURL url = toolbar_view_->GetToolbarModel()->GetURL();
218 const ToolbarModel::SecurityLevel security_level =
219 toolbar_view_->GetToolbarModel()->GetSecurityLevel(true);
220 if ((url == url_displayed_) && (security_level == security_level_))
221 return;
222
223 url_displayed_ = url;
224
225 string16 host = SiteLabelFromURL(url);
226
227 // TODO(gbillock): Deal with RTL here better? Use a separate
228 // label for cert name?
229 if ((security_level != security_level_) &&
230 (security_level == ToolbarModel::EV_SECURE)) {
231 host = l10n_util::GetStringFUTF16(IDS_SITE_CHIP_EV_SSL_LABEL,
232 toolbar_view_->GetToolbarModel()->GetEVCertName(),
233 host);
234 }
235
236 host_ = host;
237 host_label_->SetText(host_);
238 host_label_->SetTooltipText(host_);
239 SkColor toolbar_background =
240 GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR);
241 host_label_->SetEnabledColor(
242 color_utils::GetReadableColor(SK_ColorBLACK, toolbar_background));
243
244 security_level_ = security_level;
245 int icon = toolbar_view_->GetToolbarModel()->GetIconForSecurityLevel(
246 security_level_);
247 showing_16x16_icon_ = false;
248
249 if (!url.is_valid() ||
250 url.SchemeIs(chrome::kChromeUIScheme)) {
251 icon = IDR_PRODUCT_LOGO_16;
252 showing_16x16_icon_ = true;
253 }
254
255 if (url.SchemeIs(extensions::kExtensionScheme)) {
256 icon = IDR_EXTENSIONS_FAVICON;
257 showing_16x16_icon_ = true;
258
259 ExtensionService* service =
260 extensions::ExtensionSystem::Get(
261 toolbar_view_->browser()->profile())->extension_service();
262 const extensions::Extension* extension =
263 service->extensions()->GetExtensionOrAppByURL(url);
264 extension_icon_.reset(
265 new SiteChipExtensionIcon(location_icon_view_,
266 toolbar_view_->browser()->profile(),
267 extension));
268 } else {
269 extension_icon_.reset();
270 }
271
272 location_icon_view_->SetImage(GetThemeProvider()->GetImageSkiaNamed(icon));
273 location_icon_view_->ShowTooltip(true);
274
275 // TODO(gbillock): Add malware accounting.
276 if (security_level_ == ToolbarModel::SECURITY_ERROR)
277 painter_ = broken_ssl_background_painter_.get();
278 else if (security_level_ == ToolbarModel::EV_SECURE)
279 painter_ = ev_background_painter_.get();
280 else
281 painter_ = NULL;
282
73 Layout(); 283 Layout();
74 SchedulePaint(); 284 SchedulePaint();
285 // TODO(gbillock): Need to schedule paint on parent to erase any background?
286 }
287
288 void SiteChipView::OnChanged() {
289 Update(toolbar_view_->GetWebContents());
290 toolbar_view_->Layout();
291 toolbar_view_->SchedulePaint();
292 // TODO(gbillock): Also need to potentially repaint infobars to make sure the
293 // arrows are pointing to the right spot. Only needed for some edge cases.
75 } 294 }
76 295
77 gfx::Size SiteChipView::GetPreferredSize() { 296 gfx::Size SiteChipView::GetPreferredSize() {
78 gfx::Size label_size = host_label_->GetPreferredSize(); 297 gfx::Size label_size = host_label_->GetPreferredSize();
79 gfx::Size icon_size = location_icon_view_->GetPreferredSize(); 298 gfx::Size icon_size = location_icon_view_->GetPreferredSize();
80 return gfx::Size(icon_size.width() + label_size.width() + 299 int icon_spacing = showing_16x16_icon_ ?
81 kIconTextSpacing + kTrailingLabelMargin + 300 (k16x16IconLeadingSpacing + k16x16IconTrailingSpacing) : 0;
82 2 * kEdgeThickness, 301 return gfx::Size(kEdgeThickness + icon_size.width() + icon_spacing +
302 kIconTextSpacing + label_size.width() +
303 kTrailingLabelMargin + kEdgeThickness,
83 icon_size.height()); 304 icon_size.height());
84 } 305 }
85 306
86 void SiteChipView::Layout() { 307 void SiteChipView::Layout() {
308 // TODO(gbillock): Eventually we almost certainly want to use
309 // LocationBarLayout for leading and trailing decorations.
310
87 location_icon_view_->SetBounds( 311 location_icon_view_->SetBounds(
88 kEdgeThickness, 312 kEdgeThickness + (showing_16x16_icon_ ? k16x16IconLeadingSpacing : 0),
89 LocationBarView::kNormalEdgeThickness, 313 LocationBarView::kNormalEdgeThickness,
90 location_icon_view_->GetPreferredSize().width(), 314 location_icon_view_->GetPreferredSize().width(),
91 height() - 2 * LocationBarView::kNormalEdgeThickness); 315 height() - 2 * LocationBarView::kNormalEdgeThickness);
92 316
93 int host_label_x = location_icon_view_->x() + location_icon_view_->width() + 317 int host_label_x = location_icon_view_->x() + location_icon_view_->width() +
94 kIconTextSpacing; 318 kIconTextSpacing;
319 host_label_x += showing_16x16_icon_ ? k16x16IconTrailingSpacing : 0;
95 int host_label_width = 320 int host_label_width =
96 width() - host_label_x - kEdgeThickness - kTrailingLabelMargin; 321 width() - host_label_x - kEdgeThickness - kTrailingLabelMargin;
97 host_label_->SetBounds(host_label_x, 322 host_label_->SetBounds(host_label_x,
98 LocationBarView::kNormalEdgeThickness, 323 LocationBarView::kNormalEdgeThickness,
99 host_label_width, 324 host_label_width,
100 height() - 2 * LocationBarView::kNormalEdgeThickness); 325 height() - 2 * LocationBarView::kNormalEdgeThickness);
101 } 326 }
102 327
103 void SiteChipView::OnPaint(gfx::Canvas* canvas) { 328 void SiteChipView::OnPaint(gfx::Canvas* canvas) {
104 gfx::Rect rect(GetLocalBounds()); 329 gfx::Rect rect(GetLocalBounds());
105 rect.Inset(LocationBarView::kNormalEdgeThickness, 330 if (painter_)
106 LocationBarView::kNormalEdgeThickness); 331 views::Painter::PaintPainterAt(canvas, painter_, rect);
107 if (background_painter_.get())
108 views::Painter::PaintPainterAt(canvas, background_painter_.get(), rect);
109 332
110 ToolbarButton::OnPaint(canvas); 333 ToolbarButton::OnPaint(canvas);
111 } 334 }
112 335
113 // TODO(gbillock): Make the LocationBarView or OmniboxView the listener for 336 // TODO(gbillock): Make the LocationBarView or OmniboxView the listener for
114 // this button. 337 // this button.
115 void SiteChipView::ButtonPressed(views::Button* sender, 338 void SiteChipView::ButtonPressed(views::Button* sender,
116 const ui::Event& event) { 339 const ui::Event& event) {
117 toolbar_view_->location_bar()->GetOmniboxView()->SetFocus(); 340 toolbar_view_->location_bar()->GetOmniboxView()->SetFocus();
118 toolbar_view_->location_bar()->GetOmniboxView()->SelectAll(true); 341 toolbar_view_->location_bar()->GetOmniboxView()->SelectAll(true);
119 toolbar_view_->location_bar()->GetOmniboxView()->model()-> 342 toolbar_view_->location_bar()->GetOmniboxView()->model()->
120 SetCaretVisibility(true); 343 SetCaretVisibility(true);
121 } 344 }
345
346 void SiteChipView::WriteDragDataForView(View* sender,
347 const gfx::Point& press_pt,
348 OSExchangeData* data) {
349 // TODO(gbillock): Consolidate this with the identical logic in
350 // LocationBarView.
351 content::WebContents* web_contents = toolbar_view_->GetWebContents();
352 FaviconTabHelper* favicon_tab_helper =
353 FaviconTabHelper::FromWebContents(web_contents);
354 gfx::ImageSkia favicon = favicon_tab_helper->GetFavicon().AsImageSkia();
355 button_drag_utils::SetURLAndDragImage(web_contents->GetURL(),
356 web_contents->GetTitle(),
357 favicon,
358 data,
359 sender->GetWidget());
360 }
361
362 int SiteChipView::GetDragOperationsForView(View* sender,
363 const gfx::Point& p) {
msw 2013/12/11 00:16:19 nit: fix indent.
Greg Billock 2013/12/11 04:53:38 oops! will fix in next round.
364 return ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK;
365 }
366
367 bool SiteChipView::CanStartDragForView(View* sender,
368 const gfx::Point& press_pt,
msw 2013/12/11 00:16:19 nit: fix indent.
369 const gfx::Point& p) {
370 return true;
371 }
372
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/toolbar/site_chip_view.h ('k') | chrome/browser/ui/views/toolbar/toolbar_view.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698