[monet/bberg-playground: 2/4] Actually add the files.



commit baaf49e0294932d7b8b0e766b9476e6528826e8b
Author: Benjamin Berg <benjamin sipsolutions net>
Date:   Sat Aug 15 18:12:59 2009 +0200

    Actually add the files.

 monet/mn-context.c    |   70 +++++++
 monet/mn-context.h    |   42 ++++
 monet/mn-display.c    |  166 +++++++++++++++
 monet/mn-display.h    |   46 +++++
 monet/mn-stylesheet.c |  534 +++++++++++++++++++++++++++++++++++++++++++++++++
 monet/mn-stylesheet.h |   65 ++++++
 6 files changed, 923 insertions(+), 0 deletions(-)
---
diff --git a/monet/mn-context.c b/monet/mn-context.c
new file mode 100644
index 0000000..d56a4e7
--- /dev/null
+++ b/monet/mn-context.c
@@ -0,0 +1,70 @@
+#include "monet.h"
+
+G_DEFINE_TYPE (MnContext, mn_context, G_TYPE_OBJECT)
+
+#define GET_PRIVATE(o) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), MN_TYPE_CONTEXT, MnContextPrivate))
+
+typedef struct _MnContextPrivate MnContextPrivate;
+
+struct _MnContextPrivate {
+    int dummy;
+};
+
+static void
+mn_context_get_property (GObject *object, guint property_id,
+                              GValue *value, GParamSpec *pspec)
+{
+  switch (property_id) {
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+  }
+}
+
+static void
+mn_context_set_property (GObject *object, guint property_id,
+                              const GValue *value, GParamSpec *pspec)
+{
+  switch (property_id) {
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+  }
+}
+
+static void
+mn_context_dispose (GObject *object)
+{
+  G_OBJECT_CLASS (mn_context_parent_class)->dispose (object);
+}
+
+static void
+mn_context_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (mn_context_parent_class)->finalize (object);
+}
+
+static void
+mn_context_class_init (MnContextClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (MnContextPrivate));
+
+  object_class->get_property = mn_context_get_property;
+  object_class->set_property = mn_context_set_property;
+  object_class->dispose = mn_context_dispose;
+  object_class->finalize = mn_context_finalize;
+}
+
+static void
+mn_context_init (MnContext *self)
+{
+}
+
+MnContext*
+mn_context_new (void)
+{
+  return g_object_new (MN_TYPE_CONTEXT, NULL);
+}
+
+
diff --git a/monet/mn-context.h b/monet/mn-context.h
new file mode 100644
index 0000000..15125be
--- /dev/null
+++ b/monet/mn-context.h
@@ -0,0 +1,42 @@
+#ifndef _MN_CONTEXT
+#define _MN_CONTEXT
+
+#include <glib-object.h>
+#include "mn-display.h"
+
+G_BEGIN_DECLS
+
+#define MN_TYPE_CONTEXT mn_context_get_type()
+
+#define MN_CONTEXT(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), MN_TYPE_CONTEXT, MnContext))
+
+#define MN_CONTEXT_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), MN_TYPE_CONTEXT, MnContextClass))
+
+#define MN_IS_CONTEXT(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MN_TYPE_CONTEXT))
+
+#define MN_IS_CONTEXT_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), MN_TYPE_CONTEXT))
+
+#define MN_CONTEXT_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), MN_TYPE_CONTEXT, MnContextClass))
+
+typedef struct {
+  GObject parent;
+} MnContext;
+
+typedef struct {
+  GObjectClass parent_class;
+} MnContextClass;
+
+GType mn_context_get_type (void);
+
+MnContext* mn_context_new_for_display (MnDisplay *display);
+
+G_END_DECLS
+
+#endif /* _MN_CONTEXT */
+
+
diff --git a/monet/mn-display.c b/monet/mn-display.c
new file mode 100644
index 0000000..47eb48d
--- /dev/null
+++ b/monet/mn-display.c
@@ -0,0 +1,166 @@
+#include "monet.h"
+
+G_DEFINE_TYPE (MnDisplay, mn_display, G_TYPE_OBJECT)
+
+#define GET_PRIVATE(o) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), MN_TYPE_DISPLAY, MnDisplayPrivate))
+
+typedef struct _MnDisplayPrivate MnDisplayPrivate;
+
+struct _MnDisplayPrivate {
+    gchar *theme_type;
+    GSList *stylesheets;
+};
+
+enum {
+  PROP_THEME_TYPE = 1
+};
+
+enum {
+  SIGNAL_THEME_CHANGED,
+  SIGNAL_LAST
+};
+
+MnDisplay*
+mn_display_new (gchar *theme_type)
+{
+  g_assert(theme_type != NULL);
+
+  return g_object_new (MN_TYPE_DISPLAY,
+                       "theme-type", theme_type,
+                       NULL);
+}
+
+const gchar*
+mn_display_get_theme_type (MnDisplay* display)
+{
+  MnDisplayPrivate *priv = GET_PRIVATE (display);
+
+  return priv->theme_type;
+}
+
+static gint
+stylesheet_priority_cmp (gconstpointer a, gconstpointer b)
+{
+  MnStylesheet *s_a = (MnStylesheet*) a;
+  MnStylesheet *s_b = (MnStylesheet*) b;
+  MnPriority priority_a, priority_b;
+
+  priority_a = mn_stylesheet_get_priority (s_a);
+  priority_b = mn_stylesheet_get_priority (s_b);
+
+  return priority_a - priority_b;
+}
+
+static void
+stylesheet_changed_cb (MnStylesheet *stylesheet, MnDisplay *display)
+{
+  /*MnDisplayPrivate *priv = GET_PRIVATE (display);*/
+}
+
+void
+mn_display_add_stylesheet (MnDisplay *display, MnStylesheet *stylesheet)
+{
+  MnDisplayPrivate *priv = GET_PRIVATE (display);
+
+  g_return_if_fail (g_slist_find (priv->stylesheets, stylesheet) != NULL);
+
+  g_object_ref_sink (stylesheet);
+  g_signal_connect (G_OBJECT (stylesheet), "changed",
+                    G_CALLBACK (stylesheet_changed_cb), display);
+
+  priv->stylesheets = g_slist_insert_sorted (priv->stylesheets, stylesheet,
+                                             stylesheet_priority_cmp);
+}
+
+void
+mn_display_remove_stylesheet (MnDisplay *display, MnStylesheet *stylesheet)
+{
+  MnDisplayPrivate *priv = GET_PRIVATE (display);
+  GSList *item;
+
+  item = g_slist_find (priv->stylesheets, stylesheet);
+
+  g_return_if_fail (item != NULL);
+
+  g_signal_handlers_disconnect_by_func (G_OBJECT (stylesheet),
+                                        stylesheet_changed_cb,
+                                        display);
+
+  priv->stylesheets = g_slist_delete_link (priv->stylesheets, item);
+}
+
+
+static void
+mn_display_get_property (GObject *object, guint property_id,
+                              GValue *value, GParamSpec *pspec)
+{
+  MnDisplayPrivate *priv = GET_PRIVATE (object);
+
+  switch (property_id) {
+  case PROP_THEME_TYPE:
+    g_free (priv->theme_type);
+    g_value_set_string (value, priv->theme_type);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+  }
+}
+
+static void
+mn_display_set_property (GObject *object, guint property_id,
+                              const GValue *value, GParamSpec *pspec)
+{
+  MnDisplayPrivate *priv = GET_PRIVATE (object);
+
+  switch (property_id) {
+  case PROP_THEME_TYPE:
+    priv->theme_type = g_value_dup_string (value);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+  }
+}
+
+static void
+mn_display_dispose (GObject *object)
+{
+  G_OBJECT_CLASS (mn_display_parent_class)->dispose (object);
+}
+
+static void
+mn_display_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (mn_display_parent_class)->finalize (object);
+}
+
+static void
+mn_display_class_init (MnDisplayClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (MnDisplayPrivate));
+
+  object_class->get_property = mn_display_get_property;
+  object_class->set_property = mn_display_set_property;
+  object_class->dispose = mn_display_dispose;
+  object_class->finalize = mn_display_finalize;
+
+  g_object_class_install_property(object_class, PROP_THEME_TYPE,
+                                  g_param_spec_string ("theme-type",
+                                                       "Theme Type",
+                                                       "The type of theme that monet is handling.",
+                                                       NULL,
+                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+mn_display_init (MnDisplay *self)
+{
+  MnDisplayPrivate *priv = GET_PRIVATE (self);
+
+  priv->theme_type = NULL;
+  priv->stylesheets = NULL;
+}
+
+
diff --git a/monet/mn-display.h b/monet/mn-display.h
new file mode 100644
index 0000000..156be20
--- /dev/null
+++ b/monet/mn-display.h
@@ -0,0 +1,46 @@
+#ifndef _MN_DISPLAY
+#define _MN_DISPLAY
+
+#include <glib-object.h>
+#include "mn-stylesheet.h"
+
+G_BEGIN_DECLS
+
+#define MN_TYPE_DISPLAY mn_display_get_type()
+
+#define MN_DISPLAY(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), MN_TYPE_DISPLAY, MnDisplay))
+
+#define MN_DISPLAY_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), MN_TYPE_DISPLAY, MnDisplayClass))
+
+#define MN_IS_DISPLAY(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MN_TYPE_DISPLAY))
+
+#define MN_IS_DISPLAY_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), MN_TYPE_DISPLAY))
+
+#define MN_DISPLAY_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), MN_TYPE_DISPLAY, MnDisplayClass))
+
+typedef struct {
+  GObject parent;
+} MnDisplay;
+
+typedef struct {
+  GObjectClass parent_class;
+} MnDisplayClass;
+
+GType mn_display_get_type (void);
+
+MnDisplay* mn_display_new (gchar *theme_type);
+
+const gchar* mn_display_get_theme_type (MnDisplay* display);
+
+void mn_display_add_stylesheet    (MnDisplay *display, MnStylesheet *stylesheet);
+void mn_display_remove_stylesheet (MnDisplay *display, MnStylesheet *stylesheet);
+
+G_END_DECLS
+
+#endif /* _MN_DISPLAY */
+
diff --git a/monet/mn-stylesheet.c b/monet/mn-stylesheet.c
new file mode 100644
index 0000000..d575c13
--- /dev/null
+++ b/monet/mn-stylesheet.c
@@ -0,0 +1,534 @@
+#include <string.h>
+#include "monet.h"
+
+G_DEFINE_TYPE (MnStylesheet, mn_stylesheet, G_TYPE_OBJECT)
+
+#define GET_PRIVATE(o) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), MN_TYPE_STYLESHEET, MnStylesheetPrivate))
+
+
+typedef struct _MnStylesheetPrivate MnStylesheetPrivate;
+typedef struct _MnStyle MnStyle;
+typedef struct _MnSelector MnSelector;
+typedef struct _MnProperty MnProperty;
+
+struct _MnStylesheetPrivate {
+  MnPriority priority;
+  gchar *string;
+
+  GSList *styles;
+  GSList *selectors;
+};
+
+struct _MnStyle {
+  GSList *properties;
+};
+
+struct _MnProperty {
+  gchar *identifier;
+  gchar *value;
+};
+
+struct _MnSelector {
+  gchar *identifier;
+  MnStyle *style;
+};
+
+enum {
+  PROP_PRIORITY = 1,
+  PROP_STRING
+};
+
+enum {
+  SIGNAL_CHANGED,
+  SIGNAL_LAST
+};
+
+static guint stylesheet_signals[SIGNAL_LAST] = { 0 };
+
+static MnProperty*
+mn_stylesheet_property_new ()
+{
+  return g_slice_new0 (MnProperty);
+}
+
+static void
+mn_stylesheet_property_free (MnProperty *property)
+{
+  g_free (property->identifier);
+  g_free (property->value);
+  g_slice_free (MnProperty, property);
+}
+
+static MnStyle*
+mn_stylesheet_style_new ()
+{
+  MnStyle *style = g_slice_new0 (MnStyle);
+  style->properties = NULL;
+
+  return style;
+}
+
+static void
+mn_stylesheet_style_free (MnStyle *style)
+{
+  g_slist_foreach (style->properties, (GFunc) mn_stylesheet_property_free,
+                   NULL);
+  g_slist_free (style->properties);
+  g_slice_free (MnStyle, style);
+}
+
+static MnSelector*
+mn_stylesheet_selector_new ()
+{
+  return g_slice_new0 (MnSelector);
+}
+
+static void
+mn_stylesheet_selector_free (MnSelector *selector)
+{
+  g_free (selector->identifier);
+  g_slice_free (MnSelector, selector);
+}
+
+static void
+mn_stylesheet_selectors_free (GSList *selectors)
+{
+  g_slist_foreach (selectors, (GFunc) mn_stylesheet_selector_free, NULL);
+  g_slist_free (selectors);
+}
+
+static void
+mn_stylesheet_add_style_with_selectors (MnStylesheet *stylesheet,
+                                        MnStyle      *style,
+                                        GSList       *selectors)
+{
+  MnStylesheetPrivate *priv = GET_PRIVATE (stylesheet);
+  GSList *selector = selectors;
+
+  while (selector)
+    {
+      ((MnSelector*)selector->data)->style = style;
+
+      selector = selector->next;
+    }
+  priv->selectors = g_slist_concat (priv->selectors, selectors);
+  priv->styles = g_slist_append (priv->styles, style);
+}
+
+/***********************************************************/
+
+static void
+scan_complete_block (GScanner *scanner)
+{
+  GTokenType token;
+  gboolean done = FALSE;
+  gint curly = 0;
+  gint brace = 0;
+  gint paren = 0;
+
+  /* Scan until we "ate" a complete block in curly brackets */
+  while (!done)
+    {
+      token = g_scanner_get_next_token (scanner);
+      switch (token)
+        {
+        case G_TOKEN_LEFT_PAREN:
+          paren += 1;
+          break;
+        case G_TOKEN_RIGHT_PAREN:
+          paren -= 1;
+          break;
+        case G_TOKEN_LEFT_BRACE:
+          brace += 1;
+          break;
+        case G_TOKEN_RIGHT_BRACE:
+          brace -= 1;
+          break;
+        case G_TOKEN_LEFT_CURLY:
+          curly += 1;
+          break;
+        case G_TOKEN_RIGHT_CURLY:
+          curly -= 1;
+          if (curly <= 0)
+            done = TRUE;
+          break;
+        case G_TOKEN_EOF:
+          g_scanner_unexp_token (scanner, G_TOKEN_RIGHT_CURLY, NULL, NULL,
+                                 "closing brace",
+                                 "Expected a closing curly brace.", TRUE);
+          done = TRUE;
+        default:
+          break;
+        }
+    }
+}
+
+static gchar*
+scan_block_to_semicolon (GScanner *scanner)
+{
+  GTokenType token;
+  GString *str;
+  gint curly = 0;
+  gint brace = 0;
+  gint paren = 0;
+
+  str = g_string_new ("");
+
+  /* XXX: This does not keep whitespace in the correct format!
+   *      It also does not search do non-matching brackets correctly.
+   */
+  token = g_scanner_peek_next_token (scanner);
+  while ((token != ';' || curly < 0) && curly >= 0 && brace >= 0 && paren >= 0)
+    {
+      gchar *tmp;
+
+      if (token != G_TOKEN_RIGHT_CURLY)
+        g_scanner_get_next_token (scanner);
+
+      switch (token)
+        {
+        case G_TOKEN_LEFT_PAREN:
+          paren += 1;
+          g_string_append (str, " (");
+          break;
+        case G_TOKEN_RIGHT_PAREN:
+          paren -= 1;
+          g_string_append (str, " )");
+          break;
+        case G_TOKEN_LEFT_BRACE:
+          brace += 1;
+          g_string_append (str, " [");
+          break;
+        case G_TOKEN_RIGHT_BRACE:
+          brace -= 1;
+          g_string_append (str, " ]");
+          break;
+        case G_TOKEN_LEFT_CURLY:
+          curly += 1;
+          g_string_append (str, " {");
+          break;
+        case G_TOKEN_RIGHT_CURLY:
+          curly -= 1;
+          if (curly >= 0)
+            {
+              /* Need to read in the token in this case. */
+              g_scanner_get_next_token (scanner);
+              g_string_append (str, " }");
+            }
+          break;
+        case G_TOKEN_IDENTIFIER:
+          g_string_append_c (str, ' ');
+          g_string_append (str, scanner->value.v_string);
+          break;
+        case G_TOKEN_STRING:
+          tmp = g_strescape (scanner->value.v_string, NULL);
+          g_string_append (str, " \"");
+          g_string_append (str, tmp);
+          g_free (tmp);
+          g_string_append_c (str, '"');
+          break;
+        case G_TOKEN_EOF:
+          g_string_free (str, TRUE);
+          g_warning ("Hit end of file while scanning a value!");
+          return NULL;
+        case ':':
+          g_string_append_c (str, ':');
+          break;
+        case '>':
+          g_string_append_c (str, '>');
+          break;
+        case '<':
+          g_string_append_c (str, '<');
+          break;
+        case '-':
+          g_string_append_c (str, '-');
+          break;
+        case '+':
+          g_string_append_c (str, '+');
+          break;
+        case G_TOKEN_INT:
+          tmp = g_strdup_printf (" %li", scanner->value.v_int);
+          g_string_append (str, tmp);
+          g_free (tmp);
+          break;
+        case G_TOKEN_FLOAT:
+          tmp = g_strdup_printf (" %f", scanner->value.v_float);
+          g_string_append (str, tmp);
+          g_free (tmp);
+          break;
+        default:
+          g_print ("Not implemented! %c\n", token);
+          break;
+        }
+
+      token = g_scanner_peek_next_token (scanner);
+    }
+
+  /* Eat the ';' token. */
+  if (token == ';')
+    g_scanner_get_next_token (scanner);
+
+  if (str->len == 0)
+    {
+      g_string_free (str, TRUE);
+      return NULL;
+    }
+  g_string_erase (str, 0, 1);
+  return g_string_free (str, FALSE);
+}
+
+static GSList*
+mn_stylesheet_parse_selectors (MnStylesheet *stylesheet, GScanner *scanner)
+{
+  GTokenType token;
+  MnSelector *selector;
+
+  token = g_scanner_get_next_token (scanner);
+  if (token != G_TOKEN_IDENTIFIER)
+    {
+      g_scanner_unexp_token (scanner, G_TOKEN_IDENTIFIER, NULL, NULL,
+                             "selector",
+                             "Expected an identifier that is part of a stylesheet.", TRUE);
+      scan_complete_block (scanner);
+      return NULL;
+    }
+  else
+    {
+      selector = mn_stylesheet_selector_new ();
+      selector->identifier = g_strdup (scanner->value.v_identifier);
+      return g_slist_append (NULL, selector);
+    }
+}
+
+static MnStyle*
+mn_stylesheet_parse_style (MnStylesheet *stylesheet, GScanner *scanner)
+{
+  GTokenType token;
+  MnStyle *style = NULL;
+
+  token = g_scanner_get_next_token (scanner);
+  if (token != G_TOKEN_LEFT_CURLY)
+    {
+      g_scanner_unexp_token (scanner, G_TOKEN_IDENTIFIER, NULL, NULL,
+                             "opening bracket",
+                             "Expected opening curly bracket.", TRUE);
+      scan_complete_block (scanner);
+      return NULL;
+    }
+
+  token = g_scanner_get_next_token (scanner);
+  while (token != G_TOKEN_RIGHT_CURLY)
+    {
+      if (token != G_TOKEN_IDENTIFIER)
+        {
+          gchar *tmp;
+          tmp = scan_block_to_semicolon (scanner);
+          g_free (tmp);
+        }
+      else
+        {
+          MnProperty *property;
+          gchar *identifier;
+          gchar *value;
+
+          identifier = g_strdup (scanner->value.v_string);
+          token = g_scanner_get_next_token (scanner);
+          if (token != ':')
+            {
+              g_free (identifier);
+              g_print ("Expected ':', found something else!\n");
+              value = scan_block_to_semicolon (scanner);
+              g_free (value);
+              continue;
+            }
+          value = scan_block_to_semicolon (scanner);
+          if (value == NULL)
+            {
+              g_free (identifier);
+              g_print ("XXX: WARNING\n");
+              continue;
+            }
+
+          if (style == NULL)
+            style = mn_stylesheet_style_new ();
+
+          property = mn_stylesheet_property_new ();
+          property->identifier = identifier;
+          property->value = value;
+          g_print ("Adding property '%s' with value '%s'\n", identifier, value);
+          style->properties = g_slist_append(style->properties, property);
+        }
+      token = g_scanner_get_next_token (scanner);
+    }
+  return style;
+}
+
+static void
+mn_stylesheet_parse (MnStylesheet *stylesheet)
+{
+  MnStylesheetPrivate *priv = GET_PRIVATE (stylesheet);
+  GScanner *scanner;
+  GScannerConfig *config;
+  GTokenType token;
+
+  scanner = g_scanner_new (NULL);
+  config = scanner->config;
+
+  config->skip_comment_single = 0;
+
+  g_scanner_input_text (scanner, priv->string, strlen (priv->string));
+
+  token = g_scanner_peek_next_token (scanner);
+
+  while (token != G_TOKEN_EOF)
+    {
+      GSList *selectors;
+      MnStyle *style;
+
+      /*if (token == G_TOKEN_CHAR && scanner->value.v_char == "@")
+        token = mn_stylesheet_parse_at_rule (stylesheet, scanner);
+      else*/
+      selectors = mn_stylesheet_parse_selectors (stylesheet, scanner);
+      if (selectors == NULL)
+        continue;
+
+      style = mn_stylesheet_parse_style (stylesheet, scanner);
+      if (style == NULL)
+        {
+          mn_stylesheet_selectors_free (selectors);
+        }
+      mn_stylesheet_add_style_with_selectors (stylesheet, style, selectors);
+
+      token = g_scanner_peek_next_token (scanner);
+    }
+
+  g_scanner_destroy (scanner);
+}
+
+/***********************************************************/
+
+
+MnStylesheet*
+mn_stylesheet_new_from_string (const gchar *string, MnPriority priority)
+{
+  return g_object_new (MN_TYPE_STYLESHEET,
+                       "string", string,
+                       "priority", priority,
+                       NULL);
+}
+
+MnPriority
+mn_stylesheet_get_priority (MnStylesheet *stylesheet)
+{
+  MnStylesheetPrivate *priv = GET_PRIVATE (stylesheet);
+
+  return priv->priority;
+}
+
+
+static void
+mn_stylesheet_get_property (GObject *object, guint property_id,
+                              GValue *value, GParamSpec *pspec)
+{
+  MnStylesheetPrivate *priv = GET_PRIVATE (object);
+
+  switch (property_id) {
+  case PROP_PRIORITY:
+    g_value_set_enum (value, priv->priority);
+    break;
+  case PROP_STRING:
+    g_value_set_string (value, priv->string);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+  }
+}
+
+static void
+mn_stylesheet_set_property (GObject *object, guint property_id,
+                              const GValue *value, GParamSpec *pspec)
+{
+  MnStylesheetPrivate *priv = GET_PRIVATE (object);
+
+  switch (property_id) {
+  case PROP_PRIORITY:
+    priv->priority = g_value_get_enum (value);
+    break;
+  case PROP_STRING:
+    g_free (priv->string);
+    priv->string = g_value_dup_string (value);
+    mn_stylesheet_parse (MN_STYLESHEET (object));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+  }
+}
+
+static void
+mn_stylesheet_dispose (GObject *object)
+{
+  G_OBJECT_CLASS (mn_stylesheet_parent_class)->dispose (object);
+}
+
+static void
+mn_stylesheet_finalize (GObject *object)
+{
+  MnStylesheet *stylesheet = MN_STYLESHEET (object);
+  MnStylesheetPrivate *priv = GET_PRIVATE (stylesheet);
+
+  mn_stylesheet_selectors_free (priv->selectors);
+  priv->selectors = NULL;
+  g_slist_foreach (priv->styles, (GFunc) mn_stylesheet_style_free, NULL);
+  g_slist_free (priv->styles);
+  priv->styles = NULL;
+
+  G_OBJECT_CLASS (mn_stylesheet_parent_class)->finalize (object);
+}
+
+static void
+mn_stylesheet_class_init (MnStylesheetClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (MnStylesheetPrivate));
+
+  object_class->get_property = mn_stylesheet_get_property;
+  object_class->set_property = mn_stylesheet_set_property;
+  object_class->dispose = mn_stylesheet_dispose;
+  object_class->finalize = mn_stylesheet_finalize;
+
+  stylesheet_signals[SIGNAL_CHANGED] = 
+    g_signal_new ("changed",
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (MnStylesheetClass, changed),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+
+  g_object_class_install_property(object_class, PROP_PRIORITY,
+                                  g_param_spec_enum ("priority",
+                                                     "Priority of the stylesheet",
+                                                     "The priority of the stylesheet that this object represents.",
+                                                     MN_TYPE_PRIORITY,
+                                                     MN_PRIORITY_DEFAULT,
+                                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property(object_class, PROP_STRING,
+                                  g_param_spec_string ("string",
+                                                       "String to parse",
+                                                       "The string to parse for the style.",
+                                                       NULL,
+                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+mn_stylesheet_init (MnStylesheet *self)
+{
+  MnStylesheetPrivate *priv = GET_PRIVATE (self);
+
+  priv->priority = MN_PRIORITY_DEFAULT;
+  priv->string = NULL;
+}
+
diff --git a/monet/mn-stylesheet.h b/monet/mn-stylesheet.h
new file mode 100644
index 0000000..3f2811e
--- /dev/null
+++ b/monet/mn-stylesheet.h
@@ -0,0 +1,65 @@
+#ifndef _MN_STYLESHEET
+#define _MN_STYLESHEET
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define MN_TYPE_STYLESHEET mn_stylesheet_get_type()
+
+#define MN_STYLESHEET(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), MN_TYPE_STYLESHEET, MnStylesheet))
+
+#define MN_STYLESHEET_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), MN_TYPE_STYLESHEET, MnStylesheetClass))
+
+#define MN_IS_STYLESHEET(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MN_TYPE_STYLESHEET))
+
+#define MN_IS_STYLESHEET_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), MN_TYPE_STYLESHEET))
+
+#define MN_STYLESHEET_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), MN_TYPE_STYLESHEET, MnStylesheetClass))
+
+typedef enum
+{
+  MN_PRIORITY_INIT = 50,
+  MN_PRIORITY_LOW = 100,
+  MN_PRIORITY_DEFAULT = 150,
+  MN_PRIORITY_HIGH = 200
+} MnPriority;
+
+typedef struct {
+  GObject parent;
+} MnStylesheet;
+
+typedef struct {
+  GObjectClass parent_class;
+
+  /* < private > */
+  void (* changed)              (MnStylesheet     *stylesheet);
+
+  /* Padding */
+  void (*_mn_reserved1) (void);
+  void (*_mn_reserved2) (void);
+  void (*_mn_reserved3) (void);
+  void (*_mn_reserved4) (void);
+  void (*_mn_reserved5) (void);
+  void (*_mn_reserved6) (void);
+  void (*_mn_reserved7) (void);
+  void (*_mn_reserved8) (void);
+} MnStylesheetClass;
+
+
+GType mn_stylesheet_get_type (void);
+
+MnStylesheet* mn_stylesheet_new_from_string (const gchar *string,
+                                             MnPriority   priority);
+
+MnPriority mn_stylesheet_get_priority (MnStylesheet *stylesheet);
+
+G_END_DECLS
+
+#endif /* _MN_STYLESHEET */
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]