[lasem] Rework of the property handling. Base classes.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [lasem] Rework of the property handling. Base classes.
- Date: Fri, 7 Aug 2009 09:40:27 +0000 (UTC)
commit 851f1af0c64f1e9aaaa3702b8f6e48af84a70714
Author: Emmanuel Pacaud <emmanuel pacaud lapp in2p3 fr>
Date: Fri Aug 7 11:32:13 2009 +0200
Rework of the property handling. Base classes.
Properties are now stored in linked lists. It helps to reduce
memory usage, and ease the property inheritage.
src/lsm.h | 45 +++++++
src/lsmattributes.c | 237 +++++++++++++++++++++++++++++++++++
src/lsmattributes.h | 67 ++++++++++
src/lsmproperties.c | 339 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/lsmproperties.h | 77 ++++++++++++
src/lsmtraits.c | 74 +++++++++++
src/lsmtraits.h | 45 +++++++
7 files changed, 884 insertions(+), 0 deletions(-)
---
diff --git a/src/lsm.h b/src/lsm.h
new file mode 100644
index 0000000..71a93db
--- /dev/null
+++ b/src/lsm.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2009 Emmanuel Pacaud
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_H
+#define LSM_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ double x1;
+ double y1;
+ double x2;
+ double y2;
+} LsmExtents;
+
+typedef struct {
+ double x;
+ double y;
+ double width;
+ double height;
+} LsmBox;
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmattributes.c b/src/lsmattributes.c
new file mode 100644
index 0000000..611a7f8
--- /dev/null
+++ b/src/lsmattributes.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright © 2007-2009 Emmanuel Pacaud
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#include <lsmattributes.h>
+#include <lsmdebug.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+gboolean
+lsm_attribute_is_defined (const LsmAttribute *attribute)
+{
+ g_return_val_if_fail (attribute != NULL, FALSE);
+
+ return attribute->value != NULL;
+}
+
+#define ATTRIBUTE_TRAIT(attribute) ((void *) (((void *) attribute) + sizeof (LsmAttribute)))
+
+struct _LsmAttributeManager {
+ GHashTable * hash_by_name;
+};
+
+static LsmAttributeManager *
+lsm_attribute_manager_create (void)
+{
+ LsmAttributeManager *manager;
+
+ manager = g_new0 (LsmAttributeManager, 1);
+ manager->hash_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+
+ return manager;
+}
+
+LsmAttributeManager *
+lsm_attribute_manager_new (unsigned int n_attributes, const LsmAttributeInfos *attribute_infos)
+{
+ LsmAttributeManager *manager;
+
+ manager = lsm_attribute_manager_create ();
+
+ lsm_attribute_manager_add_attributes (manager, n_attributes, attribute_infos);
+
+ return manager;
+}
+
+LsmAttributeManager *
+lsm_attribute_manager_duplicate (const LsmAttributeManager *origin)
+{
+ LsmAttributeManager *manager;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_return_val_if_fail (origin != NULL, NULL);
+
+ manager = lsm_attribute_manager_create ();
+
+ g_hash_table_iter_init (&iter, origin->hash_by_name);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ g_hash_table_insert (manager->hash_by_name, key, value);
+
+ return manager;
+}
+
+void
+lsm_attribute_manager_add_attributes (LsmAttributeManager *manager,
+ unsigned int n_attributes,
+ const LsmAttributeInfos *attribute_infos)
+{
+ unsigned int i;
+
+ g_return_if_fail (n_attributes > 0);
+ g_return_if_fail (attribute_infos != NULL);
+
+ for (i = 0; i < n_attributes; i++) {
+ g_assert (attribute_infos[i].name != NULL);
+ g_assert (attribute_infos[i].attribute_offset >= 0);
+ g_assert (attribute_infos[i].trait_class != NULL);
+
+ g_hash_table_insert (manager->hash_by_name,
+ (void *) attribute_infos[i].name,
+ (void *) &attribute_infos[i]);
+ }
+
+}
+
+void
+lsm_attribute_manager_free (LsmAttributeManager *manager)
+{
+ g_return_if_fail (manager != NULL);
+
+ g_hash_table_unref (manager->hash_by_name);
+ g_free (manager);
+}
+
+gboolean
+lsm_attribute_manager_set_attribute (LsmAttributeManager *manager,
+ void *instance,
+ const char *name,
+ const char *value)
+{
+ LsmAttribute *attribute;
+ LsmAttributeInfos *attribute_infos;
+ const LsmTraitClass *trait_class;
+
+ g_return_val_if_fail (manager != NULL, FALSE);
+
+ attribute_infos = g_hash_table_lookup (manager->hash_by_name, name);
+ if (attribute_infos == NULL)
+ return FALSE;
+
+ attribute = (void *)(instance + attribute_infos->attribute_offset);
+ g_return_val_if_fail (attribute != NULL, FALSE);
+
+ trait_class = attribute_infos->trait_class;
+
+ g_free (attribute->value);
+ attribute->value = g_strdup (value);
+
+ if (attribute->value != NULL) {
+ if (trait_class->from_string)
+ trait_class->from_string (ATTRIBUTE_TRAIT (attribute), (char *) value);
+ } else {
+ if (trait_class->init)
+ trait_class->init (ATTRIBUTE_TRAIT (attribute), attribute_infos->trait_default);
+ else
+ /* Simple memcpy for default init implementation, discarde by a NULL default value. */
+ if (attribute_infos->trait_default != NULL)
+ memcpy (ATTRIBUTE_TRAIT (attribute),
+ attribute_infos->trait_default,
+ trait_class->size);
+ }
+
+ return TRUE;
+}
+
+char const *
+lsm_attribute_manager_get_attribute (LsmAttributeManager *manager,
+ void *instance,
+ const char *name)
+{
+ LsmAttributeInfos *attribute_infos;
+ LsmAttribute *attribute;
+
+ g_return_val_if_fail (manager != NULL, NULL);
+
+ attribute_infos = g_hash_table_lookup (manager->hash_by_name, name);
+ if (attribute_infos == NULL)
+ return NULL;
+
+ attribute = (void *)(instance + attribute_infos->attribute_offset);
+ g_return_val_if_fail (attribute != NULL, NULL);
+
+ return attribute->value;
+}
+
+void
+lsm_attribute_manager_clean_attributes (LsmAttributeManager *manager,
+ void *instance)
+{
+ LsmAttributeInfos *attribute_infos;
+ LsmAttribute *attribute;
+ const LsmTraitClass *trait_class;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_return_if_fail (manager != NULL);
+
+ g_hash_table_iter_init (&iter, manager->hash_by_name);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ attribute_infos = value;
+ trait_class = attribute_infos->trait_class;
+
+ if (trait_class->finalize) {
+ attribute = (void *)(instance + attribute_infos->attribute_offset);
+ trait_class->finalize (ATTRIBUTE_TRAIT (attribute));
+ }
+ }
+}
+
+char *
+lsm_attribute_manager_serialize (LsmAttributeManager *manager,
+ void *instance)
+{
+ LsmAttributeInfos *attribute_infos;
+ LsmAttribute *attribute;
+ GString *string;
+ GHashTableIter iter;
+ char *c_string;
+ gpointer key, value;
+ gboolean is_first = TRUE;
+
+ g_return_val_if_fail (manager != NULL, NULL);
+
+ string = g_string_new ("");
+
+ g_hash_table_iter_init (&iter, manager->hash_by_name);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ attribute_infos = value;
+ attribute = (void *)(instance + attribute_infos->attribute_offset);
+
+ if (is_first) {
+ g_string_append_printf (string, "%s=\"%s\"",
+ attribute_infos->name,
+ attribute->value);
+ is_first = FALSE;
+ } else {
+ g_string_append_printf (string, " %s=\"%s\"",
+ attribute_infos->name,
+ attribute->value);
+ }
+ }
+
+ c_string = string->str;
+
+ g_string_free (string, FALSE);
+
+ return c_string;
+}
diff --git a/src/lsmattributes.h b/src/lsmattributes.h
new file mode 100644
index 0000000..c00f60c
--- /dev/null
+++ b/src/lsmattributes.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2007-2009 Emmanuel Pacaud
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_ATTRIBUTES_H
+#define LSM_ATTRIBUTES_H
+
+#include <lsm.h>
+#include <lsmtraits.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ char *value;
+} LsmAttribute;
+
+gboolean lsm_attribute_is_defined (const LsmAttribute *attribute);
+
+typedef struct {
+ char const * name;
+ ptrdiff_t attribute_offset;
+ const LsmTraitClass * trait_class;
+ const void * trait_default;
+} LsmAttributeInfos;
+
+typedef struct _LsmAttributeManager LsmAttributeManager;
+
+LsmAttributeManager * lsm_attribute_manager_new (unsigned int n_attributes,
+ const LsmAttributeInfos *attribute_infos);
+void lsm_attribute_manager_free (LsmAttributeManager *manager);
+void lsm_attribute_manager_add_attributes (LsmAttributeManager *manager,
+ unsigned int n_attributes,
+ const LsmAttributeInfos *attribute_infos);
+LsmAttributeManager * lsm_attribute_manager_duplicate (const LsmAttributeManager *origin);
+
+gboolean lsm_attribute_manager_set_attribute (LsmAttributeManager *manager,
+ void *instance,
+ char const *name,
+ char const *value);
+char const * lsm_attribute_manager_get_attribute (LsmAttributeManager *manager,
+ void *instance,
+ char const *name);
+void lsm_attribute_manager_clean_attributes (LsmAttributeManager *manager,
+ void *instance);
+char * lsm_attribute_manager_serialize (LsmAttributeManager *manager,
+ void *instance);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmproperties.c b/src/lsmproperties.c
new file mode 100644
index 0000000..4f8dd35
--- /dev/null
+++ b/src/lsmproperties.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright © 2007-2009 Emmanuel Pacaud
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#include <lsmproperties.h>
+#include <lsmdebug.h>
+#include <lsmstr.h>
+#include <string.h>
+
+#define PROPERTY_TRAIT(property) ((void *) (((void *) property) + sizeof (LsmProperty)))
+#define PROPERTY_SIZE(trait_class) (trait_class->size + sizeof (LsmProperty))
+
+struct _LsmPropertyManager {
+ unsigned int n_properties;
+ const LsmPropertyInfos *property_infos;
+ GHashTable * hash_by_name;
+};
+
+LsmPropertyManager *
+lsm_property_manager_new (unsigned int n_properties, const LsmPropertyInfos *property_infos)
+{
+ LsmPropertyManager *manager;
+ guint16 i;
+
+ g_return_val_if_fail (n_properties > 0, NULL);
+ g_return_val_if_fail (property_infos != NULL, NULL);
+
+ manager = g_new (LsmPropertyManager, 1);
+ manager->hash_by_name = g_hash_table_new (g_str_hash, g_str_equal);
+ manager->n_properties = n_properties;
+ manager->property_infos = property_infos;
+
+ for (i = 0; i < n_properties; i++) {
+
+ g_assert (property_infos[i].name != NULL);
+ g_assert (property_infos[i].trait_class != NULL);
+
+ g_hash_table_insert (manager->hash_by_name,
+ (void *) property_infos[i].name,
+ (void *) &property_infos[i]);
+ }
+
+ return manager;
+}
+
+void
+lsm_property_manager_free (LsmPropertyManager *manager)
+{
+ g_return_if_fail (manager != NULL);
+
+ g_hash_table_unref (manager->hash_by_name);
+ g_free (manager);
+}
+
+static void
+property_free (LsmProperty *property, const LsmTraitClass *trait_class)
+{
+ if (trait_class != NULL && trait_class->finalize != NULL)
+ trait_class->finalize (PROPERTY_TRAIT (property));
+
+ g_free (property->value);
+ g_slice_free1 (PROPERTY_SIZE (trait_class), property);
+}
+
+static gboolean
+_set_property (LsmPropertyManager *manager,
+ LsmPropertyBag *property_bag,
+ const char *name, const char *value)
+{
+ LsmProperty *property;
+ const LsmPropertyInfos *property_infos;
+ const LsmTraitClass *trait_class;
+
+ property_infos = g_hash_table_lookup (manager->hash_by_name, name);
+ if (property_infos == NULL)
+ return FALSE;
+
+ trait_class = property_infos->trait_class;
+
+ /* We don't check for existing property in the list. The cleanup will be done later. */
+
+ property = g_slice_alloc0 (PROPERTY_SIZE (trait_class));
+ property->id = property_infos->id;
+ property->value = g_strdup (value);
+
+ if (trait_class->init)
+ trait_class->init (PROPERTY_TRAIT (property), NULL);
+
+ if (property->value != NULL && trait_class->from_string)
+ trait_class->from_string (PROPERTY_TRAIT (property), (char *) value);
+
+ property_bag->properties = g_slist_prepend (property_bag->properties, property);
+
+ return TRUE;
+}
+
+gboolean
+lsm_property_manager_set_property (LsmPropertyManager *manager,
+ LsmPropertyBag *property_bag,
+ const char *name, const char *value)
+{
+ gboolean property_found;
+ char *inline_style;
+
+ g_return_val_if_fail (property_bag != NULL, FALSE);
+ g_return_val_if_fail (manager != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ property_found = _set_property (manager, property_bag, name, value);
+ if (property_found)
+ return TRUE;
+
+ if (strcmp (name, "style") != 0)
+ return FALSE;
+
+ inline_style = g_strdup (value);
+ if (inline_style == NULL)
+ return FALSE;
+
+ {
+ char *end_ptr = inline_style;
+ char *name;
+ char *value;
+
+ while (*end_ptr != '\0') {
+
+ lsm_str_skip_spaces (&end_ptr);
+
+ name = end_ptr;
+
+ while (*end_ptr != '\0' && *end_ptr != ':' && !g_ascii_isspace (*end_ptr))
+ end_ptr++;
+
+ if (*end_ptr != '\0') {
+ *end_ptr = '\0';
+ end_ptr++;
+
+ lsm_str_skip_colon_and_spaces (&end_ptr);
+
+ if (*end_ptr != '\0') {
+ char old_char;
+
+ value = end_ptr;
+
+ while (*end_ptr != ';' && *end_ptr != '\0')
+ end_ptr++;
+
+ old_char = *end_ptr;
+ *end_ptr = '\0';
+
+ lsm_debug ("[LsmPropertyManager::set_property] inline_style %s = %s",
+ name, value);
+
+ _set_property (manager, property_bag, name, value);
+
+ *end_ptr = old_char;
+
+ lsm_str_skip_char (&end_ptr, ';');
+ }
+ }
+ }
+ g_free (inline_style);
+ }
+
+ return TRUE;
+}
+
+const char *
+lsm_property_manager_get_property (LsmPropertyManager *manager,
+ LsmPropertyBag *property_bag,
+ const char *name)
+{
+ LsmProperty *property = NULL;
+ const LsmPropertyInfos *property_infos;
+ GSList *iter;
+
+ g_return_val_if_fail (property_bag != NULL, NULL);
+ g_return_val_if_fail (manager != NULL, NULL);
+
+ property_infos = g_hash_table_lookup (manager->hash_by_name, name);
+ if (property_infos == NULL)
+ return NULL;
+
+ g_message ("Get property with name %s (%d)", name, property_infos->id);
+
+ for (iter = property_bag->properties; iter != NULL; iter = iter->next) {
+ property = iter->data;
+ if (property->id == property_infos->id)
+ break;
+ }
+
+ if (property == NULL)
+ return NULL;
+
+ return property->value;
+}
+
+void
+lsm_property_manager_clean_properties (LsmPropertyManager *manager,
+ LsmPropertyBag *property_bag)
+{
+ LsmProperty *property;
+ GSList *iter;
+
+ g_return_if_fail (property_bag != NULL);
+ g_return_if_fail (manager != NULL);
+
+ for (iter = property_bag->properties; iter != NULL; iter = iter->next) {
+ property = iter->data;
+
+ if (property->id < manager->n_properties) {
+ const LsmPropertyInfos *property_infos;
+
+ property_infos = &manager->property_infos[property->id];
+ property_free (property, property_infos->trait_class);
+ }
+ }
+
+ g_slist_free (property_bag->properties);
+ property_bag->properties = NULL;
+}
+
+char *
+lsm_property_manager_serialize (LsmPropertyManager *manager,
+ LsmPropertyBag *property_bag)
+{
+ LsmProperty *property;
+ GSList *iter;
+ GString *string;
+ char *c_string;
+
+ g_return_val_if_fail (property_bag != NULL, NULL);
+ g_return_val_if_fail (manager != NULL, NULL);
+
+ string = g_string_new ("");
+
+ for (iter = property_bag->properties; iter != NULL; iter = iter->next) {
+ property = iter->data;
+
+ if (property->id < manager->n_properties) {
+ const LsmPropertyInfos *property_infos;
+
+ property_infos = &manager->property_infos[property->id];
+ g_string_append_printf (string, "%s=\"%s\"%s",
+ property_infos->name,
+ property->value,
+ iter->next != NULL ? " ": "");
+ }
+ }
+
+ c_string = string->str;
+ g_string_free (string, FALSE);
+
+ return c_string;
+}
+
+void
+lsm_property_manager_apply_property_bag (LsmPropertyManager *manager,
+ LsmPropertyBag *bag,
+ void *style,
+ const void *parent_style)
+{
+ LsmProperty *property;
+ GSList *iter;
+
+ g_return_if_fail (bag != NULL);
+ g_return_if_fail (manager != NULL);
+
+ for (iter = bag->properties; iter != NULL; iter = iter->next) {
+ property = iter->data;
+
+ if (property->id < manager->n_properties) {
+ const LsmPropertyInfos *property_infos;
+
+ property_infos = &manager->property_infos[property->id];
+
+ if (g_strcmp0 (property->value, "inherit") != 0)
+ *((LsmProperty **) ((void*) style
+ + LSM_PROPERTY_ID_TO_OFFSET (property->id))) = property;
+ else
+ *((LsmProperty **) ((void*) style
+ + LSM_PROPERTY_ID_TO_OFFSET (property->id))) =
+ *((LsmProperty **) ((void*) parent_style
+ + LSM_PROPERTY_ID_TO_OFFSET (property->id)));
+ }
+ }
+}
+
+void lsm_property_manager_init_default_style (LsmPropertyManager *property_manager,
+ void *style)
+{
+ LsmProperty *property;
+ const LsmPropertyInfos *property_infos;
+ const LsmTraitClass *trait_class;
+ unsigned int i;
+
+ g_return_if_fail (property_manager != NULL);
+
+ for (i = 0; i < property_manager->n_properties; i++) {
+ property_infos = &property_manager->property_infos[i];
+ trait_class = property_infos->trait_class;
+
+ property = g_slice_alloc0 (PROPERTY_SIZE (trait_class));
+ property->id = property_infos->id;
+ property->value = g_strdup (property_infos->trait_default);
+
+ if (trait_class->from_string)
+ trait_class->from_string (PROPERTY_TRAIT (property),
+ (char *) property_infos->trait_default);
+
+ *((LsmProperty **) ((void*) style
+ + LSM_PROPERTY_ID_TO_OFFSET (property->id))) = property;
+ }
+}
+
+void
+lsm_property_bag_init (LsmPropertyBag *bag)
+{
+ g_return_if_fail (bag != NULL);
+
+ bag->properties = NULL;
+}
diff --git a/src/lsmproperties.h b/src/lsmproperties.h
new file mode 100644
index 0000000..bb944e4
--- /dev/null
+++ b/src/lsmproperties.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2007-2009 Emmanuel Pacaud
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+#ifndef LSM_PROPERTIES_H
+#define LSM_PROPERTIES_H
+
+#include <lsm.h>
+#include <lsmtraits.h>
+
+G_BEGIN_DECLS
+
+#define LSM_PROPERTY_OFFSET_TO_ID(structure,member) offsetof (structure, member) / sizeof (void *)
+#define LSM_PROPERTY_ID_TO_OFFSET(id) id * sizeof (void *)
+
+typedef struct {
+ guint16 id;
+ guint16 flags;
+ char * value;
+} LsmProperty;
+
+typedef struct {
+ char const * name;
+ guint16 id;
+ const LsmTraitClass * trait_class;
+ const char * trait_default;
+} LsmPropertyInfos;
+
+typedef struct {
+ GSList *properties;
+} LsmPropertyBag;
+
+typedef struct _LsmPropertyManager LsmPropertyManager;
+
+LsmPropertyManager * lsm_property_manager_new (unsigned int n_properties,
+ const LsmPropertyInfos *property_infos);
+void lsm_property_manager_free (LsmPropertyManager *manager);
+
+gboolean lsm_property_manager_set_property (LsmPropertyManager *manager,
+ LsmPropertyBag *property_bag,
+ const char *name,
+ const char *value);
+const char * lsm_property_manager_get_property (LsmPropertyManager *manager,
+ LsmPropertyBag *property_bag,
+ const char *name);
+void lsm_property_manager_clean_properties (LsmPropertyManager *manager,
+ LsmPropertyBag *property_bag);
+char * lsm_property_manager_serialize (LsmPropertyManager *property_manager,
+ LsmPropertyBag *property_bag);
+void lsm_property_manager_apply_property_bag (LsmPropertyManager *property_manager,
+ LsmPropertyBag *property_bag,
+ void *style,
+ const void *parent_style);
+void lsm_property_manager_init_default_style (LsmPropertyManager *property_manager,
+ void *style);
+
+void lsm_property_bag_init (LsmPropertyBag *bag);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmtraits.c b/src/lsmtraits.c
new file mode 100644
index 0000000..36b217c
--- /dev/null
+++ b/src/lsmtraits.c
@@ -0,0 +1,74 @@
+#include <lsmtraits.h>
+#include <lsmstr.h>
+
+const LsmTraitClass lsm_null_trait_class = {
+ .size = 0
+};
+
+static void
+lsm_double_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ double *trait = (double *) abstract_trait;
+
+ *trait = g_strtod (string, NULL);
+}
+
+static char *
+lsm_double_trait_to_string (LsmTrait *abstract_trait)
+{
+ double *trait = (double *) abstract_trait;
+
+ return g_strdup_printf ("%g", *trait);
+}
+
+const LsmTraitClass lsm_double_trait_class = {
+ .size = sizeof (double),
+ .from_string = lsm_double_trait_from_string,
+ .to_string = lsm_double_trait_to_string
+};
+
+static void
+lsm_box_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ LsmBox *trait = (LsmBox *) abstract_trait;
+ unsigned int i;
+ double value[4];
+
+ for (i = 0; i < 4 && *string != '\0'; i++) {
+ lsm_str_skip_semicolon_and_spaces (&string);
+
+ if (!lsm_str_parse_double (&string, &value[i]))
+ break;
+ }
+
+ if (i == 4) {
+ trait->x = value[0];
+ trait->y = value[1];
+ trait->width = value[2];
+ trait->height = value[3];
+
+ return;
+ }
+
+ trait->x =
+ trait->y =
+ trait->width =
+ trait->height = 0.0;
+}
+
+char *
+lsm_box_trait_to_string (LsmTrait *abstract_trait)
+{
+ LsmBox *trait = (LsmBox *) abstract_trait;
+
+ return g_strdup_printf ("%g %g %g %g",
+ trait->x, trait->y,
+ trait->width, trait->height);
+}
+
+const LsmTraitClass lsm_box_trait_class = {
+ .size = sizeof (LsmBox),
+ .from_string = lsm_box_trait_from_string,
+ .to_string = lsm_box_trait_to_string
+};
+
diff --git a/src/lsmtraits.h b/src/lsmtraits.h
new file mode 100644
index 0000000..e7f5d3e
--- /dev/null
+++ b/src/lsmtraits.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2009 Emmanuel Pacaud
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_TRAITS_H
+#define LSM_TRAITS_H
+
+#include <lsm.h>
+
+G_BEGIN_DECLS
+
+typedef void * LsmTrait;
+
+typedef struct {
+ size_t size;
+ void (*init) (LsmTrait *abstract_trait, const void *trait_default);
+ void (*finalize) (LsmTrait *abstract_trait);
+ void (*from_string) (LsmTrait *abstract_trait, char *string);
+ char * (*to_string) (LsmTrait *abstract_trait);
+} LsmTraitClass;
+
+extern const LsmTraitClass lsm_null_trait_class;
+extern const LsmTraitClass lsm_double_trait_class;
+extern const LsmTraitClass lsm_box_trait_class;
+
+G_END_DECLS
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]