[Xfce4-commits] [xfce/xfwm4] 17/32: Implement GTK2-like style calculator

noreply at xfce.org noreply at xfce.org
Tue Dec 5 09:22:03 CET 2017


This is an automated email from the git hooks/post-receive script.

o   l   i   v   i   e   r       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository xfce/xfwm4.

commit 91a9436fe11cdc2052a5c796d289351ae470082b
Author: Viktor Odintsev <zakhams at gmail.com>
Date:   Mon Jul 3 07:10:58 2017 +0300

    Implement GTK2-like style calculator
---
 src/display.h   |   1 -
 src/screen.c    |   8 --
 src/screen.h    |   4 +-
 src/settings.c  |  54 +--------
 src/settings.h  |   7 --
 src/ui_style.c  | 340 +++++++++++++++++++++++++++++++++++++-------------------
 src/ui_style.h  |   7 +-
 src/wireframe.c |  22 +---
 8 files changed, 240 insertions(+), 203 deletions(-)

diff --git a/src/display.h b/src/display.h
index c1a8adb..6b562e2 100644
--- a/src/display.h
+++ b/src/display.h
@@ -275,7 +275,6 @@ enum
 
 typedef struct _Client            Client;
 typedef struct _DisplayInfo       DisplayInfo;
-typedef struct _XfwmColor         XfwmColor;
 typedef struct _xfwmPixmap        xfwmPixmap;
 typedef struct _XfwmParams        XfwmParams;
 typedef struct _ScreenInfo        ScreenInfo;
diff --git a/src/screen.c b/src/screen.c
index e0252d5..9077260 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -306,14 +306,6 @@ myScreenInit (DisplayInfo *display_info, GdkScreen *gscr, unsigned long event_ma
 
     screen_info->font_height = 0;
     screen_info->box_gc = None;
-    screen_info->title_colors[ACTIVE].gc = NULL;
-    screen_info->title_colors[ACTIVE].allocated = FALSE;
-    screen_info->title_colors[INACTIVE].gc = NULL;
-    screen_info->title_colors[INACTIVE].allocated = FALSE;
-    screen_info->title_shadow_colors[ACTIVE].gc = NULL;
-    screen_info->title_shadow_colors[ACTIVE].allocated = FALSE;
-    screen_info->title_shadow_colors[INACTIVE].gc = NULL;
-    screen_info->title_shadow_colors[INACTIVE].allocated = FALSE;
 
     for (i = 0; i < SIDE_COUNT; i++)
     {
diff --git a/src/screen.h b/src/screen.h
index e35cc0f..87256d4 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -86,8 +86,8 @@ struct _ScreenInfo
     gint pointer_grabs;
 
     /* Theme pixmaps and other params, per screen */
-    XfwmColor title_colors[2];
-    XfwmColor title_shadow_colors[2];
+    GdkRGBA title_colors[2];
+    GdkRGBA title_shadow_colors[2];
     xfwmPixmap buttons[BUTTON_COUNT][STATE_COUNT];
     xfwmPixmap corners[CORNER_COUNT][2];
     xfwmPixmap sides[SIDE_COUNT][2];
diff --git a/src/settings.c b/src/settings.c
index 3d7065b..5b1be4c 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -248,50 +248,6 @@ loadXfconfData (ScreenInfo *screen_info, Settings *rc)
 
 }
 
-/* Simple helper function to avoid copy/paste of code */
-static void
-setXfwmColor (ScreenInfo *screen_info, XfwmColor *color, Settings *rc, int id, const gchar * name, const gchar * state)
-{
-    if (color->allocated)
-    {
-        gdk_colormap_free_colors (gdk_screen_get_system_colormap (screen_info->gscr), &color->col, 1);
-        color->allocated = FALSE;
-    }
-
-    /** do a direct value_get_string */
-    if (gdk_color_parse (g_value_get_string(rc[id].value), &color->col))
-    {
-        if (gdk_colormap_alloc_color (gdk_screen_get_system_colormap (screen_info->gscr),
-                                      &color->col, FALSE, FALSE))
-        {
-            color->allocated = TRUE;
-            if (color->gc)
-            {
-                g_object_unref (G_OBJECT (color->gc));
-            }
-            color->gc = gdk_gc_new (myScreenGetGdkWindow (screen_info));
-            gdk_gc_copy (color->gc, getUIStyle_gc (myScreenGetGtkWidget (screen_info), name, state));
-            gdk_gc_set_foreground (color->gc, &color->col);
-        }
-        else
-        {
-            gdk_beep ();
-            if (G_VALUE_TYPE(rc[id].value) == G_TYPE_STRING)
-                g_message (_("%s: Cannot allocate color %s\n"), g_get_prgname (), g_value_get_string(rc[id].value));
-            else
-                g_critical (_("%s: Cannot allocate color: GValue for color is not of type STRING"), g_get_prgname ());
-        }
-    }
-    else
-    {
-        gdk_beep ();
-        if (G_VALUE_TYPE(rc[id].value) == G_TYPE_STRING)
-            g_message (_("%s: Cannot parse color %s\n"), g_get_prgname (), g_value_get_string(rc[id].value));
-        else
-            g_critical (_("%s: Cannot parse color: GValue for color is not of type STRING"), g_get_prgname ());
-    }
-}
-
 static int
 getTitleShadow (Settings *rc, const gchar * name)
 {
@@ -425,7 +381,7 @@ loadTheme (ScreenInfo *screen_info, Settings *rc)
     {
         gchar *color;
 
-        color = getUIStyle  (widget, ui_part[i], ui_state[i]);
+        color = getUIStyleString (widget, ui_part[i], ui_state[i]);
         setStringValue (rc[i].option, color, rc);
         g_free (color);
     }
@@ -504,10 +460,10 @@ loadTheme (ScreenInfo *screen_info, Settings *rc)
         }
     }
 
-    setXfwmColor (screen_info, &screen_info->title_colors[ACTIVE], rc, 0, "fg", "selected");
-    setXfwmColor (screen_info, &screen_info->title_colors[INACTIVE], rc, 1, "fg", "insensitive");
-    setXfwmColor (screen_info, &screen_info->title_shadow_colors[ACTIVE], rc, 2, "dark", "selected");
-    setXfwmColor (screen_info, &screen_info->title_shadow_colors[INACTIVE], rc, 3, "dark", "insensitive");
+    gdk_rgba_parse (&screen_info->title_colors[ACTIVE], getStringValue ("active_text_color", rc));
+    gdk_rgba_parse (&screen_info->title_colors[INACTIVE], getStringValue ("inactive_text_color", rc));
+    gdk_rgba_parse (&screen_info->title_shadow_colors[ACTIVE], getStringValue ("active_text_shadow_color", rc));
+    gdk_rgba_parse (&screen_info->title_shadow_colors[INACTIVE], getStringValue ("inactive_text_shadow_color", rc));
 
     for (i = 0; i < SIDE_COUNT; i++)
     {
diff --git a/src/settings.h b/src/settings.h
index 845fcbe..9d4994d 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -155,13 +155,6 @@ enum
     PLACE_CENTER
 };
 
-struct _XfwmColor
-{
-    GdkColor col;
-    GdkGC *gc;
-    gboolean allocated;
-};
-
 struct _Settings
 {
     gchar  *option;
diff --git a/src/ui_style.c b/src/ui_style.c
index e38da9d..8b34e43 100644
--- a/src/ui_style.c
+++ b/src/ui_style.c
@@ -45,16 +45,23 @@ char *states[] = {
 };
 
 char *names[] = {
-    "fg", "bg", "text", "base", "light", "dark", "mid", NULL
+    "fg", "bg", "light", "dark", "mid", NULL
 };
 
 #define GTKSTYLE_FG    0
 #define GTKSTYLE_BG    1
-#define GTKSTYLE_TEXT  2
-#define GTKSTYLE_BASE  3
-#define GTKSTYLE_LIGHT 4
-#define GTKSTYLE_DARK  5
-#define GTKSTYLE_MID   6
+#define GTKSTYLE_LIGHT 2
+#define GTKSTYLE_DARK  3
+#define GTKSTYLE_MID   4
+
+#define GTKSTATE_NORMAL      0
+#define GTKSTATE_ACTIVE      1
+#define GTKSTATE_PRELIGHT    2
+#define GTKSTATE_SELECTED    3
+#define GTKSTATE_INSENSITIVE 4
+
+#define LIGHTNESS_MULT 1.3
+#define DARKNESS_MULT  0.7
 
 static gint
 state_value (const gchar * s)
@@ -69,7 +76,7 @@ state_value (const gchar * s)
     {
         return (u);
     }
-    return (0);
+    return (-1);
 }
 
 static gint
@@ -85,176 +92,277 @@ name_value (const gchar * s)
     {
         return (u);
     }
-    return (0);
+    return (-1);
 }
 
-static gchar *
-print_color (GtkWidget * win, GdkColor * c)
+static void
+rgb_to_hls (gdouble * r, gdouble * g, gdouble * b)
 {
-    gchar *s;
-    GdkColor real_color;
-    GdkColormap *cmap;
+    /* from gtkstyle.c in gtk2 branch */
+
+    gdouble min;
+    gdouble max;
+    gdouble red;
+    gdouble green;
+    gdouble blue;
+    gdouble h, l, s;
+    gdouble delta;
+
+    red = *r;
+    green = *g;
+    blue = *b;
 
-    s = g_new (gchar, 14);
-    cmap = gtk_widget_get_colormap (GTK_WIDGET (win));
-    if (cmap && GDK_IS_COLORMAP (cmap))
+    max = MAX (red, MAX (green, blue));
+    min = MIN (red, MIN (green, blue));
+
+    l = (max + min) / 2;
+    s = 0;
+    h = 0;
+
+    if (max != min)
     {
-        gdk_colormap_query_color (cmap, c->pixel, &real_color);
-        g_snprintf (s, 14, "#%04x%04x%04x", real_color.red, real_color.green,
-                    real_color.blue);
+        if (l <= 0.5)
+            s = (max - min) / (max + min);
+        else
+            s = (max - min) / (2 - max - min);
+
+        delta = max - min;
+        if (red == max)
+            h = (green - blue) / delta;
+        else if (green == max)
+            h = 2 + (blue - red) / delta;
+        else if (blue == max)
+            h = 4 + (red - green) / delta;
+
+        h *= 60;
+        if (h < 0.0)
+            h += 360;
     }
+
+    *r = h;
+    *g = l;
+    *b = s;
+}
+
+static void
+hls_to_rgb (gdouble * h, gdouble * l, gdouble * s)
+{
+    /* from gtkstyle.c in gtk2 branch */
+
+    gdouble hue;
+    gdouble lightness;
+    gdouble saturation;
+    gdouble m1, m2;
+    gdouble r, g, b;
+
+    lightness = *l;
+    saturation = *s;
+
+    if (lightness <= 0.5)
+        m2 = lightness * (1 + saturation);
     else
+        m2 = lightness + saturation - lightness * saturation;
+    m1 = 2 * lightness - m2;
+
+    if (saturation == 0)
     {
-        g_snprintf (s, 14, "#%04x%04x%04x", c->red, c->green, c->blue);
+        *h = lightness;
+        *l = lightness;
+        *s = lightness;
+    }
+    else
+    {
+        hue = *h + 120;
+        while (hue > 360)
+            hue -= 360;
+        while (hue < 0)
+            hue += 360;
+
+        if (hue < 60)
+            r = m1 + (m2 - m1) * hue / 60;
+        else if (hue < 180)
+            r = m2;
+        else if (hue < 240)
+            r = m1 + (m2 - m1) * (240 - hue) / 60;
+        else
+            r = m1;
+
+        hue = *h;
+        while (hue > 360)
+            hue -= 360;
+        while (hue < 0)
+            hue += 360;
+
+        if (hue < 60)
+            g = m1 + (m2 - m1) * hue / 60;
+        else if (hue < 180)
+            g = m2;
+        else if (hue < 240)
+            g = m1 + (m2 - m1) * (240 - hue) / 60;
+        else
+            g = m1;
+
+        hue = *h - 120;
+        while (hue > 360)
+            hue -= 360;
+        while (hue < 0)
+            hue += 360;
+
+        if (hue < 60)
+            b = m1 + (m2 - m1) * hue / 60;
+        else if (hue < 180)
+            b = m2;
+        else if (hue < 240)
+            b = m1 + (m2 - m1) * (240 - hue) / 60;
+        else
+            b = m1;
+
+        *h = r;
+        *l = g;
+        *s = b;
     }
-    return (s);
 }
 
-static gchar *
-print_colors (GtkWidget * win, GdkColor * x, int n)
+static void
+rgba_shade (GdkRGBA * color, gdouble value)
 {
-    return (print_color (win, x + n));
+  rgb_to_hls (&color->red, &color->green, &color->blue);
+  color->green = MAX (MIN (color->green * value, 1), 0);
+  color->blue = MAX (MIN (color->blue * value, 1), 0);
+  hls_to_rgb (&color->red, &color->green, &color->blue);
 }
 
-static gchar *
-print_rc_style (GtkWidget * win, const gchar * name, const gchar * state,
-                GtkStyle * style)
+gboolean
+getUIStyleColor (GtkWidget * win, const gchar * name, const gchar * state, GdkRGBA * rgba)
 {
-    gchar *s;
-    gint n, m;
+    GtkStyleContext *ctx;
+    GdkRGBA         *result;
+    GtkStateFlags    flags;
+    gint             gtkstyle;
+    gchar           *property;
+
+    TRACE ("entering getUIStyleColor");
 
-    g_return_val_if_fail (state != NULL, NULL);
-    g_return_val_if_fail (name != NULL, NULL);
+    g_return_val_if_fail (win != NULL, FALSE);
+    g_return_val_if_fail (GTK_IS_WIDGET (win), FALSE);
+    g_return_val_if_fail (gtk_widget_get_realized (win), FALSE);
 
-    n = state_value (state);
-    m = name_value (name);
+    gtkstyle = name_value (name);
 
-    switch (m)
+    switch (gtkstyle)
     {
         case GTKSTYLE_FG:
-            s = print_colors (win, style->fg, n);
+            property = GTK_STYLE_PROPERTY_COLOR;
             break;
         case GTKSTYLE_BG:
-            s = print_colors (win, style->bg, n);
-            break;
-        case GTKSTYLE_TEXT:
-            s = print_colors (win, style->text, n);
-            break;
-        case GTKSTYLE_BASE:
-            s = print_colors (win, style->base, n);
-            break;
         case GTKSTYLE_LIGHT:
-            s = print_colors (win, style->light, n);
-            break;
         case GTKSTYLE_DARK:
-            s = print_colors (win, style->dark, n);
-            break;
-        default:
         case GTKSTYLE_MID:
-            s = print_colors (win, style->mid, n);
+            property = GTK_STYLE_PROPERTY_BACKGROUND_COLOR;
             break;
+        default:
+            return FALSE;
     }
-    return (s);
-}
 
-gchar *
-getUIStyle (GtkWidget * win, const gchar * name, const gchar * state)
-{
-    GtkStyle *style;
-    gchar *s;
-
-    TRACE ("entering getUIStyle");
-
-    g_return_val_if_fail (win != NULL, NULL);
-    g_return_val_if_fail (GTK_IS_WIDGET (win), NULL);
-    g_return_val_if_fail (gtk_widget_get_realized (win), NULL);
-
-    style = gtk_rc_get_style (win);
-    if (!style)
+    switch (state_value (state))
     {
-        style = gtk_widget_get_style (win);
+        case GTKSTATE_NORMAL:
+            flags = GTK_STATE_FLAG_NORMAL;
+            break;
+        case GTKSTATE_ACTIVE:
+            flags = GTK_STATE_FLAG_ACTIVE;
+            break;
+        case GTKSTATE_PRELIGHT:
+            flags = GTK_STATE_FLAG_PRELIGHT;
+            break;
+        case GTKSTATE_SELECTED:
+            flags = GTK_STATE_FLAG_SELECTED;
+            break;
+        case GTKSTATE_INSENSITIVE:
+            flags = GTK_STATE_FLAG_INSENSITIVE;
+            break;
+        default:
+            return FALSE;
     }
-    s = print_rc_style (win, name, state, style);
-    TRACE ("%s[%s]=%s", name, state, s);
-    return (s);
-}
 
-static GdkGC *
-_getUIStyle_gc (const gchar * name, const gchar * state, GtkStyle * style)
-{
-    GdkGC *gc;
-    gint n, m;
+    ctx = gtk_widget_get_style_context (win);
 
-    g_return_val_if_fail (state != NULL, NULL);
-    g_return_val_if_fail (name != NULL, NULL);
-    g_return_val_if_fail (style != NULL, NULL);
-    g_return_val_if_fail (GTK_IS_STYLE(style), NULL);
+    gtk_style_context_save (ctx);
+    gtk_style_context_add_class (ctx, "gtkstyle-fallback");
+    gtk_style_context_get (ctx, flags, property, &result, NULL);
+    gtk_style_context_restore (ctx);
 
-    n = state_value (state);
-    m = name_value (name);
+    *rgba = *result;
 
-    switch (m)
+    switch (gtkstyle)
     {
-        case GTKSTYLE_FG:
-            gc = style->fg_gc[n];
-            break;
-        case GTKSTYLE_BG:
-            gc = style->bg_gc[n];
-            break;
-        case GTKSTYLE_TEXT:
-            gc = style->text_gc[n];
-            break;
-        case GTKSTYLE_BASE:
-            gc = style->base_gc[n];
-            break;
         case GTKSTYLE_LIGHT:
-            gc = style->light_gc[n];
+            rgba_shade (rgba, LIGHTNESS_MULT);
             break;
         case GTKSTYLE_DARK:
-            gc = style->dark_gc[n];
+            rgba_shade (rgba, DARKNESS_MULT);
             break;
-        default:
         case GTKSTYLE_MID:
-            gc = style->mid_gc[n];
+            rgba_shade (rgba, LIGHTNESS_MULT);
+            rgba_shade (result, DARKNESS_MULT);
+            rgba->red = (rgba->red + result->red) / 2;
+            rgba->green = (rgba->green + result->green) / 2;
+            rgba->blue = (rgba->blue + result->blue) / 2;
             break;
     }
 
-    return (gc);
+    gdk_rgba_free (result);
+
+    return TRUE;
 }
 
-GdkGC *
-getUIStyle_gc (GtkWidget * win, const gchar * name, const gchar * state)
+gchar *
+getUIStyleString (GtkWidget * win, const gchar * name, const gchar * state)
 {
-    GtkStyle *style;
+    GdkRGBA color = {0, };
+    GdkRGBA bg = {0, };
+    gint red;
+    gint green;
+    gint blue;
 
-    TRACE ("entering getUIStyle_gc");
+    TRACE ("entering getUIStyleString");
 
-    g_return_val_if_fail (win != NULL, NULL);
-    g_return_val_if_fail (GTK_IS_WIDGET (win), NULL);
-    g_return_val_if_fail (gtk_widget_get_realized (win), NULL);
-
-    style = gtk_rc_get_style (win);
-    if (!style)
-    {
-        style = gtk_widget_get_style (win);
-    }
-    if (!style)
+    if (getUIStyleColor (win, name, state, &color))
     {
-        style = gtk_widget_get_default_style ();
+        if (color.alpha < 1 && g_strcmp0 (name, "bg") && getUIStyleColor (win, "bg", state, &bg))
+        {
+            /* compose bg and fg colors to get opaque color */
+            color.red = color.red * color.alpha + bg.red * (1 - color.alpha);
+            color.green = color.green * color.alpha + bg.green * (1 - color.alpha);
+            color.blue = color.blue * color.alpha + bg.blue * (1 - color.alpha);
+        }
     }
-    return (_getUIStyle_gc (name, state, style));
+
+    red = color.red * 0xff;
+    green = color.green * 0xff;
+    blue = color.blue * 0xff;
+
+    return g_strdup_printf ("#%02x%02x%02x%02x%02x%02x", red, red, green, green, blue, blue);
 }
 
 PangoFontDescription *
 getUIPangoFontDesc (GtkWidget * win)
 {
+    GtkStyleContext      *ctx;
+    PangoFontDescription *font_desc;
+
     TRACE ("entering getUIPangoFontDesc");
 
     g_return_val_if_fail (win != NULL, NULL);
     g_return_val_if_fail (GTK_IS_WIDGET (win), NULL);
     g_return_val_if_fail (gtk_widget_get_realized (win), NULL);
 
-    return (win->style->font_desc);
+    ctx = gtk_widget_get_style_context (win);
+    gtk_style_context_get (ctx, GTK_STATE_FLAG_NORMAL,
+                           GTK_STYLE_PROPERTY_FONT, &font_desc,
+                           NULL);
+
+    return font_desc;
 }
 
 PangoContext *
diff --git a/src/ui_style.h b/src/ui_style.h
index aec3e3e..a38bbc0 100644
--- a/src/ui_style.h
+++ b/src/ui_style.h
@@ -31,10 +31,11 @@
 #include <gtk/gtk.h>
 #include <pango/pango-font.h>
 
-gchar                   *getUIStyle                             (GtkWidget *,
+gboolean                 getUIStyleColor                        (GtkWidget *,
                                                                  const gchar *,
-                                                                 const gchar *);
-GdkGC                   *getUIStyle_gc                          (GtkWidget *,
+                                                                 const gchar *,
+                                                                 GdkRGBA *);
+gchar                   *getUIStyleString                       (GtkWidget *,
                                                                  const gchar *,
                                                                  const gchar *);
 PangoFontDescription    *getUIPangoFontDesc                     (GtkWidget *);
diff --git a/src/wireframe.c b/src/wireframe.c
index 9ac4e17..3f7338a 100644
--- a/src/wireframe.c
+++ b/src/wireframe.c
@@ -181,26 +181,14 @@ wireframeUpdate (Client *c, WireFrame *wireframe)
 static void
 wireframeInitColor (WireFrame *wireframe)
 {
-    ScreenInfo *screen_info;
-    gchar *color;
-    GdkColor gcolor;
+    GdkRGBA rgba;
 
-    screen_info = wireframe->screen_info;
-    color = getUIStyle  (myScreenGetGtkWidget (screen_info), "bg", "selected");
-    if (gdk_color_parse (color, &gcolor))
-    {
-        wireframe->red   = (gdouble) gcolor.red / (gdouble) 65535;
-        wireframe->green = (gdouble) gcolor.green / (gdouble) 65535;
-        wireframe->blue  = (gdouble) gcolor.blue / (gdouble) 65535;
-    }
-    else
+    if (getUIStyleColor (myScreenGetGtkWidget (wireframe->screen_info), "bg", "selected", &rgba))
     {
-        g_warning ("Cannot parse color %s", color);
-        wireframe->red   = 0.0;
-        wireframe->green = 0.5;
-        wireframe->blue  = 1.0;
+        wireframe->red = rgba.red;
+        wireframe->green = rgba.green;
+        wireframe->blue = rgba.blue;
     }
-    g_free (color);
 }
 
 WireFrame *

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list