[gimp/gtk3-port: 135/232] Port theme and gtkrc file loading to CSS files using GtkCssProvider



commit 772eabb1f3a2eed7038c3d9b400621c2a2415564
Author: Michael Natterer <mitch gimp org>
Date:   Wed Dec 29 15:16:23 2010 +0100

    Port theme and gtkrc file loading to CSS files using GtkCssProvider

 app/gui/themes.c |  192 ++++++++++++++++++++----------------------------------
 libgimp/gimpui.c |   40 +++++++++---
 2 files changed, 102 insertions(+), 130 deletions(-)
---
diff --git a/app/gui/themes.c b/app/gui/themes.c
index e449c83..54cf671 100644
--- a/app/gui/themes.c
+++ b/app/gui/themes.c
@@ -52,21 +52,11 @@ static void   themes_theme_change_notify (GimpGuiConfig          *config,
                                           GParamSpec             *pspec,
                                           Gimp                   *gimp);
 
-static void   themes_draw_layout         (GtkStyle               *style,
-                                          GdkWindow              *window,
-                                          GtkStateType            state_type,
-                                          gboolean                use_text,
-                                          GdkRectangle           *area,
-                                          GtkWidget              *widget,
-                                          const gchar            *detail,
-                                          gint                    x,
-                                          gint                    y,
-                                          PangoLayout            *layout);
 
 /*  private variables  */
 
-static GHashTable *themes_hash             = NULL;
-static gpointer    pixbuf_style_type_class = NULL;
+static GHashTable       *themes_hash           = NULL;
+static GtkStyleProvider *themes_style_provider = NULL;
 
 
 /*  public functions  */
@@ -75,27 +65,9 @@ void
 themes_init (Gimp *gimp)
 {
   GimpGuiConfig *config;
-  gchar         *themerc;
 
   g_return_if_fail (GIMP_IS_GIMP (gimp));
 
-  /* This is a "quick'n dirty" trick to get appropriate colors for
-   * themes in GTK+2, and in particular dark themes which would display
-   * insensitive items with a barely readable layout.
-   * This piece of code partly duplicates code from GTK+2 (slightly
-   * modified to get readable insensitive items) and will likely have to
-   * be removed for GIMP 3.
-   * See https://bugzilla.gnome.org/show_bug.cgi?id=770424
-   */
-  if (g_type_from_name ("PixbufStyle"))
-    {
-      pixbuf_style_type_class = g_type_class_ref (g_type_from_name ("PixbufStyle"));
-      if (pixbuf_style_type_class)
-        {
-          GTK_STYLE_CLASS (pixbuf_style_type_class)->draw_layout = themes_draw_layout;
-        }
-    }
-
   config = GIMP_GUI_CONFIG (gimp->config);
 
   themes_hash = g_hash_table_new_full (g_str_hash,
@@ -159,15 +131,27 @@ themes_init (Gimp *gimp)
       g_list_free_full (path, (GDestroyNotify) g_object_unref);
     }
 
-  themes_apply_theme (gimp, config->theme);
 
-  themerc = gimp_personal_rc_file ("themerc");
-  gtk_rc_parse (themerc);
-  g_free (themerc);
+  g_object_set (gtk_settings_get_for_screen (gdk_screen_get_default ()),
+                "gtk-application-prefer-dark-theme", TRUE,
+                NULL);
+
+  themes_style_provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
+
+  /*  Use GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1 so theme files
+   *  override default styles provided by widgets themselves.
+   */
+  gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
+                                             themes_style_provider,
+                                             GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1);
+
+  g_object_unref (themes_style_provider);
 
   g_signal_connect (config, "notify::theme",
                     G_CALLBACK (themes_theme_change_notify),
                     gimp);
+
+  themes_theme_change_notify (config, NULL, gimp);
 }
 
 void
@@ -184,11 +168,8 @@ themes_exit (Gimp *gimp)
       g_hash_table_destroy (themes_hash);
       themes_hash = NULL;
     }
-  if (pixbuf_style_type_class)
-    {
-      g_type_class_unref (pixbuf_style_type_class);
-      pixbuf_style_type_class = NULL;
-    }
+
+  g_clear_object (&themes_style_provider);
 }
 
 gchar **
@@ -292,18 +273,18 @@ static void
 themes_apply_theme (Gimp        *gimp,
                     const gchar *theme_name)
 {
-  GFile         *themerc;
+  GFile         *theme_css;
   GOutputStream *output;
   GError        *error = NULL;
 
   g_return_if_fail (GIMP_IS_GIMP (gimp));
 
-  themerc = gimp_directory_file ("themerc", NULL);
+  theme_css = gimp_directory_file ("theme.css", NULL);
 
   if (gimp->be_verbose)
-    g_print ("Writing '%s'\n", gimp_file_get_utf8_name (themerc));
+    g_print ("Writing '%s'\n", gimp_file_get_utf8_name (theme_css));
 
-  output = G_OUTPUT_STREAM (g_file_replace (themerc,
+  output = G_OUTPUT_STREAM (g_file_replace (theme_css,
                                             NULL, FALSE, G_FILE_CREATE_NONE,
                                             NULL, &error));
   if (! output)
@@ -314,63 +295,67 @@ themes_apply_theme (Gimp        *gimp,
   else
     {
       GFile *theme_dir = themes_get_theme_dir (gimp, theme_name);
-      GFile *gtkrc_theme;
-      GFile *gtkrc_user;
-      gchar *esc_gtkrc_theme;
-      gchar *esc_gtkrc_user;
+      GFile *css_theme;
+      GFile *css_user;
+      gchar *esc_css_theme;
+      gchar *esc_css_user;
       gchar *tmp;
 
       if (theme_dir)
         {
-          gtkrc_theme = g_file_get_child (theme_dir, "gtkrc");
+          css_theme = g_file_get_child (theme_dir, "gimp.css");
         }
       else
         {
-          /*  get the hardcoded default theme gtkrc  */
-          gtkrc_theme = g_file_new_for_path (gimp_gtkrc ());
+          tmp = g_build_filename (gimp_data_directory (),
+                                  "themes", "Default", "gimp.css",
+                                  NULL);
+          css_theme = g_file_new_for_path (tmp);
+          g_free (tmp);
         }
 
-      gtkrc_user = gimp_directory_file ("gtkrc", NULL);
+      css_user = gimp_directory_file ("gimp.css", NULL);
 
-      tmp = g_file_get_path (gtkrc_theme);
-      esc_gtkrc_theme = g_strescape (tmp, NULL);
+      tmp = g_file_get_path (css_theme);
+      esc_css_theme = g_strescape (tmp, NULL);
       g_free (tmp);
 
-      tmp = g_file_get_path (gtkrc_user);
-      esc_gtkrc_user = g_strescape (tmp, NULL);
+      tmp = g_file_get_path (css_user);
+      esc_css_user = g_strescape (tmp, NULL);
       g_free (tmp);
 
       if (! g_output_stream_printf
             (output, NULL, NULL, &error,
-             "# GIMP themerc\n"
-             "#\n"
-             "# This file is written on GIMP startup and on every theme change.\n"
-             "# It is NOT supposed to be edited manually. Edit your personal\n"
-             "# gtkrc file instead (%s).\n"
+             "/* GIMP theme.css\n"
+             " *\n"
+             " * This file is written on GIMP startup and on every theme change.\n"
+             " * It is NOT supposed to be edited manually. Edit your personal\n"
+             " * gimp.css file instead (%s).\n"
+             " */\n"
              "\n"
-             "include \"%s\"\n"
-             "include \"%s\"\n"
+             "@import url(\"%s\");\n"
+             "@import url(\"%s\");\n"
              "\n"
-             "# end of themerc\n",
-             gimp_file_get_utf8_name (gtkrc_user),
-             esc_gtkrc_theme,
-             esc_gtkrc_user) ||
+             "/* end of theme.css */\n",
+             gimp_file_get_utf8_name (css_user),
+             esc_css_theme,
+             esc_css_user) ||
           ! g_output_stream_close (output, NULL, &error))
         {
           gimp_message (gimp, NULL, GIMP_MESSAGE_ERROR,
                         _("Error writing '%s': %s"),
-                        gimp_file_get_utf8_name (themerc), error->message);
+                        gimp_file_get_utf8_name (theme_css), error->message);
           g_clear_error (&error);
         }
 
-      g_free (esc_gtkrc_theme);
-      g_free (esc_gtkrc_user);
-      g_object_unref (gtkrc_theme);
-      g_object_unref (gtkrc_user);
+      g_free (esc_css_theme);
+      g_free (esc_css_user);
+      g_object_unref (css_theme);
+      g_object_unref (css_user);
       g_object_unref (output);
     }
 
-  g_object_unref (themerc);
+  g_object_unref (theme_css);
 }
 
 static void
@@ -397,59 +382,26 @@ themes_theme_change_notify (GimpGuiConfig *config,
                             GParamSpec    *pspec,
                             Gimp          *gimp)
 {
-  themes_apply_theme (gimp, config->theme);
-
-  gtk_rc_reparse_all ();
-}
-
-static void
-themes_draw_layout (GtkStyle      *style,
-                    GdkWindow     *window,
-                    GtkStateType   state_type,
-                    gboolean       use_text,
-                    GdkRectangle  *area,
-                    GtkWidget     *widget,
-                    const gchar   *detail,
-                    gint           x,
-                    gint           y,
-                    PangoLayout   *layout)
-{
-  GdkGC *gc;
-
-  gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
-
-  if (area)
-    gdk_gc_set_clip_rectangle (gc, area);
-
-  if (state_type == GTK_STATE_INSENSITIVE)
-    {
-      GdkGC       *copy = gdk_gc_new (window);
-      GdkGCValues  orig;
-      GdkColor     fore;
-      guint16      r, g, b;
-
-      gdk_gc_copy (copy, gc);
-      gdk_gc_get_values (gc, &orig);
+  GFile  *theme_css;
+  GError *error = NULL;
 
-      r = 0x40 + (((orig.foreground.pixel >> 16) & 0xff) >> 1);
-      g = 0x40 + (((orig.foreground.pixel >>  8) & 0xff) >> 1);
-      b = 0x40 + (((orig.foreground.pixel >>  0) & 0xff) >> 1);
+  themes_apply_theme (gimp, config->theme);
 
-      fore.pixel = (r << 16) | (g << 8) | b;
-      fore.red   = r * 257;
-      fore.green = g * 257;
-      fore.blue  = b * 257;
+  theme_css = gimp_directory_file ("theme.css", NULL);
 
-      gdk_gc_set_foreground (copy, &fore);
-      gdk_draw_layout (window, copy, x, y, layout);
+  if (gimp->be_verbose)
+    g_print ("Parsing '%s'\n",
+             gimp_file_get_utf8_name (theme_css));
 
-      g_object_unref (copy);
-    }
-  else
+  if (! gtk_css_provider_load_from_file (GTK_CSS_PROVIDER (themes_style_provider),
+                                         theme_css, &error))
     {
-      gdk_draw_layout (window, gc, x, y, layout);
+      g_printerr ("%s: error parsing %s: %s\n", G_STRFUNC,
+                  gimp_file_get_utf8_name (theme_css), error->message);
+      g_clear_error (&error);
     }
 
-  if (area)
-    gdk_gc_set_clip_rectangle (gc, NULL);
+  g_object_unref (theme_css);
+
+  gtk_style_context_reset_widgets (gdk_screen_get_default ());
 }
diff --git a/libgimp/gimpui.c b/libgimp/gimpui.c
index 1495dea..b03ca61 100644
--- a/libgimp/gimpui.c
+++ b/libgimp/gimpui.c
@@ -91,10 +91,12 @@ void
 gimp_ui_init (const gchar *prog_name,
               gboolean     preview)
 {
-  const gchar  *display_name;
-  gchar        *themerc;
-  GFileMonitor *rc_monitor;
-  GFile        *file;
+  const gchar    *display_name;
+  GtkCssProvider *css_provider;
+  gchar          *theme_css;
+  GFileMonitor   *css_monitor;
+  GFile          *file;
+  GError         *error = NULL;
 
   g_return_if_fail (prog_name != NULL);
 
@@ -127,18 +129,36 @@ gimp_ui_init (const gchar *prog_name,
 
   gtk_init (NULL, NULL);
 
-  themerc = gimp_personal_rc_file ("themerc");
-  gtk_rc_parse (themerc);
+  css_provider = gtk_css_provider_new ();
 
-  file = g_file_new_for_path (themerc);
-  g_free (themerc);
+  gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
+                                             GTK_STYLE_PROVIDER (css_provider),
+                                             GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 
-  rc_monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL);
+  g_object_unref (css_provider);
+
+  theme_css = gimp_personal_rc_file ("theme.css");
+
+  if (! gtk_css_provider_load_from_path (css_provider,
+                                         theme_css, &error))
+    {
+      g_printerr ("%s: error parsing %s: %s\n", G_STRFUNC,
+                  gimp_filename_to_utf8 (theme_css), error->message);
+      g_clear_error (&error);
+    }
+
+  file = g_file_new_for_path (theme_css);
+  g_free (theme_css);
+
+  css_monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL);
   g_object_unref (file);
 
-  g_signal_connect (rc_monitor, "changed",
+#if 0
+  /* FIXME CSS: do we still need such code on gtk3? */
+  g_signal_connect (css_monitor, "changed",
                     G_CALLBACK (gtk_rc_reparse_all),
                     NULL);
+#endif
 
   gdk_set_program_class (gimp_wm_class ());
 


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