diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 0b38fe4c8..d7ef7d809 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -332,6 +332,8 @@ struct _ClutterActorPrivate PangoContext *pango_context; ClutterActor *opacity_parent; + + ClutterTextDirection text_direction; }; enum @@ -409,7 +411,9 @@ enum PROP_ANCHOR_Y, PROP_ANCHOR_GRAVITY, - PROP_SHOW_ON_SET_PARENT + PROP_SHOW_ON_SET_PARENT, + + PROP_TEXT_DIRECTION }; enum @@ -2714,6 +2718,10 @@ clutter_actor_set_property (GObject *object, priv->show_on_set_parent = g_value_get_boolean (value); break; + case PROP_TEXT_DIRECTION: + clutter_actor_set_text_direction (actor, g_value_get_enum (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2967,6 +2975,10 @@ clutter_actor_get_property (GObject *object, g_value_set_boolean (value, priv->show_on_set_parent); break; + case PROP_TEXT_DIRECTION: + g_value_set_enum (value, priv->text_direction); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3778,6 +3790,16 @@ clutter_actor_class_init (ClutterActorClass *klass) PROP_CLIP_TO_ALLOCATION, pspec); + pspec = g_param_spec_enum ("text-direction", + "Text Direction", + "Direction of the text", + CLUTTER_TYPE_TEXT_DIRECTION, + CLUTTER_TEXT_DIRECTION_LTR, + CLUTTER_PARAM_READWRITE); + g_object_class_install_property (object_class, + PROP_TEXT_DIRECTION, + pspec); + /** * ClutterActor::destroy: * @actor: the object which received the signal @@ -6596,6 +6618,7 @@ clutter_actor_set_parent (ClutterActor *self, ClutterActor *parent) { ClutterActorPrivate *priv; + ClutterTextDirection text_dir; g_return_if_fail (CLUTTER_IS_ACTOR (self)); g_return_if_fail (CLUTTER_IS_ACTOR (parent)); @@ -6634,13 +6657,15 @@ clutter_actor_set_parent (ClutterActor *self, */ clutter_actor_update_map_state (self, MAP_STATE_CHECK); + /* propagate the parent's text direction to the child */ + text_dir = clutter_actor_get_text_direction (parent); + clutter_actor_set_text_direction (self, text_dir); + if (priv->show_on_set_parent) clutter_actor_show (self); if (CLUTTER_ACTOR_IS_MAPPED (self)) - { - clutter_actor_queue_redraw (self); - } + clutter_actor_queue_redraw (self); /* maintain the invariant that if an actor needs layout, * its parents do as well @@ -9352,3 +9377,96 @@ clutter_actor_is_in_clone_paint (ClutterActor *self) return self->priv->opacity_parent != NULL && !self->priv->enable_model_view_transform; } + +static void +set_direction_recursive (ClutterActor *actor, + gpointer user_data) +{ + ClutterTextDirection text_dir = GPOINTER_TO_INT (user_data); + + clutter_actor_set_text_direction (actor, text_dir); +} + +/** + * clutter_actor_set_text_direction: + * @self: a #ClutterActor + * @text_dir: the text direction for @self + * + * Sets the #ClutterTextDirection for an actor + * + * The passed text direction must not be %CLUTTER_TEXT_DIRECTION_DEFAULT + * + * If @self implements #ClutterContainer then this function will recurse + * inside all the children of @self (including the internal ones). + * + * Composite actors not implementing #ClutterContainer, or actors requiring + * special handling when the text direction changes, should connect to + * the #GObject::notify signal for the #ClutterActor:text-direction property + * + * Since: 1.2 + */ +void +clutter_actor_set_text_direction (ClutterActor *self, + ClutterTextDirection text_dir) +{ + ClutterActorPrivate *priv; + + g_return_if_fail (CLUTTER_IS_ACTOR (self)); + g_return_if_fail (text_dir == CLUTTER_TEXT_DIRECTION_DEFAULT); + + priv = self->priv; + + if (priv->text_direction != text_dir) + { + priv->text_direction = text_dir; + + /* we need to emit the notify::text-direction first, so that + * the sub-classes can catch that and do specific handling of + * the text direction; see clutter_text_direction_changed_cb() + * inside clutter-text.c + */ + g_object_notify (G_OBJECT (self), "text-direction"); + + /* if this is a container we need to recurse */ + if (CLUTTER_IS_CONTAINER (self)) + { + ClutterContainer *container = CLUTTER_CONTAINER (self); + + clutter_container_foreach_with_internals (container, + set_direction_recursive, + GINT_TO_POINTER (text_dir)); + } + + clutter_actor_queue_relayout (self); + } +} + +/** + * clutter_actor_get_text_direction: + * @self: a #ClutterActor + * + * Retrieves the value set using clutter_actor_set_text_direction() + * + * If no text direction has been previously set, the default text + * direction will be returned + * + * Return value: the #ClutterTextDirection for the actor + * + * Since: 1.2 + */ +ClutterTextDirection +clutter_actor_get_text_direction (ClutterActor *self) +{ + ClutterActorPrivate *priv; + + g_return_val_if_fail (CLUTTER_IS_ACTOR (self), + CLUTTER_TEXT_DIRECTION_LTR); + + priv = self->priv; + + /* if no direction has been set yet use the default */ + if (priv->text_direction == CLUTTER_TEXT_DIRECTION_DEFAULT) + priv->text_direction = clutter_get_default_text_direction (); + + return priv->text_direction; +} diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h index 4a5a38319..2f190a5ed 100644 --- a/clutter/clutter-actor.h +++ b/clutter/clutter-actor.h @@ -528,6 +528,10 @@ void clutter_actor_get_transformation_matrix (ClutterActor *self gboolean clutter_actor_is_in_clone_paint (ClutterActor *self); +void clutter_actor_set_text_direction (ClutterActor *self, + ClutterTextDirection text_dir); +ClutterTextDirection clutter_actor_get_text_direction (ClutterActor *self); + G_END_DECLS #endif /* __CLUTTER_ACTOR_H__ */ diff --git a/clutter/clutter-box-layout.c b/clutter/clutter-box-layout.c index 6e4280560..6d30bfb93 100644 --- a/clutter/clutter-box-layout.c +++ b/clutter/clutter-box-layout.c @@ -509,14 +509,16 @@ clutter_box_layout_set_container (ClutterLayoutManager *layout, static void get_preferred_width (ClutterBoxLayout *self, - const GList *children, + ClutterContainer *container, + GList *children, gfloat for_height, gfloat *min_width_p, gfloat *natural_width_p) { ClutterBoxLayoutPrivate *priv = self->priv; gint n_children = 0; - const GList *l; + gboolean is_rtl; + GList *l; if (min_width_p) *min_width_p = 0; @@ -524,7 +526,19 @@ get_preferred_width (ClutterBoxLayout *self, if (natural_width_p) *natural_width_p = 0; - for (l = children; l != NULL; l = l->next) + if (!priv->is_vertical) + { + ClutterTextDirection text_dir; + + text_dir = clutter_actor_get_text_direction (CLUTTER_ACTOR (container)); + is_rtl = (text_dir == CLUTTER_TEXT_DIRECTION_RTL) ? TRUE : FALSE; + } + else + is_rtl = FALSE; + + for (l = (is_rtl) ? g_list_last (children) : children; + l != NULL; + l = (is_rtl) ? l->prev : l->next) { ClutterActor *child = l->data; gfloat child_min = 0, child_nat = 0; @@ -572,14 +586,16 @@ get_preferred_width (ClutterBoxLayout *self, static void get_preferred_height (ClutterBoxLayout *self, - const GList *children, + ClutterContainer *container, + GList *children, gfloat for_height, gfloat *min_height_p, gfloat *natural_height_p) { ClutterBoxLayoutPrivate *priv = self->priv; gint n_children = 0; - const GList *l; + gboolean is_rtl; + GList *l; if (min_height_p) *min_height_p = 0; @@ -587,7 +603,19 @@ get_preferred_height (ClutterBoxLayout *self, if (natural_height_p) *natural_height_p = 0; - for (l = children; l != NULL; l = l->next) + if (!priv->is_vertical) + { + ClutterTextDirection text_dir; + + text_dir = clutter_actor_get_text_direction (CLUTTER_ACTOR (container)); + is_rtl = (text_dir == CLUTTER_TEXT_DIRECTION_RTL) ? TRUE : FALSE; + } + else + is_rtl = FALSE; + + for (l = (is_rtl) ? g_list_last (children) : children; + l != NULL; + l = (is_rtl) ? l->prev : l->next) { ClutterActor *child = l->data; gfloat child_min = 0, child_nat = 0; @@ -632,6 +660,78 @@ get_preferred_height (ClutterBoxLayout *self, } } +static void +allocate_box_child (ClutterBoxLayout *self, + ClutterContainer *container, + ClutterActor *child, + gfloat *position, + gfloat avail_width, + gfloat avail_height, + gfloat extra_space, + ClutterAllocationFlags flags) +{ + ClutterBoxLayoutPrivate *priv = self->priv; + ClutterActorBox child_box; + ClutterBoxChild *box_child; + ClutterLayoutMeta *meta; + gfloat child_nat; + + if (!CLUTTER_ACTOR_IS_VISIBLE (child)) + return; + + meta = clutter_layout_manager_get_child_meta (CLUTTER_LAYOUT_MANAGER (self), + container, + child); + box_child = CLUTTER_BOX_CHILD (meta); + + if (priv->is_vertical) + { + clutter_actor_get_preferred_height (child, avail_width, + NULL, &child_nat); + + child_box.y1 = floorf (*position + 0.5); + + if (box_child->expand) + child_box.y2 = floorf (*position + child_nat + extra_space + 0.5); + else + child_box.y2 = floorf (*position + child_nat + 0.5); + + child_box.x1 = 0; + child_box.x2 = floorf (avail_width + 0.5); + + allocate_fill (child, &child_box, box_child); + clutter_actor_allocate (child, &child_box, flags); + + if (box_child->expand) + *position += (child_nat + priv->spacing + extra_space); + else + *position += (child_nat + priv->spacing); + } + else + { + clutter_actor_get_preferred_width (child, avail_height, + NULL, &child_nat); + + child_box.x1 = floorf (*position + 0.5); + + if (box_child->expand) + child_box.x2 = floorf (*position + child_nat + extra_space + 0.5); + else + child_box.x2 = floorf (*position + child_nat + 0.5); + + child_box.y1 = 0; + child_box.y2 = floorf (avail_height + 0.5); + + allocate_fill (child, &child_box, box_child); + clutter_actor_allocate (child, &child_box, flags); + + if (box_child->expand) + *position += (child_nat + priv->spacing + extra_space); + else + *position += (child_nat + priv->spacing); + } +} + static void clutter_box_layout_get_preferred_width (ClutterLayoutManager *layout, ClutterContainer *container, @@ -644,7 +744,7 @@ clutter_box_layout_get_preferred_width (ClutterLayoutManager *layout, children = clutter_container_get_children (container); - get_preferred_width (self, children, for_height, + get_preferred_width (self, container, children, for_height, min_width_p, natural_width_p); @@ -663,7 +763,7 @@ clutter_box_layout_get_preferred_height (ClutterLayoutManager *layout, children = clutter_container_get_children (container); - get_preferred_height (self, children, for_width, + get_preferred_height (self, container, children, for_width, min_height_p, natural_height_p); @@ -678,9 +778,10 @@ clutter_box_layout_allocate (ClutterLayoutManager *layout, { ClutterBoxLayoutPrivate *priv = CLUTTER_BOX_LAYOUT (layout)->priv; gfloat avail_width, avail_height, pref_width, pref_height; - GList *children, *l; gint n_expand_children, extra_space; + GList *children, *l; gfloat position; + gboolean is_rtl; children = clutter_container_get_children (container); if (children == NULL) @@ -691,6 +792,7 @@ clutter_box_layout_allocate (ClutterLayoutManager *layout, if (priv->is_vertical) { get_preferred_height (CLUTTER_BOX_LAYOUT (layout), + container, children, avail_width, NULL, &pref_height); @@ -700,6 +802,7 @@ clutter_box_layout_allocate (ClutterLayoutManager *layout, else { get_preferred_width (CLUTTER_BOX_LAYOUT (layout), + container, children, avail_height, NULL, &pref_width); @@ -740,69 +843,44 @@ clutter_box_layout_allocate (ClutterLayoutManager *layout, position = 0; - for (l = (priv->is_pack_start) ? g_list_last (children) : children; - l != NULL; - l = (priv->is_pack_start) ? l->prev : l->next) + if (!priv->is_vertical) { - ClutterActor *child = l->data; - ClutterActorBox child_box; - ClutterBoxChild *box_child; - ClutterLayoutMeta *meta; - gfloat child_nat; + ClutterTextDirection text_dir; - if (!CLUTTER_ACTOR_IS_VISIBLE (child)) - continue; + text_dir = clutter_actor_get_text_direction (CLUTTER_ACTOR (container)); + is_rtl = (text_dir == CLUTTER_TEXT_DIRECTION_RTL) ? TRUE : FALSE; + } + else + is_rtl = FALSE; - meta = clutter_layout_manager_get_child_meta (layout, - container, - child); - box_child = CLUTTER_BOX_CHILD (meta); - - if (priv->is_vertical) + if (is_rtl) + { + for (l = (priv->is_pack_start) ? children : g_list_last (children); + l != NULL; + l = (priv->is_pack_start) ? l->next : l->prev) { - clutter_actor_get_preferred_height (child, avail_width, - NULL, &child_nat); + ClutterActor *child = l->data; - child_box.y1 = ceilf (position); - - if (box_child->expand) - child_box.y2 = ceilf (position + child_nat + extra_space); - else - child_box.y2 = ceilf (position + child_nat); - - child_box.x1 = 0; - child_box.x2 = ceilf (avail_width); - - allocate_fill (child, &child_box, box_child); - clutter_actor_allocate (child, &child_box, flags); - - if (box_child->expand) - position += (child_nat + priv->spacing + extra_space); - else - position += (child_nat + priv->spacing); + allocate_box_child (CLUTTER_BOX_LAYOUT (layout), container, child, + &position, + avail_width, + avail_height, + extra_space, flags); } - else + } + else + { + for (l = (priv->is_pack_start) ? g_list_last (children) : children; + l != NULL; + l = (priv->is_pack_start) ? l->prev : l->next) { - clutter_actor_get_preferred_width (child, avail_height, - NULL, &child_nat); + ClutterActor *child = l->data; - child_box.x1 = ceilf (position); - - if (box_child->expand) - child_box.x2 = ceilf (position + child_nat + extra_space); - else - child_box.x2 = ceilf (position + child_nat); - - child_box.y1 = 0; - child_box.y2 = ceilf (avail_height); - - allocate_fill (child, &child_box, box_child); - clutter_actor_allocate (child, &child_box, flags); - - if (box_child->expand) - position += (child_nat + priv->spacing + extra_space); - else - position += (child_nat + priv->spacing); + allocate_box_child (CLUTTER_BOX_LAYOUT (layout), container, child, + &position, + avail_width, + avail_height, + extra_space, flags); } } diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 57a9660b9..e8bfd2eae 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -74,7 +74,7 @@ static gboolean clutter_use_fuzzy_picking = FALSE; static guint clutter_default_fps = 60; -static PangoDirection clutter_text_direction = PANGO_DIRECTION_LTR; +static PangoDirection clutter_text_direction = CLUTTER_TEXT_DIRECTION_LTR; static guint clutter_main_loop_level = 0; static GSList *main_loops = NULL; @@ -540,7 +540,7 @@ _clutter_do_pick (ClutterStage *stage, return clutter_get_actor_by_gid (id); } -static PangoDirection +static ClutterTextDirection clutter_get_text_direction (void) { PangoDirection dir = PANGO_DIRECTION_LTR; @@ -550,9 +550,9 @@ clutter_get_text_direction (void) if (direction && *direction != '\0') { if (strcmp (direction, "rtl") == 0) - dir = PANGO_DIRECTION_RTL; + dir = CLUTTER_TEXT_DIRECTION_RTL; else if (strcmp (direction, "ltr") == 0) - dir = PANGO_DIRECTION_LTR; + dir = CLUTTER_TEXT_DIRECTION_LTR; } else { @@ -565,9 +565,9 @@ clutter_get_text_direction (void) char *e = _("default:LTR"); if (strcmp (e, "default:RTL") == 0) - dir = PANGO_DIRECTION_RTL; + dir = CLUTTER_TEXT_DIRECTION_RTL; else if (strcmp (e, "default:LTR") == 0) - dir = PANGO_DIRECTION_LTR; + dir = CLUTTER_TEXT_DIRECTION_LTR; else g_warning ("Whoever translated default:LTR did so wrongly."); } @@ -582,10 +582,17 @@ update_pango_context (ClutterBackend *backend, PangoFontDescription *font_desc; const cairo_font_options_t *font_options; const gchar *font_name; + PangoDirection pango_dir; + PangoLanguage *lang; gdouble resolution; /* update the text direction */ - pango_context_set_base_dir (context, clutter_text_direction); + if (clutter_text_direction == CLUTTER_TEXT_DIRECTION_RTL) + pango_dir = PANGO_DIRECTION_RTL; + else + pango_dir = PANGO_DIRECTION_LTR; + + pango_context_set_base_dir (context, pango_dir); /* get the configuration for the PangoContext from the backend */ font_name = clutter_backend_get_font_name (backend); @@ -634,6 +641,7 @@ _clutter_context_create_pango_context (ClutterMainContext *self) context = cogl_pango_font_map_create_context (self->font_map); update_pango_context (self->backend, context); + pango_context_set_language (context, pango_language_get_default ()); return context; } @@ -1236,8 +1244,8 @@ clutter_arg_direction_cb (const char *key, gpointer user_data) { clutter_text_direction = - (strcmp (value, "rtl") == 0) ? PANGO_DIRECTION_RTL - : PANGO_DIRECTION_LTR; + (strcmp (value, "rtl") == 0) ? CLUTTER_TEXT_DIRECTION_RTL + : CLUTTER_TEXT_DIRECTION_LTR; return TRUE; } @@ -1356,7 +1364,6 @@ clutter_init_real (GError **error) clutter_text_direction = clutter_get_text_direction (); - /* Figure out framebuffer masks used for pick */ cogl_get_bitmasks (&ctx->fb_r_mask, &ctx->fb_g_mask, &ctx->fb_b_mask, NULL); @@ -3027,3 +3034,21 @@ clutter_check_version (guint major, clutter_minor_version == minor && clutter_micro_version >= micro)); } + +void +clutter_set_default_text_direction (ClutterTextDirection text_dir) +{ + if (text_dir == CLUTTER_TEXT_DIRECTION_DEFAULT) + text_dir = clutter_get_text_direction (); + + if (text_dir != clutter_text_direction) + clutter_text_direction = text_dir; + + /* FIXME - queue a relayout on all stages */ +} + +ClutterTextDirection +clutter_get_default_text_direction (void) +{ + return clutter_text_direction; +} diff --git a/clutter/clutter-main.h b/clutter/clutter-main.h index d36f8f16f..c5f456219 100644 --- a/clutter/clutter-main.h +++ b/clutter/clutter-main.h @@ -164,6 +164,9 @@ void clutter_ungrab_pointer_for_device (gint id); PangoFontMap * clutter_get_font_map (void); +void clutter_set_default_text_direction (ClutterTextDirection text_dir); +ClutterTextDirection clutter_get_default_text_direction (void); + G_END_DECLS #endif /* _CLUTTER_MAIN_H__ */ diff --git a/clutter/clutter-text.c b/clutter/clutter-text.c index 77e132d0d..0a9d426ba 100644 --- a/clutter/clutter-text.c +++ b/clutter/clutter-text.c @@ -171,6 +171,9 @@ struct _ClutterTextPrivate /* Signal handler for when the backend changes its font settings */ guint font_changed_id; + + /* Signal handler for when the :text-direction changes */ + guint direction_changed_id; }; enum @@ -428,6 +431,15 @@ clutter_text_font_changed_cb (ClutterText *text) clutter_actor_queue_relayout (CLUTTER_ACTOR (text)); } +static void +clutter_text_direction_changed_cb (GObject *gobject, + GParamSpec *pspec) +{ + clutter_text_dirty_cache (CLUTTER_TEXT (gobject)); + + /* no need to queue a relayout: set_text_direction() will do that for us */ +} + /* * clutter_text_create_layout: * @text: a #ClutterText @@ -1098,6 +1110,12 @@ clutter_text_dispose (GObject *gobject) /* get rid of the entire cache */ clutter_text_dirty_cache (self); + if (priv->direction_changed_id) + { + g_signal_handler_disconnect (self, priv->direction_changed_id); + priv->direction_changed_id = 0; + } + if (priv->font_changed_id) { g_signal_handler_disconnect (clutter_get_default_backend (), @@ -2722,6 +2740,11 @@ clutter_text_init (ClutterText *self) "font-changed", G_CALLBACK (clutter_text_font_changed_cb), self); + + priv->direction_changed_id = + g_signal_connect (self, "notify::text-direction", + G_CALLBACK (clutter_text_direction_changed_cb), + NULL); } /** diff --git a/clutter/clutter-types.h b/clutter/clutter-types.h index 13f120307..ec7502310 100644 --- a/clutter/clutter-types.h +++ b/clutter/clutter-types.h @@ -382,6 +382,23 @@ typedef enum CLUTTER_FONT_HINTING = (1 << 1), } ClutterFontFlags; +/** + * ClutterTextDirection: + * @CLUTTER_TEXT_DIRECTION_DEFAULT: Use the default setting, as returned + * by clutter_get_default_text_direction() + * @CLUTTER_TEXT_DIRECTION_LTR: Use left-to-right text direction + * @CLUTTER_TEXT_DIRECTION_RTL: Use right-to-left text direction + * + * The text direction to be used by #ClutterActors + * + * Since: 1.2 + */ +typedef enum { + CLUTTER_TEXT_DIRECTION_DEFAULT, + CLUTTER_TEXT_DIRECTION_LTR, + CLUTTER_TEXT_DIRECTION_RTL +} ClutterTextDirection; + G_END_DECLS #endif /* __CLUTTER_TYPES_H__ */ diff --git a/doc/reference/clutter/clutter-sections.txt b/doc/reference/clutter/clutter-sections.txt index 8a57dc727..7f16c9063 100644 --- a/doc/reference/clutter/clutter-sections.txt +++ b/doc/reference/clutter/clutter-sections.txt @@ -396,6 +396,8 @@ clutter_actor_get_pango_context clutter_actor_create_pango_context clutter_actor_create_pango_layout clutter_actor_is_in_clone_paint +clutter_actor_set_text_direction +clutter_actor_get_text_direction ClutterActorBox @@ -1014,6 +1016,8 @@ ClutterFontFlags clutter_set_font_flags clutter_get_font_flags clutter_get_font_map +clutter_set_default_text_direction +clutter_get_default_text_direction clutter_threads_set_lock_functions diff --git a/tests/interactive/test-box-layout.c b/tests/interactive/test-box-layout.c index 21016c917..e45631880 100644 --- a/tests/interactive/test-box-layout.c +++ b/tests/interactive/test-box-layout.c @@ -22,6 +22,8 @@ #include #include +#include +#include "pango/cogl-pango.h" #define INSTRUCTIONS \ "Press v\t\342\236\236\tSwitch horizontal/vertical\n" \ @@ -30,6 +32,35 @@ "Press q\t\342\236\236\tQuit" static ClutterActor *hover_actor = NULL; +static guint last_index = 0; + +static void +on_paint (ClutterActor *actor, + gpointer user_data) +{ + guint index_ = GPOINTER_TO_UINT (user_data); + gchar *text = g_strdup_printf ("%u", index_); + ClutterActorBox alloc = { 0, }; + CoglColor color; + gint layout_width, layout_height; + gfloat width, height; + PangoLayout *layout; + + clutter_actor_get_allocation_box (actor, &alloc); + clutter_actor_box_get_size (&alloc, &width, &height); + + layout = clutter_actor_create_pango_layout (actor, text); + pango_layout_get_size (layout, &layout_width, &layout_height); + + cogl_color_set_from_4ub (&color, 0, 0, 0, 255); + cogl_pango_render_layout (layout, + (width - (layout_width / 1024)) / 2, + (height - (layout_height / 1024)) / 2, + &color, 0); + + g_object_unref (layout); + g_free (text); +} static void enter_event (ClutterActor *actor, @@ -93,7 +124,8 @@ button_release_event (ClutterActor *actor, } static void -add_actor (ClutterBoxLayout *box) +add_actor (ClutterBoxLayout *box, + guint index_) { ClutterActor *rect; ClutterColor color = { 0xff, 0xff, 0xff, 255 }; @@ -113,6 +145,9 @@ add_actor (ClutterBoxLayout *box) CLUTTER_BOX_ALIGNMENT_CENTER); clutter_actor_set_reactive (rect, TRUE); + g_signal_connect_after (rect, "paint", + G_CALLBACK (on_paint), + GUINT_TO_POINTER (index_)); g_signal_connect (rect, "enter-event", G_CALLBACK (enter_event), NULL); g_signal_connect (rect, "leave-event", G_CALLBACK (leave_event), NULL); g_signal_connect (rect, "button-release-event", @@ -154,7 +189,7 @@ key_release_cb (ClutterActor *actor, break; case CLUTTER_plus: - add_actor (layout); + add_actor (layout, last_index++); break; case CLUTTER_q: @@ -200,7 +235,7 @@ test_box_layout_main (int argc, char *argv[]) clutter_container_add_actor (CLUTTER_CONTAINER (stage), box); for (i = 0; i < 5; i++) - add_actor (CLUTTER_BOX_LAYOUT (layout)); + add_actor (CLUTTER_BOX_LAYOUT (layout), last_index++); g_signal_connect (stage, "key-release-event", G_CALLBACK (key_release_cb),