From 81b7c0170d525a4a7a923c22253312d88729c0c0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 26 Nov 2009 12:13:16 -0500 Subject: [PATCH] Add set_skip_paint method Ideally we'd be able to override _paint, but given that we can't at the moment, this method gives a way to implement containers which don't happen to paint all of their children. https://bugzilla.gnome.org/show_bug.cgi?id=603522 --- src/shell-generic-container.c | 107 +++++++++++++++++++++++++++++++++- src/shell-generic-container.h | 4 ++ 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/src/shell-generic-container.c b/src/shell-generic-container.c index 68b3afde2..b6cdeecc0 100644 --- a/src/shell-generic-container.c +++ b/src/shell-generic-container.c @@ -105,7 +105,7 @@ function runTestFixedBox() { G_DEFINE_TYPE(ShellGenericContainer, shell_generic_container, CLUTTER_TYPE_GROUP); struct _ShellGenericContainerPrivate { - gpointer dummy; + GHashTable *skip_paint; }; /* Signals */ @@ -182,15 +182,119 @@ shell_generic_container_get_preferred_height (ClutterActor *actor, shell_generic_container_allocation_unref (alloc); } +static void +shell_generic_container_paint (ClutterActor *actor) +{ + ShellGenericContainer *self = (ShellGenericContainer*) actor; + GList *iter, *children; + + children = clutter_container_get_children ((ClutterContainer*) actor); + + for (iter = children; iter; iter = iter->next) + { + ClutterActor *child = iter->data; + + if (g_hash_table_lookup (self->priv->skip_paint, child)) + continue; + + clutter_actor_paint (child); + } + + g_list_free (children); +} + +static void +shell_generic_container_pick (ClutterActor *actor, + const ClutterColor *color) +{ + ShellGenericContainer *self = (ShellGenericContainer*) actor; + GList *iter, *children; + + (CLUTTER_ACTOR_CLASS (g_type_class_peek (clutter_actor_get_type ())))->pick (actor, color); + + children = clutter_container_get_children ((ClutterContainer*) actor); + + for (iter = children; iter; iter = iter->next) + { + ClutterActor *child = iter->data; + + if (g_hash_table_lookup (self->priv->skip_paint, child)) + continue; + + clutter_actor_paint (child); + } + + g_list_free (children); +} + +static void +on_skip_paint_weakref (gpointer user_data, + GObject *location) +{ + ShellGenericContainer *self = SHELL_GENERIC_CONTAINER (user_data); + + g_hash_table_remove (self->priv->skip_paint, location); +} + +/** + * shell_generic_container_set_skip_paint: + * @container: A #ShellGenericContainer + * @child: Child #ClutterActor + * @skip %TRUE if we should skip painting + * + * Set whether or not we should skip painting @actor. Workaround for + * lack of gjs ability to override _paint vfunc. + */ +void +shell_generic_container_set_skip_paint (ShellGenericContainer *self, + ClutterActor *child, + gboolean skip) +{ + gboolean currently_skipping; + + currently_skipping = g_hash_table_lookup (self->priv->skip_paint, child) != NULL; + if (!!skip == currently_skipping) + return; + + if (!skip) + { + g_object_weak_unref ((GObject*) child, on_skip_paint_weakref, self); + g_hash_table_remove (self->priv->skip_paint, child); + } + else + { + g_object_weak_ref ((GObject*) child, on_skip_paint_weakref, self); + g_hash_table_insert (self->priv->skip_paint, child, child); + } +} + +static void +shell_generic_container_dispose (GObject *object) +{ + ShellGenericContainer *self = (ShellGenericContainer*) object; + + if (self->priv->skip_paint != NULL) + { + g_hash_table_destroy (self->priv->skip_paint); + self->priv->skip_paint = NULL; + } + + G_OBJECT_CLASS (shell_generic_container_parent_class)->dispose (object); +} + static void shell_generic_container_class_init (ShellGenericContainerClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + gobject_class->dispose = shell_generic_container_dispose; + actor_class->get_preferred_width = shell_generic_container_get_preferred_width; actor_class->get_preferred_height = shell_generic_container_get_preferred_height; actor_class->allocate = shell_generic_container_allocate; + actor_class->paint = shell_generic_container_paint; + actor_class->pick = shell_generic_container_pick; shell_generic_container_signals[GET_PREFERRED_WIDTH] = g_signal_new ("get-preferred-width", @@ -227,6 +331,7 @@ shell_generic_container_init (ShellGenericContainer *area) { area->priv = G_TYPE_INSTANCE_GET_PRIVATE (area, SHELL_TYPE_GENERIC_CONTAINER, ShellGenericContainerPrivate); + area->priv->skip_paint = g_hash_table_new_full (NULL, NULL, (GDestroyNotify)g_object_unref, NULL); } GType shell_generic_container_allocation_get_type (void) diff --git a/src/shell-generic-container.h b/src/shell-generic-container.h index 53e0907d5..009df5516 100644 --- a/src/shell-generic-container.h +++ b/src/shell-generic-container.h @@ -42,4 +42,8 @@ struct _ShellGenericContainerClass GType shell_generic_container_get_type (void) G_GNUC_CONST; +void shell_generic_container_set_skip_paint (ShellGenericContainer *container, + ClutterActor *actor, + gboolean skip); + #endif /* __SHELL_GENERIC_CONTAINER_H__ */