diff --git a/src/Makefile-st.am b/src/Makefile-st.am index c9428d168..d3597fdcd 100644 --- a/src/Makefile-st.am +++ b/src/Makefile-st.am @@ -74,6 +74,7 @@ st_source_h = \ st/st-button.h \ st/st-clickable.h \ st/st-clipboard.h \ + st/st-container.h \ st/st-drawing-area.h \ st/st-entry.h \ st/st-im-text.h \ @@ -120,6 +121,7 @@ st_source_c = \ st/st-button.c \ st/st-clickable.c \ st/st-clipboard.c \ + st/st-container.c \ st/st-drawing-area.c \ st/st-entry.c \ st/st-im-text.c \ diff --git a/src/shell-generic-container.c b/src/shell-generic-container.c index 9143368d3..a1773117c 100644 --- a/src/shell-generic-container.c +++ b/src/shell-generic-container.c @@ -25,12 +25,11 @@ static void shell_generic_container_iface_init (ClutterContainerIface *iface); G_DEFINE_TYPE_WITH_CODE(ShellGenericContainer, shell_generic_container, - ST_TYPE_WIDGET, + ST_TYPE_CONTAINER, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER, shell_generic_container_iface_init)); struct _ShellGenericContainerPrivate { - GList *children; GHashTable *skip_paint; }; @@ -126,11 +125,12 @@ static void shell_generic_container_paint (ClutterActor *actor) { ShellGenericContainer *self = (ShellGenericContainer*) actor; - GList *iter; + GList *iter, *children; CLUTTER_ACTOR_CLASS (shell_generic_container_parent_class)->paint (actor); - for (iter = self->priv->children; iter; iter = iter->next) + children = st_container_get_children_list (ST_CONTAINER (actor)); + for (iter = children; iter; iter = iter->next) { ClutterActor *child = iter->data; @@ -146,11 +146,12 @@ shell_generic_container_pick (ClutterActor *actor, const ClutterColor *color) { ShellGenericContainer *self = (ShellGenericContainer*) actor; - GList *iter; + GList *iter, *children; CLUTTER_ACTOR_CLASS (shell_generic_container_parent_class)->pick (actor, color); - for (iter = self->priv->children; iter; iter = iter->next) + children = st_container_get_children_list (ST_CONTAINER (actor)); + for (iter = children; iter; iter = iter->next) { ClutterActor *child = iter->data; @@ -215,29 +216,6 @@ shell_generic_container_set_skip_paint (ShellGenericContainer *self, g_hash_table_insert (self->priv->skip_paint, child, child); } -/** - * shell_generic_container_remove_all: - * @self: A #ShellGenericContainer - * - * Removes all child actors from @self. - */ -void -shell_generic_container_remove_all (ShellGenericContainer *self) -{ - /* copied from clutter_group_remove_all() */ - - GList *children; - - children = self->priv->children; - while (children) - { - ClutterActor *child = children->data; - children = children->next; - - clutter_container_remove_actor (CLUTTER_CONTAINER (self), child); - } -} - static void shell_generic_container_finalize (GObject *object) { @@ -248,17 +226,6 @@ shell_generic_container_finalize (GObject *object) G_OBJECT_CLASS (shell_generic_container_parent_class)->finalize (object); } -static void -shell_generic_container_dispose (GObject *object) -{ - ShellGenericContainerPrivate *priv = SHELL_GENERIC_CONTAINER (object)->priv; - - while (priv->children) - clutter_actor_destroy (priv->children->data); - - G_OBJECT_CLASS (shell_generic_container_parent_class)->dispose (object); -} - static void shell_generic_container_class_init (ShellGenericContainerClass *klass) { @@ -266,7 +233,6 @@ shell_generic_container_class_init (ShellGenericContainerClass *klass) ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); gobject_class->finalize = shell_generic_container_finalize; - 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; @@ -305,73 +271,18 @@ shell_generic_container_class_init (ShellGenericContainerClass *klass) } static void -shell_generic_container_add_actor (ClutterContainer *container, - ClutterActor *actor) -{ - ShellGenericContainerPrivate *priv = SHELL_GENERIC_CONTAINER (container)->priv; - - _st_container_add_actor (container, actor, &priv->children); -} - -static void -shell_generic_container_remove_actor (ClutterContainer *container, - ClutterActor *actor) +shell_generic_container_actor_removed (ClutterContainer *container, + ClutterActor *actor) { ShellGenericContainerPrivate *priv = SHELL_GENERIC_CONTAINER (container)->priv; g_hash_table_remove (priv->skip_paint, actor); - - _st_container_remove_actor (container, actor, &priv->children); -} - -static void -shell_generic_container_foreach (ClutterContainer *container, - ClutterCallback callback, - gpointer callback_data) -{ - ShellGenericContainerPrivate *priv = SHELL_GENERIC_CONTAINER (container)->priv; - - _st_container_foreach (container, callback, callback_data, - &priv->children); -} - -static void -shell_generic_container_lower (ClutterContainer *container, - ClutterActor *actor, - ClutterActor *sibling) -{ - ShellGenericContainerPrivate *priv = SHELL_GENERIC_CONTAINER (container)->priv; - - _st_container_lower (container, actor, sibling, &priv->children); -} - -static void -shell_generic_container_raise (ClutterContainer *container, - ClutterActor *actor, - ClutterActor *sibling) -{ - ShellGenericContainerPrivate *priv = SHELL_GENERIC_CONTAINER (container)->priv; - - _st_container_raise (container, actor, sibling, &priv->children); -} - -static void -shell_generic_container_sort_depth_order (ClutterContainer *container) -{ - ShellGenericContainerPrivate *priv = SHELL_GENERIC_CONTAINER (container)->priv; - - _st_container_sort_depth_order (container, &priv->children); } static void shell_generic_container_iface_init (ClutterContainerIface *iface) { - iface->add = shell_generic_container_add_actor; - iface->remove = shell_generic_container_remove_actor; - iface->foreach = shell_generic_container_foreach; - iface->lower = shell_generic_container_lower; - iface->raise = shell_generic_container_raise; - iface->sort_depth_order = shell_generic_container_sort_depth_order; + iface->actor_removed = shell_generic_container_actor_removed; } static void diff --git a/src/shell-generic-container.h b/src/shell-generic-container.h index e14ef45db..16170eca8 100644 --- a/src/shell-generic-container.h +++ b/src/shell-generic-container.h @@ -29,14 +29,14 @@ typedef struct _ShellGenericContainerPrivate ShellGenericContainerPrivate; struct _ShellGenericContainer { - StWidget parent; + StContainer parent; ShellGenericContainerPrivate *priv; }; struct _ShellGenericContainerClass { - StWidgetClass parent_class; + StContainerClass parent_class; }; GType shell_generic_container_get_type (void) G_GNUC_CONST; @@ -48,6 +48,5 @@ gboolean shell_generic_container_get_skip_paint (ShellGenericContainer *self, void shell_generic_container_set_skip_paint (ShellGenericContainer *self, ClutterActor *actor, gboolean skip); -void shell_generic_container_remove_all (ShellGenericContainer *self); #endif /* __SHELL_GENERIC_CONTAINER_H__ */ diff --git a/src/st/st-box-layout.c b/src/st/st-box-layout.c index 0b4777012..89fd91b80 100644 --- a/src/st/st-box-layout.c +++ b/src/st/st-box-layout.c @@ -57,11 +57,10 @@ #include "st-box-layout-child.h" - static void st_box_container_iface_init (ClutterContainerIface *iface); static void st_box_scrollable_interface_init (StScrollableInterface *iface); -G_DEFINE_TYPE_WITH_CODE (StBoxLayout, st_box_layout, ST_TYPE_WIDGET, +G_DEFINE_TYPE_WITH_CODE (StBoxLayout, st_box_layout, ST_TYPE_CONTAINER, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER, st_box_container_iface_init) G_IMPLEMENT_INTERFACE (ST_TYPE_SCROLLABLE, @@ -82,8 +81,6 @@ enum { struct _StBoxLayoutPrivate { - GList *children; - guint spacing; guint is_vertical : 1; @@ -93,6 +90,17 @@ struct _StBoxLayoutPrivate StAdjustment *vadjustment; }; +/* + * ClutterContainer Interface Implementation + */ +static void +st_box_sort_depth_order (ClutterContainer *container) +{ + /* The parent class' implementation would mess up the + * left-to-right order of the children - do nothing instead + */ +} + /* * StScrollable Interface Implementation */ @@ -185,76 +193,10 @@ st_box_scrollable_interface_init (StScrollableInterface *iface) iface->get_adjustments = scrollable_get_adjustments; } -/* - * ClutterContainer Implementation - */ -static void -st_box_container_add_actor (ClutterContainer *container, - ClutterActor *actor) -{ - StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (container)->priv; - - _st_container_add_actor (container, actor, &priv->children); -} - -static void -st_box_container_remove_actor (ClutterContainer *container, - ClutterActor *actor) -{ - StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (container)->priv; - - _st_container_remove_actor (container, actor, &priv->children); -} - -static void -st_box_container_foreach (ClutterContainer *container, - ClutterCallback callback, - gpointer callback_data) -{ - StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (container)->priv; - - _st_container_foreach (container, callback, callback_data, - &priv->children); -} - -static void -st_box_container_lower (ClutterContainer *container, - ClutterActor *actor, - ClutterActor *sibling) -{ - StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (container)->priv; - - _st_container_lower (container, actor, sibling, &priv->children); -} - -static void -st_box_container_raise (ClutterContainer *container, - ClutterActor *actor, - ClutterActor *sibling) -{ - StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (container)->priv; - - _st_container_raise (container, actor, sibling, &priv->children); -} - -static void -st_box_container_sort_depth_order (ClutterContainer *container) -{ - StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (container)->priv; - - _st_container_sort_depth_order (container, &priv->children); -} - static void st_box_container_iface_init (ClutterContainerIface *iface) { - iface->add = st_box_container_add_actor; - iface->remove = st_box_container_remove_actor; - iface->foreach = st_box_container_foreach; - iface->lower = st_box_container_lower; - iface->raise = st_box_container_raise; - iface->sort_depth_order = st_box_container_sort_depth_order; - + iface->sort_depth_order = st_box_sort_depth_order; iface->child_meta_type = ST_TYPE_BOX_LAYOUT_CHILD; } @@ -333,9 +275,6 @@ st_box_layout_dispose (GObject *object) { StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (object)->priv; - while (priv->children) - clutter_actor_destroy (priv->children->data); - if (priv->hadjustment) { g_object_unref (priv->hadjustment); @@ -361,12 +300,14 @@ get_content_preferred_width (StBoxLayout *self, gint n_children = 0; gint n_fixed = 0; gfloat min_width, natural_width; - GList *l; + GList *l, *children; min_width = 0; natural_width = 0; - for (l = priv->children; l; l = g_list_next (l)) + children = st_container_get_children_list (ST_CONTAINER (self)); + + for (l = children; l; l = g_list_next (l)) { ClutterActor *child = l->data; gfloat child_min = 0, child_nat = 0; @@ -392,7 +333,7 @@ get_content_preferred_width (StBoxLayout *self, } else { - clutter_container_child_get ((ClutterContainer*) self, child, + clutter_container_child_get (CLUTTER_CONTAINER (self), child, "y-fill", &child_fill, NULL); _st_actor_get_preferred_width (child, for_height, child_fill, @@ -442,12 +383,14 @@ get_content_preferred_height (StBoxLayout *self, gint n_children = 0; gint n_fixed = 0; gfloat min_height, natural_height; - GList *l; + GList *l, *children; min_height = 0; natural_height = 0; - for (l = priv->children; l; l = g_list_next (l)) + children = st_container_get_children_list (ST_CONTAINER (self)); + + for (l = children; l; l = g_list_next (l)) { ClutterActor *child = l->data; gfloat child_min = 0, child_nat = 0; @@ -560,7 +503,8 @@ compute_shrinks (StBoxLayout *self, gfloat total_shrink) { StBoxLayoutPrivate *priv = self->priv; - int n_children = g_list_length (priv->children); + GList *children = st_container_get_children_list (ST_CONTAINER (self)); + int n_children = g_list_length (children); BoxChildShrink *shrinks = g_new0 (BoxChildShrink, n_children); gfloat shrink_so_far; gfloat base_shrink = 0; /* the "= 0" is just to make gcc happy */ @@ -577,7 +521,7 @@ compute_shrinks (StBoxLayout *self, /* Find the amount of possible shrink for each child */ int n_possible_shrink_children = 0; - for (l = priv->children, i = 0; l; l = l->next, i++) + for (l = children, i = 0; l; l = l->next, i++) { ClutterActor *child = l->data; gfloat child_min, child_nat; @@ -678,7 +622,7 @@ st_box_layout_allocate (ClutterActor *actor, ClutterActorBox content_box; gfloat avail_width, avail_height, min_width, natural_width, min_height, natural_height; gfloat position, next_position; - GList *l; + GList *l, *children; gint n_expand_children = 0, i; gfloat expand_amount, shrink_amount; BoxChildShrink *shrinks = NULL; @@ -688,7 +632,8 @@ st_box_layout_allocate (ClutterActor *actor, CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->allocate (actor, box, flags); - if (priv->children == NULL) + children = st_container_get_children_list (ST_CONTAINER (actor)); + if (children == NULL) return; st_theme_node_get_content_box (theme_node, box, &content_box); @@ -762,7 +707,7 @@ st_box_layout_allocate (ClutterActor *actor, { /* count the number of children with expand set to TRUE */ n_expand_children = 0; - for (l = priv->children; l; l = l->next) + for (l = children; l; l = l->next) { ClutterActor *child = l->data; gboolean expand; @@ -798,12 +743,12 @@ st_box_layout_allocate (ClutterActor *actor, if (priv->is_pack_start) { - l = g_list_last (priv->children); - i = g_list_length (priv->children); + l = g_list_last (children); + i = g_list_length (children); } else { - l = priv->children; + l = children; i = 0; } @@ -938,7 +883,7 @@ st_box_layout_paint (ClutterActor *actor) { StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (actor)->priv; StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor)); - GList *l; + GList *l, *children; gdouble x, y; ClutterActorBox allocation_box; ClutterActorBox content_box; @@ -968,7 +913,9 @@ st_box_layout_paint (ClutterActor *actor) cogl_pop_matrix (); } - if (priv->children == NULL) + children = st_container_get_children_list (ST_CONTAINER (actor)); + + if (children == NULL) return; clutter_actor_get_allocation_box (actor, &allocation_box); @@ -988,7 +935,7 @@ st_box_layout_paint (ClutterActor *actor) (int)content_box.x2, (int)content_box.y2); - for (l = priv->children; l; l = g_list_next (l)) + for (l = children; l; l = g_list_next (l)) { ClutterActor *child = (ClutterActor*) l->data; @@ -1006,7 +953,7 @@ st_box_layout_pick (ClutterActor *actor, { StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (actor)->priv; StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor)); - GList *l; + GList *l, *children; gdouble x, y; ClutterActorBox allocation_box; ClutterActorBox content_box; @@ -1034,7 +981,9 @@ st_box_layout_pick (ClutterActor *actor, cogl_pop_matrix (); } - if (priv->children == NULL) + children = st_container_get_children_list (ST_CONTAINER (actor)); + + if (children == NULL) return; clutter_actor_get_allocation_box (actor, &allocation_box); @@ -1051,7 +1000,7 @@ st_box_layout_pick (ClutterActor *actor, (int)content_box.x2, (int)content_box.y2); - for (l = priv->children; l; l = g_list_next (l)) + for (l = children; l; l = g_list_next (l)) { ClutterActor *child = (ClutterActor*) l->data; @@ -1226,94 +1175,11 @@ st_box_layout_get_pack_start (StBoxLayout *box) return box->priv->is_pack_start; } -static void -st_box_layout_internal_remove_all (StBoxLayout *self, - gboolean destroy) -{ - StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (self)->priv; - ClutterActor *child; - - while (priv->children) - { - child = priv->children->data; - - g_object_ref (child); - priv->children = g_list_delete_link (priv->children, priv->children); - clutter_actor_unparent (child); - g_signal_emit_by_name (self, "actor-removed", child); - if (destroy) - clutter_actor_destroy (child); - g_object_unref (child); - } - - clutter_actor_queue_relayout ((ClutterActor*) self); -} - -/** - * st_box_layout_remove_all: - * @self: - * - * Efficiently unparent all children currently in this box. - */ -void -st_box_layout_remove_all (StBoxLayout *self) -{ - st_box_layout_internal_remove_all (self, FALSE); -} - -/** - * st_box_layout_destroy_children: - * @self: - * - * Efficiently unparent and destroy all children currently in this box. - */ -void -st_box_layout_destroy_children (StBoxLayout *self) -{ - st_box_layout_internal_remove_all (self, TRUE); -} - -/** - * st_box_layout_get_n_children: - * @self: a #StBoxLayout - * - * Returns the number of children in this box. - */ -guint -st_box_layout_get_n_children (StBoxLayout *self) -{ - return g_list_length (self->priv->children); -} - -void -st_box_layout_move_child (StBoxLayout *self, - ClutterActor *actor, - int pos) -{ - StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (self)->priv; - - GList *item = NULL; - - item = g_list_find (priv->children, actor); - - if (item == NULL) - { - g_warning ("Actor of type '%s' is not a child of the StBoxLayout container", - g_type_name (G_OBJECT_TYPE (actor))); - return; - } - - priv->children = g_list_delete_link (priv->children, item); - priv->children = g_list_insert (priv->children, actor, pos); - clutter_actor_queue_relayout ((ClutterActor*) self); -} - void st_box_layout_insert_actor (StBoxLayout *self, ClutterActor *actor, int pos) { clutter_container_add_actor((ClutterContainer*) self, actor); - st_box_layout_move_child(self, actor, pos); + st_container_move_child (ST_CONTAINER (self), actor, pos); } - diff --git a/src/st/st-box-layout.h b/src/st/st-box-layout.h index 33b59240a..74644c9f7 100644 --- a/src/st/st-box-layout.h +++ b/src/st/st-box-layout.h @@ -28,7 +28,7 @@ #ifndef _ST_BOX_LAYOUT_H #define _ST_BOX_LAYOUT_H -#include +#include G_BEGIN_DECLS @@ -67,14 +67,14 @@ typedef struct _StBoxLayoutPrivate StBoxLayoutPrivate; struct _StBoxLayout { /*< private >*/ - StWidget parent; + StContainer parent; StBoxLayoutPrivate *priv; }; struct _StBoxLayoutClass { - StWidgetClass parent_class; + StContainerClass parent_class; }; GType st_box_layout_get_type (void); @@ -89,16 +89,6 @@ void st_box_layout_set_pack_start (StBoxLayout *box, gboolean pack_start); gboolean st_box_layout_get_pack_start (StBoxLayout *box); -void st_box_layout_remove_all (StBoxLayout *box); - -void st_box_layout_destroy_children (StBoxLayout *box); - -guint st_box_layout_get_n_children (StBoxLayout *box); - -void st_box_layout_move_child (StBoxLayout *self, - ClutterActor *actor, - int pos); - void st_box_layout_insert_actor (StBoxLayout *self, ClutterActor *actor, int pos); diff --git a/src/st/st-container.c b/src/st/st-container.c new file mode 100644 index 000000000..32083e014 --- /dev/null +++ b/src/st/st-container.c @@ -0,0 +1,348 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * st-container.c: Base class for St container actors + * + * Copyright 2007 OpenedHand + * Copyright 2008, 2009 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * Boston, MA 02111-1307, USA. + * + * Written by: Emmanuele Bassi + * Thomas Wood + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "st-container.h" + +#define ST_CONTAINER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),ST_TYPE_CONTAINER, StContainerPrivate)) + +struct _StContainerPrivate +{ + GList *children; +}; + +static void clutter_container_iface_init (ClutterContainerIface *iface); + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (StContainer, st_container, ST_TYPE_WIDGET, + G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER, + clutter_container_iface_init)); + +/** + * st_container_remove_all: + * @container: An #StContainer + * + * Removes all child actors from @container. + */ +void +st_container_remove_all (StContainer *container) +{ + StContainerPrivate *priv = container->priv; + + /* copied from clutter_group_remove_all() */ + while (priv->children) + { + ClutterActor *child = priv->children->data; + priv->children = priv->children->next; + + clutter_container_remove_actor (CLUTTER_CONTAINER (container), child); + } +} + +/** + * st_container_destroy_children: + * @container: An #StContainer + * + * Destroys all child actors from @container. + */ +void +st_container_destroy_children (StContainer *container) +{ + StContainerPrivate *priv = container->priv; + + while (priv->children) + { + ClutterActor *child = priv->children->data; + priv->children = priv->children->next; + + clutter_actor_destroy (child); + } +} + +void +st_container_move_child (StContainer *container, + ClutterActor *actor, + int pos) +{ + StContainerPrivate *priv = container->priv; + GList *item = NULL; + + item = g_list_find (priv->children, actor); + + if (item == NULL) + { + g_warning ("Actor of type '%s' is not a child of the %s container", + g_type_name (G_OBJECT_TYPE (actor)), + g_type_name (G_OBJECT_TYPE (container))); + return; + } + + priv->children = g_list_delete_link (priv->children, item); + priv->children = g_list_insert (priv->children, actor, pos); + clutter_actor_queue_relayout ((ClutterActor*) container); +} + +/** + * st_container_get_children_list: + * @container: An #StContainer + * + * Get the internal list of @container's child actors. This function + * should only be used by subclasses of StContainer + * + * Returns: list of @container's child actors + */ +GList * +st_container_get_children_list (StContainer *container) +{ + g_return_val_if_fail (ST_IS_CONTAINER (container), NULL); + + return container->priv->children; +} + +static gint +sort_z_order (gconstpointer a, + gconstpointer b) +{ + float depth_a, depth_b; + + depth_a = clutter_actor_get_depth (CLUTTER_ACTOR (a)); + depth_b = clutter_actor_get_depth (CLUTTER_ACTOR (b)); + + if (depth_a < depth_b) + return -1; + if (depth_a > depth_b) + return 1; + return 0; +} + +static void +st_container_add (ClutterContainer *container, + ClutterActor *actor) +{ + StContainerPrivate *priv = ST_CONTAINER (container)->priv; + + g_object_ref (actor); + + priv->children = g_list_append (priv->children, actor); + clutter_actor_set_parent (actor, CLUTTER_ACTOR (container)); + + /* queue a relayout, to get the correct positioning inside + * the ::actor-added signal handlers + */ + clutter_actor_queue_relayout (CLUTTER_ACTOR (container)); + + g_signal_emit_by_name (container, "actor-added", actor); + + clutter_container_sort_depth_order (container); + + g_object_unref (actor); +} + +static void +st_container_remove (ClutterContainer *container, + ClutterActor *actor) +{ + StContainerPrivate *priv = ST_CONTAINER (container)->priv; + + g_object_ref (actor); + + priv->children = g_list_remove (priv->children, actor); + clutter_actor_unparent (actor); + + /* queue a relayout, to get the correct positioning inside + * the ::actor-removed signal handlers + */ + clutter_actor_queue_relayout (CLUTTER_ACTOR (container)); + + /* at this point, the actor passed to the "actor-removed" signal + * handlers is not parented anymore to the container but since we + * are holding a reference on it, it's still valid + */ + g_signal_emit_by_name (container, "actor-removed", actor); + + if (CLUTTER_ACTOR_IS_VISIBLE (container)) + clutter_actor_queue_redraw (CLUTTER_ACTOR (container)); + + g_object_unref (actor); +} + +static void +st_container_foreach (ClutterContainer *container, + ClutterCallback callback, + gpointer user_data) +{ + StContainerPrivate *priv = ST_CONTAINER (container)->priv; + + /* Using g_list_foreach instead of iterating the list manually + * because it has better protection against the current node being + * removed. This will happen for example if someone calls + * clutter_container_foreach(container, clutter_actor_destroy) + */ + g_list_foreach (priv->children, (GFunc) callback, user_data); +} + +static void +st_container_raise (ClutterContainer *container, + ClutterActor *actor, + ClutterActor *sibling) +{ + StContainerPrivate *priv = ST_CONTAINER (container)->priv; + + priv->children = g_list_remove (priv->children, actor); + + /* Raise at the top */ + if (!sibling) + { + GList *last_item; + + last_item = g_list_last (priv->children); + + if (last_item) + sibling = last_item->data; + + priv->children = g_list_append (priv->children, actor); + } + else + { + gint pos; + + pos = g_list_index (priv->children, sibling) + 1; + + priv->children = g_list_insert (priv->children, actor, pos); + } + + /* set Z ordering a value below, this will then call sort + * as values are equal ordering shouldn't change but Z + * values will be correct. + * + * FIXME: optimise + */ + if (sibling && + clutter_actor_get_depth (sibling) != clutter_actor_get_depth (actor)) + { + clutter_actor_set_depth (actor, clutter_actor_get_depth (sibling)); + } + + if (CLUTTER_ACTOR_IS_VISIBLE (container)) + clutter_actor_queue_redraw (CLUTTER_ACTOR (container)); +} + +static void +st_container_lower (ClutterContainer *container, + ClutterActor *actor, + ClutterActor *sibling) +{ + StContainerPrivate *priv = ST_CONTAINER (container)->priv; + + priv->children = g_list_remove (priv->children, actor); + + /* Push to bottom */ + if (!sibling) + { + GList *last_item; + + last_item = g_list_first (priv->children); + + if (last_item) + sibling = last_item->data; + + priv->children = g_list_prepend (priv->children, actor); + } + else + { + gint pos; + + pos = g_list_index (priv->children, sibling); + + priv->children = g_list_insert (priv->children, actor, pos); + } + + /* See comment in st_container_raise() for this */ + if (sibling && + clutter_actor_get_depth (sibling) != clutter_actor_get_depth (actor)) + { + clutter_actor_set_depth (actor, clutter_actor_get_depth (sibling)); + } + + if (CLUTTER_ACTOR_IS_VISIBLE (container)) + clutter_actor_queue_redraw (CLUTTER_ACTOR (container)); +} + +static void +st_container_sort_depth_order (ClutterContainer *container) +{ + StContainerPrivate *priv = ST_CONTAINER (container)->priv; + + priv->children = g_list_sort (priv->children, sort_z_order); + + if (CLUTTER_ACTOR_IS_VISIBLE (container)) + clutter_actor_queue_redraw (CLUTTER_ACTOR (container)); +} + +static void +st_container_dispose (GObject *object) +{ + StContainerPrivate *priv = ST_CONTAINER (object)->priv; + + if (priv->children) + { + g_list_foreach (priv->children, (GFunc) clutter_actor_destroy, NULL); + g_list_free (priv->children); + + priv->children = NULL; + } + + G_OBJECT_CLASS (st_container_parent_class)->dispose (object); +} + +static void +clutter_container_iface_init (ClutterContainerIface *iface) +{ + iface->add = st_container_add; + iface->remove = st_container_remove; + iface->foreach = st_container_foreach; + iface->raise = st_container_raise; + iface->lower = st_container_lower; + iface->sort_depth_order = st_container_sort_depth_order; +} + +static void +st_container_init (StContainer *container) +{ + container->priv = ST_CONTAINER_GET_PRIVATE (container); +} + +static void +st_container_class_init (StContainerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (StContainerPrivate)); + + object_class->dispose = st_container_dispose; +} diff --git a/src/st/st-container.h b/src/st/st-container.h new file mode 100644 index 000000000..ac9ef2c06 --- /dev/null +++ b/src/st/st-container.h @@ -0,0 +1,68 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * st-container.h: Base class for St container actors + * + * Copyright 2007 OpenedHand + * Copyright 2008, 2009 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * Boston, MA 02111-1307, USA. + * + */ + +#if !defined(ST_H_INSIDE) && !defined(ST_COMPILATION) +#error "Only can be included directly.h" +#endif + +#ifndef __ST_CONTAINER_H__ +#define __ST_CONTAINER_H__ + +#include + +G_BEGIN_DECLS + +#define ST_TYPE_CONTAINER (st_container_get_type ()) +#define ST_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ST_TYPE_CONTAINER, StContainer)) +#define ST_IS_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ST_TYPE_CONTAINER)) +#define ST_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ST_TYPE_CONTAINER, StContainerClass)) +#define ST_IS_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ST_TYPE_CONTAINER)) +#define ST_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ST_TYPE_CONTAINER, StContainerClass)) + +typedef struct _StContainer StContainer; +typedef struct _StContainerClass StContainerClass; +typedef struct _StContainerPrivate StContainerPrivate; + +struct _StContainer { + StWidget parent; + StContainerPrivate *priv; +}; + +struct _StContainerClass { + StWidgetClass parent_class; +}; + +GType st_container_get_type (void) G_GNUC_CONST; + +void st_container_remove_all (StContainer *container); +void st_container_destroy_children (StContainer *container); + +/* Only to be used by subclasses of StContainer */ +void st_container_move_child (StContainer *container, + ClutterActor *actor, + int pos); +GList *st_container_get_children_list (StContainer *container); + +G_END_DECLS + +#endif /* __ST_CONTAINER_H__ */ diff --git a/src/st/st-overflow-box.c b/src/st/st-overflow-box.c index 1528baff9..9743955ea 100644 --- a/src/st/st-overflow-box.c +++ b/src/st/st-overflow-box.c @@ -41,11 +41,7 @@ #include "st-private.h" #include "st-box-layout-child.h" -static void st_overflow_box_container_iface_init (ClutterContainerIface *iface); - -G_DEFINE_TYPE_WITH_CODE (StOverflowBox, st_overflow_box, ST_TYPE_WIDGET, - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER, - st_overflow_box_container_iface_init)); +G_DEFINE_TYPE (StOverflowBox, st_overflow_box, ST_TYPE_CONTAINER) #define OVERFLOW_BOX_LAYOUT_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), ST_TYPE_OVERFLOW_BOX, StOverflowBoxPrivate)) @@ -58,84 +54,12 @@ enum { struct _StOverflowBoxPrivate { - GList *children; guint min_children; guint n_visible; guint spacing; }; -/* - * ClutterContainer Implementation - */ -static void -st_overflow_box_add_actor (ClutterContainer *container, - ClutterActor *actor) -{ - StOverflowBoxPrivate *priv = ST_OVERFLOW_BOX (container)->priv; - - _st_container_add_actor (container, actor, &priv->children); -} - -static void -st_overflow_box_remove_actor (ClutterContainer *container, - ClutterActor *actor) -{ - StOverflowBoxPrivate *priv = ST_OVERFLOW_BOX (container)->priv; - - _st_container_remove_actor (container, actor, &priv->children); -} - -static void -st_overflow_box_foreach (ClutterContainer *container, - ClutterCallback callback, - gpointer callback_data) -{ - StOverflowBoxPrivate *priv = ST_OVERFLOW_BOX (container)->priv; - - _st_container_foreach (container, callback, callback_data, - &priv->children); -} - -static void -st_overflow_box_lower (ClutterContainer *container, - ClutterActor *actor, - ClutterActor *sibling) -{ - StOverflowBoxPrivate *priv = ST_OVERFLOW_BOX (container)->priv; - - _st_container_lower (container, actor, sibling, &priv->children); -} - -static void -st_overflow_box_raise (ClutterContainer *container, - ClutterActor *actor, - ClutterActor *sibling) -{ - StOverflowBoxPrivate *priv = ST_OVERFLOW_BOX (container)->priv; - - _st_container_raise (container, actor, sibling, &priv->children); -} - -static void -st_overflow_box_sort_depth_order (ClutterContainer *container) -{ - StOverflowBoxPrivate *priv = ST_OVERFLOW_BOX (container)->priv; - - _st_container_sort_depth_order (container, &priv->children); -} - -static void -st_overflow_box_container_iface_init (ClutterContainerIface *iface) -{ - iface->add = st_overflow_box_add_actor; - iface->remove = st_overflow_box_remove_actor; - iface->foreach = st_overflow_box_foreach; - iface->lower = st_overflow_box_lower; - iface->raise = st_overflow_box_raise; - iface->sort_depth_order = st_overflow_box_sort_depth_order; -} - static void st_overflow_box_get_property (GObject *object, @@ -175,17 +99,6 @@ st_overflow_box_set_property (GObject *object, } } -static void -st_overflow_box_dispose (GObject *object) -{ - StOverflowBoxPrivate *priv = ST_OVERFLOW_BOX (object)->priv; - - while (priv->children) - clutter_actor_destroy (priv->children->data); - - G_OBJECT_CLASS (st_overflow_box_parent_class)->dispose (object); -} - static void get_content_preferred_width (StOverflowBox *self, gfloat for_height, @@ -196,12 +109,13 @@ get_content_preferred_width (StOverflowBox *self, gint n_children = 0; gint n_fixed = 0; gfloat min_width, natural_width; - GList *l; + GList *l, *children; min_width = 0; natural_width = 0; - for (l = priv->children; l; l = g_list_next (l)) + children = st_container_get_children_list (ST_CONTAINER (self)); + for (l = children; l; l = g_list_next (l)) { ClutterActor *child = l->data; gfloat child_min = 0, child_nat = 0; @@ -267,12 +181,13 @@ get_content_preferred_height (StOverflowBox *self, gint n_children = 0; gint n_fixed = 0; gfloat min_height, natural_height; - GList *l; + GList *l, *children; min_height = 0; natural_height = 0; - for (l = priv->children; l; l = g_list_next (l)) + children = st_container_get_children_list (ST_CONTAINER (self)); + for (l = children; l; l = g_list_next (l)) { ClutterActor *child = l->data; gfloat child_min = 0, child_nat = 0; @@ -338,14 +253,15 @@ st_overflow_box_allocate (ClutterActor *actor, ClutterActorBox content_box; gfloat position; float avail_width, avail_height; - GList *l; + GList *l, *children; int i; gboolean done_non_fixed; CLUTTER_ACTOR_CLASS (st_overflow_box_parent_class)->allocate (actor, box, flags); - if (priv->children == NULL) + children = st_container_get_children_list (ST_CONTAINER (actor)); + if (children == NULL) return; st_theme_node_get_content_box (theme_node, box, &content_box); @@ -357,7 +273,7 @@ st_overflow_box_allocate (ClutterActor *actor, priv->n_visible = 0; done_non_fixed = FALSE; - for (l = priv->children, i = 0; l; l = l->next, i++) + for (l = children, i = 0; l; l = l->next, i++) { ClutterActor *child = (ClutterActor*) l->data; ClutterActorBox child_box; @@ -401,11 +317,12 @@ static void st_overflow_box_internal_paint (StOverflowBox *box) { StOverflowBoxPrivate *priv = box->priv; - GList *l; + GList *l, *children; int i; i = 0; - for (l = priv->children; i < priv->n_visible && l; l = l->next) + children = st_container_get_children_list (ST_CONTAINER (box)); + for (l = children; i < priv->n_visible && l; l = l->next) { ClutterActor *child = (ClutterActor*) l->data; @@ -474,7 +391,6 @@ st_overflow_box_class_init (StOverflowBoxClass *klass) object_class->get_property = st_overflow_box_get_property; object_class->set_property = st_overflow_box_set_property; - object_class->dispose = st_overflow_box_dispose; actor_class->allocate = st_overflow_box_allocate; actor_class->get_preferred_width = st_overflow_box_get_preferred_width; @@ -536,54 +452,6 @@ st_overflow_box_set_min_children (StOverflowBox *box, } } - -static void -st_overflow_box_internal_remove_all (StOverflowBox *self, - gboolean destroy) -{ - StOverflowBoxPrivate *priv = ST_OVERFLOW_BOX (self)->priv; - ClutterActor *child; - - while (priv->children) - { - child = priv->children->data; - - g_object_ref (child); - priv->children = g_list_delete_link (priv->children, priv->children); - clutter_actor_unparent (child); - g_signal_emit_by_name (self, "actor-removed", child); - if (destroy) - clutter_actor_destroy (child); - g_object_unref (child); - } - - clutter_actor_queue_relayout ((ClutterActor*) self); -} - -/** - * st_overflow_box_remove_all: - * @self: - * - * Efficiently unparent all children currently in this box. - */ -void -st_overflow_box_remove_all (StOverflowBox *self) -{ - st_overflow_box_internal_remove_all (self, FALSE); -} - -/** - * st_overflow_box_destroy_children: - * @self: - * - * Efficiently unparent and destroy all children currently in this box. - */ -void -st_overflow_box_destroy_children (StOverflowBox *self) -{ - st_overflow_box_internal_remove_all (self, TRUE); -} - /** * st_overflow_box_get_n_children: * @self: a #StOverflowBox @@ -593,7 +461,8 @@ st_overflow_box_destroy_children (StOverflowBox *self) guint st_overflow_box_get_n_children (StOverflowBox *self) { - return g_list_length (self->priv->children); + GList *children = st_container_get_children_list (ST_CONTAINER (self)); + return g_list_length (children); } /** diff --git a/src/st/st-overflow-box.h b/src/st/st-overflow-box.h index aad595345..47632ade0 100644 --- a/src/st/st-overflow-box.h +++ b/src/st/st-overflow-box.h @@ -51,21 +51,19 @@ typedef struct _StOverflowBoxPrivate StOverflowBoxPrivate; struct _StOverflowBox { /*< private >*/ - StWidget parent; + StContainer parent; StOverflowBoxPrivate *priv; }; struct _StOverflowBoxClass { - StWidgetClass parent_class; + StContainerClass parent_class; }; GType st_overflow_box_get_type (void); void st_overflow_box_set_min_children (StOverflowBox *self, guint min_children); -void st_overflow_box_remove_all (StOverflowBox *box); -void st_overflow_box_destroy_children (StOverflowBox *box); guint st_overflow_box_get_n_children (StOverflowBox *box); guint st_overflow_box_get_n_visible (StOverflowBox *box); gboolean st_overflow_box_get_min_children (StOverflowBox *box); diff --git a/src/st/st-private.c b/src/st/st-private.c index e0fee5a59..7586e2b79 100644 --- a/src/st/st-private.c +++ b/src/st/st-private.c @@ -310,231 +310,3 @@ _st_set_text_from_style (ClutterText *text, pango_attr_list_unref (attribs); } - -/** - * _st_container_add_actor: - * @container: a #ClutterContainer - * @actor: a #ClutterActor - * @children: pointer to @container's list of children - * - * A basic implementation for clutter_container_add_actor(). - * Mostly copied from clutter_group_real_add(). - */ -void -_st_container_add_actor (ClutterContainer *container, - ClutterActor *actor, - GList **children) -{ - g_object_ref (actor); - - *children = g_list_append (*children, actor); - clutter_actor_set_parent (actor, CLUTTER_ACTOR (container)); - - /* queue a relayout, to get the correct positioning inside - * the ::actor-added signal handlers - */ - clutter_actor_queue_relayout (CLUTTER_ACTOR (container)); - - g_signal_emit_by_name (container, "actor-added", actor); - - clutter_container_sort_depth_order (container); - - g_object_unref (actor); -} - -/** - * _st_container_remove_actor: - * @container: a #ClutterContainer - * @actor: a #ClutterActor - * @children: pointer to @container's list of children - * - * A basic implementation for clutter_container_remove_actor(). - * Mostly copied from clutter_group_real_remove(). - */ -void -_st_container_remove_actor (ClutterContainer *container, - ClutterActor *actor, - GList **children) -{ - g_object_ref (actor); - - *children = g_list_remove (*children, actor); - clutter_actor_unparent (actor); - - /* queue a relayout, to get the correct positioning inside - * the ::actor-removed signal handlers - */ - clutter_actor_queue_relayout (CLUTTER_ACTOR (container)); - - /* at this point, the actor passed to the "actor-removed" signal - * handlers is not parented anymore to the container but since we - * are holding a reference on it, it's still valid - */ - g_signal_emit_by_name (container, "actor-removed", actor); - - if (CLUTTER_ACTOR_IS_VISIBLE (container)) - clutter_actor_queue_redraw (CLUTTER_ACTOR (container)); - - g_object_unref (actor); -} - -/** - * _st_container_raise: - * @container: a #ClutterContainer - * @callback: callback - * @user_data: data for @callback - * @children: pointer to @container's list of children - * - * A basic implementation for clutter_container_foreach(). - * Mostly copied from clutter_group_real_foreach(). - */ -void -_st_container_foreach (ClutterContainer *container, - ClutterCallback callback, - gpointer user_data, - GList **children) -{ - GList *l; - - for (l = *children; l; l = l->next) - (* callback) (CLUTTER_ACTOR (l->data), user_data); -} - -/** - * _st_container_raise: - * @container: a #ClutterContainer - * @actor: a #ClutterActor to raise - * @sibling: the sibling to raise to, or %NULL to put on top - * @children: pointer to @container's list of children - * - * A basic implementation for clutter_container_raise(). - * Mostly copied from clutter_group_real_raise(). - */ -void -_st_container_raise (ClutterContainer *container, - ClutterActor *actor, - ClutterActor *sibling, - GList **children) -{ - *children = g_list_remove (*children, actor); - - /* Raise at the top */ - if (!sibling) - { - GList *last_item; - - last_item = g_list_last (*children); - - if (last_item) - sibling = last_item->data; - - *children = g_list_append (*children, actor); - } - else - { - gint pos; - - pos = g_list_index (*children, sibling) + 1; - - *children = g_list_insert (*children, actor, pos); - } - - /* set Z ordering a value below, this will then call sort - * as values are equal ordering shouldn't change but Z - * values will be correct. - * - * FIXME: optimise - */ - if (sibling && - clutter_actor_get_depth (sibling) != clutter_actor_get_depth (actor)) - { - clutter_actor_set_depth (actor, clutter_actor_get_depth (sibling)); - } - - if (CLUTTER_ACTOR_IS_VISIBLE (container)) - clutter_actor_queue_redraw (CLUTTER_ACTOR (container)); -} - -/** - * _st_container_lower: - * @container: a #ClutterContainer - * @actor: a #ClutterActor to lower - * @sibling: the sibling to lower to, or %NULL to put on bottom - * @children: pointer to @container's list of children - * - * A basic implementation for clutter_container_lower(). - * Mostly copied from clutter_group_real_lower(). - */ -void -_st_container_lower (ClutterContainer *container, - ClutterActor *actor, - ClutterActor *sibling, - GList **children) -{ - *children = g_list_remove (*children, actor); - - /* Push to bottom */ - if (!sibling) - { - GList *last_item; - - last_item = g_list_first (*children); - - if (last_item) - sibling = last_item->data; - - *children = g_list_prepend (*children, actor); - } - else - { - gint pos; - - pos = g_list_index (*children, sibling); - - *children = g_list_insert (*children, actor, pos); - } - - /* See comment in _st_container_raise() for this */ - if (sibling && - clutter_actor_get_depth (sibling) != clutter_actor_get_depth (actor)) - { - clutter_actor_set_depth (actor, clutter_actor_get_depth (sibling)); - } - - if (CLUTTER_ACTOR_IS_VISIBLE (container)) - clutter_actor_queue_redraw (CLUTTER_ACTOR (container)); -} - -static gint -sort_z_order (gconstpointer a, - gconstpointer b) -{ - float depth_a, depth_b; - - depth_a = clutter_actor_get_depth (CLUTTER_ACTOR (a)); - depth_b = clutter_actor_get_depth (CLUTTER_ACTOR (b)); - - if (depth_a < depth_b) - return -1; - if (depth_a > depth_b) - return 1; - return 0; -} - -/** - * _st_container_sort_depth_order: - * @container: a #ClutterContainer - * @children: pointer to @container's list of children - * - * A basic implementation for clutter_container_sort_depth_order(). - * Mostly copied from clutter_group_real_sort_depth_order(). - */ -void -_st_container_sort_depth_order (ClutterContainer *container, - GList **children) -{ - *children = g_list_sort (*children, sort_z_order); - - if (CLUTTER_ACTOR_IS_VISIBLE (container)) - clutter_actor_queue_redraw (CLUTTER_ACTOR (container)); -} diff --git a/src/st/st-private.h b/src/st/st-private.h index d22e11f1d..83686659c 100644 --- a/src/st/st-private.h +++ b/src/st/st-private.h @@ -72,25 +72,4 @@ void _st_allocate_fill (StWidget *parent, void _st_set_text_from_style (ClutterText *text, StThemeNode *theme_node); -void _st_container_add_actor (ClutterContainer *container, - ClutterActor *actor, - GList **children); -void _st_container_remove_actor (ClutterContainer *container, - ClutterActor *actor, - GList **children); -void _st_container_foreach (ClutterContainer *container, - ClutterCallback callback, - gpointer user_data, - GList **children); -void _st_container_raise (ClutterContainer *container, - ClutterActor *actor, - ClutterActor *sibling, - GList **children); -void _st_container_lower (ClutterContainer *container, - ClutterActor *actor, - ClutterActor *sibling, - GList **children); -void _st_container_sort_depth_order (ClutterContainer *container, - GList **children); - #endif /* __ST_PRIVATE_H__ */ diff --git a/src/st/st-table.c b/src/st/st-table.c index 27f4eae02..878bc6834 100644 --- a/src/st/st-table.c +++ b/src/st/st-table.c @@ -64,8 +64,6 @@ enum struct _StTablePrivate { - GList *children; - gint col_spacing; gint row_spacing; @@ -91,7 +89,7 @@ struct _StTablePrivate static void st_table_container_iface_init (ClutterContainerIface *iface); -G_DEFINE_TYPE_WITH_CODE (StTable, st_table, ST_TYPE_WIDGET, +G_DEFINE_TYPE_WITH_CODE (StTable, st_table, ST_TYPE_CONTAINER, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER, st_table_container_iface_init)); @@ -101,25 +99,17 @@ G_DEFINE_TYPE_WITH_CODE (StTable, st_table, ST_TYPE_WIDGET, * ClutterContainer Implementation */ static void -st_table_add_actor (ClutterContainer *container, - ClutterActor *actor) +st_table_actor_removed (ClutterContainer *container, + ClutterActor *actor) { StTablePrivate *priv = ST_TABLE (container)->priv; - - _st_container_add_actor (container, actor, &priv->children); -} - -static void -st_table_remove_actor (ClutterContainer *container, - ClutterActor *actor) -{ - StTablePrivate *priv = ST_TABLE (container)->priv; - GList *list; + GList *list, *children; gint n_rows = 0; gint n_cols = 0; /* Calculate and update the number of rows / columns */ - for (list = priv->children; list; list = list->next) + children = st_container_get_children_list (ST_CONTAINER (container)); + for (list = children; list; list = list->next) { ClutterActor *child = CLUTTER_ACTOR (list->data); StTableChild *meta; @@ -147,59 +137,12 @@ st_table_remove_actor (ClutterContainer *container, } g_object_thaw_notify (G_OBJECT (container)); - - _st_container_remove_actor (container, actor, &priv->children); -} - -static void -st_table_foreach (ClutterContainer *container, - ClutterCallback callback, - gpointer callback_data) -{ - StTablePrivate *priv = ST_TABLE (container)->priv; - - _st_container_foreach (container, callback, callback_data, - &priv->children); -} - -static void -st_table_lower (ClutterContainer *container, - ClutterActor *actor, - ClutterActor *sibling) -{ - StTablePrivate *priv = ST_TABLE (container)->priv; - - _st_container_lower (container, actor, sibling, &priv->children); -} - -static void -st_table_raise (ClutterContainer *container, - ClutterActor *actor, - ClutterActor *sibling) -{ - StTablePrivate *priv = ST_TABLE (container)->priv; - - _st_container_raise (container, actor, sibling, &priv->children); -} - -static void -st_table_sort_depth_order (ClutterContainer *container) -{ - StTablePrivate *priv = ST_TABLE (container)->priv; - - _st_container_sort_depth_order (container, &priv->children); } static void st_table_container_iface_init (ClutterContainerIface *iface) { - iface->add = st_table_add_actor; - iface->remove = st_table_remove_actor; - iface->foreach = st_table_foreach; - iface->lower = st_table_lower; - iface->raise = st_table_raise; - iface->sort_depth_order = st_table_sort_depth_order; - + iface->actor_removed = st_table_actor_removed; iface->child_meta_type = ST_TYPE_TABLE_CHILD; } @@ -277,23 +220,12 @@ st_table_finalize (GObject *gobject) G_OBJECT_CLASS (st_table_parent_class)->finalize (gobject); } -static void -st_table_dispose (GObject *gobject) -{ - StTablePrivate *priv = ST_TABLE (gobject)->priv; - - while (priv->children) - clutter_actor_destroy (priv->children->data); - - G_OBJECT_CLASS (st_table_parent_class)->dispose (gobject); -} - static void st_table_homogeneous_allocate (ClutterActor *self, const ClutterActorBox *content_box, gboolean flags) { - GList *list; + GList *list, *children; gfloat col_width, row_height; gint row_spacing, col_spacing; StTablePrivate *priv = ST_TABLE (self)->priv; @@ -309,7 +241,8 @@ st_table_homogeneous_allocate (ClutterActor *self, - (row_spacing * (priv->n_rows - 1))) / priv->n_rows; - for (list = priv->children; list; list = list->next) + children = st_container_get_children_list (ST_CONTAINER (self)); + for (list = children; list; list = list->next) { gint row, col, row_span, col_span; StTableChild *meta; @@ -367,7 +300,7 @@ st_table_calculate_col_widths (StTable *table, gboolean *is_expand_col; gint extra_col_width, n_expanded_cols = 0, expanded_cols = 0; gint *pref_widths, *min_widths; - GList *list; + GList *list, *children; g_array_set_size (priv->is_expand_col, 0); g_array_set_size (priv->is_expand_col, priv->n_cols); @@ -381,7 +314,9 @@ st_table_calculate_col_widths (StTable *table, g_array_set_size (priv->min_widths, priv->n_cols); min_widths = (gint *) priv->min_widths->data; - for (list = priv->children; list; list = list->next) + children = st_container_get_children_list (ST_CONTAINER (table)); + + for (list = children; list; list = list->next) { gint row, col; gfloat w_min, w_pref; @@ -469,7 +404,7 @@ st_table_calculate_row_heights (StTable *table, gint * col_widths) { StTablePrivate *priv = ST_TABLE (table)->priv; - GList *list; + GList *list, *children; gint *is_expand_row, *min_heights, *pref_heights, *row_heights, extra_row_height; gint i, total_min_height; gint expanded_rows = 0; @@ -491,8 +426,8 @@ st_table_calculate_row_heights (StTable *table, g_array_set_size (priv->pref_heights, priv->n_rows); pref_heights = (gboolean *) priv->pref_heights->data; - /* calculate minimum row widths and column heights */ - for (list = priv->children; list; list = list->next) + children = st_container_get_children_list (ST_CONTAINER (table)); + for (list = children; list; list = list->next) { gint row, col, cell_width; gfloat h_min, h_pref; @@ -643,7 +578,7 @@ st_table_preferred_allocate (ClutterActor *self, const ClutterActorBox *content_box, gboolean flags) { - GList *list; + GList *list, *children; gint row_spacing, col_spacing; gint i; gint *col_widths, *row_heights; @@ -668,8 +603,8 @@ st_table_preferred_allocate (ClutterActor *self, ltr = (st_widget_get_direction (ST_WIDGET (self)) == ST_TEXT_DIRECTION_LTR); - - for (list = priv->children; list; list = list->next) + children = st_container_get_children_list (ST_CONTAINER (self)); + for (list = children; list; list = list->next) { gint row, col, row_span, col_span; gint col_width, row_height; @@ -813,7 +748,7 @@ st_table_get_preferred_width (ClutterActor *self, gfloat total_min_width, total_pref_width; StTablePrivate *priv = ST_TABLE (self)->priv; StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (self)); - GList *list; + GList *list, *children; gint i; if (priv->n_cols < 1) @@ -835,7 +770,8 @@ st_table_get_preferred_width (ClutterActor *self, pref_widths = (gint *) priv->pref_widths->data; /* calculate minimum row widths */ - for (list = priv->children; list; list = list->next) + children = st_container_get_children_list (ST_CONTAINER (self)); + for (list = children; list; list = list->next) { gint col, col_span; gfloat w_min, w_pref; @@ -896,7 +832,7 @@ st_table_get_preferred_height (ClutterActor *self, gfloat total_min_height, total_pref_height; StTablePrivate *priv = ST_TABLE (self)->priv; StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (self)); - GList *list; + GList *list, *children; gint i; gint *min_widths; @@ -935,7 +871,8 @@ st_table_get_preferred_height (ClutterActor *self, pref_heights = (gint *) priv->pref_heights->data; /* calculate minimum row heights */ - for (list = priv->children; list; list = list->next) + children = st_container_get_children_list (ST_CONTAINER (self)); + for (list = children; list; list = list->next) { gint row, col, col_span, cell_width, row_span; gfloat min, pref; @@ -989,13 +926,13 @@ st_table_get_preferred_height (ClutterActor *self, static void st_table_paint (ClutterActor *self) { - StTablePrivate *priv = ST_TABLE (self)->priv; - GList *list; + GList *list, *children; /* make sure the background gets painted first */ CLUTTER_ACTOR_CLASS (st_table_parent_class)->paint (self); - for (list = priv->children; list; list = list->next) + children = st_container_get_children_list (ST_CONTAINER (self)); + for (list = children; list; list = list->next) { ClutterActor *child = CLUTTER_ACTOR (list->data); if (CLUTTER_ACTOR_IS_VISIBLE (child)) @@ -1007,13 +944,13 @@ static void st_table_pick (ClutterActor *self, const ClutterColor *color) { - StTablePrivate *priv = ST_TABLE (self)->priv; - GList *list; + GList *list, *children; /* Chain up so we get a bounding box painted (if we are reactive) */ CLUTTER_ACTOR_CLASS (st_table_parent_class)->pick (self, color); - for (list = priv->children; list; list = list->next) + children = st_container_get_children_list (ST_CONTAINER (self)); + for (list = children; list; list = list->next) { if (CLUTTER_ACTOR_IS_VISIBLE (list->data)) clutter_actor_paint (CLUTTER_ACTOR (list->data)); @@ -1023,10 +960,10 @@ st_table_pick (ClutterActor *self, static void st_table_show_all (ClutterActor *table) { - StTablePrivate *priv = ST_TABLE (table)->priv; - GList *l; + GList *l, *children; - for (l = priv->children; l; l = l->next) + children = st_container_get_children_list (ST_CONTAINER (table)); + for (l = children; l; l = l->next) clutter_actor_show_all (CLUTTER_ACTOR (l->data)); clutter_actor_show (table); @@ -1035,12 +972,12 @@ st_table_show_all (ClutterActor *table) static void st_table_hide_all (ClutterActor *table) { - StTablePrivate *priv = ST_TABLE (table)->priv; - GList *l; + GList *l, *children; clutter_actor_hide (table); - for (l = priv->children; l; l = l->next) + children = st_container_get_children_list (ST_CONTAINER (table)); + for (l = children; l; l = l->next) clutter_actor_hide_all (CLUTTER_ACTOR (l->data)); } @@ -1078,7 +1015,6 @@ st_table_class_init (StTableClass *klass) gobject_class->set_property = st_table_set_property; gobject_class->get_property = st_table_get_property; - gobject_class->dispose = st_table_dispose; gobject_class->finalize = st_table_finalize; actor_class->paint = st_table_paint; diff --git a/src/st/st-table.h b/src/st/st-table.h index 2bdc9051e..bce6084d5 100644 --- a/src/st/st-table.h +++ b/src/st/st-table.h @@ -30,7 +30,7 @@ #define __ST_TABLE_H__ #include -#include +#include G_BEGIN_DECLS @@ -73,14 +73,14 @@ typedef struct _StTableClass StTableClass; struct _StTable { /*< private >*/ - StWidget parent_instance; + StContainer parent_instance; StTablePrivate *priv; }; struct _StTableClass { - StWidgetClass parent_class; + StContainerClass parent_class; }; GType st_table_get_type (void) G_GNUC_CONST;