diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-06 18:45:56 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-06 18:45:56 +0000 |
commit | 7b9627d188d04b224f972fae709e7cb4f61ae504 (patch) | |
tree | 4d37368f881c9dae023e5172013e87f0b7c58676 /chrome/browser/gtk | |
parent | 72baf67602ab1dbf95c34a5d8301e0ac5f8b8b41 (diff) | |
download | chromium_src-7b9627d188d04b224f972fae709e7cb4f61ae504.zip chromium_src-7b9627d188d04b224f972fae709e7cb4f61ae504.tar.gz chromium_src-7b9627d188d04b224f972fae709e7cb4f61ae504.tar.bz2 |
Render a "sad tab" on tab crash.
Uses the NotificationRegistrar to notice TAB_CONTENTS_[DIS]CONNECTED events. When it disconnects, add a SadTabGtk to the TabContentsView. Delete it when the tab contents reconnects.
BUG=http://www.crbug.com/11081
TEST=Open http://about:crash. Verify that the sad tab renders properly. Navigate to another page to make sure the SadTabGtk is correctly replaced with a new RenderWidgetHostViewGtk.
Review URL: http://codereview.chromium.org/111003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15435 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 7 | ||||
-rw-r--r-- | chrome/browser/gtk/sad_tab_gtk.cc | 148 | ||||
-rw-r--r-- | chrome/browser/gtk/sad_tab_gtk.h | 51 |
3 files changed, 203 insertions, 3 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index dcc8c98..a1ded9e 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -213,9 +213,10 @@ gboolean HandleCustomAccelerator(guint keyval, GdkModifierType modifier, gboolean OnKeyPress(GtkWindow* window, GdkEventKey* event, Browser* browser) { TabContents* current_tab_contents = browser->tabstrip_model()->GetSelectedTabContents(); - // If there is no current tab contents or it is not focused then let the - // default GtkWindow key handler run. - if (!current_tab_contents || + // If there is no current tab contents or its view is gone (if the renderview + // crashed) or it is not focused then let the default GtkWindow key handler + // run. + if (!current_tab_contents || !current_tab_contents->GetContentNativeView() || !gtk_widget_is_focus(current_tab_contents->GetContentNativeView())) { return HandleCustomAccelerator(event->keyval, static_cast<GdkModifierType>(event->state), browser); diff --git a/chrome/browser/gtk/sad_tab_gtk.cc b/chrome/browser/gtk/sad_tab_gtk.cc new file mode 100644 index 0000000..594b2ad --- /dev/null +++ b/chrome/browser/gtk/sad_tab_gtk.cc @@ -0,0 +1,148 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/gtk/sad_tab_gtk.h" + +#include <string> + +#include "app/gfx/chrome_canvas.h" +#include "app/gfx/chrome_font.h" +#include "app/l10n_util.h" +#include "app/resource_bundle.h" +#include "base/gfx/size.h" +#include "base/lazy_instance.h" +#include "grit/generated_resources.h" +#include "grit/theme_resources.h" +#include "skia/ext/skia_utils.h" +#include "skia/include/SkGradientShader.h" + +namespace { + +// The y offset from the center at which to paint the icon. +const int kSadTabOffset = -64; +// The spacing between the icon and the title. +const int kIconTitleSpacing = 20; +// The spacing between the title and the message. +const int kTitleMessageSpacing = 15; +const SkColor kTitleTextColor = SK_ColorWHITE; +const SkColor kMessageTextColor = SK_ColorWHITE; +const SkColor kBackgroundColor = SkColorSetRGB(35, 48, 64); +const SkColor kBackgroundEndColor = SkColorSetRGB(35, 48, 64); + +struct SadTabGtkConstants { + SadTabGtkConstants() + : sad_tab_bitmap( + ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_SAD_TAB)), + title_font( + ResourceBundle::GetSharedInstance().GetFont( + ResourceBundle::BaseFont).DeriveFont(2, ChromeFont::BOLD)), + message_font( + ResourceBundle::GetSharedInstance().GetFont( + ResourceBundle::BaseFont).DeriveFont(1)), + title(l10n_util::GetString(IDS_SAD_TAB_TITLE)), + message(l10n_util::GetString(IDS_SAD_TAB_MESSAGE)) {} + + const SkBitmap* sad_tab_bitmap; + ChromeFont title_font; + ChromeFont message_font; + std::wstring title; + std::wstring message; +}; + +base::LazyInstance<SadTabGtkConstants> + g_sad_tab_constants(base::LINKER_INITIALIZED); + +} // namespace + +SadTabGtk::SadTabGtk() + : width_(0), + height_(0), + title_y_(0), + message_y_(0), + widget_(gtk_drawing_area_new()) { + gtk_widget_set_double_buffered(widget_.get(), FALSE); + g_signal_connect(widget_.get(), "expose-event", + G_CALLBACK(OnExposeThunk), this); + g_signal_connect(widget_.get(), "configure-event", + G_CALLBACK(OnConfigureThunk), this); +} + +SadTabGtk::~SadTabGtk() { + widget_.Destroy(); +} + +// static +gboolean SadTabGtk::OnExposeThunk(GtkWidget* widget, + GdkEventExpose* event, + const SadTabGtk* sad_tab) { + return sad_tab->OnExpose(widget, event); +} + +gboolean SadTabGtk::OnExpose(GtkWidget* widget, GdkEventExpose* event) const { + ChromeCanvasPaint canvas(event); + SkPaint paint; + paint.setShader(skia::CreateGradientShader(0, height_, + kBackgroundColor, + kBackgroundEndColor))->safeUnref(); + paint.setStyle(SkPaint::kFill_Style); + canvas.drawRectCoords(0, 0, + SkIntToScalar(width_), + SkIntToScalar(height_), + paint); + + const SadTabGtkConstants& sad_tab_constants = + g_sad_tab_constants.Get(); + + // Paint the sad tab icon. + canvas.DrawBitmapInt(*sad_tab_constants.sad_tab_bitmap, + icon_bounds_.x(), + icon_bounds_.y()); + + // Paint the "Aw, snap!" + canvas.DrawStringInt(sad_tab_constants.title, + sad_tab_constants.title_font, + kTitleTextColor, + 0, + title_y_, + width_, + sad_tab_constants.title_font.height(), + ChromeCanvas::TEXT_ALIGN_CENTER); + + // Paint the explanatory message. + canvas.DrawStringInt(sad_tab_constants.message, + sad_tab_constants.message_font, + kMessageTextColor, + 0, + message_y_, + width_, + sad_tab_constants.message_font.height(), + ChromeCanvas::TEXT_ALIGN_CENTER); + return TRUE; +} + +// static +gboolean SadTabGtk::OnConfigureThunk(GtkWidget* widget, + GdkEventConfigure* event, + SadTabGtk* sad_tab) { + return sad_tab->OnConfigure(widget, event); +} + +gboolean SadTabGtk::OnConfigure(GtkWidget* widget, GdkEventConfigure* event) { + const SadTabGtkConstants& sad_tab_constants = + g_sad_tab_constants.Get(); + width_ = event->width; + height_= event->height; + int icon_width = sad_tab_constants.sad_tab_bitmap->width(); + int icon_height = sad_tab_constants.sad_tab_bitmap->height(); + int icon_x = (event->width - icon_width) / 2; + int icon_y = ((event->height - icon_height) / 2) + kSadTabOffset; + icon_bounds_.SetRect(icon_x, icon_y, icon_width, icon_height); + + title_y_ = + icon_bounds_.bottom() + kIconTitleSpacing; + int title_height = sad_tab_constants.title_font.height(); + message_y_ = + title_y_ + title_height + kTitleMessageSpacing; + return TRUE; +} diff --git a/chrome/browser/gtk/sad_tab_gtk.h b/chrome/browser/gtk/sad_tab_gtk.h new file mode 100644 index 0000000..aed2454 --- /dev/null +++ b/chrome/browser/gtk/sad_tab_gtk.h @@ -0,0 +1,51 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GTK_SAD_TAB_GTK_H_ +#define CHROME_BROWSER_GTK_SAD_TAB_GTK_H_ + +#include <gtk/gtk.h> + +#include "base/basictypes.h" +#include "base/gfx/rect.h" +#include "chrome/common/owned_widget_gtk.h" + +class SadTabGtk { + public: + SadTabGtk(); + ~SadTabGtk(); + + GtkWidget* widget() { return widget_.get(); } + + private: + // expose-event handler that redraws the SadTabGtk. + static gboolean OnExposeThunk(GtkWidget* widget, + GdkEventExpose* event, + const SadTabGtk* sad_tab); + + gboolean OnExpose(GtkWidget* widget, GdkEventExpose* event) const; + + // configure-event handler that gets the new bounds of the SadTabGtk. + static gboolean OnConfigureThunk(GtkWidget* widget, + GdkEventConfigure* event, + SadTabGtk* sad_tab); + + gboolean OnConfigure(GtkWidget* widget, GdkEventConfigure* event); + + // Track the view's width and height from configure-event signals. + int width_; + int height_; + + // Regions within the display for different components, set on a + // configure-event. These are relative to the bounds of the widget. + gfx::Rect icon_bounds_; + int title_y_; + int message_y_; + + OwnedWidgetGtk widget_; + + DISALLOW_COPY_AND_ASSIGN(SadTabGtk); +}; + +#endif // CHROME_BROWSER_GTK_SAD_TAB_GTK_H__ |