[monet/monet-xml: 1/10] Simplify into a cairo based abstraction layer for GtkStyle



commit 09b72a3730e6bb2c70b7c07e55a684faba9fd215
Author: Thomas Wood <thos gnome org>
Date:   Sun Apr 4 18:31:48 2010 +0100

    Simplify into a cairo based abstraction layer for GtkStyle
    
    Start as an abstraction layer for the current GTK+ theme engine API to
    get something working quickly. This can then be developed into a more
    advanced widget drawing framework.

 Makefile.am                          |    2 +-
 configure.ac                         |    8 +
 monet-gtk/AUTHORS                    |    2 -
 monet-gtk/COPYING                    |  481 --------------------
 monet-gtk/INSTALL                    |  229 ----------
 monet-gtk/Makefile.am                |   22 +-
 monet-gtk/autogen.sh                 |   19 -
 monet-gtk/git.mk                     |  182 --------
 monet-gtk/gtkrc                      |    5 +
 monet-gtk/{src => }/main.c           |    8 +-
 monet-gtk/monetrc                    |   23 +
 monet-gtk/{src => }/rcstyle.c        |   59 ++--
 monet-gtk/rcstyle.h                  |   54 +++
 monet-gtk/src/Makefile.am            |   17 -
 monet-gtk/src/rcstyle.h              |   54 ---
 monet-gtk/src/style.c                |  375 ----------------
 monet-gtk/src/style.h                |   46 --
 monet-gtk/style.c                    |  601 +++++++++++++++++++++++++
 monet-gtk/style.h                    |   50 +++
 monet-gtk/test/Makefile.am           |  118 -----
 monet-gtk/test/exported              |   25 -
 monet-gtk/test/gtkrcs/buildin        |   12 -
 monet-gtk/test/gtkrcs/noop           |   12 -
 monet-gtk/test/runinx                |   42 --
 monet-gtk/test/torture               |   62 ---
 monet-gtk/test/torturetest.c         |  706 ------------------------------
 monet-gtk/test/valgrind-suppressions |   57 ---
 monet/Makefile.am                    |   21 +-
 monet/mn-color.c                     |   26 ++
 monet/mn-color.h                     |    2 +-
 monet/mn-palette.c                   |   70 +++-
 monet/mn-palette.h                   |   16 +-
 monet/mn-parts.h                     |   78 ----
 monet/mn-style.c                     |  563 ++++++++++++++++++++++++
 monet/mn-style.h                     |  231 ++++++++++
 monet/mn-theme-engine.c              |   83 ----
 monet/mn-theme-engine.h              |   64 ---
 monet/mn-types.h                     |    3 +-
 monet/mn-widget.c                    |  145 ------
 monet/mn-widget.h                    |   54 ---
 monet/monet.h                        |    4 +-
 monet/widgets/mn-button.c            |   94 ----
 monet/widgets/mn-button.h            |   76 ----
 stylable/mn-item.c                   |  240 ----------
 stylable/mn-item.h                   |   73 ---
 stylable/mn-stylable.c               |  650 ---------------------------
 stylable/mn-stylable.h               |   93 ----
 stylable/mn-style.c                  |  797 ----------------------------------
 stylable/mn-style.h                  |   89 ----
 49 files changed, 1694 insertions(+), 5049 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 8f06f80..8519c9b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = monet tests
+SUBDIRS = monet monet-gtk
 
 -include $(top_srcdir)/git.mk
diff --git a/configure.ac b/configure.ac
index 00e2196..ff664ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,11 +18,19 @@ PKG_CHECK_MODULES(MONET, [cairo glib-2.0 gobject-2.0])
 AC_SUBST(MONET_LIBS)
 AC_SUBST(MONET_CFLAGS)
 
+PKG_CHECK_MODULES(GTK, [gtk+-2.0])
+AC_SUBST(GTK_LIBS)
+AC_SUBST(GTK_CFLAGS)
+
+GTK_VERSION="`$PKG_CONFIG --variable=gtk_binary_version gtk+-2.0`"
+AC_SUBST(GTK_VERSION)
+
 MONET_MAINTAINER_CFLAGS="-Werror -Wall -Wshadow -Wcast-align -Wno-uninitialized -Wempty-body -Wformat-security -Winit-self -Wmissing-declarations -Wredundant-decls"
 AC_SUBST(MONET_MAINTAINER_CFLAGS)
 
 AC_OUTPUT([
 Makefile
 monet/Makefile
+monet-gtk/Makefile
 tests/Makefile
 ])
diff --git a/monet-gtk/Makefile.am b/monet-gtk/Makefile.am
index 178a5e6..dd06447 100644
--- a/monet-gtk/Makefile.am
+++ b/monet-gtk/Makefile.am
@@ -1,6 +1,22 @@
-SUBDIRS = src test
+themedir = $(prefix)/share/themes/Monet/gtk-2.0
 
-test: all
-	cd test && $(MAKE) $(AM_MAKEFLAGS) test
+INCLUDES = $(GTK_CFLAGS) -I$(top_srcdir) -DTHEMEDIR=\"$(themedir)\"
+
+enginedir = $(libdir)/gtk-2.0/$(GTK_VERSION)/engines
+
+engine_LTLIBRARIES = libmonet-gtk.la
+
+libmonet_gtk_la_SOURCES = \
+		main.c \
+		rcstyle.c \
+		rcstyle.h \
+		style.c \
+		style.h
+
+libmonet_gtk_la_LDFLAGS = -avoid-version -module -no-undefined
+libmonet_gtk_la_LIBADD = $(GTK_LIBS) -lmonet
+
+theme_DATA = gtkrc \
+	     monetrc
 
 -include $(top_srcdir)/git.mk
diff --git a/monet-gtk/gtkrc b/monet-gtk/gtkrc
new file mode 100644
index 0000000..f76f71e
--- /dev/null
+++ b/monet-gtk/gtkrc
@@ -0,0 +1,5 @@
+style "default"
+{
+  engine "monet"
+}
+widget "GtkWidget" style "default"
diff --git a/monet-gtk/src/main.c b/monet-gtk/main.c
similarity index 90%
rename from monet-gtk/src/main.c
rename to monet-gtk/main.c
index 2a76a5f..9116624 100644
--- a/monet-gtk/src/main.c
+++ b/monet-gtk/main.c
@@ -1,4 +1,4 @@
-/*  Noop GTK engine: main.c
+/*  MonetGtk GTK engine: main.c
  *  
  *  Copyright (C) 2008  Benjamin Berg <benjamin sipsolutions net>
  *  
@@ -32,8 +32,8 @@ G_MODULE_EXPORT const gchar* g_module_check_init (GModule *module);
 G_MODULE_EXPORT void
 theme_init (GTypeModule *module)
 {
-  noop_rc_style_register_type (module);
-  noop_style_register_type (module);
+  monet_gtk_rc_style_register_type (module);
+  monet_gtk_style_register_type (module);
 }
 
 G_MODULE_EXPORT void
@@ -45,7 +45,7 @@ theme_exit (void)
 G_MODULE_EXPORT GtkRcStyle *
 theme_create_rc_style (void)
 {
-  return GTK_RC_STYLE (g_object_new (NOOP_TYPE_RC_STYLE, NULL));
+  return GTK_RC_STYLE (g_object_new (MONET_GTK_TYPE_RC_STYLE, NULL));
 }
 
 /* The following function will be called by GTK+ when the module
diff --git a/monet-gtk/monetrc b/monet-gtk/monetrc
new file mode 100644
index 0000000..3cbf612
--- /dev/null
+++ b/monet-gtk/monetrc
@@ -0,0 +1,23 @@
+[colors]
+white = #fff
+gray = #ccc
+lightgray = #eee
+
+[button]
+border = #ff0000
+border:hover = #00ff00
+bg = @lightgray
+bg:hover = @white
+fg = #fff
+
+[check-box]
+border = #0f0
+bg = #fff
+fg = #f00
+
+[radio-button]
+border = #000
+bg = #fff
+fg = #f00
+bg:active = #00f
+
diff --git a/monet-gtk/src/rcstyle.c b/monet-gtk/rcstyle.c
similarity index 60%
rename from monet-gtk/src/rcstyle.c
rename to monet-gtk/rcstyle.c
index 14076f4..3771a7a 100644
--- a/monet-gtk/src/rcstyle.c
+++ b/monet-gtk/rcstyle.c
@@ -1,4 +1,4 @@
-/*  Noop GTK engine: rcstyle.c
+/*  MonetGtk GTK engine: rcstyle.c
  *  
  *  Copyright (C) 2008  Benjamin Berg <benjamin sipsolutions net>
  *  
@@ -23,57 +23,58 @@
 #include "style.h"
 #include "rcstyle.h"
 
-static void      noop_rc_style_init         (NoopRcStyle      *style);
-static void      noop_rc_style_class_init   (NoopRcStyleClass *klass);
-static GtkStyle *noop_rc_style_create_style (GtkRcStyle       *rc_style);
+static void      monet_gtk_rc_style_init         (MonetGtkRcStyle      *style);
+static void      monet_gtk_rc_style_class_init   (MonetGtkRcStyleClass *klass);
+static GtkStyle *monet_gtk_rc_style_create_style (GtkRcStyle       *rc_style);
 
 static GtkRcStyleClass *parent_class;
 
-GType noop_type_rc_style = 0;
+GType monet_gtk_type_rc_style = 0;
 
 void
-noop_rc_style_register_type (GTypeModule *module)
+monet_gtk_rc_style_register_type (GTypeModule *module)
 {
-  if (!noop_type_rc_style) {
+  if (!monet_gtk_type_rc_style) {
     static const GTypeInfo object_info =
     {
-      sizeof (NoopRcStyleClass),
+      sizeof (MonetGtkRcStyleClass),
       (GBaseInitFunc) NULL,
       (GBaseFinalizeFunc) NULL,
-      (GClassInitFunc) noop_rc_style_class_init,
+      (GClassInitFunc) monet_gtk_rc_style_class_init,
       NULL,           /* class_finalize */
       NULL,           /* class_data */
-      sizeof (NoopRcStyle),
+      sizeof (MonetGtkRcStyle),
       0,              /* n_preallocs */
-      (GInstanceInitFunc) noop_rc_style_init,
+      (GInstanceInitFunc) monet_gtk_rc_style_init,
       NULL
     };
 
-    noop_type_rc_style = g_type_module_register_type (module,
+    monet_gtk_type_rc_style = g_type_module_register_type (module,
                              GTK_TYPE_RC_STYLE,
-                             "NoopRcStyle",
+                             "MonetGtkRcStyle",
                              &object_info, 0);
   }
 }
 
 static void
-noop_rc_style_init (NoopRcStyle *style)
+monet_gtk_rc_style_init (MonetGtkRcStyle *style)
 {
-  /* Initilize any variables of the NoopRcStyle object here */
+  /* Initilize any variables of the MonetGtkRcStyle object here */
 }
 
 static void
-noop_rc_style_finalize (NoopRcStyle *style)
+monet_gtk_rc_style_finalize (MonetGtkRcStyle *style)
 {
   /* Clean up any data from the RC style in here. */
 }
 
 static void
-noop_rc_style_merge (GtkRcStyle *dest, GtkRcStyle *src)
+monet_gtk_rc_style_merge (GtkRcStyle *dest,
+                          GtkRcStyle *src)
 {
   parent_class->merge (dest, src);
 
-  if (!NOOP_IS_RC_STYLE (src))
+  if (!MONET_GTK_IS_RC_STYLE (src))
     return;
 
   /* This function "merges" two RC styles. All matched styles from the
@@ -88,17 +89,17 @@ noop_rc_style_merge (GtkRcStyle *dest, GtkRcStyle *src)
 }
 
 static guint
-noop_rc_style_parse (GtkRcStyle   *rc_style,
-                     GtkSettings  *settings,
-                     GScanner     *scanner)
+monet_gtk_rc_style_parse (GtkRcStyle  *rc_style,
+                          GtkSettings *settings,
+                          GScanner    *scanner)
 {
-  NoopRcStyle *noop_rc_style = NOOP_RC_STYLE (rc_style);
+  MonetGtkRcStyle *monet_gtk_rc_style = MONET_GTK_RC_STYLE (rc_style);
 
   return G_TOKEN_NONE;
 }
 
 static void
-noop_rc_style_class_init (NoopRcStyleClass *klass)
+monet_gtk_rc_style_class_init (MonetGtkRcStyleClass *klass)
 {
   GtkRcStyleClass *rc_style_class = GTK_RC_STYLE_CLASS (klass);
   GObjectClass    *g_object_class = G_OBJECT_CLASS (klass);
@@ -108,19 +109,19 @@ noop_rc_style_class_init (NoopRcStyleClass *klass)
   /* These are the functions we override from the GtkRcStyle class.
    * We need to override at least create_style. (Uncomment the other
    * two to override them) */
-  rc_style_class->create_style = noop_rc_style_create_style;
-  /*rc_style_class->merge = noop_rc_style_merge;
-  rc_style_class->parse        = noop_rc_style_parse;
+  rc_style_class->create_style = monet_gtk_rc_style_create_style;
+  /*rc_style_class->merge = monet_gtk_rc_style_merge;
+  rc_style_class->parse        = monet_gtk_rc_style_parse;
 
-  g_object_class->finalize     = noop_rc_style_finalize;*/
+  g_object_class->finalize     = monet_gtk_rc_style_finalize;*/
 }
 
 /* Create an empty style suitable to this RC style
  */
 static GtkStyle *
-noop_rc_style_create_style (GtkRcStyle *rc_style)
+monet_gtk_rc_style_create_style (GtkRcStyle *rc_style)
 {
-  return GTK_STYLE (g_object_new (NOOP_TYPE_STYLE, NULL));
+  return GTK_STYLE (g_object_new (MONET_GTK_TYPE_STYLE, NULL));
 }
 
 
diff --git a/monet-gtk/rcstyle.h b/monet-gtk/rcstyle.h
new file mode 100644
index 0000000..b61fca4
--- /dev/null
+++ b/monet-gtk/rcstyle.h
@@ -0,0 +1,54 @@
+/*  MonetGtk GTK engine: rcstyle.h
+ *
+ *  Copyright (C) 2008  Benjamin Berg <benjamin sipsolutions net>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Library General Publi License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __RCSTYLE_H
+#define __RCSTYLE_H
+
+#include <gtk/gtk.h>
+#include <gtk/gtkrc.h>
+
+typedef struct _MonetGtkRcStyle MonetGtkRcStyle;
+typedef struct _MonetGtkRcStyleClass MonetGtkRcStyleClass;
+
+
+GType monet_gtk_type_rc_style G_GNUC_INTERNAL;
+
+#define MONET_GTK_TYPE_RC_STYLE              monet_gtk_type_rc_style
+#define MONET_GTK_RC_STYLE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MONET_GTK_TYPE_RC_STYLE, MonetGtkRcStyle))
+#define MONET_GTK_RC_STYLE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MONET_GTK_TYPE_RC_STYLE, MonetGtkRcStyleClass))
+#define MONET_GTK_IS_RC_STYLE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MONET_GTK_TYPE_RC_STYLE))
+#define MONET_GTK_IS_RC_STYLE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MONET_GTK_TYPE_RC_STYLE))
+#define MONET_GTK_RC_STYLE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MONET_GTK_TYPE_RC_STYLE, MonetGtkRcStyleClass))
+
+struct _MonetGtkRcStyle
+{
+  GtkRcStyle parent_instance;
+};
+
+struct _MonetGtkRcStyleClass
+{
+  GtkRcStyleClass parent_class;
+};
+
+void monet_gtk_rc_style_register_type (GTypeModule *module) G_GNUC_INTERNAL;
+void monet_gtk_rc_style_load_groups (MonetGtkRcStyle * rcstyle) G_GNUC_INTERNAL;
+
+void monet_gtk_cleanup_everything (void) G_GNUC_INTERNAL;
+
+#endif /* __RCSTYLE_H */
diff --git a/monet-gtk/style.c b/monet-gtk/style.c
new file mode 100644
index 0000000..9cedd34
--- /dev/null
+++ b/monet-gtk/style.c
@@ -0,0 +1,601 @@
+/*  MonetGtk GTK engine: style.c
+ *
+ *  Copyright (C) 2008  Benjamin Berg <benjamin sipsolutions net>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "style.h"
+
+#define DETAIL(x) (detail && (x) && !strcmp (detail, x))
+
+static GtkStyleClass *monet_gtk_style_parent_class;
+
+static void
+monet_state_flags_from_gtk_state (GtkStateType  gtk_state,
+                                  MnState      *state,
+                                  MnFlags      *flags)
+{
+  g_return_if_fail (state != NULL);
+  g_return_if_fail (flags != NULL);
+
+  *state = MN_STATE_NORMAL;
+  *flags = 0;
+
+  switch (gtk_state)
+    {
+    case GTK_STATE_NORMAL:
+      *state = MN_STATE_NORMAL;
+      break;
+    case GTK_STATE_ACTIVE:
+      *state = MN_STATE_ACTIVE;
+      break;
+    case GTK_STATE_PRELIGHT:
+      *state = MN_STATE_HOVER;
+      break;
+    case GTK_STATE_INSENSITIVE:
+      *state = MN_STATE_DISABLED;
+      break;
+
+    case GTK_STATE_SELECTED:
+      *flags |= MN_FLAGS_SELECTED;
+    }
+}
+
+static MnColor*
+monet_color_from_gtk (GdkColor *gtk_color,
+                      MnColor  *mn_color)
+{
+  g_return_val_if_fail (gtk_color != NULL, NULL);
+  g_return_val_if_fail (mn_color != NULL, NULL);
+
+  mn_color->red = 255 * (gtk_color->red / 65535.f);
+  mn_color->green = 255 * (gtk_color->green / 65535.f);
+  mn_color->blue = 255 * (gtk_color->blue / 65535.f);
+
+  mn_color->alpha = 0xff;
+
+  return mn_color;
+}
+
+static MnPalette*
+monet_palette_from_gtk_style (GtkStyle *style)
+{
+  MnPalette *new;
+  MnColor color;
+  MnState state;
+  MnFlags flags;
+  GtkStateType gtk_state;
+
+  g_return_if_fail (style != NULL);
+
+
+  new = mn_palette_new ();
+
+  for (gtk_state = 0; gtk_state < 5; gtk_state++)
+    {
+      /* skip "selected" state, as this is not a state type in Monet */
+      if (gtk_state == GTK_STATE_SELECTED)
+        continue;
+
+      monet_state_flags_from_gtk_state (gtk_state, &state, &flags);
+
+      /* fg colours */
+      mn_palette_set_color (new, MN_COLOR_BG, state,
+                            monet_color_from_gtk (&style->bg[gtk_state],
+                                                  &color));
+
+      mn_palette_set_color (new, MN_COLOR_BORDER, state,
+                            monet_color_from_gtk (&style->bg[gtk_state],
+                                                  &color));
+
+      /* bg colours */
+      mn_palette_set_color (new, MN_COLOR_FG, state,
+                            monet_color_from_gtk (&style->fg[gtk_state],
+                                                  &color));
+
+      /* highlight colours */
+      mn_palette_set_color (new, MN_COLOR_HIGHLIGHT_BG, state,
+                            monet_color_from_gtk (&style->bg[GTK_STATE_SELECTED],
+                                                  &color));
+
+      mn_palette_set_color (new, MN_COLOR_HIGHLIGHT_FG, state,
+                            monet_color_from_gtk (&style->fg[GTK_STATE_SELECTED],
+                                                  &color));
+    }
+
+  return new;
+}
+
+static void
+monet_params_init (GtkStyle      *style,
+                   GdkWindow     *window,
+                   GtkStateType   gtk_state,
+                   MnStyle      **mn_style,
+                   cairo_t      **cr,
+                   MnState       *state,
+                   MnFlags       *flags,
+                   MnPalette    **colors)
+{
+  g_return_if_fail (cr != NULL);
+  g_return_if_fail (state != NULL);
+  g_return_if_fail (flags != NULL);
+  g_return_if_fail (colors != NULL);
+  g_return_if_fail (mn_style != NULL);
+
+  *cr = gdk_cairo_create (window);
+
+  monet_state_flags_from_gtk_state (gtk_state, state, flags);
+
+  //*colors = monet_palette_from_gtk_style (style);
+  *colors = NULL;
+
+  *mn_style = MONET_GTK_STYLE (style)->mn_style;
+}
+
+
+
+static void
+monet_gtk_draw_hline (GtkStyle     *style,
+                      GdkWindow    *window,
+                      GtkStateType  state_type,
+                      GdkRectangle *area,
+                      GtkWidget    *widget,
+                      const gchar  *detail,
+                      gint          x1,
+                      gint          x2,
+                      gint          y)
+{
+  monet_gtk_style_parent_class->draw_hline (style, window, state_type, area, widget, detail, x1, x2, y);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_vline (GtkStyle     *style,
+                      GdkWindow    *window,
+                      GtkStateType  state_type,
+                      GdkRectangle *area,
+                      GtkWidget    *widget,
+                      const gchar  *detail,
+                      gint          y1,
+                      gint          y2,
+                      gint          x)
+{
+  monet_gtk_style_parent_class->draw_vline (style, window, state_type, area, widget, detail, y1, y2, x);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_shadow (GtkStyle      *style,
+                       GdkWindow     *window,
+                       GtkStateType   state_type,
+                       GtkShadowType  shadow_type,
+                       GdkRectangle  *area,
+                       GtkWidget     *widget,
+                       const gchar   *detail,
+                       gint           x,
+                       gint           y,
+                       gint           width,
+                       gint           height)
+{
+  cairo_t *cr;
+  MnPalette *mn_palette;
+  MnState mn_state;
+  MnFlags mn_flags;
+  MnStyle *mn_style;
+
+  monet_params_init (style, window, state_type,
+                     &mn_style, &cr, &mn_state, &mn_flags, &mn_palette);
+
+  if (DETAIL ("entry"))
+    {
+      mn_style_paint_entry (mn_style, cr, x, y, width, height, mn_palette,
+                            mn_state, mn_flags);
+    }
+  else
+    {
+      monet_gtk_style_parent_class->draw_shadow (style, window, state_type,
+                                                 shadow_type, area, widget,
+                                                 detail, x, y, width, height);
+    }
+
+  cairo_destroy (cr);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_arrow (GtkStyle      *style,
+                      GdkWindow     *window,
+                      GtkStateType   state_type,
+                      GtkShadowType  shadow_type,
+                      GdkRectangle  *area,
+                      GtkWidget     *widget,
+                      const gchar   *detail,
+                      GtkArrowType   arrow_type,
+                      gboolean       fill,
+                      gint           x,
+                      gint           y,
+                      gint           width,
+                      gint           height)
+{
+  monet_gtk_style_parent_class->draw_arrow (style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
+}
+
+/*##################################*/
+
+static void
+monet_gtk_draw_box (GtkStyle      *style,
+                    GdkWindow     *window,
+                    GtkStateType   state_type,
+                    GtkShadowType  shadow_type,
+                    GdkRectangle  *area,
+                    GtkWidget     *widget,
+                    const gchar   *detail,
+                    gint           x,
+                    gint           y,
+                    gint           width,
+                    gint           height)
+{
+  cairo_t *cr;
+  MnPalette *mn_palette;
+  MnState mn_state;
+  MnFlags mn_flags;
+  MnStyle *mn_style;
+
+  monet_params_init (style, window, state_type,
+                     &mn_style, &cr, &mn_state, &mn_flags, &mn_palette);
+
+  if (DETAIL ("button"))
+    {
+      mn_style_paint_button (mn_style, cr, x, y, width, height, mn_palette,
+                             mn_state, mn_flags);
+    }
+  else if (DETAIL ("menu"))
+    {
+      mn_style_paint_menu (mn_style, cr, x, y, width, height, mn_palette,
+                           mn_state, mn_flags);
+    }
+  else if (DETAIL ("menuitem"))
+    {
+      mn_style_paint_menu_item (mn_style, cr, x, y, width, height, mn_palette,
+                                mn_state, mn_flags);
+    }
+  else if (DETAIL ("menubar"))
+    {
+      mn_style_paint_menu_bar (mn_style, cr, x, y, width, height, mn_palette,
+                               mn_state, mn_flags);
+    }
+
+  cairo_destroy (cr);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_flat_box (GtkStyle      *style,
+                         GdkWindow     *window,
+                         GtkStateType   state_type,
+                         GtkShadowType  shadow_type,
+                         GdkRectangle  *area,
+                         GtkWidget     *widget,
+                         const gchar   *detail,
+                         gint           x,
+                         gint           y,
+                         gint           width,
+                         gint           height)
+{
+  printf ("draw_flat_box: %s\n", detail);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_check (GtkStyle      *style,
+                      GdkWindow     *window,
+                      GtkStateType   state_type,
+                      GtkShadowType  shadow_type,
+                      GdkRectangle  *area,
+                      GtkWidget     *widget,
+                      const gchar   *detail,
+                      gint           x,
+                      gint           y,
+                      gint           width,
+                      gint           height)
+{
+  cairo_t *cr;
+  MnPalette *mn_palette;
+  MnState mn_state;
+  MnFlags mn_flags;
+  MnStyle *mn_style;
+
+  monet_params_init (style, window, state_type,
+                     &mn_style, &cr, &mn_state, &mn_flags, &mn_palette);
+
+  if (shadow_type == GTK_SHADOW_IN)
+    mn_flags |= MN_FLAGS_CHECKED;
+
+  mn_style_paint_check_box (mn_style, cr, x, y, width, height, mn_palette,
+                            mn_state, mn_flags);
+
+  cairo_destroy (cr);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_option (GtkStyle      *style,
+                       GdkWindow     *window,
+                       GtkStateType   state_type,
+                       GtkShadowType  shadow_type,
+                       GdkRectangle  *area,
+                       GtkWidget     *widget,
+                       const gchar   *detail,
+                       gint           x,
+                       gint           y,
+                       gint           width,
+                       gint           height)
+{
+  cairo_t *cr;
+  MnPalette *mn_palette;
+  MnState mn_state;
+  MnFlags mn_flags;
+  MnStyle *mn_style;
+
+  monet_params_init (style, window, state_type,
+                     &mn_style, &cr, &mn_state, &mn_flags, &mn_palette);
+
+  if (shadow_type == GTK_SHADOW_IN)
+    mn_flags |= MN_FLAGS_CHECKED;
+
+  mn_style_paint_radio_button (mn_style, cr, x, y, width, height, mn_palette,
+                               mn_state, mn_flags);
+
+  cairo_destroy (cr);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_tab (GtkStyle        *style,
+               GdkWindow       *window,
+               GtkStateType     state_type,
+               GtkShadowType    shadow_type,
+               GdkRectangle    *area,
+               GtkWidget       *widget,
+               const gchar     *detail,
+               gint             x,
+               gint             y,
+               gint             width,
+               gint             height)
+{
+  monet_gtk_style_parent_class->draw_tab (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_shadow_gap (GtkStyle        *style,
+                           GdkWindow       *window,
+                           GtkStateType     state_type,
+                           GtkShadowType    shadow_type,
+                           GdkRectangle    *area,
+                           GtkWidget       *widget,
+                           const gchar     *detail,
+                           gint             x,
+                           gint             y,
+                           gint             width,
+                           gint             height,
+                           GtkPositionType  gap_side,
+                           gint             gap_x,
+                           gint             gap_width)
+{
+  monet_gtk_style_parent_class->draw_shadow_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_box_gap(GtkStyle        *style,
+                       GdkWindow       *window,
+                       GtkStateType     state_type,
+                       GtkShadowType    shadow_type,
+                       GdkRectangle    *area,
+                       GtkWidget       *widget,
+                       const gchar     *detail,
+                       gint             x,
+                       gint             y,
+                       gint             width,
+                       gint             height,
+                       GtkPositionType  gap_side,
+                       gint             gap_x,
+                       gint             gap_width)
+{
+  monet_gtk_style_parent_class->draw_shadow_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_extension (GtkStyle        *style,
+                          GdkWindow       *window,
+                          GtkStateType     state_type,
+                          GtkShadowType    shadow_type,
+                          GdkRectangle    *area,
+                          GtkWidget       *widget,
+                          const gchar     *detail,
+                          gint             x,
+                          gint             y,
+                          gint             width,
+                          gint             height,
+                          GtkPositionType  gap_side)
+{
+  monet_gtk_style_parent_class->draw_extension (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_focus (GtkStyle     *style,
+                      GdkWindow    *window,
+                      GtkStateType  state_type,
+                      GdkRectangle *area,
+                      GtkWidget    *widget,
+                      const gchar  *detail,
+                      gint          x,
+                      gint          y,
+                      gint          width,
+                      gint          height)
+{
+  monet_gtk_style_parent_class->draw_focus (style, window, state_type, area, widget, detail, x, y, width, height);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_slider (GtkStyle       *style,
+                       GdkWindow      *window,
+                       GtkStateType    state_type,
+                       GtkShadowType   shadow_type,
+                       GdkRectangle   *area,
+                       GtkWidget      *widget,
+                       const gchar    *detail,
+                       gint            x,
+                       gint            y,
+                       gint            width,
+                       gint            height,
+                       GtkOrientation  orientation)
+{
+  monet_gtk_style_parent_class->draw_slider (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_handle (GtkStyle       *style,
+                       GdkWindow      *window,
+                       GtkStateType    state_type,
+                       GtkShadowType   shadow_type,
+                       GdkRectangle   *area,
+                       GtkWidget      *widget,
+                       const gchar    *detail,
+                       gint            x,
+                       gint            y,
+                       gint            width,
+                       gint            height,
+                       GtkOrientation  orientation)
+{
+  monet_gtk_style_parent_class->draw_handle (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_expander (GtkStyle         *style,
+                         GdkWindow        *window,
+                         GtkStateType      state_type,
+                         GdkRectangle     *area,
+                         GtkWidget        *widget,
+                         const gchar      *detail,
+                         gint              x,
+                         gint              y,
+                         GtkExpanderStyle  expander_style)
+{
+  monet_gtk_style_parent_class->draw_expander (style, window, state_type, area, widget, detail, x, y, expander_style);
+}
+/*##################################*/
+
+static void
+monet_gtk_draw_resize_grip (GtkStyle      *style,
+                            GdkWindow     *window,
+                            GtkStateType   state_type,
+                            GdkRectangle  *area,
+                            GtkWidget     *widget,
+                            const gchar   *detail,
+                            GdkWindowEdge  edge,
+                            gint           x,
+                            gint           y,
+                            gint           width,
+                            gint           height)
+{
+  monet_gtk_style_parent_class->draw_resize_grip (style, window, state_type, area, widget, detail, edge, x, y, width, height);
+}
+
+
+static void
+monet_gtk_style_class_init (MonetGtkStyleClass * klass)
+{
+  GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
+
+  monet_gtk_style_parent_class = g_type_class_peek_parent (klass);
+
+  /* All functions that have prototypes here are not commented out. */
+  style_class->draw_hline       = monet_gtk_draw_hline;
+  style_class->draw_vline       = monet_gtk_draw_vline;
+  style_class->draw_shadow      = monet_gtk_draw_shadow;
+  style_class->draw_arrow       = monet_gtk_draw_arrow;
+  style_class->draw_box         = monet_gtk_draw_box;
+  style_class->draw_flat_box    = monet_gtk_draw_flat_box;
+  style_class->draw_check       = monet_gtk_draw_check;
+  style_class->draw_option      = monet_gtk_draw_option;
+  style_class->draw_tab         = monet_gtk_draw_tab;
+  style_class->draw_shadow_gap  = monet_gtk_draw_shadow_gap;
+  style_class->draw_box_gap     = monet_gtk_draw_box_gap;
+  style_class->draw_extension   = monet_gtk_draw_extension;
+  style_class->draw_focus       = monet_gtk_draw_focus;
+  style_class->draw_slider      = monet_gtk_draw_slider;
+  style_class->draw_handle      = monet_gtk_draw_handle;
+  style_class->draw_expander    = monet_gtk_draw_expander;
+  style_class->draw_resize_grip = monet_gtk_draw_resize_grip;
+  /*style_class->render_icon      = monet_gtk_render_icon;
+  style_class->draw_layout      = monet_gtk_draw_layout; */
+
+  /* There are some more functions in GtkStyleClass that may be overridden.
+   * See gtkstyle.h in the GTK+ sources for a list and help for most of them. */
+}
+
+static void
+monet_gtk_style_init (GObject *self)
+{
+  GError *err = NULL;
+
+  MonetGtkStyle *mn_gtk = MONET_GTK_STYLE (self);
+
+  mn_gtk->mn_style = mn_style_new ();
+
+  mn_style_load_config (mn_gtk->mn_style, THEMEDIR"/monetrc", &err);
+
+  if (err)
+    {
+      g_warning ("Error loading theme config: %s", err->message);
+
+      g_error_free (err);
+    }
+}
+
+void
+monet_gtk_style_register_type (GTypeModule * module)
+{
+  if (!monet_gtk_type_style) {
+    static const GTypeInfo object_info =
+    {
+      sizeof (MonetGtkStyleClass),
+      (GBaseInitFunc) NULL,
+      (GBaseFinalizeFunc) NULL,
+      (GClassInitFunc) monet_gtk_style_class_init,
+      NULL,     /* class_finalize */
+      NULL,     /* class_data */
+      sizeof (MonetGtkStyle),
+      0,        /* n_preallocs */
+      (GInstanceInitFunc) monet_gtk_style_init,
+      NULL
+    };
+
+    monet_gtk_type_style = g_type_module_register_type (module,
+                                                        GTK_TYPE_STYLE,
+                                                        "MonetGtkStyle",
+                                                        &object_info, 0);
+  }
+}
diff --git a/monet-gtk/style.h b/monet-gtk/style.h
new file mode 100644
index 0000000..19b2c5c
--- /dev/null
+++ b/monet-gtk/style.h
@@ -0,0 +1,50 @@
+/*  monet_gtk GTK engine: style.h
+ *
+ *  Copyright (C) 2008  Benjamin Berg <benjamin sipsolutions net>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <gtk/gtkstyle.h>
+
+#include <monet/monet.h>
+
+typedef struct _MonetGtkStyle MonetGtkStyle;
+typedef struct _MonetGtkStyleClass MonetGtkStyleClass;
+
+
+GType monet_gtk_type_style G_GNUC_INTERNAL;
+
+#define MONET_GTK_TYPE_STYLE              monet_gtk_type_style
+#define MONET_GTK_STYLE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MONET_GTK_TYPE_STYLE, MonetGtkStyle))
+#define MONET_GTK_STYLE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MONET_GTK_TYPE_STYLE, MonetGtkStyleClass))
+#define MONET_GTK_IS_STYLE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MONET_GTK_TYPE_STYLE))
+#define MONET_GTK_IS_STYLE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MONET_GTK_TYPE_STYLE))
+#define MONET_GTK_STYLE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MONET_GTK_TYPE_STYLE, MonetGtkStyleClass))
+
+struct _MonetGtkStyle
+{
+  GtkStyle parent_instance;
+
+  MnStyle *mn_style;
+};
+
+struct _MonetGtkStyleClass
+{
+  GtkStyleClass parent_class;
+};
+
+void monet_gtk_style_register_type (GTypeModule *module) G_GNUC_INTERNAL;
+
diff --git a/monet/Makefile.am b/monet/Makefile.am
index 47f2a16..6e82675 100644
--- a/monet/Makefile.am
+++ b/monet/Makefile.am
@@ -14,20 +14,22 @@ STAMP_FILES = \
 source_h = \
 	mn-color.h \
 	mn-palette.h \
-	mn-parts.h \
-	mn-theme-engine.h \
+	mn-style.h \
 	mn-types.h \
-	mn-widget.h \
-	widgets/mn-button.h \
 	monet.h
 
+source_c = \
+	mn-color.c	 \
+	mn-style.c	 \
+	mn-palette.c	 \
+	monet.c
+
 source_h_priv = mn-private.h
 
 mn-enum-types.h: stamp-mn-enum-types.h Makefile
 	@true
 
-# glib-mkenums seems really picky about how it parses files...
-enum_source_h = mn-types.h mn-parts.h
+enum_source_h = mn-types.h
 stamp-mn-enum-types.h: $(source_h) mn-enum-types.h.in
 	( cd $(srcdir) && \
 	  $(GLIB_MKENUMS) \
@@ -72,12 +74,7 @@ libmonet_la_SOURCES = \
 	$(BUILT_SOURCES) \
 	$(source_h)	 \
 	$(source_h_priv) \
-	mn-color.c	 \
-	mn-palette.c	 \
-	mn-theme-engine.c\
-	mn-widget.c	 \
-	widgets/mn-button.c \
-	monet.c
+	$(source_c)
 
 libmonet_la_LIBADD = $(MONET_LIBS)
 
diff --git a/monet/mn-color.c b/monet/mn-color.c
index 1add978..2cea38c 100644
--- a/monet/mn-color.c
+++ b/monet/mn-color.c
@@ -414,6 +414,32 @@ mn_color_from_string (MnColor *color,
 
               return TRUE;
             }
+          else if (strlen (str) == 7)
+            {
+              /* #rrggbbaa */
+              color->red   = (result >> 16) & 0xff;
+              color->green = (result >>  8) & 0xff;
+              color->blue  = result & 0xff;
+
+              color->alpha = 0xff;
+
+              return TRUE;
+            }
+          else if (strlen (str) == 4)
+            {
+              /* #rgba */
+              color->red   = ((result >> 8) & 0xf);
+              color->green = ((result >> 4) & 0xf);
+              color->blue  = result & 0xf;
+
+              color->red   = (color->red   << 4) | color->red;
+              color->green = (color->green << 4) | color->green;
+              color->blue  = (color->blue  << 4) | color->blue;
+
+             color->alpha = 0xff;
+
+              return TRUE;
+            }
         }
     }
 
diff --git a/monet/mn-color.h b/monet/mn-color.h
index cd0a3f0..5daf38c 100644
--- a/monet/mn-color.h
+++ b/monet/mn-color.h
@@ -78,7 +78,7 @@ void          mn_color_shade       (const MnColor *color,
 
 gchar *       mn_color_to_string   (const MnColor *color);
 gboolean      mn_color_from_string (MnColor       *color,
-                                    const gchar        *str);
+                                    const gchar   *str);
 
 void          mn_color_to_hls      (const MnColor *color,
                                     gfloat             *hue,
diff --git a/monet/mn-palette.c b/monet/mn-palette.c
index 62a70df..5385e51 100644
--- a/monet/mn-palette.c
+++ b/monet/mn-palette.c
@@ -30,6 +30,8 @@ struct _MnPalette
   MnColor highlight_fg_colors[4];
   MnColor highlight_bg_colors[4];
   MnColor border_colors[4];
+
+  guint32 colors_set;
 };
 
 MnPalette *
@@ -51,20 +53,35 @@ mn_palette_get_color (MnPalette      *palette,
 {
   switch (index)
     {
-    case MN_FG_COLOR:
-      return &palette->fg_colors[state];
+    case MN_COLOR_FG:
+      if (palette->colors_set & (1 << (index * 4 + state)))
+        return &palette->fg_colors[state];
+      else
+        return &palette->fg_colors[MN_STATE_NORMAL];
 
-    case MN_BG_COLOR:
-      return &palette->bg_colors[state];
+    case MN_COLOR_BG:
+      if (palette->colors_set & (1 << (index * 4 + state)))
+        return &palette->bg_colors[state];
+      else
+        return &palette->bg_colors[MN_STATE_NORMAL];
 
-    case MN_HIGHLIGHT_BG_COLOR:
-      return &palette->highlight_bg_colors[state];
+    case MN_COLOR_HIGHLIGHT_BG:
+      if (palette->colors_set & (1 << (index * 4 + state)))
+        return &palette->highlight_bg_colors[state];
+      else
+        return &palette->highlight_bg_colors[state];
 
-    case MN_HIGHLIGHT_FG_COLOR:
-      return &palette->highlight_fg_colors[state];
+    case MN_COLOR_HIGHLIGHT_FG:
+      if (palette->colors_set & (1 << (index * 4 + state)))
+        return &palette->highlight_fg_colors[state];
+      else
+        return &palette->highlight_fg_colors[MN_STATE_NORMAL];
 
-    case MN_BORDER_COLOR:
-      return &palette->border_colors[state];
+    case MN_COLOR_BORDER:
+      if (palette->colors_set & (1 << (index * 4 + state)))
+        return &palette->border_colors[state];
+      else
+        return &palette->border_colors[MN_STATE_NORMAL];
 
     default:
       return NULL;
@@ -77,26 +94,49 @@ mn_palette_set_color (MnPalette      *palette,
                       MnState         state,
                       const MnColor   *color)
 {
+
+  palette->colors_set |= (1 << (index * 4 + state));
+
   switch (index)
     {
-    case MN_FG_COLOR:
+    case MN_COLOR_FG:
       palette->fg_colors[state] = *color;
       break;
 
-    case MN_BG_COLOR:
+    case MN_COLOR_BG:
       palette->bg_colors[state] = *color;
       break;
 
-    case MN_HIGHLIGHT_BG_COLOR:
+    case MN_COLOR_HIGHLIGHT_BG:
       palette->highlight_bg_colors[state] = *color;
       break;
 
-    case MN_HIGHLIGHT_FG_COLOR:
+    case MN_COLOR_HIGHLIGHT_FG:
       palette->highlight_fg_colors[state] = *color;
       break;
 
-    case MN_BORDER_COLOR:
+    case MN_COLOR_BORDER:
       palette->border_colors[state] = *color;
       break;
     }
 }
+
+void
+mn_cairo_set_source_from_palette (cairo_t  *cr,
+                                  MnPalette *palette,
+                                  MnPaletteIndex index,
+                                  MnState state)
+{
+  const MnColor *color;
+
+  g_return_if_fail (palette != NULL);
+
+  color = mn_palette_get_color (palette, index, state);
+
+  cairo_set_source_rgba (cr,
+                         color->red / 255.0,
+                         color->green / 255.0,
+                         color->blue / 255.0,
+                         color->alpha / 255.0);
+}
+
diff --git a/monet/mn-palette.h b/monet/mn-palette.h
index 69bd5f2..a50b82a 100644
--- a/monet/mn-palette.h
+++ b/monet/mn-palette.h
@@ -27,16 +27,18 @@
 #include "mn-color.h"
 #include "mn-types.h"
 
+#include <cairo/cairo.h>
+
 typedef struct _MnPalette MnPalette;
 typedef enum _MnPaletteIndex MnPaletteIndex;
 
 enum _MnPaletteIndex
 {
-  MN_BG_COLOR,
-  MN_FG_COLOR,
-  MN_HIGHLIGHT_BG_COLOR,
-  MN_HIGHLIGHT_FG_COLOR,
-  MN_BORDER_COLOR
+  MN_COLOR_BG,
+  MN_COLOR_FG,
+  MN_COLOR_HIGHLIGHT_BG,
+  MN_COLOR_HIGHLIGHT_FG,
+  MN_COLOR_BORDER
 };
 
 
@@ -51,5 +53,9 @@ void             mn_palette_set_color (MnPalette      *palette,
                                        MnPaletteIndex  index,
                                        MnState         state,
                                        const MnColor  *color);
+void mn_cairo_set_source_from_palette (cairo_t        *cr,
+                                       MnPalette      *palette,
+                                       MnPaletteIndex  index,
+                                       MnState         state);
 
 #endif /* MN_PALETTE_H */
diff --git a/monet/mn-style.c b/monet/mn-style.c
new file mode 100644
index 0000000..01b9d3b
--- /dev/null
+++ b/monet/mn-style.c
@@ -0,0 +1,563 @@
+/*
+ * Copyright 2010 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
+ * USA
+ *
+ * Author: Thomas Wood <thos gnome org>
+ */
+
+#include "mn-style.h"
+
+#include <math.h>
+#include <string.h>
+
+G_DEFINE_TYPE (MnStyle, mn_style, G_TYPE_OBJECT)
+
+#define STYLE_PRIVATE(o) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), MN_TYPE_STYLE, MnStylePrivate))
+
+struct _MnStylePrivate
+{
+  GHashTable *colors;
+};
+
+
+static void
+mn_style_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_style_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_style_dispose (GObject *object)
+{
+  G_OBJECT_CLASS (mn_style_parent_class)->dispose (object);
+}
+
+static void
+mn_style_finalize (GObject *object)
+{
+
+  MnStylePrivate *priv = MN_STYLE (object)->priv;
+
+  g_hash_table_destroy (priv->colors);
+
+  G_OBJECT_CLASS (mn_style_parent_class)->finalize (object);
+}
+
+static void
+mn_style_class_init (MnStyleClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (MnStylePrivate));
+
+  object_class->get_property = mn_style_get_property;
+  object_class->set_property = mn_style_set_property;
+  object_class->dispose = mn_style_dispose;
+  object_class->finalize = mn_style_finalize;
+}
+
+static void
+mn_style_init (MnStyle *self)
+{
+  self->priv = STYLE_PRIVATE (self);
+
+  self->priv->colors = g_hash_table_new_full (g_str_hash,
+                                              g_str_equal,
+                                              g_free,
+                                              (GDestroyNotify) mn_palette_free);
+}
+
+static MnPalette*
+mn_style_find_colors (MnStyle     *style,
+                      const gchar *paint,
+                      MnPalette   *colors)
+{
+  /* if colors is NULL, find the colours for the paint function */
+  if (!colors)
+    {
+      colors = g_hash_table_lookup (style->priv->colors, paint);
+
+      if (!colors)
+        {
+          g_warning ("No colors specified for %ss", paint);
+
+          /* returns a new transparent palette! */
+
+          return mn_palette_new ();
+        }
+
+    }
+  return colors;
+}
+
+MnStyle *
+mn_style_new (void)
+{
+  return g_object_new (MN_TYPE_STYLE, NULL);
+}
+
+gboolean
+mn_style_load_config (MnStyle      *style,
+                      const gchar  *filename,
+                      GError      **error)
+{
+  MnStylePrivate *priv = style->priv;
+  GKeyFile *file;
+  GError *err = NULL;
+  gchar **groups, **g;
+  GHashTable *symbolic_colors;
+
+  file = g_key_file_new ();
+  g_key_file_load_from_file (file, filename, 0, &err);
+
+  if (err)
+    {
+      g_propagate_error (error, err);
+
+      return FALSE;
+    }
+
+  symbolic_colors = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+                                           (GDestroyNotify) mn_color_free);
+
+  groups = g_key_file_get_groups (file, NULL);
+
+  for (g = groups; *g; g++)
+    {
+      gchar **keys, **k;
+      MnPalette *palette;
+
+      /* load symbolic colors */
+      if (!strcmp (*g, "colors"))
+        {
+          keys = g_key_file_get_keys (file, *g, NULL, &err);
+
+          if (err)
+            {
+              g_propagate_error (error, err);
+
+              g_strfreev (groups);
+              g_hash_table_destroy (symbolic_colors);
+              return FALSE;
+            }
+
+          for (k = keys; *k; k++)
+           {
+             MnColor color;
+             gchar *value;
+
+             value = g_key_file_get_string (file, *g, *k, NULL);
+
+             if (!value || !mn_color_from_string (&color, value))
+               {
+                 g_warning ("Could not parse value of symbolic color \"%s\"",
+                            *k);
+                 continue;
+               }
+
+             g_hash_table_insert (symbolic_colors, *k, mn_color_copy (&color));
+           }
+
+
+          /* done loading symbolics colours, so go to the next group */
+          continue;
+        }
+
+      palette = g_hash_table_lookup (priv->colors, *g);
+
+      if (!palette)
+        {
+          g_debug ("Adding hash table for %s", *g);
+
+          palette = mn_palette_new ();
+          g_hash_table_insert (priv->colors, g_strdup (*g), palette);
+        }
+
+      keys = g_key_file_get_keys (file, *g, NULL, &err);
+
+      if (err)
+        {
+          g_propagate_error (error, err);
+
+          g_strfreev (groups);
+          g_hash_table_destroy (symbolic_colors);
+          return FALSE;
+        }
+
+      for (k = keys; *k; k++)
+        {
+          gchar **split, *value;
+          MnState state = MN_STATE_NORMAL;
+          MnPaletteIndex pindex;
+          MnColor color;
+
+
+          split = g_strsplit (*k, ":", 2);
+
+          /* find the colour name */
+          if (!strcmp (split[0], "bg"))
+            pindex = MN_COLOR_BG;
+          else if (!strcmp (split[0], "fg"))
+            pindex = MN_COLOR_FG;
+          else if (!strcmp (split[0], "highlight-fg"))
+            pindex = MN_COLOR_HIGHLIGHT_FG;
+          else if (!strcmp (split[0], "highlight-bg"))
+            pindex = MN_COLOR_HIGHLIGHT_BG;
+          else if (!strcmp (split[0], "border"))
+            pindex = MN_COLOR_BORDER;
+          else
+            {
+              g_warning ("Unknown colour \"%s\" for \"%s\"", *k, *g);
+              g_strfreev (split);
+              continue;
+            }
+
+          /* see if there is a state flag */
+          if (split[1] != NULL)
+            {
+              gchar *s = split[1];
+
+              switch (s[0])
+                {
+                case 'h': /* "hover" */
+                  state = MN_STATE_HOVER;
+                  break;
+                case 'a': /* "active" */
+                  state = MN_STATE_ACTIVE;
+                  break;
+                case 'd': /* "disabled" */
+                  state = MN_STATE_DISABLED;
+                  break;
+                }
+            }
+
+          g_strfreev (split);
+          split = NULL;
+
+          value = g_key_file_get_string (file, *g, *k, &err);
+          if (err)
+            {
+              g_propagate_error (error, err);
+
+              g_strfreev (groups);
+              g_strfreev (keys);
+              g_hash_table_destroy (symbolic_colors);
+
+              return FALSE;
+            }
+
+          if (value[0] == '@')
+            {
+              MnColor *c;
+
+              /* symbolic color */
+              c = g_hash_table_lookup (symbolic_colors, value + 1);
+              if (!c)
+                {
+                  g_warning ("Could not find symbolic color \"%s\"", value + 1);
+                  continue;
+                }
+              else
+                color = *c;
+            }
+          else if (!mn_color_from_string (&color, value))
+            {
+              g_warning ("Could not parse \"%s\" as a color", value);
+              continue;
+            }
+
+          mn_palette_set_color (palette, pindex, state, &color);
+
+          g_debug ("Added %s color (%s) for %s", *k,
+                   mn_color_to_string (&color), *g);
+
+        }
+
+      g_strfreev (keys);
+
+    }
+
+  g_strfreev (groups);
+  g_hash_table_destroy (symbolic_colors);
+
+
+  return TRUE;
+}
+
+void
+mn_style_paint_entry (MnStyle   *style,
+                      cairo_t   *cr,
+                      gdouble    x,
+                      gdouble    y,
+                      gdouble    width,
+                      gdouble    height,
+                      MnPalette *colors,
+                      MnState    state,
+                      MnFlags    flags)
+{
+  cairo_save (cr);
+
+  colors = mn_style_find_colors (style, "entry", colors);
+
+  cairo_translate (cr, 0.5, 0.5);
+  width--; height--;
+  cairo_set_line_width (cr, 1.0);
+
+  cairo_rectangle (cr, x, y, width, height);
+
+  mn_cairo_set_source_from_palette (cr, colors, MN_COLOR_FG, state);
+
+  cairo_stroke (cr);
+
+  cairo_restore (cr);
+}
+
+void
+mn_style_paint_button (MnStyle   *style,
+                       cairo_t   *cr,
+                       gdouble    x,
+                       gdouble    y,
+                       gdouble    width,
+                       gdouble    height,
+                       MnPalette *colors,
+                       MnState    state,
+                       MnFlags    flags)
+{
+  cairo_save (cr);
+
+  cairo_translate (cr, 0.5, 0.5);
+  cairo_set_line_width (cr, 1.0);
+  width--; height--;
+
+  cairo_rectangle (cr, x, y, width, height);
+
+  colors = mn_style_find_colors (style, "button", colors);
+
+
+  mn_cairo_set_source_from_palette (cr, colors, MN_COLOR_BG, state);
+
+  cairo_fill_preserve (cr);
+
+  mn_cairo_set_source_from_palette (cr, colors, MN_COLOR_BORDER, state);
+
+  cairo_stroke (cr);
+
+  cairo_restore (cr);
+}
+
+void
+mn_style_paint_check_box (MnStyle   *style,
+                          cairo_t   *cr,
+                          gdouble    x,
+                          gdouble    y,
+                          gdouble    width,
+                          gdouble    height,
+                          MnPalette *colors,
+                          MnState    state,
+                          MnFlags    flags)
+{
+  cairo_save (cr);
+
+  colors = mn_style_find_colors (style, "check-box", colors);
+
+  cairo_translate (cr, 0.5, 0.5);
+  width--; height--;
+  cairo_set_line_width (cr, 1.0);
+
+  cairo_rectangle (cr, x, y, width, height);
+
+  mn_cairo_set_source_from_palette (cr, colors, MN_COLOR_BORDER, state);
+  cairo_stroke_preserve (cr);
+
+  mn_cairo_set_source_from_palette (cr, colors, MN_COLOR_BG, state);
+  cairo_stroke (cr);
+
+  if (flags & MN_FLAGS_CHECKED)
+    {
+      cairo_rectangle (cr, x + 2.5, y + 2.5, width - 5, height - 5);
+
+      mn_cairo_set_source_from_palette (cr, colors, MN_COLOR_FG,
+                                        state);
+
+      cairo_fill (cr);
+    }
+
+  cairo_restore (cr);
+}
+
+void
+mn_style_paint_radio_button (MnStyle   *style,
+                             cairo_t   *cr,
+                             gdouble    x,
+                             gdouble    y,
+                             gdouble    width,
+                             gdouble    height,
+                             MnPalette *colors,
+                             MnState    state,
+                             MnFlags    flags)
+{
+  cairo_save (cr);
+
+  colors = mn_style_find_colors (style, "radio-button", colors);
+
+  cairo_translate (cr, 0.5, 0.5);
+  width--; height--;
+  cairo_set_line_width (cr, 1.0);
+
+  cairo_arc (cr, x + width / 2.0, y + width / 2.0, width / 2.0, 0, 2 * M_PI);
+
+  mn_cairo_set_source_from_palette (cr, colors, MN_COLOR_BG, state);
+  cairo_fill_preserve (cr);
+
+  mn_cairo_set_source_from_palette (cr, colors, MN_COLOR_BORDER, state);
+  cairo_stroke (cr);
+
+  if (flags & MN_FLAGS_CHECKED)
+    {
+      cairo_arc (cr,
+                 x + width / 2.0,
+                 y + width / 2.0,
+                 width / 2.0 - 2.5, 0, 2 * M_PI);
+
+      mn_cairo_set_source_from_palette (cr, colors, MN_COLOR_FG,
+                                        state);
+
+      cairo_fill (cr);
+    }
+
+  cairo_restore (cr);
+}
+
+
+
+void
+mn_style_paint_scroll_bar (MnStyle   *style,
+                           cairo_t   *cr,
+                           gdouble    x,
+                           gdouble    y,
+                           gdouble    width,
+                           gdouble    height,
+                           MnPalette *colors,
+                           MnState    state,
+                           MnFlags    flags)
+{
+}
+
+void
+mn_style_paint_menu (MnStyle   *style,
+                     cairo_t   *cr,
+                     gdouble    x,
+                     gdouble    y,
+                     gdouble    width,
+                     gdouble    height,
+                     MnPalette *colors,
+                     MnState    state,
+                     MnFlags    flags)
+{
+  cairo_save (cr);
+
+  colors = mn_style_find_colors (style, "menu", colors);
+
+  cairo_translate (cr, 0.5, 0.5);
+  width--; height--;
+  cairo_set_line_width (cr, 1.0);
+
+  cairo_rectangle (cr, x, y, width, height);
+
+  mn_cairo_set_source_from_palette (cr, colors, MN_COLOR_BORDER, state);
+
+  cairo_stroke (cr);
+
+  cairo_restore (cr);
+}
+
+void
+mn_style_paint_menu_item (MnStyle   *style,
+                          cairo_t   *cr,
+                          gdouble    x,
+                          gdouble    y,
+                          gdouble    width,
+                          gdouble    height,
+                          MnPalette *colors,
+                          MnState    state,
+                          MnFlags    flags)
+{
+  cairo_save (cr);
+
+  colors = mn_style_find_colors (style, "menu-item", colors);
+
+  cairo_translate (cr, 0.5, 0.5);
+  width--; height--;
+  cairo_set_line_width (cr, 1.0);
+
+  cairo_rectangle (cr, x, y, width, height);
+
+  mn_cairo_set_source_from_palette (cr, colors, MN_COLOR_BORDER, state);
+
+  cairo_stroke (cr);
+
+  cairo_restore (cr);
+}
+
+void
+mn_style_paint_menu_bar (MnStyle   *style,
+                         cairo_t   *cr,
+                         gdouble    x,
+                         gdouble    y,
+                         gdouble    width,
+                         gdouble    height,
+                         MnPalette *colors,
+                         MnState    state,
+                         MnFlags    flags)
+{
+  cairo_save (cr);
+
+  colors = mn_style_find_colors (style, "menu-bar", colors);
+
+  cairo_translate (cr, 0.5, 0.5);
+  width--; height--;
+  cairo_set_line_width (cr, 1.0);
+
+  cairo_rectangle (cr, x, y, width, height);
+
+  mn_cairo_set_source_from_palette (cr, colors, MN_COLOR_BORDER, state);
+
+  cairo_stroke (cr);
+
+  cairo_restore (cr);
+}
diff --git a/monet/mn-style.h b/monet/mn-style.h
new file mode 100644
index 0000000..9fcf8fe
--- /dev/null
+++ b/monet/mn-style.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2010 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
+ * USA
+ *
+ * Author: Thomas Wood <thos gnome org>
+ */
+
+
+
+#ifndef _MN_STYLE_H
+#define _MN_STYLE_H
+
+#include "mn-palette.h"
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define MN_TYPE_STYLE mn_style_get_type()
+
+#define MN_STYLE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  MN_TYPE_STYLE, MnStyle))
+
+#define MN_STYLE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  MN_TYPE_STYLE, MnStyleClass))
+
+#define MN_IS_STYLE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  MN_TYPE_STYLE))
+
+#define MN_IS_STYLE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  MN_TYPE_STYLE))
+
+#define MN_STYLE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  MN_TYPE_STYLE, MnStyleClass))
+
+typedef struct _MnStyle MnStyle;
+typedef struct _MnStyleClass MnStyleClass;
+typedef struct _MnStylePrivate MnStylePrivate;
+
+struct _MnStyle
+{
+  GObject parent;
+
+  MnStylePrivate *priv;
+};
+
+struct _MnStyleClass
+{
+  GObjectClass parent_class;
+
+  void (*mn_style_paint_entry)        (MnStyle *style,
+                                       cairo_t   *cr,
+                                       gdouble    x,
+                                       gdouble    y,
+                                       gdouble    width,
+                                       gdouble    height,
+                                       MnPalette *colors,
+                                       MnState    state,
+                                       MnFlags    flags);
+  void (*mn_style_paint_button)       (MnStyle *style,
+                                       cairo_t   *cr,
+                                       gdouble    x,
+                                       gdouble    y,
+                                       gdouble    width,
+                                       gdouble    height,
+                                       MnPalette *colors,
+                                       MnState    state,
+                                       MnFlags    flags);
+  void (*mn_style_paint_menu)         (MnStyle *style,
+                                       cairo_t   *cr,
+                                       gdouble    x,
+                                       gdouble    y,
+                                       gdouble    width,
+                                       gdouble    height,
+                                       MnPalette *colors,
+                                       MnState    state,
+                                       MnFlags    flags);
+  void (*mn_style_paint_menu_bar)     (MnStyle *style,
+                                       cairo_t   *cr,
+                                       gdouble    x,
+                                       gdouble    y,
+                                       gdouble    width,
+                                       gdouble    height,
+                                       MnPalette *colors,
+                                       MnState    state,
+                                       MnFlags    flags);
+  void (*mn_style_paint_menu_item)    (MnStyle *style,
+                                       cairo_t   *cr,
+                                       gdouble    x,
+                                       gdouble    y,
+                                       gdouble    width,
+                                       gdouble    height,
+                                       MnPalette *colors,
+                                       MnState    state,
+                                       MnFlags    flags);
+  void (*mn_style_paint_radio_button) (MnStyle *style,
+                                       cairo_t   *cr,
+                                       gdouble    x,
+                                       gdouble    y,
+                                       gdouble    width,
+                                       gdouble    height,
+                                       MnPalette *colors,
+                                       MnState    state,
+                                       MnFlags    flags);
+  void (*mn_style_paint_check_box)    (MnStyle *style,
+                                       cairo_t   *cr,
+                                       gdouble    x,
+                                       gdouble    y,
+                                       gdouble    width,
+                                       gdouble    height,
+                                       MnPalette *colors,
+                                       MnState    state,
+                                       MnFlags    flags);
+  void (*mn_style_paint_scroll_bar)   (MnStyle *style,
+                                       cairo_t   *cr,
+                                       gdouble    x,
+                                       gdouble    y,
+                                       gdouble    width,
+                                       gdouble    height,
+                                       MnPalette *colors,
+                                       MnState    state,
+                                       MnFlags    flags);
+
+
+};
+
+GType mn_style_get_type (void) G_GNUC_CONST;
+
+MnStyle *mn_style_new (void);
+
+gboolean mn_style_load_config    (MnStyle      *style,
+                                  const gchar  *filename,
+                                  GError      **error);
+
+
+void mn_style_paint_entry        (MnStyle *style,
+                                  cairo_t   *cr,
+                                  gdouble    x,
+                                  gdouble    y,
+                                  gdouble    width,
+                                  gdouble    height,
+                                  MnPalette *colors,
+                                  MnState    state,
+                                  MnFlags    flags);
+void mn_style_paint_button       (MnStyle *style,
+                                  cairo_t   *cr,
+                                  gdouble    x,
+                                  gdouble    y,
+                                  gdouble    width,
+                                  gdouble    height,
+                                  MnPalette *colors,
+                                  MnState    state,
+                                  MnFlags    flags);
+void mn_style_paint_menu         (MnStyle *style,
+                                  cairo_t   *cr,
+                                  gdouble    x,
+                                  gdouble    y,
+                                  gdouble    width,
+                                  gdouble    height,
+                                  MnPalette *colors,
+                                  MnState    state,
+                                  MnFlags    flags);
+void mn_style_paint_menu_bar     (MnStyle *style,
+                                  cairo_t   *cr,
+                                  gdouble    x,
+                                  gdouble    y,
+                                  gdouble    width,
+                                  gdouble    height,
+                                  MnPalette *colors,
+                                  MnState    state,
+                                  MnFlags    flags);
+void mn_style_paint_menu_item    (MnStyle *style,
+                                  cairo_t   *cr,
+                                  gdouble    x,
+                                  gdouble    y,
+                                  gdouble    width,
+                                  gdouble    height,
+                                  MnPalette *colors,
+                                  MnState    state,
+                                  MnFlags    flags);
+void mn_style_paint_radio_button (MnStyle *style,
+                                  cairo_t   *cr,
+                                  gdouble    x,
+                                  gdouble    y,
+                                  gdouble    width,
+                                  gdouble    height,
+                                  MnPalette *colors,
+                                  MnState    state,
+                                  MnFlags    flags);
+void mn_style_paint_check_box    (MnStyle *style,
+                                  cairo_t   *cr,
+                                  gdouble    x,
+                                  gdouble    y,
+                                  gdouble    width,
+                                  gdouble    height,
+                                  MnPalette *colors,
+                                  MnState    state,
+                                  MnFlags    flags);
+void mn_style_paint_scroll_bar   (MnStyle *style,
+                                  cairo_t   *cr,
+                                  gdouble    x,
+                                  gdouble    y,
+                                  gdouble    width,
+                                  gdouble    height,
+                                  MnPalette *colors,
+                                  MnState    state,
+                                  MnFlags    flags);
+
+
+
+G_END_DECLS
+
+#endif /* _MN_STYLE_H */
diff --git a/monet/mn-types.h b/monet/mn-types.h
index 66993be..774354a 100644
--- a/monet/mn-types.h
+++ b/monet/mn-types.h
@@ -35,7 +35,8 @@ typedef enum
 typedef enum
 {
   MN_FLAGS_FOCUS    = 1 << 0,
-  MN_FLAGS_CHECKED  = 1 << 1
+  MN_FLAGS_CHECKED  = 1 << 1,
+  MN_FLAGS_SELECTED = 1 << 2
 } MnFlags;
 
 typedef struct
diff --git a/monet/monet.h b/monet/monet.h
index 60d0964..0b25269 100644
--- a/monet/monet.h
+++ b/monet/monet.h
@@ -30,11 +30,9 @@
 #include <monet/mn-color.h>
 #include <monet/mn-enum-types.h>
 #include <monet/mn-marshal.h>
-#include <monet/mn-parts.h>
 #include <monet/mn-types.h>
-#include <monet/mn-widget.h>
-#include <monet/mn-theme-engine.h>
 #include <monet/mn-palette.h>
+#include <monet/mn-style.h>
 
 #undef MONET_H_INSIDE
 



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