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

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: Unused var 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 virtual ~SiteChipExtensionIcon();
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 k16x16IconLeadingSpacing = 3;
98 const int k16x16IconTrailingSpacing = 3;
99 const int kIconTextSpacing = 3;
100 const int kTrailingLabelMargin = 0;
101
102 } // namespace
103
104 string16 SiteChipView::SiteLabelFromURL(const GURL& url) {
msw 2013/12/11 21:54:44 You definition order should match the declaration
Greg Billock 2013/12/11 22:34:08 Yeah. I left them skewed to simplify patch diffs;
msw 2013/12/11 22:42:19 A separate move-only CL would probably work best.
Greg Billock 2013/12/11 23:00:45 OK. I'll leave the next one as-is, then. After tha
105 // The NTP.
106 if (!url.is_valid())
107 return string16(UTF8ToUTF16("Chrome"));
108
109 // TODO(gbillock): for kChromeUIScheme and kAboutScheme, return the title of
110 // the page.
111 // See url_constants.cc for hosts. ?? Or just show "Chrome"?
112 if (url.SchemeIs(chrome::kChromeUIScheme) ||
113 url.SchemeIs(chrome::kAboutScheme)) {
114 return string16(UTF8ToUTF16("Chrome"));
115 }
116
117 // For file: urls, return the full URL.
118 if (url.SchemeIsFile())
119 return base::UTF8ToUTF16(url.spec());
120
121 // TODO(gbillock): Handle filesystem urls the same way?
122 // Also: should handle interstitials differently?
123
124 // TODO(gbillock): think about view-source?
125
126 Profile* profile = toolbar_view_->browser()->profile();
127
128 // For chrome-extension urls, return the extension name.
129 if (url.SchemeIs(extensions::kExtensionScheme)) {
130 ExtensionService* service =
131 extensions::ExtensionSystem::Get(profile)->extension_service();
132 const extensions::Extension* extension =
133 service->extensions()->GetExtensionOrAppByURL(url);
134 return extension ?
135 base::UTF8ToUTF16(extension->name()) : UTF8ToUTF16(url.host());
msw 2013/12/11 21:54:44 nit: be consistent about using the base:: namespac
Greg Billock 2013/12/11 22:34:08 Yes. I've been fighting with merges on this during
136 }
137
138 if (url.SchemeIsHTTPOrHTTPS()) {
139 // See ToolbarModelImpl::GetText(). Does not pay attention to any user
140 // edits, and uses GetURL/net::FormatUrl -- We don't really care about
141 // length or the autocomplete parser.
142 // TODO(gbillock): This uses an algorithm very similar to GetText, which
143 // is probably too conservative. Try out just using a simpler mechanism of
144 // StripWWW() and IDNToUnicode().
145 std::string languages;
146 if (profile)
147 languages = profile->GetPrefs()->GetString(prefs::kAcceptLanguages);
148
149 base::string16 formatted = net::FormatUrl(url.GetOrigin(), languages,
150 net::kFormatUrlOmitAll, net::UnescapeRule::NORMAL, NULL, NULL, NULL);
151 // Remove scheme, "www.", and trailing "/".
152 if (StartsWith(formatted, ASCIIToUTF16("http://"), false))
msw 2013/12/11 21:54:44 chrome/browser/autocomplete/url_prefix.h might hel
Greg Billock 2013/12/11 22:34:08 We hope to swap this out for a more direct approac
153 formatted = formatted.substr(7);
154 if (StartsWith(formatted, ASCIIToUTF16("https://"), false))
155 formatted = formatted.substr(8);
156 if (StartsWith(formatted, ASCIIToUTF16("www."), false))
157 formatted = formatted.substr(4);
158 if (EndsWith(formatted, ASCIIToUTF16("/"), false))
159 formatted = formatted.substr(0, formatted.size()-1);
160 return formatted;
161 }
162
163 // For FTP, prepend "ftp:" to hostname.
164 if (url.SchemeIs(content::kFtpScheme)) {
165 return string16(UTF8ToUTF16(std::string("ftp:") + url.host()));
166 }
167
168 // If all else fails, return hostname.
169 return string16(UTF8ToUTF16(url.host()));
msw 2013/12/11 21:54:44 nit: the string16() here seems like an unnecessary
Greg Billock 2013/12/11 22:34:08 Agreed. I removed this subsequently.
170 }
33 171
34 SiteChipView::SiteChipView(ToolbarView* toolbar_view) 172 SiteChipView::SiteChipView(ToolbarView* toolbar_view)
35 : ToolbarButton(this, NULL), 173 : ToolbarButton(this, NULL),
36 toolbar_view_(toolbar_view) { 174 toolbar_view_(toolbar_view),
175 painter_(NULL),
176 showing_16x16_icon_(false) {
177 set_drag_controller(this);
37 } 178 }
38 179
39 SiteChipView::~SiteChipView() { 180 SiteChipView::~SiteChipView() {
40 } 181 }
41 182
42 void SiteChipView::Init() { 183 void SiteChipView::Init() {
43 ToolbarButton::Init(); 184 ToolbarButton::Init();
44 185
45 // TODO(gbillock): Would be nice to just use stock LabelButton stuff here. 186 // TODO(gbillock): Would be nice to just use stock LabelButton stuff here.
46 location_icon_view_ = new LocationIconView(toolbar_view_->location_bar()); 187 location_icon_view_ = new LocationIconView(toolbar_view_->location_bar());
47 host_label_ = new views::Label(); 188 host_label_ = new views::Label();
48 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 189 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
49 host_label_->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont)); 190 host_label_->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont));
50 191
51 AddChildView(location_icon_view_); 192 AddChildView(location_icon_view_);
52 AddChildView(host_label_); 193 AddChildView(host_label_);
53 194
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( 195 location_icon_view_->SetImage(GetThemeProvider()->GetImageSkiaNamed(
61 IDR_OMNIBOX_HTTPS_VALID)); 196 IDR_LOCATION_BAR_HTTP));
62 location_icon_view_->ShowTooltip(true); 197 location_icon_view_->ShowTooltip(true);
63 198
64 // temporary filler text. 199 const int kEVBackgroundImages[] = IMAGE_GRID(IDR_SITE_CHIP_EV);
65 host_label_->SetText(ASCIIToUTF16("site.chip")); 200 ev_background_painter_.reset(
201 views::Painter::CreateImageGridPainter(kEVBackgroundImages));
202 const int kBrokenSSLBackgroundImages[] = IMAGE_GRID(IDR_SITE_CHIP_BROKENSSL);
203 broken_ssl_background_painter_.reset(
204 views::Painter::CreateImageGridPainter(kBrokenSSLBackgroundImages));
66 } 205 }
67 206
68 bool SiteChipView::ShouldShow() { 207 bool SiteChipView::ShouldShow() {
69 return chrome::ShouldDisplayOriginChip(); 208 return chrome::ShouldDisplayOriginChip();
70 } 209 }
71 210
72 void SiteChipView::Update(content::WebContents* tab) { 211 void SiteChipView::Update(content::WebContents* web_contents) {
msw 2013/12/11 21:54:44 Why is this argument necessary?
Greg Billock 2013/12/11 22:34:08 It's used in subsequent changes -- easier to keep
212 if (!web_contents)
msw 2013/12/11 21:54:44 What happens on chrome://crash and chrome://hang?
Greg Billock 2013/12/11 22:34:08 Good question. I'll try those out, but in general
213 return;
214
215 // Note: security level can change async as the connection is made.
216 GURL url = toolbar_view_->GetToolbarModel()->GetURL();
217 const ToolbarModel::SecurityLevel security_level =
218 toolbar_view_->GetToolbarModel()->GetSecurityLevel(true);
219 if ((url == url_displayed_) && (security_level == security_level_))
220 return;
221
222 url_displayed_ = url;
223
224 string16 host = SiteLabelFromURL(url);
225
226 // TODO(gbillock): Deal with RTL here better? Use a separate
227 // label for cert name?
228 if ((security_level != security_level_) &&
229 (security_level == ToolbarModel::EV_SECURE)) {
230 host = l10n_util::GetStringFUTF16(IDS_SITE_CHIP_EV_SSL_LABEL,
231 toolbar_view_->GetToolbarModel()->GetEVCertName(),
232 host);
233 }
234
235 host_ = host;
236 host_label_->SetText(host_);
237 host_label_->SetTooltipText(host_);
238 SkColor toolbar_background =
239 GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR);
240 host_label_->SetEnabledColor(
241 color_utils::GetReadableColor(SK_ColorBLACK, toolbar_background));
msw 2013/12/11 21:54:44 Label does this automatically if you SetBackground
Greg Billock 2013/12/11 22:34:08 ok, so it manages visibility itself? Should I do i
msw 2013/12/11 22:42:19 Label::SetBackgroundColor won't draw a background,
Greg Billock 2013/12/11 23:00:45 Nice! So I need to adjust for the specialized back
msw 2013/12/11 23:49:20 Yeah, updating for those backgrounds should help.
242
243 security_level_ = security_level;
244 int icon = toolbar_view_->GetToolbarModel()->GetIconForSecurityLevel(
245 security_level_);
246 showing_16x16_icon_ = false;
247
248 if (!url.is_valid() ||
249 url.SchemeIs(chrome::kChromeUIScheme)) {
msw 2013/12/11 21:54:44 Should you check for kAboutScheme as you do above?
Greg Billock 2013/12/11 22:34:08 This changes in the subsequent patch to deal with
250 icon = IDR_PRODUCT_LOGO_16;
251 showing_16x16_icon_ = true;
252 }
253
254 if (url.SchemeIs(extensions::kExtensionScheme)) {
255 icon = IDR_EXTENSIONS_FAVICON;
256 showing_16x16_icon_ = true;
257
258 ExtensionService* service =
259 extensions::ExtensionSystem::Get(
260 toolbar_view_->browser()->profile())->extension_service();
261 const extensions::Extension* extension =
262 service->extensions()->GetExtensionOrAppByURL(url);
263 extension_icon_.reset(
264 new SiteChipExtensionIcon(location_icon_view_,
265 toolbar_view_->browser()->profile(),
266 extension));
267 } else {
268 extension_icon_.reset();
269 }
270
271 location_icon_view_->SetImage(GetThemeProvider()->GetImageSkiaNamed(icon));
msw 2013/12/11 21:54:44 Won't this potentially stomp the extension icon ch
Greg Billock 2013/12/11 22:34:08 Good point. I think you're right this should move
272 location_icon_view_->ShowTooltip(true);
273
274 // TODO(gbillock): Add malware accounting.
275 if (security_level_ == ToolbarModel::SECURITY_ERROR)
276 painter_ = broken_ssl_background_painter_.get();
277 else if (security_level_ == ToolbarModel::EV_SECURE)
278 painter_ = ev_background_painter_.get();
279 else
280 painter_ = NULL;
281
73 Layout(); 282 Layout();
74 SchedulePaint(); 283 SchedulePaint();
284 // TODO(gbillock): Need to schedule paint on parent to erase any background?
285 }
286
287 void SiteChipView::OnChanged() {
288 Update(toolbar_view_->GetWebContents());
289 toolbar_view_->Layout();
290 toolbar_view_->SchedulePaint();
291 // TODO(gbillock): Also need to potentially repaint infobars to make sure the
292 // arrows are pointing to the right spot. Only needed for some edge cases.
75 } 293 }
76 294
77 gfx::Size SiteChipView::GetPreferredSize() { 295 gfx::Size SiteChipView::GetPreferredSize() {
78 gfx::Size label_size = host_label_->GetPreferredSize(); 296 gfx::Size label_size = host_label_->GetPreferredSize();
79 gfx::Size icon_size = location_icon_view_->GetPreferredSize(); 297 gfx::Size icon_size = location_icon_view_->GetPreferredSize();
80 return gfx::Size(icon_size.width() + label_size.width() + 298 int icon_spacing = showing_16x16_icon_ ?
81 kIconTextSpacing + kTrailingLabelMargin + 299 (k16x16IconLeadingSpacing + k16x16IconTrailingSpacing) : 0;
82 2 * kEdgeThickness, 300 return gfx::Size(kEdgeThickness + icon_size.width() + icon_spacing +
301 kIconTextSpacing + label_size.width() +
302 kTrailingLabelMargin + kEdgeThickness,
83 icon_size.height()); 303 icon_size.height());
84 } 304 }
85 305
86 void SiteChipView::Layout() { 306 void SiteChipView::Layout() {
307 // TODO(gbillock): Eventually we almost certainly want to use
308 // LocationBarLayout for leading and trailing decorations.
309
87 location_icon_view_->SetBounds( 310 location_icon_view_->SetBounds(
88 kEdgeThickness, 311 kEdgeThickness + (showing_16x16_icon_ ? k16x16IconLeadingSpacing : 0),
89 LocationBarView::kNormalEdgeThickness, 312 LocationBarView::kNormalEdgeThickness,
90 location_icon_view_->GetPreferredSize().width(), 313 location_icon_view_->GetPreferredSize().width(),
91 height() - 2 * LocationBarView::kNormalEdgeThickness); 314 height() - 2 * LocationBarView::kNormalEdgeThickness);
92 315
93 int host_label_x = location_icon_view_->x() + location_icon_view_->width() + 316 int host_label_x = location_icon_view_->x() + location_icon_view_->width() +
94 kIconTextSpacing; 317 kIconTextSpacing;
318 host_label_x += showing_16x16_icon_ ? k16x16IconTrailingSpacing : 0;
95 int host_label_width = 319 int host_label_width =
96 width() - host_label_x - kEdgeThickness - kTrailingLabelMargin; 320 width() - host_label_x - kEdgeThickness - kTrailingLabelMargin;
97 host_label_->SetBounds(host_label_x, 321 host_label_->SetBounds(host_label_x,
98 LocationBarView::kNormalEdgeThickness, 322 LocationBarView::kNormalEdgeThickness,
99 host_label_width, 323 host_label_width,
100 height() - 2 * LocationBarView::kNormalEdgeThickness); 324 height() - 2 * LocationBarView::kNormalEdgeThickness);
101 } 325 }
102 326
103 void SiteChipView::OnPaint(gfx::Canvas* canvas) { 327 void SiteChipView::OnPaint(gfx::Canvas* canvas) {
104 gfx::Rect rect(GetLocalBounds()); 328 gfx::Rect rect(GetLocalBounds());
105 rect.Inset(LocationBarView::kNormalEdgeThickness, 329 if (painter_)
106 LocationBarView::kNormalEdgeThickness); 330 views::Painter::PaintPainterAt(canvas, painter_, rect);
107 if (background_painter_.get())
108 views::Painter::PaintPainterAt(canvas, background_painter_.get(), rect);
109 331
110 ToolbarButton::OnPaint(canvas); 332 ToolbarButton::OnPaint(canvas);
111 } 333 }
112 334
113 // TODO(gbillock): Make the LocationBarView or OmniboxView the listener for 335 // TODO(gbillock): Make the LocationBarView or OmniboxView the listener for
114 // this button. 336 // this button.
115 void SiteChipView::ButtonPressed(views::Button* sender, 337 void SiteChipView::ButtonPressed(views::Button* sender,
116 const ui::Event& event) { 338 const ui::Event& event) {
117 toolbar_view_->location_bar()->GetOmniboxView()->SetFocus(); 339 toolbar_view_->location_bar()->GetOmniboxView()->SetFocus();
118 toolbar_view_->location_bar()->GetOmniboxView()->SelectAll(true); 340 toolbar_view_->location_bar()->GetOmniboxView()->SelectAll(true);
119 toolbar_view_->location_bar()->GetOmniboxView()->model()-> 341 toolbar_view_->location_bar()->GetOmniboxView()->model()->
120 SetCaretVisibility(true); 342 SetCaretVisibility(true);
121 } 343 }
344
345 void SiteChipView::WriteDragDataForView(View* sender,
346 const gfx::Point& press_pt,
347 OSExchangeData* data) {
348 // TODO(gbillock): Consolidate this with the identical logic in
349 // LocationBarView.
350 content::WebContents* web_contents = toolbar_view_->GetWebContents();
351 FaviconTabHelper* favicon_tab_helper =
352 FaviconTabHelper::FromWebContents(web_contents);
353 gfx::ImageSkia favicon = favicon_tab_helper->GetFavicon().AsImageSkia();
354 button_drag_utils::SetURLAndDragImage(web_contents->GetURL(),
355 web_contents->GetTitle(),
356 favicon,
357 data,
358 sender->GetWidget());
359 }
360
361 int SiteChipView::GetDragOperationsForView(View* sender,
362 const gfx::Point& p) {
363 return ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK;
364 }
365
366 bool SiteChipView::CanStartDragForView(View* sender,
367 const gfx::Point& press_pt,
368 const gfx::Point& p) {
369 return true;
370 }
371
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698