[goffice] Gtk: import css helper function from Gnumeric.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Gtk: import css helper function from Gnumeric.
- Date: Sun, 10 Dec 2017 19:37:09 +0000 (UTC)
commit 3b9e40bb1eeebeb5e781c506ca609e15e27e92b5
Author: Morten Welinder <terra gnome org>
Date: Sun Dec 10 14:36:30 2017 -0500
Gtk: import css helper function from Gnumeric.
ChangeLog | 5 ++
goffice/gtk/goffice-gtk.c | 151 +++++++++++++++++++++++++++++++++++++++++++++
goffice/gtk/goffice-gtk.h | 3 +
3 files changed, 159 insertions(+), 0 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c799891..9ab1c8e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2017-12-10 Morten Welinder <terra gnome org>
+
+ * goffice/gtk/goffice-gtk.c (go_style_context_from_selector):
+ Import from Gnumeric (in turn from gtk+).
+
2017-12-05 Morten Welinder <terra gnome org>
* tests/constants.c (main): Improve checking if double math
diff --git a/goffice/gtk/goffice-gtk.c b/goffice/gtk/goffice-gtk.c
index 7866aac..c058c76 100644
--- a/goffice/gtk/goffice-gtk.c
+++ b/goffice/gtk/goffice-gtk.c
@@ -1686,6 +1686,157 @@ _go_gtk_new_theming (void)
#endif
}
+// ---------------------------------------------------------------------------
+// Foreign drawing style code copied from foreigndrawing.c
+
+#if GTK_CHECK_VERSION(3,20,0)
+static void
+append_element (GtkWidgetPath *path,
+ const char *selector)
+{
+ static const struct {
+ const char *name;
+ GtkStateFlags state_flag;
+ } pseudo_classes[] = {
+ { "active", GTK_STATE_FLAG_ACTIVE },
+ { "hover", GTK_STATE_FLAG_PRELIGHT },
+ { "selected", GTK_STATE_FLAG_SELECTED },
+ { "disabled", GTK_STATE_FLAG_INSENSITIVE },
+ { "indeterminate", GTK_STATE_FLAG_INCONSISTENT },
+ { "focus", GTK_STATE_FLAG_FOCUSED },
+ { "backdrop", GTK_STATE_FLAG_BACKDROP },
+ { "dir(ltr)", GTK_STATE_FLAG_DIR_LTR },
+ { "dir(rtl)", GTK_STATE_FLAG_DIR_RTL },
+ { "link", GTK_STATE_FLAG_LINK },
+ { "visited", GTK_STATE_FLAG_VISITED },
+ { "checked", GTK_STATE_FLAG_CHECKED },
+ { "drop(active)", GTK_STATE_FLAG_DROP_ACTIVE }
+ };
+ const char *next;
+ char *name;
+ char type;
+ guint i;
+
+ next = strpbrk (selector, "#.:");
+ if (next == NULL)
+ next = selector + strlen (selector);
+
+ name = g_strndup (selector, next - selector);
+ if (g_ascii_isupper (selector[0]))
+ {
+ GType gtype;
+ gtype = g_type_from_name (name);
+ if (gtype == G_TYPE_INVALID)
+ {
+ g_critical ("Unknown type name `%s'", name);
+ g_free (name);
+ return;
+ }
+ gtk_widget_path_append_type (path, gtype);
+ }
+ else
+ {
+ /* Omit type, we're using name */
+ gtk_widget_path_append_type (path, G_TYPE_NONE);
+ gtk_widget_path_iter_set_object_name (path, -1, name);
+ }
+ g_free (name);
+
+ while (*next != '\0')
+ {
+ type = *next;
+ selector = next + 1;
+ next = strpbrk (selector, "#.:");
+ if (next == NULL)
+ next = selector + strlen (selector);
+ name = g_strndup (selector, next - selector);
+
+ switch (type)
+ {
+ case '#':
+ gtk_widget_path_iter_set_name (path, -1, name);
+ break;
+
+ case '.':
+ gtk_widget_path_iter_add_class (path, -1, name);
+ break;
+
+ case ':':
+ for (i = 0; i < G_N_ELEMENTS (pseudo_classes); i++)
+ {
+ if (g_str_equal (pseudo_classes[i].name, name))
+ {
+ gtk_widget_path_iter_set_state (path,
+ -1,
+ gtk_widget_path_iter_get_state (path,
-1)
+ | pseudo_classes[i].state_flag);
+ break;
+ }
+ }
+ if (i == G_N_ELEMENTS (pseudo_classes))
+ g_critical ("Unknown pseudo-class :%s", name);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ g_free (name);
+ }
+}
+
+static GtkStyleContext *
+create_context_for_path (GtkWidgetPath *path,
+ GtkStyleContext *parent)
+{
+ GtkStyleContext *context;
+
+ context = gtk_style_context_new ();
+ gtk_style_context_set_path (context, path);
+ gtk_style_context_set_parent (context, parent);
+ /* Unfortunately, we have to explicitly set the state again here
+ * for it to take effect
+ */
+ gtk_style_context_set_state (context, gtk_widget_path_iter_get_state (path, -1));
+ gtk_widget_path_unref (path);
+
+ return context;
+}
+#endif
+
+/**
+ * go_style_context_from_selector:
+ * @parent: (allow-none): style context for container
+ * @selector: a css selector
+ *
+ * Returns: (transfer full): a new style context.
+ */
+GtkStyleContext *
+go_style_context_from_selector (GtkStyleContext *parent,
+ const char *selector)
+{
+#if GTK_CHECK_VERSION(3,20,0)
+ GtkWidgetPath *path;
+
+ g_return_val_if_fail (selector != NULL, NULL);
+
+ path = parent
+ ? gtk_widget_path_copy (gtk_style_context_get_path (parent))
+ : gtk_widget_path_new ();
+
+ append_element (path, selector);
+
+ return create_context_for_path (path, parent);
+#else
+ (void)parent;
+ g_return_val_if_fail (selector != NULL, NULL);
+ g_assert_not_reached ();
+ return NULL;
+#endif
+}
+
+// ---------------------------------------------------------------------------
void
_go_gtk_shutdown (void)
diff --git a/goffice/gtk/goffice-gtk.h b/goffice/gtk/goffice-gtk.h
index 829ab7d..4c2beb1 100644
--- a/goffice/gtk/goffice-gtk.h
+++ b/goffice/gtk/goffice-gtk.h
@@ -61,6 +61,9 @@ void _go_gtk_shutdown (void);
// Add goffice-specific css provider
void _go_gtk_widget_add_css_provider (GtkWidget *w);
+GtkStyleContext *go_style_context_from_selector (GtkStyleContext *parent,
+ const char *selector);
+
gboolean _go_gtk_new_theming (void);
void go_gtk_editable_enters (GtkWindow *window, GtkWidget *w);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]