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

Side by Side Diff: chrome/browser/gtk/tabs/tab_renderer_gtk.cc

Issue 115489: Implement the sad tab crash animation for tabs in linux. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/gtk/tabs/tab_renderer_gtk.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/gtk/tabs/tab_renderer_gtk.h" 5 #include "chrome/browser/gtk/tabs/tab_renderer_gtk.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "app/resource_bundle.h" 8 #include "app/resource_bundle.h"
9 #include "chrome/browser/browser.h" 9 #include "chrome/browser/browser.h"
10 #include "chrome/browser/browser_theme_provider.h" 10 #include "chrome/browser/browser_theme_provider.h"
(...skipping 25 matching lines...) Expand all
36 36
37 const SkScalar kTabCapWidth = 15; 37 const SkScalar kTabCapWidth = 15;
38 const SkScalar kTabTopCurveWidth = 4; 38 const SkScalar kTabTopCurveWidth = 4;
39 const SkScalar kTabBottomCurveWidth = 3; 39 const SkScalar kTabBottomCurveWidth = 3;
40 40
41 // The vertical and horizontal offset used to position the close button 41 // The vertical and horizontal offset used to position the close button
42 // in the tab. TODO(jhawkins): Ask pkasting what the Fuzz is about. 42 // in the tab. TODO(jhawkins): Ask pkasting what the Fuzz is about.
43 const int kCloseButtonVertFuzz = 0; 43 const int kCloseButtonVertFuzz = 0;
44 const int kCloseButtonHorzFuzz = 5; 44 const int kCloseButtonHorzFuzz = 5;
45 45
46 SkBitmap* crashed_fav_icon = NULL;
47
46 TabRendererGtk::LoadingAnimation::Data loading_animation_data; 48 TabRendererGtk::LoadingAnimation::Data loading_animation_data;
47 49
48 // Loads the loading animation images and data. 50 // Loads the loading animation images and data.
49 void InitializeLoadingAnimationData( 51 void InitializeLoadingAnimationData(
50 ResourceBundle* rb, TabRendererGtk::LoadingAnimation::Data* data) { 52 ResourceBundle* rb, TabRendererGtk::LoadingAnimation::Data* data) {
51 // The loading animation image is a strip of states. Each state must be 53 // The loading animation image is a strip of states. Each state must be
52 // square, so the height must divide the width evenly. 54 // square, so the height must divide the width evenly.
53 data->loading_animation_frames = rb->GetBitmapNamed(IDR_THROBBER); 55 data->loading_animation_frames = rb->GetBitmapNamed(IDR_THROBBER);
54 DCHECK(data->loading_animation_frames); 56 DCHECK(data->loading_animation_frames);
55 DCHECK_EQ(data->loading_animation_frames->width() % 57 DCHECK_EQ(data->loading_animation_frames->width() %
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 animation_frame_ = ++animation_frame_ % 121 animation_frame_ = ++animation_frame_ %
120 ((animation_state_ == ANIMATION_WAITING) ? 122 ((animation_state_ == ANIMATION_WAITING) ?
121 data_->waiting_animation_frame_count : 123 data_->waiting_animation_frame_count :
122 data_->loading_animation_frame_count); 124 data_->loading_animation_frame_count);
123 } else { 125 } else {
124 animation_frame_ = 0; 126 animation_frame_ = 0;
125 } 127 }
126 } 128 }
127 129
128 //////////////////////////////////////////////////////////////////////////////// 130 ////////////////////////////////////////////////////////////////////////////////
131 // FaviconCrashAnimation
132 //
133 // A custom animation subclass to manage the favicon crash animation.
134 class TabRendererGtk::FavIconCrashAnimation : public Animation,
135 public AnimationDelegate {
136 public:
137 explicit FavIconCrashAnimation(TabRendererGtk* target)
138 : ALLOW_THIS_IN_INITIALIZER_LIST(Animation(1000, 25, this)),
139 target_(target) {
140 }
141 virtual ~FavIconCrashAnimation() {}
142
143 // Animation overrides:
144 virtual void AnimateToState(double state) {
145 const double kHidingOffset = 27;
146
147 if (state < .5) {
148 target_->SetFavIconHidingOffset(
149 static_cast<int>(floor(kHidingOffset * 2.0 * state)));
150 } else {
151 target_->DisplayCrashedFavIcon();
152 target_->SetFavIconHidingOffset(
153 static_cast<int>(
154 floor(kHidingOffset - ((state - .5) * 2.0 * kHidingOffset))));
155 }
156 }
157
158 // AnimationDelegate overrides:
159 virtual void AnimationCanceled(const Animation* animation) {
160 target_->SetFavIconHidingOffset(0);
161 }
162
163 private:
164 TabRendererGtk* target_;
165
166 DISALLOW_COPY_AND_ASSIGN(FavIconCrashAnimation);
167 };
168
169 ////////////////////////////////////////////////////////////////////////////////
129 // TabRendererGtk, public: 170 // TabRendererGtk, public:
130 171
131 TabRendererGtk::TabRendererGtk() 172 TabRendererGtk::TabRendererGtk()
132 : showing_icon_(false), 173 : showing_icon_(false),
133 showing_download_icon_(false), 174 showing_download_icon_(false),
134 showing_close_button_(false), 175 showing_close_button_(false),
135 fav_icon_hiding_offset_(0), 176 fav_icon_hiding_offset_(0),
136 should_display_crashed_favicon_(false), 177 should_display_crashed_favicon_(false),
137 loading_animation_(&loading_animation_data) { 178 loading_animation_(&loading_animation_data) {
138 InitResources(); 179 InitResources();
(...skipping 26 matching lines...) Expand all
165 // we display the throbber. 206 // we display the throbber.
166 data_.loading = contents->is_loading(); 207 data_.loading = contents->is_loading();
167 data_.show_icon = contents->ShouldDisplayFavIcon(); 208 data_.show_icon = contents->ShouldDisplayFavIcon();
168 209
169 theme_provider_ = contents->profile()->GetThemeProvider(); 210 theme_provider_ = contents->profile()->GetThemeProvider();
170 } 211 }
171 212
172 void TabRendererGtk::UpdateFromModel() { 213 void TabRendererGtk::UpdateFromModel() {
173 // Force a layout, since the tab may have grown a favicon. 214 // Force a layout, since the tab may have grown a favicon.
174 Layout(); 215 Layout();
216 SchedulePaint();
217
218 if (data_.crashed) {
219 if (!should_display_crashed_favicon_ && !IsPerformingCrashAnimation())
220 StartCrashAnimation();
221 } else {
222 if (IsPerformingCrashAnimation())
223 StopCrashAnimation();
224 ResetCrashedFavIcon();
225 }
175 } 226 }
176 227
177 bool TabRendererGtk::IsSelected() const { 228 bool TabRendererGtk::IsSelected() const {
178 return true; 229 return true;
179 } 230 }
180 231
181 bool TabRendererGtk::IsVisible() const { 232 bool TabRendererGtk::IsVisible() const {
182 return GTK_WIDGET_FLAGS(tab_.get()) & GTK_VISIBLE; 233 return GTK_WIDGET_FLAGS(tab_.get()) & GTK_VISIBLE;
183 } 234 }
184 235
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 AnimationEnded(animation); 334 AnimationEnded(animation);
284 } 335 }
285 336
286 void TabRendererGtk::AnimationEnded(const Animation* animation) { 337 void TabRendererGtk::AnimationEnded(const Animation* animation) {
287 gtk_widget_queue_draw(tab_.get()); 338 gtk_widget_queue_draw(tab_.get());
288 } 339 }
289 340
290 //////////////////////////////////////////////////////////////////////////////// 341 ////////////////////////////////////////////////////////////////////////////////
291 // TabRendererGtk, private: 342 // TabRendererGtk, private:
292 343
344 void TabRendererGtk::StartCrashAnimation() {
345 if (!crash_animation_.get())
346 crash_animation_.reset(new FavIconCrashAnimation(this));
347 crash_animation_->Reset();
348 crash_animation_->Start();
349 }
350
351 void TabRendererGtk::StopCrashAnimation() {
352 if (!crash_animation_.get())
353 return;
354 crash_animation_->Stop();
355 }
356
357 bool TabRendererGtk::IsPerformingCrashAnimation() const {
358 return crash_animation_.get() && crash_animation_->IsAnimating();
359 }
360
361 void TabRendererGtk::SetFavIconHidingOffset(int offset) {
362 fav_icon_hiding_offset_ = offset;
363 SchedulePaint();
364 }
365
366 void TabRendererGtk::DisplayCrashedFavIcon() {
367 should_display_crashed_favicon_ = true;
368 }
369
370 void TabRendererGtk::ResetCrashedFavIcon() {
371 should_display_crashed_favicon_ = false;
372 }
373
293 void TabRendererGtk::Paint(GdkEventExpose* event) { 374 void TabRendererGtk::Paint(GdkEventExpose* event) {
294 gfx::CanvasPaint canvas(event, false); 375 gfx::CanvasPaint canvas(event, false);
295 if (canvas.isEmpty()) 376 if (canvas.isEmpty())
296 return; 377 return;
297 378
298 // Don't paint if we're narrower than we can render correctly. (This should 379 // Don't paint if we're narrower than we can render correctly. (This should
299 // only happen during animations). 380 // only happen during animations).
300 if (width() < GetMinimumUnselectedSize().width()) 381 if (width() < GetMinimumUnselectedSize().width())
301 return; 382 return;
302 383
303 // See if the model changes whether the icons should be painted. 384 // See if the model changes whether the icons should be painted.
304 const bool show_icon = ShouldShowIcon(); 385 const bool show_icon = ShouldShowIcon();
305 const bool show_download_icon = data_.show_download_icon; 386 const bool show_download_icon = data_.show_download_icon;
306 const bool show_close_button = ShouldShowCloseBox(); 387 const bool show_close_button = ShouldShowCloseBox();
307 if (show_icon != showing_icon_ || 388 if (show_icon != showing_icon_ ||
308 show_download_icon != showing_download_icon_ || 389 show_download_icon != showing_download_icon_ ||
309 show_close_button != showing_close_button_) 390 show_close_button != showing_close_button_)
310 Layout(); 391 Layout();
311 392
312 PaintTabBackground(&canvas); 393 PaintTabBackground(&canvas);
313 394
314 if (show_icon) { 395 if (show_icon) {
315 if (loading_animation_.animation_state() != ANIMATION_NONE) { 396 if (loading_animation_.animation_state() != ANIMATION_NONE) {
316 PaintLoadingAnimation(&canvas); 397 PaintLoadingAnimation(&canvas);
317 } else if (!data_.favicon.isNull()) { 398 } else {
318 canvas.DrawBitmapInt(data_.favicon, favicon_bounds_.x(), 399 canvas.save();
319 favicon_bounds_.y() + fav_icon_hiding_offset_); 400 canvas.ClipRectInt(0, 0, width(), height() - kFavIconTitleSpacing);
401 if (should_display_crashed_favicon_) {
402 canvas.DrawBitmapInt(*crashed_fav_icon, 0, 0,
403 crashed_fav_icon->width(),
404 crashed_fav_icon->height(),
405 favicon_bounds_.x(),
406 favicon_bounds_.y() + fav_icon_hiding_offset_,
407 kFavIconSize, kFavIconSize,
408 true);
409 } else {
410 if (!data_.favicon.isNull()) {
411 // TODO(pkasting): Use code in tab_icon_view.cc:PaintIcon() (or switch
412 // to using that class to render the favicon).
413 canvas.DrawBitmapInt(data_.favicon, 0, 0,
414 data_.favicon.width(),
415 data_.favicon.height(),
416 favicon_bounds_.x(),
417 favicon_bounds_.y() + fav_icon_hiding_offset_,
418 kFavIconSize, kFavIconSize,
419 true);
420 }
421 }
422 canvas.restore();
320 } 423 }
321 } 424 }
322 425
323 if (show_download_icon) { 426 if (show_download_icon) {
324 canvas.DrawBitmapInt(*download_icon_, 427 canvas.DrawBitmapInt(*download_icon_,
325 download_icon_bounds_.x(), download_icon_bounds_.y()); 428 download_icon_bounds_.x(), download_icon_bounds_.y());
326 } 429 }
327 430
328 // Paint the Title. 431 // Paint the Title.
329 std::wstring title = data_.title; 432 std::wstring title = data_.title;
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 LoadTabImages(); 703 LoadTabImages();
601 704
602 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 705 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
603 // Force the font size to 10pt. 706 // Force the font size to 10pt.
604 gfx::Font base_font = rb.GetFont(ResourceBundle::BaseFont); 707 gfx::Font base_font = rb.GetFont(ResourceBundle::BaseFont);
605 title_font_ = new gfx::Font(gfx::Font::CreateFont(base_font.FontName(), 10)); 708 title_font_ = new gfx::Font(gfx::Font::CreateFont(base_font.FontName(), 10));
606 title_font_height_ = title_font_->height(); 709 title_font_height_ = title_font_->height();
607 710
608 InitializeLoadingAnimationData(&rb, &loading_animation_data); 711 InitializeLoadingAnimationData(&rb, &loading_animation_data);
609 712
713 crashed_fav_icon = rb.GetBitmapNamed(IDR_SAD_FAVICON);
714
610 initialized_ = true; 715 initialized_ = true;
611 } 716 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/tabs/tab_renderer_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698