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

Side by Side Diff: chrome/browser/ui/views/sad_tab_view.cc

Issue 1129513002: Sad tab redesign for Windows, Linux and CrOS (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months 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
OLDNEW
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/sad_tab_view.h" 5 #include "chrome/browser/ui/views/sad_tab_view.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/metrics/field_trial.h" 9 #include "base/metrics/field_trial.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/browser_process.h"
msw 2015/05/14 23:50:20 Is this needed?
edwardjung 2015/05/18 12:02:36 Removed
12 #include "chrome/browser/ui/browser.h" 13 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_finder.h" 14 #include "chrome/browser/ui/browser_finder.h"
14 #include "chrome/browser/ui/chrome_pages.h" 15 #include "chrome/browser/ui/chrome_pages.h"
15 #include "chrome/common/url_constants.h" 16 #include "chrome/common/url_constants.h"
16 #include "chrome/grit/generated_resources.h" 17 #include "chrome/grit/generated_resources.h"
17 #include "components/feedback/feedback_util.h" 18 #include "components/feedback/feedback_util.h"
18 #include "content/public/browser/navigation_controller.h" 19 #include "content/public/browser/navigation_controller.h"
19 #include "content/public/browser/web_contents.h" 20 #include "content/public/browser/web_contents.h"
20 #include "grit/components_strings.h" 21 #include "grit/components_strings.h"
21 #include "grit/theme_resources.h" 22 #include "grit/theme_resources.h"
22 #include "ui/base/l10n/l10n_util.h" 23 #include "ui/base/l10n/l10n_util.h"
23 #include "ui/base/resource/resource_bundle.h" 24 #include "ui/base/resource/resource_bundle.h"
24 #include "ui/views/background.h" 25 #include "ui/views/background.h"
26 #include "ui/views/controls/button/blue_button.h"
25 #include "ui/views/controls/button/label_button.h" 27 #include "ui/views/controls/button/label_button.h"
26 #include "ui/views/controls/button/label_button_border.h" 28 #include "ui/views/controls/button/label_button_border.h"
27 #include "ui/views/controls/image_view.h" 29 #include "ui/views/controls/image_view.h"
28 #include "ui/views/controls/label.h" 30 #include "ui/views/controls/label.h"
29 #include "ui/views/controls/link.h" 31 #include "ui/views/controls/link.h"
32 #include "ui/views/controls/scroll_view.h"
msw 2015/05/14 23:50:20 Is this needed?
edwardjung 2015/05/18 12:02:36 Removed. Had experimented with having a scroll vie
33 #include "ui/views/controls/styled_label.h"
30 #include "ui/views/layout/grid_layout.h" 34 #include "ui/views/layout/grid_layout.h"
31 #include "ui/views/widget/widget.h" 35 #include "ui/views/widget/widget.h"
32 36
33 using content::OpenURLParams; 37 using content::OpenURLParams;
34 using content::WebContents; 38 using content::WebContents;
35 39
36 namespace { 40 namespace {
37 41
38 const int kPadding = 20; 42 const int kPadding = 24;
msw 2015/05/14 23:50:20 Find corresponding (or close enough) ui/views/layo
edwardjung 2015/05/18 12:02:35 Switched to the layout constants.
39 const float kMessageSize = 0.65f; 43 const int kParagraphPadding = 16;
40 const SkColor kTextColor = SK_ColorWHITE; 44 const int kTopPadding = 50;
41 const SkColor kCrashColor = SkColorSetRGB(35, 48, 64); 45 const int kIconBottomMargin = 40;
42 const SkColor kKillColor = SkColorSetRGB(57, 48, 88); 46 const int kLineHeight = 24;
47 const int kMaxContentWidth = 600;
48 const int kMinColumnWidth = 120;
49 const SkColor kTextColor = SkColorSetRGB(100, 100, 100);
msw 2015/05/14 23:50:20 Let's see a screenshot with these colors versus my
50 const SkColor kTitleColor = SkColorSetRGB(51, 51, 51);
51 const SkColor kBackgroundColor = SkColorSetRGB(247, 247, 247);
43 52
44 const char kCategoryTagCrash[] = "Crash"; 53 const char kCategoryTagCrash[] = "Crash";
45 54
46 } // namespace 55 } // namespace
47 56
48 SadTabView::SadTabView(WebContents* web_contents, chrome::SadTabKind kind) 57 SadTabView::SadTabView(WebContents* web_contents, chrome::SadTabKind kind)
49 : web_contents_(web_contents), 58 : web_contents_(web_contents),
50 kind_(kind), 59 kind_(kind),
51 painted_(false), 60 painted_(false),
52 message_(NULL), 61 message_(NULL),
53 help_link_(NULL), 62 help_link_(NULL),
54 feedback_link_(NULL), 63 feedback_link_(NULL),
55 reload_button_(NULL) { 64 reload_button_(NULL),
65 title_(NULL) {
msw 2015/05/14 23:50:19 Init the other new members too and use nullptr ins
edwardjung 2015/05/18 12:02:35 Done.
56 DCHECK(web_contents); 66 DCHECK(web_contents);
57 67
58 // Sometimes the user will never see this tab, so keep track of the total 68 // Sometimes the user will never see this tab, so keep track of the total
59 // number of creation events to compare to display events. 69 // number of creation events to compare to display events.
60 // TODO(jamescook): Remove this after R20 stable. Keep it for now so we can 70 // TODO(jamescook): Remove this after R20 stable. Keep it for now so we can
61 // compare R20 to earlier versions. 71 // compare R20 to earlier versions.
62 UMA_HISTOGRAM_COUNTS("SadTab.Created", kind_); 72 UMA_HISTOGRAM_COUNTS("SadTab.Created", kind_);
63 73
64 // These stats should use the same counting approach and bucket size used for 74 // These stats should use the same counting approach and bucket size used for
65 // tab discard events in chromeos::OomPriorityManager so they can be 75 // tab discard events in chromeos::OomPriorityManager so they can be
(...skipping 11 matching lines...) Expand all
77 static int killed = 0; 87 static int killed = 0;
78 killed++; 88 killed++;
79 UMA_HISTOGRAM_CUSTOM_COUNTS( 89 UMA_HISTOGRAM_CUSTOM_COUNTS(
80 "Tabs.SadTab.KillCreated", killed, 1, 1000, 50); 90 "Tabs.SadTab.KillCreated", killed, 1, 1000, 50);
81 break; 91 break;
82 } 92 }
83 default: 93 default:
84 NOTREACHED(); 94 NOTREACHED();
85 } 95 }
86 96
97 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
98 gfx::FontList body_font_list_ = rb.GetFontList(ui::ResourceBundle::BaseFont);
msw 2015/05/14 23:50:20 Don't use the underscore postfix for stack locals.
edwardjung 2015/05/18 12:02:36 Removed.
99
87 // Set the background color. 100 // Set the background color.
88 set_background(views::Background::CreateSolidBackground( 101 set_background(views::Background::CreateSolidBackground(kBackgroundColor));
89 (kind_ == chrome::SAD_TAB_KIND_CRASHED) ? kCrashColor : kKillColor));
90 102
91 views::GridLayout* layout = new views::GridLayout(this); 103 views::GridLayout* layout = new views::GridLayout(this);
92 SetLayoutManager(layout); 104 SetLayoutManager(layout);
93 105
94 const int column_set_id = 0; 106 const int column_set_id = 0;
95 views::ColumnSet* columns = layout->AddColumnSet(column_set_id); 107 views::ColumnSet* columns = layout->AddColumnSet(column_set_id);
96 columns->AddPaddingColumn(1, kPadding); 108 columns->AddPaddingColumn(1, kPadding);
97 columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, 109 columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, 0,
98 0, views::GridLayout::USE_PREF, 0, 0); 110 views::GridLayout::USE_PREF, 0, kMinColumnWidth);
111 columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::LEADING, 0,
112 views::GridLayout::USE_PREF, 0, kMinColumnWidth);
99 columns->AddPaddingColumn(1, kPadding); 113 columns->AddPaddingColumn(1, kPadding);
100 114
101 views::ImageView* image = new views::ImageView(); 115 views::ImageView* image = new views::ImageView();
102 image->SetImage(ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( 116 image->SetImage(
103 (kind_ == chrome::SAD_TAB_KIND_CRASHED) ? IDR_SAD_TAB : IDR_KILLED_TAB)); 117 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(IDR_SAD_TAB));
104 layout->StartRowWithPadding(0, column_set_id, 1, kPadding); 118 layout->AddPaddingRow(1, kTopPadding);
105 layout->AddView(image); 119 layout->StartRow(0, column_set_id);
120 layout->AddView(image, 2, 1);
106 121
107 views::Label* title = CreateLabel(l10n_util::GetStringUTF16( 122 title_ = CreateLabel(l10n_util::GetStringUTF16(
108 (kind_ == chrome::SAD_TAB_KIND_CRASHED) ? 123 (kind_ == chrome::SAD_TAB_KIND_CRASHED) ? IDS_SAD_TAB_TITLE
msw 2015/05/14 23:50:20 nit: maybe cache a local const bool crashed for he
edwardjung 2015/05/18 12:02:35 Done.
109 IDS_SAD_TAB_TITLE : IDS_KILLED_TAB_TITLE)); 124 : IDS_KILLED_TAB_TITLE));
110 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 125 title_->SetFontList(rb.GetFontList(ui::ResourceBundle::LargeFont));
111 title->SetFontList(rb.GetFontList(ui::ResourceBundle::MediumFont)); 126 title_->SetMultiLine(true);
msw 2015/05/14 23:50:20 I wonder if "Aw Snap" or "He's Dead Jim" really ne
edwardjung 2015/05/18 12:02:36 In my testing of Russian and Arabic, He's Dead Jim
msw 2015/05/18 19:24:50 Acknowledged.
112 layout->StartRowWithPadding(0, column_set_id, 0, kPadding); 127 title_->SetEnabledColor(kTitleColor);
113 layout->AddView(title); 128 title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
129 layout->StartRowWithPadding(0, column_set_id, 0, kIconBottomMargin);
130 layout->AddView(title_, 2, 1);
114 131
115 message_ = CreateLabel(l10n_util::GetStringUTF16( 132 message_ = CreateLabel(l10n_util::GetStringUTF16(
116 (kind_ == chrome::SAD_TAB_KIND_CRASHED) ? 133 (kind_ == chrome::SAD_TAB_KIND_CRASHED) ?
117 IDS_SAD_TAB_MESSAGE : IDS_KILLED_TAB_MESSAGE)); 134 IDS_SAD_TAB_MESSAGE : IDS_KILLED_TAB_MESSAGE));
135 message_->SetFontList(body_font_list_);
118 message_->SetMultiLine(true); 136 message_->SetMultiLine(true);
119 layout->StartRowWithPadding(0, column_set_id, 0, kPadding); 137 message_->SetEnabledColor(kTextColor);
120 layout->AddView(message_); 138 message_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
139 message_->SetLineHeight(kLineHeight);
140
141 layout->StartRowWithPadding(0, column_set_id, 0, kParagraphPadding);
142 layout->AddView(message_, 2, 1, views::GridLayout::LEADING,
143 views::GridLayout::LEADING);
121 144
122 if (web_contents_) { 145 if (web_contents_) {
123 layout->StartRowWithPadding(0, column_set_id, 0, kPadding); 146 reload_button_ = new views::BlueButton(
124 reload_button_ = new views::LabelButton( 147 this, l10n_util::GetStringUTF16(IDS_SAD_TAB_RELOAD_LABEL));
125 this, 148 reload_button_->SetFontList(body_font_list_);
126 l10n_util::GetStringUTF16(IDS_SAD_TAB_RELOAD_LABEL)); 149 reload_button_->SetMinSize(gfx::Size(90, 36));
msw 2015/05/14 23:50:20 What does the button look like if this isn't speci
edwardjung 2015/05/18 12:02:36 Looks fine. Remove.
127 reload_button_->SetStyle(views::Button::STYLE_BUTTON);
128 // Always render the reload button with chrome style borders; never rely on
129 // native styles.
130 reload_button_->SetBorder(scoped_ptr<views::Border>(
131 new views::LabelButtonBorder(reload_button_->style())));
132 layout->AddView(reload_button_);
133
134 help_link_ = CreateLink(l10n_util::GetStringUTF16(
135 (kind_ == chrome::SAD_TAB_KIND_CRASHED) ?
136 IDS_SAD_TAB_HELP_LINK : IDS_LEARN_MORE));
137 150
138 if (kind_ == chrome::SAD_TAB_KIND_CRASHED) { 151 if (kind_ == chrome::SAD_TAB_KIND_CRASHED) {
139 size_t offset = 0; 152 size_t offset = 0;
140 base::string16 help_text( 153 base::string16 help_text(
141 l10n_util::GetStringFUTF16(IDS_SAD_TAB_HELP_MESSAGE, 154 l10n_util::GetStringFUTF16(IDS_SAD_TAB_HELP_MESSAGE,
142 base::string16(), &offset)); 155 base::string16(), &offset));
143 views::Label* help_prefix = CreateLabel(help_text.substr(0, offset));
144 views::Label* help_suffix = CreateLabel(help_text.substr(offset));
145 156
146 const int help_column_set_id = 1; 157 base::string16 link_text =
147 views::ColumnSet* help_columns = layout->AddColumnSet(help_column_set_id); 158 l10n_util::GetStringUTF16(IDS_SAD_TAB_HELP_LINK);
148 help_columns->AddPaddingColumn(1, kPadding);
149 // Center three middle columns for the help's [prefix][link][suffix].
150 for (size_t column = 0; column < 3; column++)
151 help_columns->AddColumn(views::GridLayout::CENTER,
152 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0);
153 help_columns->AddPaddingColumn(1, kPadding);
154 159
155 layout->StartRowWithPadding(0, help_column_set_id, 0, kPadding); 160 base::string16 help_prefix = help_text.substr(0, offset);
156 layout->AddView(help_prefix); 161 base::string16 help_suffix = help_text.substr(offset);
157 layout->AddView(help_link_); 162 base::string16 help_message_string = help_prefix;
158 layout->AddView(help_suffix); 163 help_message_string.append(link_text).append(help_suffix);
164
165 help_message_ = new views::StyledLabel(help_message_string, this);
166
167 views::StyledLabel::RangeStyleInfo link_style =
168 views::StyledLabel::RangeStyleInfo::CreateForLink();
169 link_style.font_style = gfx::Font::UNDERLINE;
170 link_style.color = kTextColor;
171
172 views::StyledLabel::RangeStyleInfo normal_style =
173 views::StyledLabel::RangeStyleInfo::CreateForLink();
msw 2015/05/14 23:50:20 This doesn't seem correct, why use CreateForLink f
edwardjung 2015/05/18 12:02:35 Fixed.
174 normal_style.font_style = gfx::Font::NORMAL;
175 normal_style.color = kTextColor;
176 normal_style.is_link = false;
177
178 help_message_->SetBaseFontList(body_font_list_);
179 help_message_->SetDefaultStyle(normal_style);
180 help_message_->SetLineHeight(kLineHeight);
181
182 help_message_->AddStyleRange(
183 gfx::Range(help_prefix.length(), help_message_string.length() - 1),
msw 2015/05/14 23:50:19 Using |help_message_string.length() - 1| is incorr
edwardjung 2015/05/18 12:02:35 Good point. Not all languages will have a punctuat
184 link_style);
185
186 layout->StartRowWithPadding(0, column_set_id, 0, kParagraphPadding);
187 layout->AddView(help_message_, 2, 1, views::GridLayout::LEADING,
188 views::GridLayout::TRAILING);
189 layout->StartRowWithPadding(0, column_set_id, 0, kTopPadding);
190 layout->SkipColumns(1);
159 } else { 191 } else {
192 feedback_link_ =
193 CreateLink(l10n_util::GetStringUTF16(IDS_KILLED_TAB_FEEDBACK_LINK));
194 feedback_link_->SetFontList(body_font_list_);
195 feedback_link_->SetLineHeight(kLineHeight);
196 feedback_link_->SetMultiLine(true);
197 feedback_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
198
160 layout->StartRowWithPadding(0, column_set_id, 0, kPadding); 199 layout->StartRowWithPadding(0, column_set_id, 0, kPadding);
161 layout->AddView(help_link_); 200 layout->AddView(feedback_link_, 2, 1, views::GridLayout::LEADING,
201 views::GridLayout::LEADING);
162 202
163 feedback_link_ = CreateLink( 203 help_link_ = CreateLink(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
164 l10n_util::GetStringUTF16(IDS_KILLED_TAB_FEEDBACK_LINK)); 204 help_link_->SetFontList(body_font_list_);
165 layout->StartRowWithPadding(0, column_set_id, 0, kPadding); 205 layout->StartRowWithPadding(0, column_set_id, 0, kTopPadding);
166 layout->AddView(feedback_link_); 206 layout->AddView(help_link_, 1, 1, views::GridLayout::LEADING,
207 views::GridLayout::CENTER);
167 } 208 }
209 layout->AddView(reload_button_, 1, 1, views::GridLayout::TRAILING,
210 views::GridLayout::LEADING);
168 } 211 }
169 layout->AddPaddingRow(1, kPadding); 212 layout->AddPaddingRow(5, kPadding);
170 } 213 }
171 214
172 SadTabView::~SadTabView() {} 215 SadTabView::~SadTabView() {}
173 216
174 void SadTabView::LinkClicked(views::Link* source, int event_flags) { 217 void SadTabView::LinkClicked(views::Link* source, int event_flags) {
175 DCHECK(web_contents_); 218 DCHECK(web_contents_);
176 if (source == help_link_) { 219 if (source == help_link_) {
177 GURL help_url((kind_ == chrome::SAD_TAB_KIND_CRASHED) ? 220 GURL help_url((kind_ == chrome::SAD_TAB_KIND_CRASHED) ?
178 chrome::kCrashReasonURL : chrome::kKillReasonURL); 221 chrome::kCrashReasonURL : chrome::kKillReasonURL);
179 OpenURLParams params( 222 OpenURLParams params(
180 help_url, content::Referrer(), CURRENT_TAB, 223 help_url, content::Referrer(), CURRENT_TAB,
181 ui::PAGE_TRANSITION_LINK, false); 224 ui::PAGE_TRANSITION_LINK, false);
182 web_contents_->OpenURL(params); 225 web_contents_->OpenURL(params);
183 } else if (source == feedback_link_) { 226 } else if (source == feedback_link_) {
184 chrome::ShowFeedbackPage( 227 chrome::ShowFeedbackPage(
185 chrome::FindBrowserWithWebContents(web_contents_), 228 chrome::FindBrowserWithWebContents(web_contents_),
186 l10n_util::GetStringUTF8(IDS_KILLED_TAB_FEEDBACK_MESSAGE), 229 l10n_util::GetStringUTF8(IDS_KILLED_TAB_FEEDBACK_MESSAGE),
187 std::string(kCategoryTagCrash)); 230 std::string(kCategoryTagCrash));
188 } 231 }
189 } 232 }
190 233
234 void SadTabView::StyledLabelLinkClicked(const gfx::Range& range,
235 int event_flags) {
236 GURL help_url(chrome::kCrashReasonURL);
msw 2015/05/14 23:50:19 As I said in my earlier comment... Don't copy code
edwardjung 2015/05/18 12:02:35 Switched to call LinkClicked.
237 OpenURLParams params(help_url, content::Referrer(), CURRENT_TAB,
238 ui::PAGE_TRANSITION_LINK, false);
239 web_contents_->OpenURL(params);
240 }
241
191 void SadTabView::ButtonPressed(views::Button* sender, 242 void SadTabView::ButtonPressed(views::Button* sender,
192 const ui::Event& event) { 243 const ui::Event& event) {
193 DCHECK(web_contents_); 244 DCHECK(web_contents_);
194 DCHECK_EQ(reload_button_, sender); 245 DCHECK_EQ(reload_button_, sender);
195 web_contents_->GetController().Reload(true); 246 web_contents_->GetController().Reload(true);
196 } 247 }
197 248
198 void SadTabView::Layout() { 249 void SadTabView::Layout() {
199 // Specify the maximum message width explicitly. 250 // Specify the maximum message width explicitly.
200 message_->SizeToFit(static_cast<int>(width() * kMessageSize)); 251 int messageWidth = width() - kPadding * 2;
msw 2015/05/14 23:50:20 nit: use the unix_hacker naming convention.
edwardjung 2015/05/18 12:02:35 Done.
252 int width = messageWidth > kMaxContentWidth ? kMaxContentWidth : messageWidth;
msw 2015/05/14 23:50:19 Just do const int width = std::min(width() - kPadd
edwardjung 2015/05/18 12:02:36 Done.
253 message_->SizeToFit(width);
254 title_->SizeToFit(width);
255
256 if (kind_ == chrome::SAD_TAB_KIND_KILLED) {
msw 2015/05/14 23:50:20 Just check if |feedback_link_| and |help_message_|
edwardjung 2015/05/18 12:02:36 Done.
257 feedback_link_->SizeToFit(width);
258 } else if (kind_ == chrome::SAD_TAB_KIND_CRASHED) {
259 help_message_->SizeToFit(width);
260 }
201 View::Layout(); 261 View::Layout();
202 } 262 }
203 263
204 void SadTabView::OnPaint(gfx::Canvas* canvas) { 264 void SadTabView::OnPaint(gfx::Canvas* canvas) {
205 if (!painted_) { 265 if (!painted_) {
206 // User actually saw the error, keep track for user experience stats. 266 // User actually saw the error, keep track for user experience stats.
207 // TODO(jamescook): Remove this after R20 stable. Keep it for now so we can 267 // TODO(jamescook): Remove this after R20 stable. Keep it for now so we can
208 // compare R20 to earlier versions. 268 // compare R20 to earlier versions.
209 UMA_HISTOGRAM_COUNTS("SadTab.Displayed", kind_); 269 UMA_HISTOGRAM_COUNTS("SadTab.Displayed", kind_);
210 270
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 } 334 }
275 335
276 namespace chrome { 336 namespace chrome {
277 337
278 SadTab* SadTab::Create(content::WebContents* web_contents, 338 SadTab* SadTab::Create(content::WebContents* web_contents,
279 SadTabKind kind) { 339 SadTabKind kind) {
280 return new SadTabView(web_contents, kind); 340 return new SadTabView(web_contents, kind);
281 } 341 }
282 342
283 } // namespace chrome 343 } // namespace chrome
OLDNEW
« chrome/app/theme/theme_resources.grd ('K') | « chrome/browser/ui/views/sad_tab_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698