172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/sad_tab_view.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/utf_string_conversions.h" 84a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/google/google_util.h" 94a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/common/url_constants.h" 10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h" 11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_delegate.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/locale_settings.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/skia/include/effects/SkGradientShader.h" 1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h" 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/canvas.h" 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/canvas_skia.h" 2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/size.h" 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/skia_util.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kSadTabOffset = -64; 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kIconTitleSpacing = 20; 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kTitleMessageSpacing = 15; 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kMessageBottomMargin = 20; 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const float kMessageSize = 0.65f; 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const SkColor kTitleColor = SK_ColorWHITE; 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const SkColor kMessageColor = SK_ColorWHITE; 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const SkColor kLinkColor = SK_ColorWHITE; 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic const SkColor kCrashBackgroundColor = SkColorSetRGB(35, 48, 64); 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic const SkColor kCrashBackgroundEndColor = SkColorSetRGB(35, 48, 64); 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// TODO(gspencer): update these colors when the UI team has picked 3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// official versions. See http://crosbug.com/10711. 3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic const SkColor kKillBackgroundColor = SkColorSetRGB(57, 48, 88); 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic const SkColor kKillBackgroundEndColor = SkColorSetRGB(57, 48, 88); 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 38201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Font size correction. 39201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#if defined(CROS_FONTS_USING_BCI) 40201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstatic const int kTitleFontSizeDelta = 1; 41201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstatic const int kMessageFontSizeDelta = 0; 42201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#else 43201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstatic const int kTitleFontSizeDelta = 2; 44201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstatic const int kMessageFontSizeDelta = 1; 45201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#endif 46201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSkBitmap* SadTabView::sad_tab_bitmap_ = NULL; 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Font* SadTabView::title_font_ = NULL; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Font* SadTabView::message_font_ = NULL; 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::wstring SadTabView::title_; 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::wstring SadTabView::message_; 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint SadTabView::title_width_; 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSadTabView::SadTabView(TabContents* tab_contents, Kind kind) 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : tab_contents_(tab_contents), 5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen learn_more_link_(NULL), 5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen kind_(kind) { 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(tab_contents); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen InitClass(kind); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tab_contents != NULL) { 643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen learn_more_link_ = 653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen new views::Link(UTF16ToWide(l10n_util::GetStringUTF16(IDS_LEARN_MORE))); 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch learn_more_link_->SetFont(*message_font_); 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch learn_more_link_->SetNormalColor(kLinkColor); 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch learn_more_link_->SetController(this); 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddChildView(learn_more_link_); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 73dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenSadTabView::~SadTabView() {} 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid SadTabView::OnPaint(gfx::Canvas* canvas) { 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkPaint paint; 7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SkSafeUnref(paint.setShader( 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen gfx::CreateGradientShader( 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 0, 8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen height(), 8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen kind_ == CRASHED ? kCrashBackgroundColor : kKillBackgroundColor, 8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen kind_ == CRASHED ? 8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen kCrashBackgroundEndColor : kKillBackgroundEndColor))); 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch paint.setStyle(SkPaint::kFill_Style); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch canvas->AsCanvasSkia()->drawRectCoords( 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 0, SkIntToScalar(width()), SkIntToScalar(height()), paint); 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch canvas->DrawBitmapInt(*sad_tab_bitmap_, icon_bounds_.x(), icon_bounds_.y()); 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen canvas->DrawStringInt(WideToUTF16Hack(title_), *title_font_, kTitleColor, 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen title_bounds_.x(), title_bounds_.y(), 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen title_bounds_.width(), title_bounds_.height(), 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Canvas::TEXT_ALIGN_CENTER); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen canvas->DrawStringInt(WideToUTF16Hack(message_), *message_font_, 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen kMessageColor, message_bounds_.x(), message_bounds_.y(), 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch message_bounds_.width(), message_bounds_.height(), 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Canvas::MULTI_LINE); 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (learn_more_link_ != NULL) 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch learn_more_link_->SetBounds(link_bounds_.x(), link_bounds_.y(), 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch link_bounds_.width(), link_bounds_.height()); 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SadTabView::Layout() { 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int icon_width = sad_tab_bitmap_->width(); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int icon_height = sad_tab_bitmap_->height(); 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int icon_x = (width() - icon_width) / 2; 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int icon_y = ((height() - icon_height) / 2) + kSadTabOffset; 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch icon_bounds_.SetRect(icon_x, icon_y, icon_width, icon_height); 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int title_x = (width() - title_width_) / 2; 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int title_y = icon_bounds_.bottom() + kIconTitleSpacing; 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int title_height = title_font_->GetHeight(); 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch title_bounds_.SetRect(title_x, title_y, title_width_, title_height); 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::CanvasSkia cc(0, 0, true); 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int message_width = static_cast<int>(width() * kMessageSize); 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int message_height = 0; 120201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch cc.SizeStringInt(WideToUTF16Hack(message_), *message_font_, &message_width, 121201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &message_height, gfx::Canvas::MULTI_LINE); 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int message_x = (width() - message_width) / 2; 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int message_y = title_bounds_.bottom() + kTitleMessageSpacing; 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch message_bounds_.SetRect(message_x, message_y, message_width, message_height); 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (learn_more_link_ != NULL) { 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size sz = learn_more_link_->GetPreferredSize(); 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Insets insets = learn_more_link_->GetInsets(); 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch link_bounds_.SetRect((width() - sz.width()) / 2, 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch message_bounds_.bottom() + kTitleMessageSpacing - 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch insets.top(), sz.width(), sz.height()); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SadTabView::LinkActivated(views::Link* source, int event_flags) { 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tab_contents_ != NULL && source == learn_more_link_) { 1374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch GURL help_url = 13872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen google_util::AppendGoogleLocaleParam(GURL(kind_ == CRASHED ? 13972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen chrome::kCrashReasonURL : 14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen chrome::kKillReasonURL)); 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen tab_contents_->OpenURL(help_url, GURL(), CURRENT_TAB, PageTransition::LINK); 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SadTabView::InitClass(Kind kind) { 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static bool initialized = false; 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!initialized) { 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch title_font_ = new gfx::Font( 151201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch rb.GetFont(ResourceBundle::BaseFont).DeriveFont(kTitleFontSizeDelta, 152201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch gfx::Font::BOLD)); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch message_font_ = new gfx::Font( 154201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch rb.GetFont(ResourceBundle::BaseFont).DeriveFont(kMessageFontSizeDelta)); 15572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sad_tab_bitmap_ = rb.GetBitmapNamed( 15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen kind == CRASHED ? IDR_SAD_TAB : IDR_KILLED_TAB); 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen title_ = UTF16ToWide(l10n_util::GetStringUTF16( 15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen kind == CRASHED ? IDS_SAD_TAB_TITLE : IDS_KILLED_TAB_TITLE)); 1603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen title_width_ = title_font_->GetStringWidth(WideToUTF16Hack(title_)); 16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen message_ = UTF16ToWide(l10n_util::GetStringUTF16( 16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen kind == CRASHED ? IDS_SAD_TAB_MESSAGE : IDS_KILLED_TAB_MESSAGE)); 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch initialized = true; 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 167