[gnumeric] css: implement #ifdef for built-in css.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] css: implement #ifdef for built-in css.
- Date: Thu, 18 Feb 2021 02:05:34 +0000 (UTC)
commit afbae66f9dd43a121b8f2b52e58143786332a78f
Author: Morten Welinder <terra gnome org>
Date: Wed Feb 17 20:57:12 2021 -0500
css: implement #ifdef for built-in css.
This is a poor man's preprocessor. A very poor man's. It understands
basically two things at the moment:
| #ifdef DARK
| ...
| #else
| ...
| #endif
and
| #if GTK_CHECK_VERSION(...)
| ...
| #else
| ...
| #endif
Note, that "DARK" is set iff running under a dark theme. The gtk version
check is a run-time check.
Note: this code is not in play when ~/.config/gtk-3.0/gtk.css is being read.
NEWS | 1 +
src/gnumeric.css | 72 ++++++++++++++++++++++++++++++++------------------------
src/gui-util.c | 18 ++++++++++++++
src/gui-util.h | 1 +
src/gutils.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/gutils.h | 2 ++
src/wbc-gtk.c | 14 ++++++++---
7 files changed, 146 insertions(+), 34 deletions(-)
---
diff --git a/NEWS b/NEWS
index c85b68ffe..c3029d7de 100644
--- a/NEWS
+++ b/NEWS
@@ -30,6 +30,7 @@ Morten:
* Check for yelp in autogen. [#558]
* Fix ssconvert problem with conditional styles.
* Move from style regions to style classes in css.
+ * Implement #ifdef for built-in css.
--------------------------------------------------------------------------
Gnumeric 1.12.48
diff --git a/src/gnumeric.css b/src/gnumeric.css
index 48bca6a38..be12d703b 100644
--- a/src/gnumeric.css
+++ b/src/gnumeric.css
@@ -189,17 +189,6 @@ GocItem.object-size.rubber-band {
color: black;
}
-/* ------------------------------------------------------------------------- */
-/* Auto filter in two versions: the first one for "all", second for others. */
-
-GtkArrow.auto-filter {
- color: black;
-}
-
-GtkArrow.auto-filter:active {
- color: yellow;
-}
-
/* ------------------------------------------------------------------------- */
/* GnmNotebookButton is the sheet name buttons used to select sheets. */
@@ -219,24 +208,7 @@ GtkDialog GtkTextView.function-help {
-GtkWidget-link-color: #4040ff;
}
-/* ------------------------------------------------------------------------- */
-/* This is the vertical line used in the fixed-width part of the stf */
-/* import dialog to show where a new column division will be placed */
-
-GtkDialog.fixed-format-ruler {
- color: red;
-}
-
-/* ------------------------------------------------------------------------- */
-/* Extra space around multiple toolbars adds up quickly so avoid it. */
-
-GtkBox.toolbarzone GtkToolbar {
- padding: 0px;
-}
-GtkBox.toolbarzone GtkToolbar * {
- padding: 1px;
-}
-
+#if GTK_CHECK_VERSION(3,20,0)
/* ------------------------------------------------------------------------- */
/* Styles for Gtk+ 3.20 and later */
/* ------------------------------------------------------------------------- */
@@ -256,8 +228,8 @@ button.itembar, button.itembar * {
/* The whole column/row selected. */
button:active.itembar, button:active.itembar * {
- color: red;
- font-weight: bold;
+ color: red;
+ font-weight: bold;
}
/* Some, but not all, of a column/row selected. */
@@ -278,8 +250,46 @@ box > box:last-child > toolbar {
padding-bottom: 1pt;
}
+/* This is the vertical line used in the fixed-width part of the stf */
+/* import dialog to show where a new column division will be placed */
dialog.fixed-format-ruler {
color: red;
}
+/* Auto filter in two versions: the first one for "all", second for others. */
+/* Not working: */
+arrow.auto-filter {
+ color: black;
+}
+arrow.auto-filter:active {
+ color: yellow;
+}
+
+#else
+
+/* Extra space around multiple toolbars adds up quickly so avoid it. */
+GtkBox.toolbarzone GtkToolbar {
+ padding: 0px;
+}
+GtkBox.toolbarzone GtkToolbar * {
+ padding: 1px;
+}
+
+/* This is the vertical line used in the fixed-width part of the stf */
+/* import dialog to show where a new column division will be placed */
+GtkDialog.fixed-format-ruler {
+ color: red;
+}
+
+/* Auto filter in two versions: the first one for "all", second for others. */
+GtkArrow.auto-filter {
+ color: black;
+}
+
+GtkArrow.auto-filter:active {
+ color: yellow;
+}
+
+#endif
+
/* ------------------------------------------------------------------------- */
diff --git a/src/gui-util.c b/src/gui-util.c
index c00b15d22..84c0b19a0 100644
--- a/src/gui-util.c
+++ b/src/gui-util.c
@@ -1404,4 +1404,22 @@ gnm_get_link_color (G_GNUC_UNUSED GtkWidget *widget, GdkRGBA *res)
}
#endif /* GTK_STATE_FLAG_LINK */
+gboolean
+gnm_theme_is_dark (GtkWidget *widget)
+{
+ GtkStyleContext *context;
+ GdkRGBA fg_color;
+ double lum;
+
+ context = gtk_widget_get_style_context (widget);
+ gnm_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &fg_color);
+
+ // One of many possible versions.
+ lum = 0.299 * fg_color.red + 0.587 * fg_color.green + 0.114 * fg_color.blue;
+
+ // Theme is dark if fg is light.
+ return lum > 0.5;
+}
+
+
// ----------------------------------------------------------------------------
diff --git a/src/gui-util.h b/src/gui-util.h
index 785879810..8dd6dd65e 100644
--- a/src/gui-util.h
+++ b/src/gui-util.h
@@ -187,6 +187,7 @@ void gnm_style_context_get_color (GtkStyleContext *context,
GdkRGBA *color);
void gnm_get_link_color (GtkWidget *widget, GdkRGBA *res);
+gboolean gnm_theme_is_dark (GtkWidget *widget);
G_END_DECLS
diff --git a/src/gutils.c b/src/gutils.c
index a2a5696a8..10a2a3010 100644
--- a/src/gutils.c
+++ b/src/gutils.c
@@ -1014,3 +1014,75 @@ gnm_file_saver_common_export_option (GOFileSaver const *fs,
return TRUE;
}
+
+
+static int
+gnm_cpp_expr (const char *expr, G_GNUC_UNUSED GHashTable *vars)
+{
+ int vmajor, vminor, vmicro;
+
+ while (g_ascii_isspace (*expr))
+ expr++;
+
+ if (sscanf (expr, "GTK_CHECK_VERSION (%d,%d,%d) ", &vmajor, &vminor, &vmicro) == 3) {
+ return gtk_check_version (vmajor, vminor, vmicro) ? 0 : 1;
+ }
+
+ g_warning ("Unhandled cpp expression %s", expr);
+ return 0;
+}
+
+
+char *
+gnm_cpp (const char *src, GHashTable *vars)
+{
+ GString *res = g_string_new (NULL);
+ GString *ifdefs = g_string_new ("1");
+
+ while (*src) {
+ const char *end;
+
+ end = strchr (src, '\n');
+ if (end)
+ end++;
+ else
+ end = src + strlen (src);
+
+ if (*src == '#') {
+ if (strncmp (src, "#ifdef ", 7) == 0 || strncmp (src, "#ifndef ", 8) == 0) {
+ int is_not = (src[3] == 'n');
+ const char *var = src + 7 + is_not;
+ char *w;
+ gboolean res;
+
+ while (g_ascii_isspace (*var))
+ var++;
+ src = var;
+ while (g_ascii_isalnum (*src))
+ src++;
+ w = g_strndup (var, src - var);
+ res = is_not ^ !!g_hash_table_lookup (vars, w);
+ g_string_append_c (ifdefs, ifdefs->str[ifdefs->len - 1] && res);
+ g_free (w);
+ } else if (strncmp (src, "#if ", 4) == 0) {
+ gboolean res = gnm_cpp_expr (src + 4, vars) > 0;
+ g_string_append_c (ifdefs, ifdefs->str[ifdefs->len - 1] && res);
+ } else if (strncmp (src, "#else", 5) == 0) {
+ ifdefs->str[ifdefs->len - 1] =
+ !ifdefs->str[ifdefs->len - 1] &&
+ ifdefs->str[ifdefs->len - 2];
+ } else if (strncmp (src, "#endif", 6) == 0 && ifdefs->len > 1) {
+ g_string_set_size (ifdefs, ifdefs->len - 1);
+ } else {
+ g_warning ("cpp failure");
+ }
+ } else {
+ if (ifdefs->str[ifdefs->len - 1])
+ g_string_append_len (res, src, end - src);
+ }
+ src = end;
+ }
+
+ g_string_free (ifdefs, TRUE);
+ return g_string_free (res, FALSE);
+}
diff --git a/src/gutils.h b/src/gutils.h
index 945b5a425..42d96844a 100644
--- a/src/gutils.h
+++ b/src/gutils.h
@@ -74,6 +74,8 @@ gboolean gnm_file_saver_common_export_option (GOFileSaver const *fs,
const char *value,
GError **err);
+char *gnm_cpp (const char *src, GHashTable *vars);
+
G_END_DECLS
#endif /* _GNM_GUTILS_H_ */
diff --git a/src/wbc-gtk.c b/src/wbc-gtk.c
index e330105f4..93544d94b 100644
--- a/src/wbc-gtk.c
+++ b/src/wbc-gtk.c
@@ -2367,10 +2367,17 @@ cb_screen_changed (GtkWidget *widget)
data = g_object_get_data (app, app_key);
if (!data) {
- const char *resource = "/org/gnumeric/gnumeric/ui/gnumeric.css";
- GBytes *cssbytes = g_resources_lookup_data (resource, 0, NULL);
- const char *csstext = g_bytes_get_data (cssbytes, NULL);
gboolean debug = gnm_debug_flag ("css");
+ gboolean q_dark = gnm_theme_is_dark (widget);
+ const char *resource = "/org/gnumeric/gnumeric/ui/gnumeric.css";
+ GBytes *cssbytes;
+ char *csstext;
+ GHashTable *vars = g_hash_table_new (g_str_hash, g_str_equal);
+
+ cssbytes = g_resources_lookup_data (resource, 0, NULL);
+ if (q_dark)
+ g_hash_table_insert (vars, "DARK", "1");
+ csstext = gnm_cpp (g_bytes_get_data (cssbytes, NULL), vars);
data = g_new (struct css_provider_data, 1);
data->css = gtk_css_provider_new ();
@@ -2386,6 +2393,7 @@ cb_screen_changed (GtkWidget *widget)
gtk_css_provider_load_from_data (data->css, csstext, -1, NULL);
g_object_set_data_full (app, app_key, data, cb_unload_providers);
g_bytes_unref (cssbytes);
+ g_free (csstext);
}
if (screen && !g_slist_find (data->screens, screen)) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]