diff options
Diffstat (limited to 'chrome/browser/gtk/throb_controller_gtk.cc')
-rw-r--r-- | chrome/browser/gtk/throb_controller_gtk.cc | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/chrome/browser/gtk/throb_controller_gtk.cc b/chrome/browser/gtk/throb_controller_gtk.cc new file mode 100644 index 0000000..422d388 --- /dev/null +++ b/chrome/browser/gtk/throb_controller_gtk.cc @@ -0,0 +1,95 @@ +// Copyright (c) 2010 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/throb_controller_gtk.h" + +#include "base/message_loop.h" +#include "chrome/browser/gtk/gtk_chrome_button.h" + +static const gchar* kThrobControllerGtkKey = "__THROB_CONTROLLER_GTK__"; + +ThrobControllerGtk::ThrobControllerGtk(GtkWidget* button) + : animation_(this), + button_(button) { + g_object_ref(button_); + g_signal_connect(button_, "destroy", G_CALLBACK(OnButtonDestroy), this); + +#ifndef NDEBUG + if (g_object_get_data(G_OBJECT(button_), kThrobControllerGtkKey)) + NOTREACHED(); +#endif // !NDEBUG + + g_object_set_data(G_OBJECT(button), kThrobControllerGtkKey, this); +} + +ThrobControllerGtk::~ThrobControllerGtk() { +} + +void ThrobControllerGtk::StartThrobbing(int cycles) { + animation_.StartThrobbing(cycles); +} + +// static +ThrobControllerGtk* ThrobControllerGtk::GetThrobControllerGtk( + GtkWidget* button) { + return reinterpret_cast<ThrobControllerGtk*>( + g_object_get_data(G_OBJECT(button), kThrobControllerGtkKey)); +} + +// static +void ThrobControllerGtk::ThrobFor(GtkWidget* button) { + if (!GTK_IS_CHROME_BUTTON(button)) { + NOTREACHED(); + return; + } + + (new ThrobControllerGtk(button))-> + StartThrobbing(std::numeric_limits<int>::max()); +} + +void ThrobControllerGtk::Destroy() { + gtk_chrome_button_set_hover_state(GTK_CHROME_BUTTON(button_), -1.0); + g_signal_handlers_disconnect_by_func( + button_, + reinterpret_cast<gpointer>(OnButtonDestroy), + this); + g_object_set_data(G_OBJECT(button_), kThrobControllerGtkKey, NULL); + g_object_unref(button_); + button_ = NULL; + + // Since this can be called from within AnimationEnded(), which is called + // while ThrobAnimation is still doing work, we need to let the stack unwind + // before |animation_| gets deleted. + MessageLoop::current()->DeleteSoon(FROM_HERE, this); +} + +void ThrobControllerGtk::AnimationProgressed(const Animation* animation) { + if (!button_) + return; + + gtk_chrome_button_set_hover_state(GTK_CHROME_BUTTON(button_), + animation->GetCurrentValue()); +} + +void ThrobControllerGtk::AnimationEnded(const Animation* animation) { + if (!button_) + return; + + if (animation_.cycles_remaining() <= 1) + Destroy(); +} + +void ThrobControllerGtk::AnimationCanceled(const Animation* animation) { + if (!button_) + return; + + if (animation_.cycles_remaining() <= 1) + Destroy(); +} + +// static +void ThrobControllerGtk::OnButtonDestroy(GtkWidget* widget, + ThrobControllerGtk* button) { + button->Destroy(); +} |