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

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

Issue 7610011: Update Sad Tab help text and link. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix message centering. Created 9 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "base/metrics/histogram.h" 7 #include "base/metrics/histogram.h"
8 #include "base/utf_string_conversions.h" 8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/google/google_util.h" 9 #include "chrome/browser/google/google_util.h"
10 #include "chrome/browser/ui/browser.h" 10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/webui/bug_report_ui.h" 11 #include "chrome/browser/ui/webui/bug_report_ui.h"
12 #include "chrome/browser/userfeedback/proto/extension.pb.h" 12 #include "chrome/browser/userfeedback/proto/extension.pb.h"
13 #include "chrome/common/url_constants.h" 13 #include "chrome/common/url_constants.h"
14 #include "content/browser/tab_contents/tab_contents.h" 14 #include "content/browser/tab_contents/tab_contents.h"
15 #include "content/browser/tab_contents/tab_contents_delegate.h"
16 #include "grit/generated_resources.h" 15 #include "grit/generated_resources.h"
17 #include "grit/locale_settings.h"
18 #include "grit/theme_resources.h" 16 #include "grit/theme_resources.h"
19 #include "third_party/skia/include/effects/SkGradientShader.h"
20 #include "ui/base/l10n/l10n_util.h" 17 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/base/resource/resource_bundle.h" 18 #include "ui/base/resource/resource_bundle.h"
22 #include "ui/gfx/canvas.h"
23 #include "ui/gfx/canvas_skia.h"
24 #include "ui/gfx/font.h" 19 #include "ui/gfx/font.h"
25 #include "ui/gfx/size.h"
26 #include "ui/gfx/skia_util.h"
27 #include "views/controls/link.h" 20 #include "views/controls/link.h"
21 #include "views/controls/label.h"
22 #include "views/controls/image_view.h"
23 #include "views/layout/box_layout.h"
24 #include "views/layout/center_layout.h"
28 25
29 static const int kSadTabOffset = -64; 26 static const int kSadTabOffset = -64;
30 static const int kIconTitleSpacing = 20; 27 static const int kSpacing = 20;
31 static const int kTitleMessageSpacing = 15;
32 static const int kMessageBottomMargin = 20;
33 static const float kMessageSize = 0.65f; 28 static const float kMessageSize = 0.65f;
34 static const SkColor kTitleColor = SK_ColorWHITE; 29 static const SkColor kTextColor = SK_ColorWHITE;
35 static const SkColor kMessageColor = SK_ColorWHITE; 30 static const SkColor kCrashColor1 = SkColorSetRGB(35, 48, 64);
Peter Kasting 2011/08/31 17:28:34 Seems like we can do away with one of the copies o
msw 2011/09/01 03:30:49 Done.
36 static const SkColor kLinkColor = SK_ColorWHITE; 31 static const SkColor kCrashColor2 = SkColorSetRGB(35, 48, 64);
37 static const SkColor kCrashBackgroundColor = SkColorSetRGB(35, 48, 64);
38 static const SkColor kCrashBackgroundEndColor = SkColorSetRGB(35, 48, 64);
39 // TODO(gspencer): update these colors when the UI team has picked 32 // TODO(gspencer): update these colors when the UI team has picked
40 // official versions. See http://crosbug.com/10711. 33 // official versions. See http://crosbug.com/10711.
41 static const SkColor kKillBackgroundColor = SkColorSetRGB(57, 48, 88); 34 static const SkColor kKillColor1 = SkColorSetRGB(57, 48, 88);
42 static const SkColor kKillBackgroundEndColor = SkColorSetRGB(57, 48, 88); 35 static const SkColor kKillColor2 = SkColorSetRGB(57, 48, 88);
43 static const int kMessageFlags = gfx::Canvas::MULTI_LINE |
44 gfx::Canvas::NO_ELLIPSIS | gfx::Canvas::TEXT_ALIGN_CENTER;
45 36
46 // Font size correction. 37 // Font size correction.
47 #if defined(CROS_FONTS_USING_BCI) 38 #if defined(CROS_FONTS_USING_BCI)
48 static const int kTitleFontSizeDelta = 1; 39 static const int kTitleFontSizeDelta = 1;
49 static const int kMessageFontSizeDelta = 0; 40 static const int kMessageFontSizeDelta = 0;
50 #else 41 #else
51 static const int kTitleFontSizeDelta = 2; 42 static const int kTitleFontSizeDelta = 2;
52 static const int kMessageFontSizeDelta = 1; 43 static const int kMessageFontSizeDelta = 1;
53 #endif 44 #endif
54 45
55 SadTabView::SadTabView(TabContents* tab_contents, Kind kind) 46 SadTabView::SadTabView(TabContents* tab_contents, Kind kind)
56 : tab_contents_(tab_contents), 47 : tab_contents_(tab_contents),
57 learn_more_link_(NULL),
58 feedback_link_(NULL),
59 kind_(kind), 48 kind_(kind),
60 painted_(false) { 49 painted_(false) {
61 DCHECK(tab_contents); 50 DCHECK(tab_contents);
62 51
63 // Sometimes the user will never see this tab, so keep track of the total 52 // Sometimes the user will never see this tab, so keep track of the total
64 // number of creation events to compare to display events. 53 // number of creation events to compare to display events.
65 UMA_HISTOGRAM_COUNTS("SadTab.Created", kind); 54 UMA_HISTOGRAM_COUNTS("SadTab.Created", kind_);
66 55
67 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 56 // Set the background gradient.
68 title_font_ = new gfx::Font( 57 SkColor color1 = (kind_ == CRASHED) ? kCrashColor1 : kKillColor1;
69 rb.GetFont(ResourceBundle::BaseFont).DeriveFont(kTitleFontSizeDelta, 58 SkColor color2 = (kind_ == CRASHED) ? kCrashColor2 : kKillColor2;
70 gfx::Font::BOLD)); 59 set_background(
71 message_font_ = new gfx::Font( 60 views::Background::CreateVerticalGradientBackground(color1, color2));
72 rb.GetFont(ResourceBundle::BaseFont).DeriveFont(kMessageFontSizeDelta));
73 sad_tab_bitmap_ = rb.GetBitmapNamed(
74 kind == CRASHED ? IDR_SAD_TAB : IDR_KILLED_TAB);
75
76 title_ = l10n_util::GetStringUTF16(
77 kind == CRASHED ? IDS_SAD_TAB_TITLE : IDS_KILLED_TAB_TITLE);
78 title_width_ = title_font_->GetStringWidth(title_);
79 message_ = l10n_util::GetStringUTF16(
80 kind == CRASHED ? IDS_SAD_TAB_MESSAGE : IDS_KILLED_TAB_MESSAGE);
81
82 if (tab_contents != NULL) {
83 learn_more_link_ =
84 new views::Link(UTF16ToWide(l10n_util::GetStringUTF16(IDS_LEARN_MORE)));
85 learn_more_link_->SetFont(*message_font_);
86 learn_more_link_->SetNormalColor(kLinkColor);
87 learn_more_link_->set_listener(this);
88 AddChildView(learn_more_link_);
89
90 if (kind == KILLED) {
91 feedback_link_ = new views::Link(
92 UTF16ToWide(l10n_util::GetStringUTF16(IDS_KILLED_TAB_FEEDBACK_LINK)));
93 feedback_link_->SetFont(*message_font_);
94 feedback_link_->SetNormalColor(kLinkColor);
95 feedback_link_->set_listener(this);
96 AddChildView(feedback_link_);
97 }
98 }
99 } 61 }
100 62
101 SadTabView::~SadTabView() {} 63 SadTabView::~SadTabView() {}
102 64
103 void SadTabView::OnPaint(gfx::Canvas* canvas) {
104 if (!painted_) {
105 // User actually saw the error, keep track for user experience stats.
106 UMA_HISTOGRAM_COUNTS("SadTab.Displayed", kind_);
107 painted_ = true;
108 }
109 SkPaint paint;
110 SkSafeUnref(paint.setShader(
111 gfx::CreateGradientShader(
112 0,
113 height(),
114 kind_ == CRASHED ? kCrashBackgroundColor : kKillBackgroundColor,
115 kind_ == CRASHED ?
116 kCrashBackgroundEndColor : kKillBackgroundEndColor)));
117 paint.setStyle(SkPaint::kFill_Style);
118 canvas->AsCanvasSkia()->drawRectCoords(
119 0, 0, SkIntToScalar(width()), SkIntToScalar(height()), paint);
120
121 canvas->DrawBitmapInt(*sad_tab_bitmap_, icon_bounds_.x(), icon_bounds_.y());
122
123 canvas->DrawStringInt(title_, *title_font_, kTitleColor,
124 title_bounds_.x(), title_bounds_.y(),
125 title_bounds_.width(), title_bounds_.height(),
126 gfx::Canvas::TEXT_ALIGN_CENTER);
127
128 canvas->DrawStringInt(message_, *message_font_,
129 kMessageColor, message_bounds_.x(), message_bounds_.y(),
130 message_bounds_.width(), message_bounds_.height(),
131 kMessageFlags);
132
133 if (learn_more_link_ != NULL) {
134 learn_more_link_->SetBounds(
135 learn_more_bounds_.x(), learn_more_bounds_.y(),
136 learn_more_bounds_.width(), learn_more_bounds_.height());
137 }
138 if (feedback_link_ != NULL) {
139 feedback_link_->SetBounds(
140 feedback_bounds_.x(), feedback_bounds_.y(),
141 feedback_bounds_.width(), feedback_bounds_.height());
142 }
143 }
144
145 void SadTabView::Layout() {
146 int icon_width = sad_tab_bitmap_->width();
147 int icon_height = sad_tab_bitmap_->height();
148 int icon_x = (width() - icon_width) / 2;
149 int icon_y = ((height() - icon_height) / 2) + kSadTabOffset;
150 icon_bounds_.SetRect(icon_x, icon_y, icon_width, icon_height);
151
152 int title_x = (width() - title_width_) / 2;
153 int title_y = icon_bounds_.bottom() + kIconTitleSpacing;
154 int title_height = title_font_->GetHeight();
155 title_bounds_.SetRect(title_x, title_y, title_width_, title_height);
156
157 int message_width = static_cast<int>(width() * kMessageSize);
158 int message_height = 0;
159 gfx::CanvasSkia::SizeStringInt(message_,
160 *message_font_, &message_width,
161 &message_height, kMessageFlags);
162 int message_x = (width() - message_width) / 2;
163 int message_y = title_bounds_.bottom() + kTitleMessageSpacing;
164 message_bounds_.SetRect(message_x, message_y, message_width, message_height);
165 int bottom = message_bounds_.bottom();
166
167 if (learn_more_link_ != NULL) {
168 gfx::Size sz = learn_more_link_->GetPreferredSize();
169 gfx::Insets insets = learn_more_link_->GetInsets();
170 learn_more_bounds_.SetRect((width() - sz.width()) / 2,
171 bottom + kTitleMessageSpacing - insets.top(),
172 sz.width(),
173 sz.height());
174 bottom = learn_more_bounds_.bottom();
175 }
176
177 if (feedback_link_ != NULL) {
178 gfx::Size sz = feedback_link_->GetPreferredSize();
179 gfx::Insets insets = feedback_link_->GetInsets();
180 feedback_bounds_.SetRect((width() - sz.width()) / 2,
181 bottom + kTitleMessageSpacing - insets.top(),
182 sz.width(),
183 sz.height());
184 }
185 }
186
187 void SadTabView::LinkClicked(views::Link* source, int event_flags) { 65 void SadTabView::LinkClicked(views::Link* source, int event_flags) {
188 if (tab_contents_ != NULL && source == learn_more_link_) { 66 if (tab_contents_ != NULL && source == help_link_) {
189 GURL help_url = 67 GURL help_url =
190 google_util::AppendGoogleLocaleParam(GURL(kind_ == CRASHED ? 68 google_util::AppendGoogleLocaleParam(GURL(kind_ == CRASHED ?
191 chrome::kCrashReasonURL : 69 chrome::kCrashReasonURL :
192 chrome::kKillReasonURL)); 70 chrome::kKillReasonURL));
193 tab_contents_->OpenURL(help_url, GURL(), CURRENT_TAB, PageTransition::LINK); 71 tab_contents_->OpenURL(help_url, GURL(), CURRENT_TAB, PageTransition::LINK);
194 } else if (tab_contents_ != NULL && source == feedback_link_) { 72 } else if (tab_contents_ != NULL && source == feedback_link_) {
195 browser::ShowHtmlBugReportView( 73 browser::ShowHtmlBugReportView(
196 Browser::GetBrowserForController(&tab_contents_->controller(), NULL), 74 Browser::GetBrowserForController(&tab_contents_->controller(), NULL),
197 l10n_util::GetStringUTF8(IDS_KILLED_TAB_FEEDBACK_MESSAGE), 75 l10n_util::GetStringUTF8(IDS_KILLED_TAB_FEEDBACK_MESSAGE),
198 userfeedback::ChromeOsData_ChromeOsCategory_CRASH); 76 userfeedback::ChromeOsData_ChromeOsCategory_CRASH);
199 } 77 }
200 } 78 }
79
80 void SadTabView::Layout() {
81 // Specify the maximum message width explicitly.
82 message_->SizeToFit(static_cast<int>(width() * kMessageSize));
83 // Layout centers |contents_view_| and |message_view_| in the SadTabView.
84 View::Layout();
85 // Run |message_view_| layout explicity, to center |message_|.
86 message_view_->Layout();
Peter Kasting 2011/08/31 17:28:34 Why is this necessary? Shouldn't the Layout() cal
msw 2011/09/01 03:30:49 I'm glad sky joined the review... The new GridLayo
87 }
88
89 void SadTabView::ViewHierarchyChanged(bool is_add,
90 views::View* parent,
91 views::View* child) {
92 if (child != this || !is_add)
93 return;
94
95 // Center the actual contents in |contents_view_| within the SadTabView.
96 SetLayoutManager(new views::CenterLayout());
97 contents_view_ = new views::View();
98 contents_view_->SetLayoutManager(
99 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, kSpacing));
100 AddChildView(contents_view_);
101
102 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
Peter Kasting 2011/08/31 17:28:34 Nit: Push each of these down to just above their f
msw 2011/09/01 03:30:49 Done.
103 const gfx::Font& base_font = rb.GetFont(ResourceBundle::BaseFont);
104
105 int image = (kind_ == CRASHED) ? IDR_SAD_TAB : IDR_KILLED_TAB;
Peter Kasting 2011/08/31 17:28:34 Nit: Just roll this into the call below and avoid
msw 2011/09/01 03:30:49 Done.
106 image_ = new views::ImageView();
107 image_->SetImage(rb.GetBitmapNamed(image));
108 contents_view_->AddChildView(image_);
109
110 int title = (kind_ == CRASHED) ? IDS_SAD_TAB_TITLE : IDS_KILLED_TAB_TITLE;
111 title_ = new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(title)));
112 title_->SetFont(base_font.DeriveFont(kTitleFontSizeDelta, gfx::Font::BOLD));
113 title_->SetColor(kTextColor);
114 contents_view_->AddChildView(title_);
115
116 int msg = (kind_ == CRASHED) ? IDS_SAD_TAB_MESSAGE : IDS_KILLED_TAB_MESSAGE;
117 message_ = new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(msg)));
118 message_->SetFont(base_font.DeriveFont(kMessageFontSizeDelta));
119 message_->SetColor(kTextColor);
120 message_->SetMultiLine(true);
121 // Center the label horizontally for when it's less wide than other views.
122 // Otherwise, the box layout will expand the label to the full sad tab width.
123 message_view_ = new views::View();
124 message_view_->SetLayoutManager(new views::CenterLayout());
125 message_view_->AddChildView(message_);
126 contents_view_->AddChildView(message_view_);
127
128 if (tab_contents_) {
129 size_t link = (kind_ == CRASHED) ? IDS_SAD_TAB_HELP_LINK : IDS_LEARN_MORE;
130 std::wstring help_link(UTF16ToWide(l10n_util::GetStringUTF16(link)));
131 help_link_ = new views::Link(help_link);
132 help_link_->SetFont(base_font.DeriveFont(kMessageFontSizeDelta));
133 help_link_->SetNormalColor(kTextColor);
134 help_link_->set_listener(this);
135
136 if (kind_ == CRASHED) {
137 // |help_view_| centers |help_contents_view_|.
138 help_view_ = new views::View();
139 help_view_->SetLayoutManager(new views::CenterLayout());
140 contents_view_->AddChildView(help_view_);
141
142 // |help_contents_view_| lays out [HELP PREFIX][HELP LINK][HELP SUFFIX].
143 help_contents_view_ = new views::View();
144 help_contents_view_->SetLayoutManager(
145 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
146 help_view_->AddChildView(help_contents_view_);
147
148 size_t offset = 0;
149 int help = IDS_SAD_TAB_HELP_MESSAGE;
150 string16 help_text(l10n_util::GetStringFUTF16(help, string16(), &offset));
151
152 help_prefix_ = new views::Label(UTF16ToWide(help_text.substr(0, offset)));
153 help_prefix_->SetFont(base_font.DeriveFont(kMessageFontSizeDelta));
154 help_prefix_->SetColor(kTextColor);
155 help_contents_view_->AddChildView(help_prefix_);
156
157 help_contents_view_->AddChildView(help_link_);
158
159 help_suffix_ = new views::Label(UTF16ToWide(help_text.substr(offset)));
160 help_suffix_->SetFont(base_font.DeriveFont(kMessageFontSizeDelta));
161 help_suffix_->SetColor(kTextColor);
162 help_contents_view_->AddChildView(help_suffix_);
163 } else {
164 contents_view_->AddChildView(help_link_);
165
166 feedback_link_ = new views::Link(UTF16ToWide(
167 l10n_util::GetStringUTF16(IDS_KILLED_TAB_FEEDBACK_LINK)));
168 feedback_link_->SetFont(base_font.DeriveFont(kMessageFontSizeDelta));
169 feedback_link_->SetNormalColor(kTextColor);
170 feedback_link_->set_listener(this);
171 contents_view_->AddChildView(feedback_link_);
172 }
173 }
174 }
175
176 void SadTabView::OnPaint(gfx::Canvas* canvas) {
177 if (!painted_) {
178 // User actually saw the error, keep track for user experience stats.
179 UMA_HISTOGRAM_COUNTS("SadTab.Displayed", kind_);
180 painted_ = true;
181 }
182 View::OnPaint(canvas);
183 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698