2009-07-21 01:16:56 +00:00
/* GTK - The GIMP Toolkit
*
* Copyright ( C ) 2007 John Stowers , Neil Jagdish Patel .
* Copyright ( C ) 2009 Bastien Nocera , David Zeuthen
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the
* Free Software Foundation , Inc . , 59 Temple Place - Suite 330 ,
* Boston , MA 02111 - 1307 , USA .
*
* Code adapted from egg - spinner
* by Christian Hergert < christian . hergert @ gmail . com >
*/
/*
* Modified by the GTK + Team and others 2007. See the AUTHORS
* file for a list of people on the GTK + Team . See the ChangeLog
* files for a list of changes . These files are distributed with
* GTK + at ftp : //ftp.gtk.org/pub/gtk/.
*/
# include "config.h"
# include "gtkintl.h"
# include "gtkaccessible.h"
# include "gtkimage.h"
# include "gtkspinner.h"
# include "gtkstyle.h"
2009-10-14 17:25:23 +00:00
/**
* SECTION : gtkspinner
* @ Short_description : Show a spinner animation
* @ Title : GtkSpinner
* @ See_also : # GtkCellRendererSpinner , # GtkProgressBar
*
* A GtkSpinner widget displays an icon - size spinning animation .
* It is often used as an alternative to a # GtkProgressBar for
* displaying indefinite activity , instead of actual progress .
*
* To start the animation , use gtk_spinner_start ( ) , to stop it
* use gtk_spinner_stop ( ) .
*/
2010-09-13 23:09:53 +00:00
# define SPINNER_SIZE 12
2009-07-21 01:16:56 +00:00
enum {
PROP_0 ,
PROP_ACTIVE
} ;
struct _GtkSpinnerPrivate
{
2009-10-14 22:11:43 +00:00
gboolean active ;
2009-07-21 01:16:56 +00:00
} ;
2010-09-03 16:30:30 +00:00
static gboolean gtk_spinner_draw ( GtkWidget * widget ,
cairo_t * cr ) ;
2009-10-14 17:25:23 +00:00
static void gtk_spinner_get_property ( GObject * object ,
guint param_id ,
GValue * value ,
GParamSpec * pspec ) ;
static void gtk_spinner_set_property ( GObject * object ,
guint param_id ,
const GValue * value ,
GParamSpec * pspec ) ;
2009-10-15 11:59:01 +00:00
static void gtk_spinner_set_active ( GtkSpinner * spinner ,
gboolean active ) ;
2010-09-21 14:35:17 +00:00
static void gtk_spinner_get_preferred_width ( GtkWidget * widget ,
gint * minimum_size ,
gint * natural_size ) ;
static void gtk_spinner_get_preferred_height ( GtkWidget * widget ,
gint * minimum_size ,
gint * natural_size ) ;
2009-10-14 17:25:23 +00:00
static AtkObject * gtk_spinner_get_accessible ( GtkWidget * widget ) ;
static GType gtk_spinner_accessible_get_type ( void ) ;
2009-07-21 01:16:56 +00:00
2010-09-21 14:35:17 +00:00
G_DEFINE_TYPE ( GtkSpinner , gtk_spinner , GTK_TYPE_WIDGET )
2010-09-13 23:19:48 +00:00
2009-07-21 01:16:56 +00:00
static void
gtk_spinner_class_init ( GtkSpinnerClass * klass )
{
GObjectClass * gobject_class ;
GtkWidgetClass * widget_class ;
gobject_class = G_OBJECT_CLASS ( klass ) ;
g_type_class_add_private ( gobject_class , sizeof ( GtkSpinnerPrivate ) ) ;
gobject_class - > get_property = gtk_spinner_get_property ;
gobject_class - > set_property = gtk_spinner_set_property ;
widget_class = GTK_WIDGET_CLASS ( klass ) ;
2010-09-03 16:30:30 +00:00
widget_class - > draw = gtk_spinner_draw ;
2009-07-21 01:16:56 +00:00
widget_class - > get_accessible = gtk_spinner_get_accessible ;
2010-09-21 14:35:17 +00:00
widget_class - > get_preferred_width = gtk_spinner_get_preferred_width ;
widget_class - > get_preferred_height = gtk_spinner_get_preferred_height ;
2009-07-21 01:16:56 +00:00
2009-10-14 17:25:23 +00:00
/* GtkSpinner:active:
2009-07-21 01:16:56 +00:00
*
* Whether the spinner is active
*
2009-10-30 05:07:15 +00:00
* Since : 2.20
2009-07-21 01:16:56 +00:00
*/
g_object_class_install_property ( gobject_class ,
PROP_ACTIVE ,
g_param_spec_boolean ( " active " ,
P_ ( " Active " ) ,
P_ ( " Whether the spinner is active " ) ,
FALSE ,
G_PARAM_READWRITE ) ) ;
/**
2009-10-14 17:25:23 +00:00
* GtkSpinner : num - steps :
2009-07-21 01:16:56 +00:00
*
2009-10-14 17:25:23 +00:00
* The number of steps for the spinner to complete a full loop .
2009-10-14 17:43:05 +00:00
* The animation will complete a full cycle in one second by default
* ( see the # GtkSpinner : cycle - duration style property ) .
2009-07-21 01:16:56 +00:00
*
* Since : 2.20
2010-11-24 22:25:14 +00:00
*
* Deprecated : 3.0
2009-07-21 01:16:56 +00:00
*/
gtk_widget_class_install_style_property ( widget_class ,
g_param_spec_uint ( " num-steps " ,
P_ ( " Number of steps " ) ,
2009-10-14 21:38:28 +00:00
P_ ( " The number of steps for the spinner to complete a full loop. The animation will complete a full cycle in one second by default (see #GtkSpinner:cycle-duration). " ) ,
2009-07-21 01:16:56 +00:00
1 ,
G_MAXUINT ,
12 ,
G_PARAM_READABLE ) ) ;
2009-10-14 17:43:05 +00:00
/**
2009-10-14 21:38:28 +00:00
* GtkSpinner : cycle - duration :
2009-10-14 17:43:05 +00:00
*
* The duration in milliseconds for the spinner to complete a full cycle .
*
* Since : 2.20
2010-11-24 22:25:14 +00:00
*
* Deprecated : 3.0
2009-10-14 17:43:05 +00:00
*/
gtk_widget_class_install_style_property ( widget_class ,
g_param_spec_uint ( " cycle-duration " ,
P_ ( " Animation duration " ) ,
P_ ( " The length of time in milliseconds for the spinner to complete a full loop " ) ,
500 ,
G_MAXUINT ,
1000 ,
G_PARAM_READABLE ) ) ;
2009-07-21 01:16:56 +00:00
}
static void
gtk_spinner_get_property ( GObject * object ,
guint param_id ,
GValue * value ,
GParamSpec * pspec )
{
GtkSpinnerPrivate * priv ;
2009-10-15 11:59:01 +00:00
priv = GTK_SPINNER ( object ) - > priv ;
2009-07-21 01:16:56 +00:00
switch ( param_id )
{
case PROP_ACTIVE :
2009-10-14 22:11:43 +00:00
g_value_set_boolean ( value , priv - > active ) ;
2009-07-21 01:16:56 +00:00
break ;
default :
G_OBJECT_WARN_INVALID_PROPERTY_ID ( object , param_id , pspec ) ;
}
}
static void
gtk_spinner_set_property ( GObject * object ,
guint param_id ,
const GValue * value ,
GParamSpec * pspec )
{
switch ( param_id )
{
case PROP_ACTIVE :
2009-10-15 11:59:01 +00:00
gtk_spinner_set_active ( GTK_SPINNER ( object ) , g_value_get_boolean ( value ) ) ;
2009-07-21 01:16:56 +00:00
break ;
default :
G_OBJECT_WARN_INVALID_PROPERTY_ID ( object , param_id , pspec ) ;
}
}
static void
gtk_spinner_init ( GtkSpinner * spinner )
{
GtkSpinnerPrivate * priv ;
2010-11-24 22:25:14 +00:00
GtkStyleContext * context ;
2009-07-21 01:16:56 +00:00
2010-07-12 23:09:28 +00:00
priv = G_TYPE_INSTANCE_GET_PRIVATE ( spinner ,
GTK_TYPE_SPINNER ,
GtkSpinnerPrivate ) ;
2009-10-15 11:59:01 +00:00
spinner - > priv = priv ;
2010-03-06 10:29:31 +00:00
gtk_widget_set_has_window ( GTK_WIDGET ( spinner ) , FALSE ) ;
2010-11-24 22:25:14 +00:00
context = gtk_widget_get_style_context ( GTK_WIDGET ( spinner ) ) ;
gtk_style_context_add_class ( context , GTK_STYLE_CLASS_SPINNER ) ;
2009-07-21 01:16:56 +00:00
}
2010-09-13 23:25:07 +00:00
static void
2010-09-21 14:35:17 +00:00
gtk_spinner_get_preferred_width ( GtkWidget * widget ,
gint * minimum_size ,
gint * natural_size )
2010-09-13 23:25:07 +00:00
{
if ( minimum_size )
* minimum_size = SPINNER_SIZE ;
if ( natural_size )
* natural_size = SPINNER_SIZE ;
}
static void
2010-09-21 14:35:17 +00:00
gtk_spinner_get_preferred_height ( GtkWidget * widget ,
gint * minimum_size ,
gint * natural_size )
2010-09-13 23:25:07 +00:00
{
if ( minimum_size )
* minimum_size = SPINNER_SIZE ;
if ( natural_size )
* natural_size = SPINNER_SIZE ;
}
2009-07-21 01:16:56 +00:00
static gboolean
2010-09-03 16:30:30 +00:00
gtk_spinner_draw ( GtkWidget * widget ,
cairo_t * cr )
2009-07-21 01:16:56 +00:00
{
GtkSpinnerPrivate * priv ;
2010-11-24 22:25:14 +00:00
GtkStyleContext * context ;
GtkStateFlags state ;
2009-07-21 01:16:56 +00:00
2009-10-15 11:59:01 +00:00
priv = GTK_SPINNER ( widget ) - > priv ;
2010-11-24 22:25:14 +00:00
context = gtk_widget_get_style_context ( widget ) ;
state = gtk_widget_get_state_flags ( widget ) ;
2009-07-21 01:16:56 +00:00
2010-11-24 22:25:14 +00:00
gtk_style_context_set_state ( context , state ) ;
gtk_render_activity ( context , cr , 0 , 0 ,
gtk_widget_get_allocated_width ( widget ) ,
gtk_widget_get_allocated_height ( widget ) ) ;
2009-07-21 01:16:56 +00:00
return FALSE ;
}
static void
2010-11-29 15:43:43 +00:00
gtk_spinner_set_active ( GtkSpinner * spinner ,
gboolean active )
2009-07-21 01:16:56 +00:00
{
2010-11-29 15:43:43 +00:00
GtkSpinnerPrivate * priv = spinner - > priv ;
2009-07-21 01:16:56 +00:00
2010-11-29 15:43:43 +00:00
active = ! ! active ;
2009-10-15 11:59:01 +00:00
if ( priv - > active ! = active )
2009-07-21 01:16:56 +00:00
{
2009-10-15 11:59:01 +00:00
priv - > active = active ;
2010-11-29 15:43:43 +00:00
2009-10-15 11:59:01 +00:00
g_object_notify ( G_OBJECT ( spinner ) , " active " ) ;
2010-11-24 22:25:14 +00:00
if ( active )
gtk_widget_set_state_flags ( GTK_WIDGET ( spinner ) ,
GTK_STATE_FLAG_ACTIVE , FALSE ) ;
else
gtk_widget_unset_state_flags ( GTK_WIDGET ( spinner ) ,
GTK_STATE_FLAG_ACTIVE ) ;
2009-07-21 01:16:56 +00:00
}
}
2010-11-29 15:43:43 +00:00
/* accessible implementation */
2009-07-21 01:16:56 +00:00
static void
gtk_spinner_accessible_image_get_size ( AtkImage * image ,
2009-10-14 17:25:23 +00:00
gint * width ,
gint * height )
2009-07-21 01:16:56 +00:00
{
2010-08-11 20:54:47 +00:00
GtkAllocation allocation ;
2009-07-21 01:16:56 +00:00
GtkWidget * widget ;
2010-05-22 23:55:33 +00:00
widget = gtk_accessible_get_widget ( GTK_ACCESSIBLE ( image ) ) ;
2010-11-29 15:43:43 +00:00
if ( widget = = NULL )
2009-07-21 01:16:56 +00:00
{
* width = * height = 0 ;
}
else
{
2010-08-11 20:54:47 +00:00
gtk_widget_get_allocation ( widget , & allocation ) ;
* width = allocation . width ;
* height = allocation . height ;
2009-07-21 01:16:56 +00:00
}
}
static void
2010-11-29 15:43:43 +00:00
gtk_spinner_accessible_image_iface_init ( AtkImageIface * iface )
2009-07-21 01:16:56 +00:00
{
iface - > get_image_size = gtk_spinner_accessible_image_get_size ;
}
2010-11-29 15:43:43 +00:00
/* dummy typedef */
typedef struct _GtkSpinnerAccessible GtkSpinnerAccessible ;
typedef struct _GtkSpinnerAccessibleClass GtkSpinnerAccessibleClass ;
ATK_DEFINE_TYPE_WITH_CODE ( GtkSpinnerAccessible ,
gtk_spinner_accessible ,
GTK_TYPE_IMAGE ,
G_IMPLEMENT_INTERFACE ( ATK_TYPE_IMAGE ,
gtk_spinner_accessible_image_iface_init ) ) ;
static void
gtk_spinner_accessible_initialize ( AtkObject * accessible ,
gpointer widget )
2009-07-21 01:16:56 +00:00
{
2010-11-29 15:43:43 +00:00
ATK_OBJECT_CLASS ( gtk_spinner_accessible_parent_class ) - > initialize ( accessible , widget ) ;
2009-07-21 01:16:56 +00:00
2010-11-29 15:43:43 +00:00
atk_object_set_name ( accessible , C_ ( " throbbing progress animation widget " , " Spinner " ) ) ;
atk_object_set_description ( accessible , _ ( " Provides visual indication of progress " ) ) ;
}
2009-07-21 01:16:56 +00:00
2010-11-29 15:43:43 +00:00
static void
gtk_spinner_accessible_class_init ( GtkSpinnerAccessibleClass * klass )
{
AtkObjectClass * atk_class = ATK_OBJECT_CLASS ( klass ) ;
2009-07-21 01:16:56 +00:00
2010-11-29 15:43:43 +00:00
atk_class - > initialize = gtk_spinner_accessible_initialize ;
}
2009-07-21 01:16:56 +00:00
2010-11-29 15:43:43 +00:00
static void
gtk_spinner_accessible_init ( GtkSpinnerAccessible * self )
{
}
2009-07-21 01:16:56 +00:00
2010-11-29 15:43:43 +00:00
/* factory */
typedef AtkObjectFactory GtkSpinnerAccessibleFactory ;
typedef AtkObjectFactoryClass GtkSpinnerAccessibleFactoryClass ;
2009-07-21 01:16:56 +00:00
2010-11-29 15:43:43 +00:00
G_DEFINE_TYPE ( GtkSpinnerAccessibleFactory ,
gtk_spinner_accessible_factory ,
ATK_TYPE_OBJECT_FACTORY ) ;
2009-07-21 01:16:56 +00:00
2010-11-29 15:43:43 +00:00
static GType
gtk_spinner_accessible_factory_get_accessible_type ( void )
{
return gtk_spinner_accessible_get_type ( ) ;
}
2009-07-21 01:16:56 +00:00
2010-11-29 15:43:43 +00:00
static AtkObject *
gtk_spinner_accessible_factory_create_accessible ( GObject * obj )
{
AtkObject * accessible ;
accessible = g_object_new ( gtk_spinner_accessible_get_type ( ) , NULL ) ;
atk_object_initialize ( accessible , obj ) ;
return accessible ;
}
static void
gtk_spinner_accessible_factory_class_init ( AtkObjectFactoryClass * klass )
{
klass - > create_accessible = gtk_spinner_accessible_factory_create_accessible ;
klass - > get_accessible_type = gtk_spinner_accessible_factory_get_accessible_type ;
}
2009-07-21 01:16:56 +00:00
2010-11-29 15:43:43 +00:00
static void
gtk_spinner_accessible_factory_init ( AtkObjectFactory * factory )
{
2009-07-21 01:16:56 +00:00
}
static AtkObject *
gtk_spinner_get_accessible ( GtkWidget * widget )
{
static gboolean first_time = TRUE ;
if ( first_time )
{
AtkObjectFactory * factory ;
AtkRegistry * registry ;
GType derived_type ;
GType derived_atk_type ;
/*
* Figure out whether accessibility is enabled by looking at the
* type of the accessible object which would be created for
* the parent type of GtkSpinner .
*/
derived_type = g_type_parent ( GTK_TYPE_SPINNER ) ;
registry = atk_get_default_registry ( ) ;
2010-11-29 15:43:43 +00:00
factory = atk_registry_get_factory ( registry , derived_type ) ;
2009-07-21 01:16:56 +00:00
derived_atk_type = atk_object_factory_get_accessible_type ( factory ) ;
if ( g_type_is_a ( derived_atk_type , GTK_TYPE_ACCESSIBLE ) )
atk_registry_set_factory_type ( registry ,
GTK_TYPE_SPINNER ,
gtk_spinner_accessible_factory_get_type ( ) ) ;
first_time = FALSE ;
}
2010-11-29 15:43:43 +00:00
2009-07-21 01:16:56 +00:00
return GTK_WIDGET_CLASS ( gtk_spinner_parent_class ) - > get_accessible ( widget ) ;
}
/**
2009-10-14 17:25:23 +00:00
* gtk_spinner_new :
2009-07-21 01:16:56 +00:00
*
* Returns a new spinner widget . Not yet started .
*
* Return value : a new # GtkSpinner
*
* Since : 2.20
*/
GtkWidget *
gtk_spinner_new ( void )
{
return g_object_new ( GTK_TYPE_SPINNER , NULL ) ;
}
/**
2009-10-14 17:25:23 +00:00
* gtk_spinner_start :
* @ spinner : a # GtkSpinner
2009-07-21 01:16:56 +00:00
*
2009-10-14 17:25:23 +00:00
* Starts the animation of the spinner .
2009-07-21 01:16:56 +00:00
*
* Since : 2.20
*/
void
gtk_spinner_start ( GtkSpinner * spinner )
{
g_return_if_fail ( GTK_IS_SPINNER ( spinner ) ) ;
2009-10-15 11:59:01 +00:00
gtk_spinner_set_active ( spinner , TRUE ) ;
2009-07-21 01:16:56 +00:00
}
/**
2009-10-14 17:25:23 +00:00
* gtk_spinner_stop :
* @ spinner : a # GtkSpinner
2009-07-21 01:16:56 +00:00
*
2009-10-14 17:25:23 +00:00
* Stops the animation of the spinner .
2009-07-21 01:16:56 +00:00
*
* Since : 2.20
*/
void
gtk_spinner_stop ( GtkSpinner * spinner )
{
g_return_if_fail ( GTK_IS_SPINNER ( spinner ) ) ;
2009-10-15 11:59:01 +00:00
gtk_spinner_set_active ( spinner , FALSE ) ;
2009-07-21 01:16:56 +00:00
}