Home | History | Annotate | Download | only in views
      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
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/views/sad_tab_view.h"
      6 
      7 #include "base/utf_string_conversions.h"
      8 #include "chrome/browser/google/google_util.h"
      9 #include "chrome/common/url_constants.h"
     10 #include "content/browser/tab_contents/tab_contents.h"
     11 #include "content/browser/tab_contents/tab_contents_delegate.h"
     12 #include "grit/generated_resources.h"
     13 #include "grit/locale_settings.h"
     14 #include "grit/theme_resources.h"
     15 #include "third_party/skia/include/effects/SkGradientShader.h"
     16 #include "ui/base/l10n/l10n_util.h"
     17 #include "ui/base/resource/resource_bundle.h"
     18 #include "ui/gfx/canvas.h"
     19 #include "ui/gfx/canvas_skia.h"
     20 #include "ui/gfx/size.h"
     21 #include "ui/gfx/skia_util.h"
     22 
     23 static const int kSadTabOffset = -64;
     24 static const int kIconTitleSpacing = 20;
     25 static const int kTitleMessageSpacing = 15;
     26 static const int kMessageBottomMargin = 20;
     27 static const float kMessageSize = 0.65f;
     28 static const SkColor kTitleColor = SK_ColorWHITE;
     29 static const SkColor kMessageColor = SK_ColorWHITE;
     30 static const SkColor kLinkColor = SK_ColorWHITE;
     31 static const SkColor kCrashBackgroundColor = SkColorSetRGB(35, 48, 64);
     32 static const SkColor kCrashBackgroundEndColor = SkColorSetRGB(35, 48, 64);
     33 // TODO(gspencer): update these colors when the UI team has picked
     34 // official versions.  See http://crosbug.com/10711.
     35 static const SkColor kKillBackgroundColor = SkColorSetRGB(57, 48, 88);
     36 static const SkColor kKillBackgroundEndColor = SkColorSetRGB(57, 48, 88);
     37 
     38 // Font size correction.
     39 #if defined(CROS_FONTS_USING_BCI)
     40 static const int kTitleFontSizeDelta = 1;
     41 static const int kMessageFontSizeDelta = 0;
     42 #else
     43 static const int kTitleFontSizeDelta = 2;
     44 static const int kMessageFontSizeDelta = 1;
     45 #endif
     46 
     47 // static
     48 SkBitmap* SadTabView::sad_tab_bitmap_ = NULL;
     49 gfx::Font* SadTabView::title_font_ = NULL;
     50 gfx::Font* SadTabView::message_font_ = NULL;
     51 std::wstring SadTabView::title_;
     52 std::wstring SadTabView::message_;
     53 int SadTabView::title_width_;
     54 
     55 SadTabView::SadTabView(TabContents* tab_contents, Kind kind)
     56     : tab_contents_(tab_contents),
     57       learn_more_link_(NULL),
     58       kind_(kind) {
     59   DCHECK(tab_contents);
     60 
     61   InitClass(kind);
     62 
     63   if (tab_contents != NULL) {
     64     learn_more_link_ =
     65         new views::Link(UTF16ToWide(l10n_util::GetStringUTF16(IDS_LEARN_MORE)));
     66     learn_more_link_->SetFont(*message_font_);
     67     learn_more_link_->SetNormalColor(kLinkColor);
     68     learn_more_link_->SetController(this);
     69     AddChildView(learn_more_link_);
     70   }
     71 }
     72 
     73 SadTabView::~SadTabView() {}
     74 
     75 void SadTabView::OnPaint(gfx::Canvas* canvas) {
     76   SkPaint paint;
     77   SkSafeUnref(paint.setShader(
     78       gfx::CreateGradientShader(
     79           0,
     80           height(),
     81           kind_ == CRASHED ? kCrashBackgroundColor : kKillBackgroundColor,
     82           kind_ == CRASHED ?
     83             kCrashBackgroundEndColor : kKillBackgroundEndColor)));
     84   paint.setStyle(SkPaint::kFill_Style);
     85   canvas->AsCanvasSkia()->drawRectCoords(
     86       0, 0, SkIntToScalar(width()), SkIntToScalar(height()), paint);
     87 
     88   canvas->DrawBitmapInt(*sad_tab_bitmap_, icon_bounds_.x(), icon_bounds_.y());
     89 
     90   canvas->DrawStringInt(WideToUTF16Hack(title_), *title_font_, kTitleColor,
     91                         title_bounds_.x(), title_bounds_.y(),
     92                         title_bounds_.width(), title_bounds_.height(),
     93                         gfx::Canvas::TEXT_ALIGN_CENTER);
     94 
     95   canvas->DrawStringInt(WideToUTF16Hack(message_), *message_font_,
     96                         kMessageColor, message_bounds_.x(), message_bounds_.y(),
     97                         message_bounds_.width(), message_bounds_.height(),
     98                         gfx::Canvas::MULTI_LINE);
     99 
    100   if (learn_more_link_ != NULL)
    101     learn_more_link_->SetBounds(link_bounds_.x(), link_bounds_.y(),
    102                                 link_bounds_.width(), link_bounds_.height());
    103 }
    104 
    105 void SadTabView::Layout() {
    106   int icon_width = sad_tab_bitmap_->width();
    107   int icon_height = sad_tab_bitmap_->height();
    108   int icon_x = (width() - icon_width) / 2;
    109   int icon_y = ((height() - icon_height) / 2) + kSadTabOffset;
    110   icon_bounds_.SetRect(icon_x, icon_y, icon_width, icon_height);
    111 
    112   int title_x = (width() - title_width_) / 2;
    113   int title_y = icon_bounds_.bottom() + kIconTitleSpacing;
    114   int title_height = title_font_->GetHeight();
    115   title_bounds_.SetRect(title_x, title_y, title_width_, title_height);
    116 
    117   gfx::CanvasSkia cc(0, 0, true);
    118   int message_width = static_cast<int>(width() * kMessageSize);
    119   int message_height = 0;
    120   cc.SizeStringInt(WideToUTF16Hack(message_), *message_font_, &message_width,
    121                    &message_height, gfx::Canvas::MULTI_LINE);
    122   int message_x = (width() - message_width) / 2;
    123   int message_y = title_bounds_.bottom() + kTitleMessageSpacing;
    124   message_bounds_.SetRect(message_x, message_y, message_width, message_height);
    125 
    126   if (learn_more_link_ != NULL) {
    127     gfx::Size sz = learn_more_link_->GetPreferredSize();
    128     gfx::Insets insets = learn_more_link_->GetInsets();
    129     link_bounds_.SetRect((width() - sz.width()) / 2,
    130                          message_bounds_.bottom() + kTitleMessageSpacing -
    131                          insets.top(), sz.width(), sz.height());
    132   }
    133 }
    134 
    135 void SadTabView::LinkActivated(views::Link* source, int event_flags) {
    136   if (tab_contents_ != NULL && source == learn_more_link_) {
    137     GURL help_url =
    138         google_util::AppendGoogleLocaleParam(GURL(kind_ == CRASHED ?
    139                                                   chrome::kCrashReasonURL :
    140                                                   chrome::kKillReasonURL));
    141     tab_contents_->OpenURL(help_url, GURL(), CURRENT_TAB, PageTransition::LINK);
    142   }
    143 }
    144 
    145 // static
    146 void SadTabView::InitClass(Kind kind) {
    147   static bool initialized = false;
    148   if (!initialized) {
    149     ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    150     title_font_ = new gfx::Font(
    151         rb.GetFont(ResourceBundle::BaseFont).DeriveFont(kTitleFontSizeDelta,
    152                                                         gfx::Font::BOLD));
    153     message_font_ = new gfx::Font(
    154         rb.GetFont(ResourceBundle::BaseFont).DeriveFont(kMessageFontSizeDelta));
    155     sad_tab_bitmap_ = rb.GetBitmapNamed(
    156         kind == CRASHED ? IDR_SAD_TAB : IDR_KILLED_TAB);
    157 
    158     title_ = UTF16ToWide(l10n_util::GetStringUTF16(
    159         kind == CRASHED ? IDS_SAD_TAB_TITLE : IDS_KILLED_TAB_TITLE));
    160     title_width_ = title_font_->GetStringWidth(WideToUTF16Hack(title_));
    161     message_ = UTF16ToWide(l10n_util::GetStringUTF16(
    162         kind == CRASHED ? IDS_SAD_TAB_MESSAGE : IDS_KILLED_TAB_MESSAGE));
    163 
    164     initialized = true;
    165   }
    166 }
    167