actor: Add :text-direction property
authorEmmanuele Bassi <ebassi@linux.intel.com>
Fri, 6 Nov 2009 16:55:46 +0000 (16:55 +0000)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Tue, 10 Nov 2009 12:16:55 +0000 (12:16 +0000)
Every actor should have a property for retrieving (and setting) the
text direction.

The text direction is used to provide a consisten behaviour in both
left-to-right and right-to-left languages. For instance, ClutterText
should perform key navigation following text direction. Layout
managers should also take into account text direction to derive the
right packing order for their children.

clutter/clutter-actor.c
clutter/clutter-actor.h

index 0b38fe4..efbce27 100644 (file)
@@ -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
@@ -9352,3 +9374,95 @@ 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 (priv->text_direction == CLUTTER_TEXT_DIRECTION_DEFAULT)
+    return clutter_get_default_text_direction ();
+
+  return priv->text_direction;
+}
index 4a5a383..2f190a5 100644 (file)
@@ -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__ */