[gnome-builder] theme: auto load theme overrides and icons for plugins
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] theme: auto load theme overrides and icons for plugins
- Date: Mon, 21 Dec 2015 07:56:43 +0000 (UTC)
commit 77a17d14d866fa32e2e27e89b43f901922577be7
Author: Christian Hergert <chergert redhat com>
Date: Tue Dec 1 23:55:14 2015 -0800
theme: auto load theme overrides and icons for plugins
Place theme overrides in:
/org/gnome/builder/plugins/<plugin-name>/theme/
and name them such as:
Adwaita.css
Adwaita-dark.css
...
Place icons in:
/org/gnome/builder/plugins/<plugin-name>/icons/scalable/icon-name.svg
libide/Makefile.am | 2 +
libide/ide-application-private.h | 4 +-
libide/ide-application.c | 9 +--
libide/ide-css-provider.c | 84 ++++++++++++++++++---
libide/ide-css-provider.h | 2 +-
libide/ide-theme-manager.c | 157 ++++++++++++++++++++++++++++++++++++++
libide/ide-theme-manager.h | 34 ++++++++
7 files changed, 274 insertions(+), 18 deletions(-)
---
diff --git a/libide/Makefile.am b/libide/Makefile.am
index 2886125..f68c4e2 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -317,6 +317,8 @@ libide_1_0_la_SOURCES = \
ide-source-view-movements.h \
ide-text-iter.c \
ide-text-iter.h \
+ ide-theme-manager.c \
+ ide-theme-manager.h \
ide-tree-private.h \
ide-workbench-actions.c \
ide-workbench-private.h \
diff --git a/libide/ide-application-private.h b/libide/ide-application-private.h
index 622bd74..5259a24 100644
--- a/libide/ide-application-private.h
+++ b/libide/ide-application-private.h
@@ -25,6 +25,7 @@
#include "ide-application.h"
#include "ide-keybindings.h"
#include "ide-recent-projects.h"
+#include "ide-theme-manager.h"
#include "ide-worker-manager.h"
G_BEGIN_DECLS
@@ -42,7 +43,6 @@ struct _IdeApplication
gchar **tool_arguments;
PeasPluginInfo *worker;
-
IdeWorkerManager *worker_manager;
IdeKeybindings *keybindings;
@@ -50,6 +50,8 @@ struct _IdeApplication
IdeRecentProjects *recent_projects;
GDateTime *started_at;
+
+ IdeThemeManager *theme_manager;
};
void ide_application_discover_plugins (IdeApplication *self) G_GNUC_INTERNAL;
diff --git a/libide/ide-application.c b/libide/ide-application.c
index 6db7d8f..cb40426 100644
--- a/libide/ide-application.c
+++ b/libide/ide-application.c
@@ -41,6 +41,7 @@
#include "ide-internal.h"
#include "ide-macros.h"
#include "ide-resources.h"
+#include "ide-theme-manager.h"
#include "ide-workbench.h"
#include "ide-worker.h"
@@ -84,14 +85,9 @@ ide_application_register_theme_overrides (IdeApplication *self)
g_assert (IDE_IS_APPLICATION (self));
- gtk_icon_theme_add_resource_path (gtk_icon_theme_get_default (),
- "/org/gnome/builder/icons/");
+ self->theme_manager = ide_theme_manager_new ();
- provider = ide_css_provider_new ();
screen = gdk_screen_get_default ();
- gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-
gtk_settings = gtk_settings_get_for_screen (screen);
settings = g_settings_new ("org.gnome.builder");
g_settings_bind (settings, "night-mode",
@@ -358,6 +354,7 @@ ide_application_finalize (GObject *object)
g_clear_object (&self->worker_manager);
g_clear_object (&self->keybindings);
g_clear_object (&self->recent_projects);
+ g_clear_object (&self->theme_manager);
G_OBJECT_CLASS (ide_application_parent_class)->finalize (object);
}
diff --git a/libide/ide-css-provider.c b/libide/ide-css-provider.c
index 7495399..c617fa4 100644
--- a/libide/ide-css-provider.c
+++ b/libide/ide-css-provider.c
@@ -25,17 +25,27 @@
struct _IdeCssProvider
{
- GtkCssProvider parent_instance;
-
- GtkSettings *settings;
+ GtkCssProvider parent_instance;
+ GtkSettings *settings;
+ gchar *base_path;
};
G_DEFINE_TYPE (IdeCssProvider, ide_css_provider, GTK_TYPE_CSS_PROVIDER)
+enum {
+ PROP_0,
+ PROP_BASE_PATH,
+ LAST_PROP
+};
+
+static GParamSpec *properties [LAST_PROP];
+
GtkCssProvider *
-ide_css_provider_new (void)
+ide_css_provider_new (const gchar *base_path)
{
- return g_object_new (IDE_TYPE_CSS_PROVIDER, NULL);
+ return g_object_new (IDE_TYPE_CSS_PROVIDER,
+ "base-path", base_path,
+ NULL);
}
static void
@@ -57,16 +67,20 @@ ide_css_provider_update (IdeCssProvider *self)
"gtk-application-prefer-dark-theme", &prefer_dark_theme,
NULL);
- resource_path = g_strdup_printf ("/org/gnome/builder/theme/%s%s.css",
- theme_name,
- prefer_dark_theme ? "-dark" : "");
+ resource_path = g_strdup_printf ("%s/theme/%s%s.css",
+ self->base_path,
+ theme_name, prefer_dark_theme ? "-dark" : "");
if (!g_resources_get_info (resource_path, G_RESOURCE_LOOKUP_FLAGS_NONE, &len, &flags, NULL))
{
g_free (resource_path);
- resource_path = g_strdup ("/org/gnome/builder/theme/shared.css");
+ resource_path = g_strdup_printf ("%s/theme/shared.css", self->base_path);
}
+ /* Nothing to load */
+ if (!g_resources_get_info (resource_path, G_RESOURCE_LOOKUP_FLAGS_NONE, &len, &flags, NULL))
+ return;
+
IDE_TRACE_MSG ("Loading css overrides \"%s\"", resource_path);
gtk_css_provider_load_from_resource (GTK_CSS_PROVIDER (self), resource_path);
@@ -151,20 +165,70 @@ ide_css_provider_finalize (GObject *object)
IdeCssProvider *self = (IdeCssProvider *)object;
g_clear_object (&self->settings);
+ g_clear_pointer (&self->base_path, g_free);
G_OBJECT_CLASS (ide_css_provider_parent_class)->finalize (object);
}
static void
+ide_css_provider_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeCssProvider *self = IDE_CSS_PROVIDER(object);
+
+ switch (prop_id)
+ {
+ case PROP_BASE_PATH:
+ g_value_set_string (value, self->base_path);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void
+ide_css_provider_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdeCssProvider *self = IDE_CSS_PROVIDER(object);
+
+ switch (prop_id)
+ {
+ case PROP_BASE_PATH:
+ self->base_path = g_value_dup_string (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void
ide_css_provider_class_init (IdeCssProviderClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkCssProviderClass *provider_class = GTK_CSS_PROVIDER_CLASS (klass);
- object_class->finalize = ide_css_provider_finalize;
object_class->constructed = ide_css_provider_constructed;
+ object_class->finalize = ide_css_provider_finalize;
+ object_class->get_property = ide_css_provider_get_property;
+ object_class->set_property = ide_css_provider_set_property;
provider_class->parsing_error = ide_css_provider_parsing_error;
+
+ properties [PROP_BASE_PATH] =
+ g_param_spec_string ("base-path",
+ "Base Path",
+ "The base resource path to discover themes",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
}
static void
diff --git a/libide/ide-css-provider.h b/libide/ide-css-provider.h
index cd36e30..0c6b18a 100644
--- a/libide/ide-css-provider.h
+++ b/libide/ide-css-provider.h
@@ -27,7 +27,7 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (IdeCssProvider, ide_css_provider, IDE, CSS_PROVIDER, GtkCssProvider)
-GtkCssProvider *ide_css_provider_new (void);
+GtkCssProvider *ide_css_provider_new (const gchar *base_path);
G_END_DECLS
diff --git a/libide/ide-theme-manager.c b/libide/ide-theme-manager.c
new file mode 100644
index 0000000..6d86407
--- /dev/null
+++ b/libide/ide-theme-manager.c
@@ -0,0 +1,157 @@
+/* ide-theme-manager.c
+ *
+ * Copyright (C) 2015 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-theme-manager"
+
+#include <libpeas/peas.h>
+
+#include "ide-css-provider.h"
+#include "ide-theme-manager.h"
+
+struct _IdeThemeManager
+{
+ GObject parent_instance;
+
+ GtkCssProvider *app_provider;
+ GHashTable *plugin_providers;
+};
+
+G_DEFINE_TYPE (IdeThemeManager, ide_theme_manager, G_TYPE_OBJECT)
+
+static void
+provider_destroy_notify (gpointer data)
+{
+ GtkStyleProvider *provider = data;
+ GdkScreen *screen = gdk_screen_get_default ();
+
+ g_assert (GTK_IS_STYLE_PROVIDER (provider));
+ g_assert (GDK_IS_SCREEN (screen));
+
+ gtk_style_context_remove_provider_for_screen (screen, provider);
+ g_object_unref (provider);
+}
+
+static void
+ide_theme_manager_load_plugin (IdeThemeManager *self,
+ PeasPluginInfo *plugin_info,
+ PeasEngine *engine)
+{
+ GtkCssProvider *provider;
+ const gchar *module_name;
+ GdkScreen *screen;
+ gchar *path;
+
+ g_assert (IDE_IS_THEME_MANAGER (self));
+ g_assert (plugin_info != NULL);
+ g_assert (PEAS_IS_ENGINE (engine));
+
+ module_name = peas_plugin_info_get_module_name (plugin_info);
+ screen = gdk_screen_get_default ();
+
+ path = g_strdup_printf ("/org/gnome/builder/plugins/%s", module_name);
+ provider = ide_css_provider_new (path);
+ gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1);
+ g_hash_table_insert (self->plugin_providers, g_strdup (module_name), provider);
+ g_free (path);
+
+ path = g_strdup_printf ("/org/gnome/builder/plugins/%s/icons/", module_name);
+ gtk_icon_theme_add_resource_path (gtk_icon_theme_get_default (), path);
+ g_free (path);
+}
+
+static void
+ide_theme_manager_unload_plugin (IdeThemeManager *self,
+ PeasPluginInfo *plugin_info,
+ PeasEngine *engine)
+{
+ g_assert (IDE_IS_THEME_MANAGER (self));
+ g_assert (plugin_info != NULL);
+ g_assert (PEAS_IS_ENGINE (engine));
+
+ g_hash_table_remove (self->plugin_providers,
+ peas_plugin_info_get_module_name (plugin_info));
+
+ /* XXX: No opposite to gtk_icon_theme_add_resource_path() */
+}
+
+static void
+ide_theme_manager_finalize (GObject *object)
+{
+ IdeThemeManager *self = (IdeThemeManager *)object;
+
+ g_clear_pointer (&self->app_provider, provider_destroy_notify);
+ g_clear_pointer (&self->plugin_providers, g_hash_table_unref);
+
+ G_OBJECT_CLASS (ide_theme_manager_parent_class)->finalize (object);
+}
+
+static void
+ide_theme_manager_class_init (IdeThemeManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = ide_theme_manager_finalize;
+}
+
+static void
+ide_theme_manager_init (IdeThemeManager *self)
+{
+ PeasEngine *engine = peas_engine_get_default ();
+ GdkScreen *screen = gdk_screen_get_default ();
+ const GList *list;
+
+ self->plugin_providers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+ provider_destroy_notify);
+
+ self->app_provider = ide_css_provider_new ("/org/gnome/builder");
+ gtk_style_context_add_provider_for_screen (screen,
+ GTK_STYLE_PROVIDER (self->app_provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+ gtk_icon_theme_add_resource_path (gtk_icon_theme_get_default (),
+ "/org/gnome/builder/icons/");
+
+ g_signal_connect_object (engine,
+ "load-plugin",
+ G_CALLBACK (ide_theme_manager_load_plugin),
+ self,
+ G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (engine,
+ "unload-plugin",
+ G_CALLBACK (ide_theme_manager_unload_plugin),
+ self,
+ G_CONNECT_SWAPPED);
+
+ list = peas_engine_get_plugin_list (engine);
+
+ for (; list != NULL; list = list->next)
+ {
+ PeasPluginInfo *plugin_info = list->data;
+
+ if (peas_plugin_info_is_loaded (plugin_info))
+ ide_theme_manager_load_plugin (self, plugin_info, engine);
+ }
+}
+
+IdeThemeManager *
+ide_theme_manager_new (void)
+{
+ return g_object_new (IDE_TYPE_THEME_MANAGER, NULL);
+}
diff --git a/libide/ide-theme-manager.h b/libide/ide-theme-manager.h
new file mode 100644
index 0000000..6851834
--- /dev/null
+++ b/libide/ide-theme-manager.h
@@ -0,0 +1,34 @@
+/* ide-theme-manager.h
+ *
+ * Copyright (C) 2015 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IDE_THEME_MANAGER_H
+#define IDE_THEME_MANAGER_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_THEME_MANAGER (ide_theme_manager_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeThemeManager, ide_theme_manager, IDE, THEME_MANAGER, GObject)
+
+IdeThemeManager *ide_theme_manager_new (void);
+
+G_END_DECLS
+
+#endif /* IDE_THEME_MANAGER_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]