1 // Copyright (c) 2012 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.
5 #include "chrome/browser/ui/gtk/throbber_gtk.h"
7 #include "base/logging.h"
8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
10 #include "content/public/browser/notification_source.h"
11 #include "grit/ui_resources.h"
12 #include "ui/gfx/animation/tween.h"
13 #include "ui/gfx/image/cairo_cached_surface.h"
17 // The length of a single cycle of the animation in milliseconds.
18 const int kThrobberDurationMs
= 750;
22 ThrobberGtk::ThrobberGtk(GtkThemeService
* theme_service
)
23 : theme_service_(theme_service
),
26 DCHECK(theme_service_
);
30 ThrobberGtk::~ThrobberGtk() {
34 void ThrobberGtk::Start() {
38 void ThrobberGtk::Stop() {
42 void ThrobberGtk::AnimationEnded(const gfx::Animation
* animation
) {
47 void ThrobberGtk::AnimationProgressed(const gfx::Animation
* animation
) {
48 gtk_widget_queue_draw(widget_
.get());
51 void ThrobberGtk::Observe(int type
,
52 const content::NotificationSource
& source
,
53 const content::NotificationDetails
& details
) {
54 DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED
, type
);
56 gtk_widget_queue_draw(widget_
.get());
59 gboolean
ThrobberGtk::OnExpose(GtkWidget
* widget
, GdkEventExpose
* expose
) {
60 cairo_t
* cairo_context
=
61 gdk_cairo_create(GDK_DRAWABLE(gtk_widget_get_window(widget
)));
62 GtkAllocation allocation
;
63 gtk_widget_get_allocation(widget
, &allocation
);
64 cairo_translate(cairo_context
, allocation
.x
, allocation
.y
);
66 gfx::CairoCachedSurface
* cairo_frames
= frames_
.ToCairo();
68 static_cast<int>(animation_
.GetCurrentValue() * (num_frames_
- 1));
69 const int image_size
= cairo_frames
->Height();
70 const int image_offset
= frame
* image_size
;
72 cairo_frames
->SetSource(cairo_context
, widget
, -image_offset
, 0);
73 cairo_rectangle(cairo_context
, 0, 0, image_size
, image_size
);
74 cairo_fill(cairo_context
);
75 cairo_destroy(cairo_context
);
80 void ThrobberGtk::Init() {
81 animation_
.SetSlideDuration(kThrobberDurationMs
);
82 animation_
.SetTweenType(gfx::Tween::LINEAR
);
83 widget_
.Own(gtk_image_new());
84 gtk_widget_set_can_focus(widget_
.get(), FALSE
);
85 g_signal_connect(widget_
.get(), "expose-event", G_CALLBACK(OnExposeThunk
),
88 theme_service_
->InitThemesFor(this);
89 registrar_
.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED
,
90 content::Source
<ThemeService
>(theme_service_
));
93 void ThrobberGtk::LoadFrames() {
94 frames_
= theme_service_
->GetImageNamed(IDR_THROBBER
);
95 DCHECK(!frames_
.IsEmpty());
96 const int width
= frames_
.ToCairo()->Width();
97 const int height
= frames_
.ToCairo()->Height();
98 DCHECK_EQ(0, width
% height
);
99 num_frames_
= width
/ height
;
101 gtk_widget_set_size_request(widget_
.get(), height
, height
);