From 9b1a53510ed5a9f1bb1888e111f0a3dc7dc8656d Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Tue, 25 Jan 2011 15:20:20 +0900 Subject: [PATCH] Delay the initialization of EekClutter* until ClutterActor::realize. --- eek/eek-clutter-key.c | 200 +++++++++++++++++++++++-------------- eek/eek-clutter-keyboard.c | 152 ++++++++++++++++++---------- eek/eek-clutter-section.c | 140 ++++++++++++++++++-------- 3 files changed, 327 insertions(+), 165 deletions(-) diff --git a/eek/eek-clutter-key.c b/eek/eek-clutter-key.c index c5fce722..25898f17 100644 --- a/eek/eek-clutter-key.c +++ b/eek/eek-clutter-key.c @@ -24,6 +24,13 @@ #include "eek-clutter-key.h" +enum { + PROP_0, + PROP_KEY, + PROP_RENDERER, + PROP_LAST +}; + G_DEFINE_TYPE (EekClutterKey, eek_clutter_key, CLUTTER_TYPE_ACTOR); #define EEK_CLUTTER_KEY_GET_PRIVATE(obj) \ @@ -36,21 +43,62 @@ struct _EekClutterKeyPrivate }; static void -eek_clutter_key_dispose (GObject *object) +on_pressed (EekKey *key, gpointer user_data) { - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object); + ClutterActor *actor = user_data, *parent; - if (priv->renderer) { - g_object_unref (priv->renderer); - priv->renderer = NULL; - } + parent = clutter_actor_get_parent (actor); + clutter_actor_raise_top (parent); + clutter_actor_raise_top (actor); + clutter_actor_set_scale_with_gravity (actor, + 1.0, + 1.0, + CLUTTER_GRAVITY_CENTER); - if (priv->key && g_object_is_floating (priv->key)) { - g_object_unref (priv->key); - priv->key = NULL; - } + clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, 150, + "scale-x", 1.5, + "scale-y", 1.5, + NULL); +} - G_OBJECT_CLASS (eek_clutter_key_parent_class)->dispose (object); +static void +on_released (EekKey *key, gpointer user_data) +{ + ClutterActor *actor = user_data, *parent; + + parent = clutter_actor_get_parent (actor); + clutter_actor_raise_top (parent); + clutter_actor_raise_top (actor); + clutter_actor_set_scale_with_gravity (actor, + 1.5, + 1.5, + CLUTTER_GRAVITY_CENTER); + clutter_actor_animate (actor, CLUTTER_EASE_OUT_SINE, 150, + "scale-x", 1.0, + "scale-y", 1.0, + NULL); +} + +static void +eek_clutter_key_real_realize (ClutterActor *self) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + EekBounds bounds; + gdouble scale; + + eek_element_get_bounds (EEK_ELEMENT(priv->key), &bounds); + scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer)); + + clutter_actor_set_position (self, + bounds.x * scale, + bounds.y * scale); + + clutter_actor_set_reactive (self, TRUE); + + g_signal_connect (priv->key, "pressed", + G_CALLBACK(on_pressed), self); + g_signal_connect (priv->key, "released", + G_CALLBACK(on_released), self); } static void @@ -136,15 +184,60 @@ eek_clutter_key_real_leave_event (ClutterActor *self, return TRUE; } +static void +eek_clutter_key_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_KEY: + priv->key = g_value_get_object (value); + g_object_ref_sink (priv->key); + break; + case PROP_RENDERER: + priv->renderer = g_value_get_object (value); + g_object_ref (priv->renderer); + break; + default: + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_clutter_key_dispose (GObject *object) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object); + + if (priv->renderer) { + g_object_unref (priv->renderer); + priv->renderer = NULL; + } + + if (priv->key && g_object_is_floating (priv->key)) { + g_object_unref (priv->key); + priv->key = NULL; + } + + G_OBJECT_CLASS (eek_clutter_key_parent_class)->dispose (object); +} + static void eek_clutter_key_class_init (EekClutterKeyClass *klass) { ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; g_type_class_add_private (gobject_class, sizeof (EekClutterKeyPrivate)); + actor_class->realize = eek_clutter_key_real_realize; actor_class->paint = eek_clutter_key_real_paint; actor_class->get_preferred_width = eek_clutter_key_real_get_preferred_width; @@ -160,7 +253,26 @@ eek_clutter_key_class_init (EekClutterKeyClass *klass) actor_class->leave_event = eek_clutter_key_real_leave_event; + gobject_class->set_property = eek_clutter_key_set_property; gobject_class->dispose = eek_clutter_key_dispose; + + pspec = g_param_spec_object ("key", + "Key", + "Key", + EEK_TYPE_KEY, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE); + g_object_class_install_property (gobject_class, + PROP_KEY, + pspec); + + pspec = g_param_spec_object ("renderer", + "Renderer", + "Renderer", + EEK_TYPE_RENDERER, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE); + g_object_class_install_property (gobject_class, + PROP_RENDERER, + pspec); } static void @@ -172,69 +284,11 @@ eek_clutter_key_init (EekClutterKey *self) priv->renderer = NULL; } -static void -on_pressed (EekKey *key, gpointer user_data) -{ - ClutterActor *actor = user_data, *parent; - - parent = clutter_actor_get_parent (actor); - clutter_actor_raise_top (parent); - clutter_actor_raise_top (actor); - clutter_actor_set_scale_with_gravity (actor, - 1.0, - 1.0, - CLUTTER_GRAVITY_CENTER); - - clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, 150, - "scale-x", 1.5, - "scale-y", 1.5, - NULL); -} - -static void -on_released (EekKey *key, gpointer user_data) -{ - ClutterActor *actor = user_data, *parent; - - parent = clutter_actor_get_parent (actor); - clutter_actor_raise_top (parent); - clutter_actor_raise_top (actor); - clutter_actor_set_scale_with_gravity (actor, - 1.5, - 1.5, - CLUTTER_GRAVITY_CENTER); - clutter_actor_animate (actor, CLUTTER_EASE_OUT_SINE, 150, - "scale-x", 1.0, - "scale-y", 1.0, - NULL); -} - ClutterActor * eek_clutter_key_new (EekKey *key, EekClutterRenderer *renderer) { - ClutterActor *actor; - EekClutterKeyPrivate *priv; - EekBounds bounds; - gdouble scale; - - actor = g_object_new (EEK_TYPE_CLUTTER_KEY, NULL); - priv = EEK_CLUTTER_KEY_GET_PRIVATE(actor); - priv->key = g_object_ref_sink (key); - priv->renderer = g_object_ref (renderer); - - eek_element_get_bounds (EEK_ELEMENT(key), &bounds); - scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer)); - - clutter_actor_set_position (actor, - bounds.x * scale, - bounds.y * scale); - - clutter_actor_set_reactive (actor, TRUE); - - g_signal_connect (priv->key, "pressed", - G_CALLBACK(on_pressed), actor); - g_signal_connect (priv->key, "released", - G_CALLBACK(on_released), actor); - - return actor; + return g_object_new (EEK_TYPE_CLUTTER_KEY, + "key", key, + "renderer", renderer, + NULL); } diff --git a/eek/eek-clutter-keyboard.c b/eek/eek-clutter-keyboard.c index 24621c04..be1a953a 100644 --- a/eek/eek-clutter-keyboard.c +++ b/eek/eek-clutter-keyboard.c @@ -34,6 +34,12 @@ #include "eek-clutter-renderer.h" #include "eek-keyboard.h" +enum { + PROP_0, + PROP_KEYBOARD, + PROP_LAST +}; + G_DEFINE_TYPE (EekClutterKeyboard, eek_clutter_keyboard, CLUTTER_TYPE_GROUP); #define EEK_CLUTTER_KEYBOARD_GET_PRIVATE(obj) \ @@ -45,6 +51,45 @@ struct _EekClutterKeyboardPrivate EekClutterRenderer *renderer; }; +struct _CreateSectionCallbackData { + ClutterActor *actor; + EekClutterRenderer *renderer; +}; +typedef struct _CreateSectionCallbackData CreateSectionCallbackData; + +static void +create_section (EekElement *element, gpointer user_data) +{ + CreateSectionCallbackData *data = user_data; + ClutterActor *section; + + section = eek_clutter_section_new (EEK_SECTION(element), data->renderer); + clutter_container_add_actor (CLUTTER_CONTAINER(data->actor), section); +} + +static void +eek_clutter_keyboard_real_realize (ClutterActor *self) +{ + EekClutterKeyboardPrivate *priv; + CreateSectionCallbackData data; + EekBounds bounds; + gdouble scale; + + priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); + + scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer)); + clutter_actor_set_position (CLUTTER_ACTOR(self), + bounds.x * scale, + bounds.y * scale); + + data.actor = CLUTTER_ACTOR(self); + data.renderer = priv->renderer; + + eek_container_foreach_child (EEK_CONTAINER(priv->keyboard), + create_section, + &data); +} + static void eek_clutter_keyboard_real_get_preferred_width (ClutterActor *self, float for_height, @@ -89,6 +134,49 @@ eek_clutter_keyboard_real_allocate (ClutterActor *self, allocate (self, box, flags); } +static void +create_renderer (EekClutterKeyboard *self) +{ + EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); + PangoContext *pcontext; + PangoFontDescription *font; + EekBounds bounds; + + pcontext = clutter_actor_get_pango_context (CLUTTER_ACTOR(self)); + font = pango_font_description_from_string ("Sans 48px"); + pango_context_set_font_description (pcontext, font); + pango_font_description_free (font); + + priv->renderer = eek_clutter_renderer_new (priv->keyboard, pcontext); + + eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds); + eek_renderer_set_allocation_size (EEK_RENDERER(priv->renderer), + bounds.width, + bounds.height); +} + +static void +eek_clutter_keyboard_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_KEYBOARD: + priv->keyboard = g_value_get_object (value); + g_object_ref_sink (priv->keyboard); + create_renderer (EEK_CLUTTER_KEYBOARD(object)); + break; + default: + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + static void eek_clutter_keyboard_dispose (GObject *object) { @@ -112,17 +200,30 @@ eek_clutter_keyboard_class_init (EekClutterKeyboardClass *klass) { ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; g_type_class_add_private (gobject_class, sizeof (EekClutterKeyboardPrivate)); + actor_class->realize = + eek_clutter_keyboard_real_realize; actor_class->get_preferred_width = eek_clutter_keyboard_real_get_preferred_width; actor_class->get_preferred_height = eek_clutter_keyboard_real_get_preferred_height; actor_class->allocate = eek_clutter_keyboard_real_allocate; + gobject_class->set_property = eek_clutter_keyboard_set_property; gobject_class->dispose = eek_clutter_keyboard_dispose; + + pspec = g_param_spec_object ("keyboard", + "Keyboard", + "Keyboard", + EEK_TYPE_KEYBOARD, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE); + g_object_class_install_property (gobject_class, + PROP_KEYBOARD, + pspec); } static void @@ -135,22 +236,6 @@ eek_clutter_keyboard_init (EekClutterKeyboard *self) priv->renderer = NULL; } -struct _CreateSectionCallbackData { - ClutterActor *actor; - EekClutterRenderer *renderer; -}; -typedef struct _CreateSectionCallbackData CreateSectionCallbackData; - -static void -create_section (EekElement *element, gpointer user_data) -{ - CreateSectionCallbackData *data = user_data; - ClutterActor *section; - - section = eek_clutter_section_new (EEK_SECTION(element), data->renderer); - clutter_container_add_actor (CLUTTER_CONTAINER(data->actor), section); -} - /** * eek_clutter_keyboard_new: * @keyboard: an #EekKeyboard @@ -161,38 +246,5 @@ create_section (EekElement *element, gpointer user_data) ClutterActor * eek_clutter_keyboard_new (EekKeyboard *keyboard) { - ClutterActor *actor; - EekClutterKeyboardPrivate *priv; - PangoContext *pcontext; - CreateSectionCallbackData data; - EekBounds bounds; - gdouble scale; - PangoFontDescription *font; - - actor = g_object_new (EEK_TYPE_CLUTTER_KEYBOARD, NULL); - priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(actor); - priv->keyboard = g_object_ref_sink (keyboard); - - pcontext = clutter_actor_get_pango_context (actor); - font = pango_font_description_from_string ("Sans 48px"); - pango_context_set_font_description (pcontext, font); - pango_font_description_free (font); - - priv->renderer = eek_clutter_renderer_new (priv->keyboard, pcontext); - - eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds); - eek_renderer_set_allocation_size (EEK_RENDERER(priv->renderer), - bounds.width, - bounds.height); - scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer)); - clutter_actor_set_position (actor, bounds.x * scale, bounds.y * scale); - - data.actor = actor; - data.renderer = priv->renderer; - - eek_container_foreach_child (EEK_CONTAINER(priv->keyboard), - create_section, - &data); - - return actor; + return g_object_new (EEK_TYPE_CLUTTER_KEYBOARD, "keyboard", keyboard, NULL); } diff --git a/eek/eek-clutter-section.c b/eek/eek-clutter-section.c index c35c16fc..c5ab6aa4 100644 --- a/eek/eek-clutter-section.c +++ b/eek/eek-clutter-section.c @@ -25,6 +25,13 @@ #include "eek-clutter-section.h" #include "eek-clutter-key.h" +enum { + PROP_0, + PROP_SECTION, + PROP_RENDERER, + PROP_LAST +}; + G_DEFINE_TYPE (EekClutterSection, eek_clutter_section, CLUTTER_TYPE_GROUP); #define EEK_CLUTTER_SECTION_GET_PRIVATE(obj) \ @@ -36,6 +43,45 @@ struct _EekClutterSectionPrivate EekClutterRenderer *renderer; }; +struct _CreateKeyCallbackData { + ClutterActor *actor; + EekClutterRenderer *renderer; +}; +typedef struct _CreateKeyCallbackData CreateKeyCallbackData; + +static void +create_key (EekElement *element, gpointer user_data) +{ + CreateKeyCallbackData *data = user_data; + ClutterActor *key; + + key = eek_clutter_key_new (EEK_KEY(element), data->renderer); + clutter_container_add_actor (CLUTTER_CONTAINER(data->actor), key); +} + +static void +eek_clutter_section_real_realize (ClutterActor *self) +{ + EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); + CreateKeyCallbackData data; + EekBounds bounds; + gdouble scale; + + eek_element_get_bounds (EEK_ELEMENT(priv->section), &bounds); + scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer)); + clutter_actor_set_position (self, bounds.x * scale, bounds.y * scale); + clutter_actor_set_rotation (self, + CLUTTER_Z_AXIS, + eek_section_get_angle (priv->section), + 0.0f, 0.0f, 0.0f); + + data.actor = self; + data.renderer = priv->renderer; + eek_container_foreach_child (EEK_CONTAINER(priv->section), + create_key, + &data); +} + static void eek_clutter_section_real_get_preferred_width (ClutterActor *self, float for_height, @@ -77,6 +123,31 @@ eek_clutter_section_real_allocate (ClutterActor *self, allocate (self, box, flags); } +static void +eek_clutter_section_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_SECTION: + priv->section = g_value_get_object (value); + g_object_ref_sink (priv->section); + break; + case PROP_RENDERER: + priv->renderer = g_value_get_object (value); + g_object_ref (priv->renderer); + break; + default: + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + static void eek_clutter_section_dispose (GObject *object) { @@ -100,15 +171,38 @@ eek_clutter_section_class_init (EekClutterSectionClass *klass) { ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; g_type_class_add_private (gobject_class, sizeof (EekClutterSectionPrivate)); + actor_class->realize = + eek_clutter_section_real_realize; actor_class->get_preferred_width = eek_clutter_section_real_get_preferred_width; actor_class->get_preferred_height = eek_clutter_section_real_get_preferred_height; actor_class->allocate = eek_clutter_section_real_allocate; + + gobject_class->set_property = eek_clutter_section_set_property; gobject_class->dispose = eek_clutter_section_dispose; + + pspec = g_param_spec_object ("section", + "Section", + "Section", + EEK_TYPE_SECTION, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE); + g_object_class_install_property (gobject_class, + PROP_SECTION, + pspec); + + pspec = g_param_spec_object ("renderer", + "Renderer", + "Renderer", + EEK_TYPE_RENDERER, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE); + g_object_class_install_property (gobject_class, + PROP_RENDERER, + pspec); } static void @@ -120,50 +214,12 @@ eek_clutter_section_init (EekClutterSection *self) priv->renderer = NULL; } -struct _CreateKeyCallbackData { - ClutterActor *actor; - EekClutterRenderer *renderer; -}; -typedef struct _CreateKeyCallbackData CreateKeyCallbackData; - -static void -create_key (EekElement *element, gpointer user_data) -{ - CreateKeyCallbackData *data = user_data; - ClutterActor *key; - - key = eek_clutter_key_new (EEK_KEY(element), data->renderer); - clutter_container_add_actor (CLUTTER_CONTAINER(data->actor), key); -} - ClutterActor * eek_clutter_section_new (EekSection *section, EekClutterRenderer *renderer) { - ClutterActor *actor; - EekClutterSectionPrivate *priv; - CreateKeyCallbackData data; - EekBounds bounds; - gdouble scale; - - actor = g_object_new (EEK_TYPE_CLUTTER_SECTION, NULL); - priv = EEK_CLUTTER_SECTION_GET_PRIVATE(actor); - priv->section = g_object_ref_sink (section); - priv->renderer = g_object_ref (renderer); - - eek_element_get_bounds (EEK_ELEMENT(section), &bounds); - scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer)); - clutter_actor_set_position (actor, bounds.x * scale, bounds.y * scale); - clutter_actor_set_rotation (actor, - CLUTTER_Z_AXIS, - eek_section_get_angle (section), - 0.0f, 0.0f, 0.0f); - - data.actor = actor; - data.renderer = priv->renderer; - eek_container_foreach_child (EEK_CONTAINER(priv->section), - create_key, - &data); - - return actor; + return g_object_new (EEK_TYPE_CLUTTER_SECTION, + "section", section, + "renderer", renderer, + NULL); }