X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkspinner.c;h=06840c88fe441b6674fae97de6a8be4f074583c6;hb=3b2182e711ace4a2d6843848208224cd7525d530;hp=b3da6dd6d120a2ec8473fcf650913fa3c38621e7;hpb=e06d04032b9e2da61b8ea82d03298cbebef48640;p=~andy%2Fgtk diff --git a/gtk/gtkspinner.c b/gtk/gtkspinner.c index b3da6dd6d..06840c88f 100644 --- a/gtk/gtkspinner.c +++ b/gtk/gtkspinner.c @@ -14,9 +14,7 @@ * 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. + * License along with this library. If not, see . * * Code adapted from egg-spinner * by Christian Hergert @@ -31,12 +29,12 @@ #include "config.h" -#include "gtkintl.h" -#include "gtkaccessible.h" -#include "gtkimage.h" -#include "gtksizerequest.h" #include "gtkspinner.h" -#include "gtkstyle.h" + +#include "gtkimage.h" +#include "gtkintl.h" +#include "gtkstylecontext.h" +#include "a11y/gtkspinneraccessible.h" /** @@ -63,20 +61,11 @@ enum { struct _GtkSpinnerPrivate { - guint current; - guint num_steps; - guint cycle_duration; gboolean active; - guint timeout; }; -static void gtk_spinner_dispose (GObject *gobject); -static void gtk_spinner_map (GtkWidget *widget); -static void gtk_spinner_unmap (GtkWidget *widget); -static gboolean gtk_spinner_expose (GtkWidget *widget, - GdkEventExpose *event); -static void gtk_spinner_style_set (GtkWidget *widget, - GtkStyle *prev_style); +static gboolean gtk_spinner_draw (GtkWidget *widget, + cairo_t *cr); static void gtk_spinner_get_property (GObject *object, guint param_id, GValue *value, @@ -87,13 +76,15 @@ static void gtk_spinner_set_property (GObject *object, GParamSpec *pspec); static void gtk_spinner_set_active (GtkSpinner *spinner, gboolean active); -static AtkObject *gtk_spinner_get_accessible (GtkWidget *widget); -static GType gtk_spinner_accessible_get_type (void); -static void gtk_spinner_size_request_init (GtkSizeRequestIface *iface); +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); -G_DEFINE_TYPE_WITH_CODE (GtkSpinner, gtk_spinner, GTK_TYPE_WIDGET, - G_IMPLEMENT_INTERFACE (GTK_TYPE_SIZE_REQUEST, - gtk_spinner_size_request_init)) + +G_DEFINE_TYPE (GtkSpinner, gtk_spinner, GTK_TYPE_WIDGET) static void gtk_spinner_class_init (GtkSpinnerClass *klass) @@ -103,16 +94,13 @@ gtk_spinner_class_init (GtkSpinnerClass *klass) gobject_class = G_OBJECT_CLASS(klass); g_type_class_add_private (gobject_class, sizeof (GtkSpinnerPrivate)); - gobject_class->dispose = gtk_spinner_dispose; gobject_class->get_property = gtk_spinner_get_property; gobject_class->set_property = gtk_spinner_set_property; widget_class = GTK_WIDGET_CLASS(klass); - widget_class->map = gtk_spinner_map; - widget_class->unmap = gtk_spinner_unmap; - widget_class->expose_event = gtk_spinner_expose; - widget_class->style_set = gtk_spinner_style_set; - widget_class->get_accessible = gtk_spinner_get_accessible; + widget_class->draw = gtk_spinner_draw; + widget_class->get_preferred_width = gtk_spinner_get_preferred_width; + widget_class->get_preferred_height = gtk_spinner_get_preferred_height; /* GtkSpinner:active: * @@ -127,39 +115,8 @@ gtk_spinner_class_init (GtkSpinnerClass *klass) P_("Whether the spinner is active"), FALSE, G_PARAM_READWRITE)); - /** - * GtkSpinner:num-steps: - * - * 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 the #GtkSpinner:cycle-duration style property). - * - * Since: 2.20 - */ - gtk_widget_class_install_style_property (widget_class, - g_param_spec_uint ("num-steps", - P_("Number of steps"), - 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)."), - 1, - G_MAXUINT, - 12, - G_PARAM_READABLE)); - - /** - * GtkSpinner:cycle-duration: - * - * The duration in milliseconds for the spinner to complete a full cycle. - * - * Since: 2.20 - */ - 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)); + + gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_SPINNER_ACCESSIBLE); } static void @@ -202,22 +159,23 @@ static void gtk_spinner_init (GtkSpinner *spinner) { GtkSpinnerPrivate *priv; + GtkStyleContext *context; priv = G_TYPE_INSTANCE_GET_PRIVATE (spinner, GTK_TYPE_SPINNER, GtkSpinnerPrivate); - priv->current = 0; - priv->timeout = 0; - spinner->priv = priv; gtk_widget_set_has_window (GTK_WIDGET (spinner), FALSE); + + context = gtk_widget_get_style_context (GTK_WIDGET (spinner)); + gtk_style_context_add_class (context, GTK_STYLE_CLASS_SPINNER); } static void -gtk_spinner_get_width (GtkSizeRequest *widget, - gint *minimum_size, - gint *natural_size) +gtk_spinner_get_preferred_width (GtkWidget *widget, + gint *minimum_size, + gint *natural_size) { if (minimum_size) *minimum_size = SPINNER_SIZE; @@ -227,9 +185,9 @@ gtk_spinner_get_width (GtkSizeRequest *widget, } static void -gtk_spinner_get_height (GtkSizeRequest *widget, - gint *minimum_size, - gint *natural_size) +gtk_spinner_get_preferred_height (GtkWidget *widget, + gint *minimum_size, + gint *natural_size) { if (minimum_size) *minimum_size = SPINNER_SIZE; @@ -238,354 +196,49 @@ gtk_spinner_get_height (GtkSizeRequest *widget, *natural_size = SPINNER_SIZE; } -static void -gtk_spinner_size_request_init (GtkSizeRequestIface *iface) -{ - iface->get_width = gtk_spinner_get_width; - iface->get_height = gtk_spinner_get_height; -} - - static gboolean -gtk_spinner_expose (GtkWidget *widget, - GdkEventExpose *event) +gtk_spinner_draw (GtkWidget *widget, + cairo_t *cr) { - GtkAllocation allocation; - GtkStateType state_type; - GtkSpinnerPrivate *priv; - int width, height; + GtkStyleContext *context; + gint width, height; + gint size; - priv = GTK_SPINNER (widget)->priv; + context = gtk_widget_get_style_context (widget); - gtk_widget_get_allocation (widget, &allocation); - width = allocation.width; - height = allocation.height; + width = gtk_widget_get_allocated_width (widget); + height = gtk_widget_get_allocated_height (widget); + size = MIN (width, height); - state_type = GTK_STATE_NORMAL; - if (!gtk_widget_is_sensitive (widget)) - state_type = GTK_STATE_INSENSITIVE; - - gtk_paint_spinner (gtk_widget_get_style (widget), - gtk_widget_get_window (widget), - state_type, - &event->area, - widget, - "spinner", - priv->current, - event->area.x, event->area.y, - event->area.width, event->area.height); + gtk_render_activity (context, cr, + (width - size) / 2, + (height - size) / 2, + size, size); return FALSE; } -static gboolean -gtk_spinner_timeout (gpointer data) -{ - GtkSpinnerPrivate *priv; - - priv = GTK_SPINNER (data)->priv; - - if (priv->current + 1 >= priv->num_steps) - priv->current = 0; - else - priv->current++; - - gtk_widget_queue_draw (GTK_WIDGET (data)); - - return TRUE; -} - -static void -gtk_spinner_add_timeout (GtkSpinner *spinner) -{ - GtkSpinnerPrivate *priv; - - priv = spinner->priv; - - priv->timeout = gdk_threads_add_timeout ((guint) priv->cycle_duration / priv->num_steps, gtk_spinner_timeout, spinner); -} - -static void -gtk_spinner_remove_timeout (GtkSpinner *spinner) -{ - GtkSpinnerPrivate *priv; - - priv = spinner->priv; - - g_source_remove (priv->timeout); - priv->timeout = 0; -} - static void -gtk_spinner_map (GtkWidget *widget) +gtk_spinner_set_active (GtkSpinner *spinner, + gboolean active) { - GtkSpinner *spinner = GTK_SPINNER (widget); GtkSpinnerPrivate *priv = spinner->priv; - GTK_WIDGET_CLASS (gtk_spinner_parent_class)->map (widget); - - if (priv->active) - gtk_spinner_add_timeout (spinner); -} - -static void -gtk_spinner_unmap (GtkWidget *widget) -{ - GtkSpinner *spinner = GTK_SPINNER (widget); - GtkSpinnerPrivate *priv = spinner->priv; - - if (priv->timeout != 0) - gtk_spinner_remove_timeout (spinner); - - GTK_WIDGET_CLASS (gtk_spinner_parent_class)->unmap (widget); -} - -static void -gtk_spinner_style_set (GtkWidget *widget, - GtkStyle *prev_style) -{ - GtkSpinnerPrivate *priv; - - priv = GTK_SPINNER (widget)->priv; - - gtk_widget_style_get (GTK_WIDGET (widget), - "num-steps", &(priv->num_steps), - "cycle-duration", &(priv->cycle_duration), - NULL); - - if (priv->current > priv->num_steps) - priv->current = 0; -} - -static void -gtk_spinner_dispose (GObject *gobject) -{ - GtkSpinnerPrivate *priv; - - priv = GTK_SPINNER (gobject)->priv; - - if (priv->timeout != 0) - { - gtk_spinner_remove_timeout (GTK_SPINNER (gobject)); - } - - G_OBJECT_CLASS (gtk_spinner_parent_class)->dispose (gobject); -} - -static void -gtk_spinner_set_active (GtkSpinner *spinner, gboolean active) -{ - GtkSpinnerPrivate *priv; - - active = active != FALSE; - - priv = GTK_SPINNER (spinner)->priv; + active = !!active; if (priv->active != active) { priv->active = active; - g_object_notify (G_OBJECT (spinner), "active"); - - if (active && gtk_widget_get_realized (GTK_WIDGET (spinner)) && priv->timeout == 0) - { - gtk_spinner_add_timeout (spinner); - } - else if (!active && priv->timeout != 0) - { - gtk_spinner_remove_timeout (spinner); - } - } -} - -static GType -gtk_spinner_accessible_factory_get_accessible_type (void) -{ - return gtk_spinner_accessible_get_type (); -} - -static AtkObject * -gtk_spinner_accessible_new (GObject *obj) -{ - AtkObject *accessible; - - g_return_val_if_fail (GTK_IS_WIDGET (obj), NULL); - - accessible = g_object_new (gtk_spinner_accessible_get_type (), NULL); - atk_object_initialize (accessible, obj); - - return accessible; -} - -static AtkObject* -gtk_spinner_accessible_factory_create_accessible (GObject *obj) -{ - return gtk_spinner_accessible_new (obj); -} - -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; -} - -static GType -gtk_spinner_accessible_factory_get_type (void) -{ - static GType type = 0; - - if (!type) - { - const GTypeInfo tinfo = - { - sizeof (AtkObjectFactoryClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) gtk_spinner_accessible_factory_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (AtkObjectFactory), - 0, /* n_preallocs */ - NULL, NULL - }; - - type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY, - I_("GtkSpinnerAccessibleFactory"), - &tinfo, 0); - } - return type; -} - -static AtkObjectClass *a11y_parent_class = NULL; - -static void -gtk_spinner_accessible_initialize (AtkObject *accessible, - gpointer widget) -{ - atk_object_set_name (accessible, C_("throbbing progress animation widget", "Spinner")); - atk_object_set_description (accessible, _("Provides visual indication of progress")); - - a11y_parent_class->initialize (accessible, widget); -} - -static void -gtk_spinner_accessible_class_init (AtkObjectClass *klass) -{ - a11y_parent_class = g_type_class_peek_parent (klass); - - klass->initialize = gtk_spinner_accessible_initialize; -} -static void -gtk_spinner_accessible_image_get_size (AtkImage *image, - gint *width, - gint *height) -{ - GtkAllocation allocation; - GtkWidget *widget; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image)); - if (!widget) - { - *width = *height = 0; - } - else - { - gtk_widget_get_allocation (widget, &allocation); - *width = allocation.width; - *height = allocation.height; - } -} - -static void -gtk_spinner_accessible_image_interface_init (AtkImageIface *iface) -{ - iface->get_image_size = gtk_spinner_accessible_image_get_size; -} - -static GType -gtk_spinner_accessible_get_type (void) -{ - static GType type = 0; - - /* Action interface - Name etc. ... */ - if (G_UNLIKELY (type == 0)) - { - const GInterfaceInfo atk_image_info = { - (GInterfaceInitFunc) gtk_spinner_accessible_image_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - GType parent_atk_type; - GTypeInfo tinfo = { 0 }; - GTypeQuery query; - AtkObjectFactory *factory; - - if ((type = g_type_from_name ("GtkSpinnerAccessible"))) - return type; - - factory = atk_registry_get_factory (atk_get_default_registry (), - GTK_TYPE_IMAGE); - if (!factory) - return G_TYPE_INVALID; - - parent_atk_type = atk_object_factory_get_accessible_type (factory); - if (!parent_atk_type) - return G_TYPE_INVALID; - - /* - * Figure out the size of the class and instance - * we are deriving from - */ - g_type_query (parent_atk_type, &query); - - tinfo.class_init = (GClassInitFunc) gtk_spinner_accessible_class_init; - tinfo.class_size = query.class_size; - tinfo.instance_size = query.instance_size; - - /* Register the type */ - type = g_type_register_static (parent_atk_type, - "GtkSpinnerAccessible", - &tinfo, 0); - - g_type_add_interface_static (type, ATK_TYPE_IMAGE, - &atk_image_info); - } - - return type; -} - -static AtkObject * -gtk_spinner_get_accessible (GtkWidget *widget) -{ - static gboolean first_time = TRUE; + g_object_notify (G_OBJECT (spinner), "active"); - 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 (); - factory = atk_registry_get_factory (registry, - derived_type); - 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; + 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); } - return GTK_WIDGET_CLASS (gtk_spinner_parent_class)->get_accessible (widget); } /**