[gtk/theme-redux: 56/58] Add some theme apis



commit e69e84021f5669d01fad64e1a1583e4dff676475
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Apr 12 00:20:27 2020 -0400

    Add some theme apis
    
    Add apis to get the list of available themes,
    as well as the dark or light variant of a theme.

 docs/reference/gtk/gtk4-sections.txt |   6 ++
 gtk/gtk.h                            |   1 +
 gtk/gtkcssprovider.c                 |   4 +-
 gtk/gtkcssproviderprivate.h          |   2 +
 gtk/gtksettings.c                    |  64 +------------
 gtk/gtktheme.c                       | 181 +++++++++++++++++++++++++++++++++++
 gtk/gtktheme.h                       |  38 ++++++++
 gtk/meson.build                      |   2 +
 8 files changed, 235 insertions(+), 63 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index d438d4bc3d..4c681a04b6 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -2304,6 +2304,12 @@ GtkSettingsValue
 gtk_settings_get_default
 gtk_settings_get_for_display
 gtk_settings_reset_property
+
+<SUBSECTION>
+gtk_theme_get_dark_variant
+gtk_theme_get_light_variant
+gtk_theme_get_available_themes
+
 <SUBSECTION Standard>
 GtkSettingsClass
 GTK_IS_SETTINGS
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 8fe078e6a9..b1fd3de207 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -230,6 +230,7 @@
 #include <gtk/gtktexttag.h>
 #include <gtk/gtktexttagtable.h>
 #include <gtk/gtktextview.h>
+#include <gtk/gtktheme.h>
 #include <gtk/gtktogglebutton.h>
 #include <gtk/gtktooltip.h>
 #include <gtk/gtktestutils.h>
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index 5ade761eaf..0ae06f3952 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -1266,8 +1266,8 @@ _gtk_css_find_theme_dir (const gchar *dir,
 
 #undef MINOR
 
-static gchar *
-_gtk_css_find_theme (const gchar *name)
+char *
+_gtk_css_find_theme (const char *name)
 {
   gchar *path;
   const char *const *dirs;
diff --git a/gtk/gtkcssproviderprivate.h b/gtk/gtkcssproviderprivate.h
index e345d00120..cef6706f62 100644
--- a/gtk/gtkcssproviderprivate.h
+++ b/gtk/gtkcssproviderprivate.h
@@ -26,6 +26,8 @@ gchar *_gtk_get_theme_dir (void);
 
 const gchar *_gtk_css_provider_get_theme_dir (GtkCssProvider *provider);
 
+char *_gtk_css_find_theme (const char *theme);
+
 void   gtk_css_provider_set_keep_css_sections (void);
 
 G_END_DECLS
diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c
index 301575705e..b1b1a99a9c 100644
--- a/gtk/gtksettings.c
+++ b/gtk/gtksettings.c
@@ -29,6 +29,7 @@
 #include "gtkstyleproviderprivate.h"
 #include "gtktypebuiltins.h"
 #include "gtkversion.h"
+#include "gtktheme.h"
 #include "gtkwidget.h"
 
 #include "gdk/gdk-private.h"
@@ -1635,65 +1636,6 @@ settings_update_provider (GdkDisplay      *display,
  * NAME/NAME-dark
  */
 
-extern char *_gtk_css_find_theme (const char *theme);
-
-static gboolean
-theme_exists (const char *theme)
-{
-  char *path;
-
-  path = _gtk_css_find_theme (theme);
-  if (path)
-    {
-      g_free (path);
-      return TRUE;
-    }
-
-  return FALSE;
-}
-
-static char *
-get_light_theme_variant (const char *theme)
-{
-  if (g_str_equal (theme, "HighContrastInverse"))
-    return g_strdup ("HighContrast");
-
-  if (g_str_equal (theme, "Adwaita-dark"))
-    return g_strdup ("Adwaita");
-
-  if (g_str_has_suffix (theme, "-dark"))
-    {
-      char *light = g_strndup (theme, strlen (theme) - strlen ("-dark"));
-      if (theme_exists (light))
-        return light;
-
-      g_free (light);   
-    }
-
-  return g_strdup (theme);
-}
-
-static char *
-get_dark_theme_variant (const char *theme)
-{
-  if (g_str_equal (theme, "HighContrast"))
-    return g_strdup ("HighContrastInverse");
-
-  if (g_str_equal (theme, "Adwaita"))
-    return g_strdup ("Adwaita-dark");
-
-  if (!g_str_has_suffix (theme, "-dark"))
-    {
-      char *dark = g_strconcat (theme, "-dark", NULL);
-      if (theme_exists (dark))
-        return dark;
-
-      g_free (dark);   
-    }
-
-  return g_strdup (theme);
-}
-
 static char *
 get_theme_name (GtkSettings  *settings)
 {
@@ -1715,11 +1657,11 @@ get_theme_name (GtkSettings  *settings)
   switch (user_pref)
     {
     case 0:
-      theme = get_light_theme_variant (theme_name);
+      theme = gtk_theme_get_light_variant (theme_name);
       g_free (theme_name);
       break;
     case 1:
-      theme = get_dark_theme_variant (theme_name);
+      theme = gtk_theme_get_dark_variant (theme_name);
       g_free (theme_name);
       break;
     default:
diff --git a/gtk/gtktheme.c b/gtk/gtktheme.c
new file mode 100644
index 0000000000..36785ede1a
--- /dev/null
+++ b/gtk/gtktheme.c
@@ -0,0 +1,181 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2020 Red Hat, Inc.
+ *
+ * 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 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gtktheme.h"
+#include "gtkcssproviderprivate.h"
+
+static gboolean
+theme_exists (const char *theme)
+{
+  char *path;
+
+  path = _gtk_css_find_theme (theme);
+  if (path)
+    {
+      g_free (path);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+/**
+ * gtk_theme_get_dark_variant:
+ * @theme: a theme name
+ *
+ * Returns the name of the dark variant of the
+ * given theme, if such a variant is available.
+ * Otherwise, @theme is returned.
+ *
+ * Returns: (transfer full): name of the dark variant
+ *     of @theme. Free with g_free()
+ */
+char *
+gtk_theme_get_dark_variant (const char *theme)
+{
+  if (g_str_equal (theme, "HighContrast"))
+    return g_strdup ("HighContrastInverse");
+
+  if (g_str_equal (theme, "Adwaita"))
+    return g_strdup ("Adwaita-dark");
+
+  if (!g_str_has_suffix (theme, "-dark"))
+    {
+      char *dark = g_strconcat (theme, "-dark", NULL);
+      if (theme_exists (dark))
+        return dark;
+
+      g_free (dark);
+    }
+
+  return g_strdup (theme);
+}
+
+/**
+ * gtk_theme_get_light_variant:
+ * @theme: a theme name
+ *
+ * Returns the name of the light variant of the
+ * given theme, if such a variant is available.
+ * Otherwise, @theme is returned.
+ *
+ * Returns: (transfer full): name of the light variant
+ *     of @theme. Free with g_free()
+ */
+char *
+gtk_theme_get_light_variant (const char *theme)
+{
+  if (g_str_equal (theme, "HighContrastInverse"))
+    return g_strdup ("HighContrast");
+
+  if (g_str_equal (theme, "Adwaita-dark"))
+    return g_strdup ("Adwaita");
+
+  if (g_str_has_suffix (theme, "-dark"))
+    {
+      char *light = g_strndup (theme, strlen (theme) - strlen ("-dark"));
+      if (theme_exists (light))
+        return light;
+
+      g_free (light);
+    }
+
+  return g_strdup (theme);
+}
+
+static void
+fill_gtk (const gchar *path,
+          GHashTable  *t)
+{
+  const gchar *dir_entry;
+  GDir *dir = g_dir_open (path, 0, NULL);
+
+  if (!dir)
+    return;
+
+  while ((dir_entry = g_dir_read_name (dir)))
+    {
+      gchar *filename = g_build_filename (path, dir_entry, "gtk-4.0", "gtk.css", NULL);
+
+      if (g_file_test (filename, G_FILE_TEST_IS_REGULAR) &&
+          !g_hash_table_contains (t, dir_entry))
+        g_hash_table_add (t, g_strdup (dir_entry));
+
+      g_free (filename);
+    }
+
+  g_dir_close (dir);
+}
+
+/**
+ * gtk_theme_get_available_themes:
+ *
+ * Returns the list of available themes.
+ *
+ * Returns: (transfer full): an array of theme names
+ */
+char **
+gtk_theme_get_available_themes (void)
+{
+  GHashTable *t;
+  GHashTableIter iter;
+  gchar *theme, *path;
+  gchar **builtin_themes;
+  guint i;
+  const gchar * const *dirs;
+  char **keys;
+  char **result;
+
+  t = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+  /* Builtin themes */
+  builtin_themes = g_resources_enumerate_children ("/org/gtk/libgtk/theme", 0, NULL);
+  for (i = 0; builtin_themes[i] != NULL; i++)
+    {
+      if (g_str_has_suffix (builtin_themes[i], "/"))
+        g_hash_table_add (t, g_strndup (builtin_themes[i], strlen (builtin_themes[i]) - 1));
+    }
+  g_strfreev (builtin_themes);
+
+  path = _gtk_get_theme_dir ();
+  fill_gtk (path, t);
+  g_free (path);
+
+  path = g_build_filename (g_get_user_data_dir (), "themes", NULL);
+  fill_gtk (path, t);
+  g_free (path);
+
+  path = g_build_filename (g_get_home_dir (), ".themes", NULL);
+  fill_gtk (path, t);
+  g_free (path);
+
+  dirs = g_get_system_data_dirs ();
+  for (i = 0; dirs[i]; i++)
+    {
+      path = g_build_filename (dirs[i], "themes", NULL);
+      fill_gtk (path, t);
+      g_free (path);
+    }
+
+  keys = (char **)g_hash_table_get_keys_as_array (t, NULL);
+  result = g_strdupv (keys);
+  g_free (keys);
+  g_hash_table_destroy (t);
+
+  return result;
+}
diff --git a/gtk/gtktheme.h b/gtk/gtktheme.h
new file mode 100644
index 0000000000..20b46d995a
--- /dev/null
+++ b/gtk/gtktheme.h
@@ -0,0 +1,38 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2020 Red Hat, Inc.
+ *
+ * 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 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_THEME_H__
+#define __GTK_THEME_H__
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gtk/gtktypes.h>
+
+G_BEGIN_DECLS
+
+GDK_AVAILABLE_IN_ALL
+char * gtk_theme_get_dark_variant     (const char *theme);
+GDK_AVAILABLE_IN_ALL
+char * gtk_theme_get_light_variant    (const char *theme);
+GDK_AVAILABLE_IN_ALL
+char **gtk_theme_get_available_themes (void);
+
+G_END_DECLS
+
+#endif /* __GTK_THEME_H__ */
diff --git a/gtk/meson.build b/gtk/meson.build
index 28e23b6781..dec1aff698 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -370,6 +370,7 @@ gtk_public_sources = files([
   'gtktexttypes.c',
   'gtktextutil.c',
   'gtktextview.c',
+  'gtktheme.c',
   'gtktogglebutton.c',
   'gtktooltip.c',
   'gtktooltipwindow.c',
@@ -602,6 +603,7 @@ gtk_public_headers = files([
   'gtktexttag.h',
   'gtktexttagtable.h',
   'gtktextview.h',
+  'gtktheme.h',
   'gtktogglebutton.h',
   'gtktooltip.h',
   'gtktreednd.h',


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