[gnome-power-manager/wip/albfan/dark-mode] Draw correctly on dark mode




commit 16a0905db6f016d39e7853a7d3edea960c15d0c2
Author: agurk <timothy moll+github gmail com>
Date:   Sun Aug 23 16:47:00 2020 +0200

    Draw correctly on dark mode
    
    Allow to select a theme
    Define colors for dark and ligth theme

 data/org.gnome.power-manager.gschema.xml |  10 +++
 src/egg-graph-widget.c                   | 148 ++++++++++++++++++++++++-------
 src/egg-graph-widget.h                   |   3 +
 src/gpm-statistics.c                     |  84 +++++++++++++++---
 4 files changed, 199 insertions(+), 46 deletions(-)
---
diff --git a/data/org.gnome.power-manager.gschema.xml b/data/org.gnome.power-manager.gschema.xml
index 85b70222..db307a4d 100644
--- a/data/org.gnome.power-manager.gschema.xml
+++ b/data/org.gnome.power-manager.gschema.xml
@@ -45,5 +45,15 @@
       <summary>The ID of the last device selected</summary>
       <description>The identifier of the last device which is used to return focus to the correct 
device.</description>
     </key>
+    <key name="info-graph-colors" type="s">
+      <choices>
+          <choice value='auto'/>
+          <choice value='dark'/>
+          <choice value='light'/>
+      </choices>
+      <default>'auto'</default>
+      <summary>The colors used to draw the graphs</summary>
+      <description>The colours used to draw the graphs and if these should be autodetected.</description>
+    </key>
   </schema>
 </schemalist>
diff --git a/src/egg-graph-widget.c b/src/egg-graph-widget.c
index 2a99053c..57a38af0 100644
--- a/src/egg-graph-widget.c
+++ b/src/egg-graph-widget.c
@@ -47,6 +47,16 @@ typedef struct {
        gint                     box_width;
        gint                     box_height;
 
+       guint32                  text_color;
+       guint32                  line_color;
+       guint32                  legend_line_color;
+       guint32                  legend_text_color;
+       guint32                  dot_stroke_color;
+       guint32                  background_color;
+       guint32                  background_stroke_color;
+       guint32                  outline_color;
+       gboolean                 dark_colors;
+
        guint                    divs_x; /* number of divisions */
 
        gdouble                  unit_x; /* box pixels per x unit */
@@ -83,6 +93,7 @@ enum
        PROP_START_Y,
        PROP_STOP_X,
        PROP_STOP_Y,
+       PROP_DARK_MODE,
        PROP_LAST
 };
 
@@ -135,6 +146,13 @@ egg_graph_widget_get_use_legend (EggGraphWidget *graph)
        return priv->use_legend;
 }
 
+void
+egg_graph_widget_set_dark_colors (EggGraphWidget *graph, gboolean dark_colors)
+{
+       EggGraphWidgetPrivate *priv = GET_PRIVATE (graph);
+       priv->dark_colors = dark_colors;
+}
+
 static void
 up_graph_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
 {
@@ -174,6 +192,9 @@ up_graph_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec
        case PROP_STOP_Y:
                g_value_set_double (value, priv->stop_y);
                break;
+       case PROP_DARK_MODE:
+               g_value_set_boolean (value, priv->dark_colors);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -220,6 +241,9 @@ up_graph_set_property (GObject *object, guint prop_id, const GValue *value, GPar
        case PROP_STOP_Y:
                priv->stop_y = g_value_get_double (value);
                break;
+       case PROP_DARK_MODE:
+               priv->dark_colors = g_value_get_boolean (value);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -301,6 +325,50 @@ egg_graph_widget_class_init (EggGraphWidgetClass *class)
                                         g_param_spec_double ("stop-y", NULL, NULL,
                                                           -G_MAXDOUBLE, G_MAXDOUBLE, 100.f,
                                                           G_PARAM_READWRITE));
+       g_object_class_install_property (object_class,
+                                        PROP_DARK_MODE,
+                                        g_param_spec_boolean ("dark-mode", NULL, NULL,
+                                                          FALSE,
+                                                          G_PARAM_READWRITE));
+}
+
+static guint32
+gpm_color_from_rgb (guint8 red, guint8 green, guint8 blue)
+{
+       guint32 color = 0;
+       color += (guint32) red * 0x10000;
+       color += (guint32) green * 0x100;
+       color += (guint32) blue;
+       return color;
+}
+
+static void
+egg_graph_widget_set_colors (EggGraphWidget *graph) {
+       EggGraphWidgetPrivate *priv = GET_PRIVATE (graph);
+       gboolean dark = priv->dark_colors;
+
+       if (dark) {
+               priv->text_color = gpm_color_from_rgb (205, 205, 205);
+               priv->line_color = gpm_color_from_rgb (230, 230, 230);
+               priv->legend_text_color = gpm_color_from_rgb (255, 255, 255);
+               priv->legend_line_color = gpm_color_from_rgb (230, 230, 230);
+               priv->dot_stroke_color = gpm_color_from_rgb (255, 255, 255);
+               /* background is set to transparent if dark_colors is set */
+               priv->background_color = gpm_color_from_rgb (0, 0, 0);
+               priv->background_stroke_color = gpm_color_from_rgb (230, 230, 230);
+               priv->outline_color = gpm_color_from_rgb (100, 100, 100);
+       } else {
+               priv->text_color = gpm_color_from_rgb (50, 50, 50);
+               priv->line_color = gpm_color_from_rgb (25, 25, 25);
+               priv->legend_text_color = gpm_color_from_rgb (0, 0, 0);
+               priv->legend_line_color = gpm_color_from_rgb (25, 25, 25);
+               priv->dot_stroke_color = gpm_color_from_rgb (0, 0, 0);
+               /* background is set to transparent if dark_colors is set */
+               priv->background_color = gpm_color_from_rgb (255, 255, 255);
+               priv->background_stroke_color = gpm_color_from_rgb (25, 25, 25);
+               priv->outline_color = gpm_color_from_rgb (155, 155, 155);
+       }
+
 }
 
 static void
@@ -323,6 +391,8 @@ egg_graph_widget_init (EggGraphWidget *graph)
        priv->type_x = EGG_GRAPH_WIDGET_KIND_TIME;
        priv->type_y = EGG_GRAPH_WIDGET_KIND_PERCENTAGE;
 
+       egg_graph_widget_set_colors (graph);
+
        /* do pango stuff */
        context = gtk_widget_get_pango_context (GTK_WIDGET (graph));
        pango_context_set_base_gravity (context, PANGO_GRAVITY_AUTO);
@@ -453,6 +523,22 @@ egg_graph_widget_get_axis_label (EggGraphWidgetKind axis, gdouble value)
        return text;
 }
 
+static void
+egg_color_to_rgb (guint32 color, guint8 *red, guint8 *green, guint8 *blue)
+{
+       *red = (color & 0xff0000) / 0x10000;
+       *green = (color & 0x00ff00) / 0x100;
+       *blue = color & 0x0000ff;
+}
+
+static void
+egg_graph_widget_set_color (cairo_t *cr, guint32 color)
+{
+       guint8 r, g, b;
+       egg_color_to_rgb (color, &r, &g, &b);
+       cairo_set_source_rgb (cr, ((gdouble) r)/256.0f, ((gdouble) g)/256.0f, ((gdouble) b)/256.0f);
+}
+
 static void
 egg_graph_widget_draw_grid (EggGraphWidget *graph, cairo_t *cr)
 {
@@ -469,7 +555,7 @@ egg_graph_widget_draw_grid (EggGraphWidget *graph, cairo_t *cr)
        cairo_set_dash (cr, dotted, 2, 0.0);
 
        /* do vertical lines */
-       cairo_set_source_rgb (cr, 0.1, 0.1, 0.1);
+       egg_graph_widget_set_color (cr, priv->line_color);
        for (i = 1; i < priv->divs_x; i++) {
                b = priv->box_x + ((gdouble) i * divwidth);
                cairo_move_to (cr, (gint)b + 0.5f, priv->box_y);
@@ -506,7 +592,7 @@ egg_graph_widget_draw_labels (EggGraphWidget *graph, cairo_t *cr)
        cairo_save (cr);
 
        /* do x text */
-       cairo_set_source_rgb (cr, 0.2f, 0.2f, 0.2f);
+       egg_graph_widget_set_color (cr, priv->text_color);
        for (i = 0; i < priv->divs_x + 1; i++) {
                g_autofree gchar *text = NULL;
                b = priv->box_x + ((gdouble) i * divwidth);
@@ -555,14 +641,6 @@ egg_graph_widget_draw_labels (EggGraphWidget *graph, cairo_t *cr)
        cairo_restore (cr);
 }
 
-static void
-egg_color_to_rgb (guint32 color, guint8 *red, guint8 *green, guint8 *blue)
-{
-       *red = (color & 0xff0000) / 0x10000;
-       *green = (color & 0x00ff00) / 0x100;
-       *blue = color & 0x0000ff;
-}
-
 static guint
 egg_graph_widget_get_y_label_max_width (EggGraphWidget *graph, cairo_t *cr)
 {
@@ -839,14 +917,6 @@ egg_graph_widget_autorange_y (EggGraphWidget *graph)
                   priv->start_y, priv->stop_y);
 }
 
-static void
-egg_graph_widget_set_color (cairo_t *cr, guint32 color)
-{
-       guint8 r, g, b;
-       egg_color_to_rgb (color, &r, &g, &b);
-       cairo_set_source_rgb (cr, ((gdouble) r)/256.0f, ((gdouble) g)/256.0f, ((gdouble) b)/256.0f);
-}
-
 /**
  * egg_graph_widget_draw_legend_line:
  * @cr: Cairo drawing context
@@ -857,8 +927,9 @@ egg_graph_widget_set_color (cairo_t *cr, guint32 color)
  * Draw the legend line on the graph of a specified color
  **/
 static void
-egg_graph_widget_draw_legend_line (cairo_t *cr, gdouble x, gdouble y, guint32 color)
+egg_graph_widget_draw_legend_line (EggGraphWidget *graph, cairo_t *cr, gdouble x, gdouble y, guint32 color)
 {
+       EggGraphWidgetPrivate *priv = GET_PRIVATE (graph);
        gdouble width = 10;
        gdouble height = 6;
        /* background */
@@ -867,7 +938,7 @@ egg_graph_widget_draw_legend_line (cairo_t *cr, gdouble x, gdouble y, guint32 co
        cairo_fill (cr);
        /* solid outline box */
        cairo_rectangle (cr, (int) (x - (width/2)) + 0.5, (int) (y - (height/2)) + 0.5, width, height);
-       cairo_set_source_rgb (cr, 0.1, 0.1, 0.1);
+       egg_graph_widget_set_color (cr, priv->legend_line_color);
        cairo_set_line_width (cr, 1);
        cairo_stroke (cr);
 }
@@ -891,8 +962,9 @@ egg_graph_widget_get_pos_on_graph (EggGraphWidget *graph,
 }
 
 static void
-egg_graph_widget_draw_dot (cairo_t *cr, gdouble x, gdouble y, guint32 color)
+egg_graph_widget_draw_dot (EggGraphWidget *graph, cairo_t *cr, gdouble x, gdouble y, guint32 color)
 {
+       EggGraphWidgetPrivate *priv = GET_PRIVATE (graph);
        gdouble width;
        /* box */
        width = 4.0;
@@ -900,7 +972,8 @@ egg_graph_widget_draw_dot (cairo_t *cr, gdouble x, gdouble y, guint32 color)
        egg_graph_widget_set_color (cr, color);
        cairo_fill (cr);
        cairo_rectangle (cr, (gint)x + 0.5f - (width/2), (gint)y + 0.5f - (width/2), width, width);
-       cairo_set_source_rgb (cr, 0, 0, 0);
+
+       egg_graph_widget_set_color (cr, priv->dot_stroke_color);
        cairo_set_line_width (cr, 0.5);
        cairo_stroke (cr);
 }
@@ -939,11 +1012,11 @@ egg_graph_widget_draw_line (EggGraphWidget *graph, cairo_t *cr)
 
                /* plot points */
                if (plot == EGG_GRAPH_WIDGET_PLOT_POINTS || plot == EGG_GRAPH_WIDGET_PLOT_BOTH) {
-                       egg_graph_widget_draw_dot (cr, x, y, point->color);
+                       egg_graph_widget_draw_dot (graph, cr, x, y, point->color);
                        for (i = 1; i < data->len; i++) {
                                point = (EggGraphPoint *) g_ptr_array_index (data, i);
                                egg_graph_widget_get_pos_on_graph (graph, point->x, point->y, &x, &y);
-                               egg_graph_widget_draw_dot (cr, x, y, point->color);
+                               egg_graph_widget_draw_dot (graph, cr, x, y, point->color);
                        }
                }
 
@@ -1003,15 +1076,21 @@ egg_graph_widget_draw_line (EggGraphWidget *graph, cairo_t *cr)
  * @height: The item height
  **/
 static void
-egg_graph_widget_draw_bounding_box (cairo_t *cr, gint x, gint y, gint width, gint height)
+egg_graph_widget_draw_bounding_box (EggGraphWidget *graph, cairo_t *cr, gint x, gint y, gint width, gint 
height)
 {
+       EggGraphWidgetPrivate *priv = GET_PRIVATE (graph);
        /* background */
        cairo_rectangle (cr, x, y, width, height);
-       cairo_set_source_rgb (cr, 1, 1, 1);
+
+       if (priv->dark_colors)
+               cairo_set_source_rgba (cr, 0, 0, 0, 0);
+       else
+               egg_graph_widget_set_color (cr, priv->background_color);
+
        cairo_fill (cr);
        /* solid outline box */
        cairo_rectangle (cr, x + 0.5f, y + 0.5f, width - 1, height - 1);
-       cairo_set_source_rgb (cr, 0.1, 0.1, 0.1);
+       egg_graph_widget_set_color (cr, priv->background_stroke_color);
        cairo_set_line_width (cr, 1);
        cairo_stroke (cr);
 }
@@ -1033,15 +1112,16 @@ egg_graph_widget_draw_legend (EggGraphWidget *graph, cairo_t *cr,
        guint i;
        EggGraphWidgetLegendData *legend_data;
 
-       egg_graph_widget_draw_bounding_box (cr, x, y, width, height);
+       egg_graph_widget_draw_bounding_box (graph, cr, x, y, width, height);
        y_count = y + 10;
 
        /* add the line colors to the legend */
        for (i = 0; i < priv->legend_list->len; i++) {
                legend_data = g_ptr_array_index (priv->legend_list, i);
-               egg_graph_widget_draw_legend_line (cr, x + 8, y_count, legend_data->color);
+               egg_graph_widget_draw_legend_line (graph, cr, x + 8, y_count, legend_data->color);
                cairo_move_to (cr, x + 8 + 10, y_count - 6);
-               cairo_set_source_rgb (cr, 0, 0, 0);
+               egg_graph_widget_set_color (cr, priv->legend_text_color);
+               //cairo_set_source_rgb (cr, 0, 0, 0);
                pango_layout_set_text (priv->layout, legend_data->desc, -1);
                pango_cairo_show_layout (cr, priv->layout);
                y_count = y_count + EGG_GRAPH_WIDGET_LEGEND_SPACING;
@@ -1108,6 +1188,8 @@ egg_graph_widget_draw (GtkWidget *widget, cairo_t *cr)
        egg_graph_widget_legend_calculate_size (graph, cr, &legend_width, &legend_height);
        cairo_save (cr);
 
+       egg_graph_widget_set_colors (graph);
+
        /* we need this so we know the y text */
        if (priv->autorange_x)
                egg_graph_widget_autorange_x (graph);
@@ -1132,15 +1214,15 @@ egg_graph_widget_draw (GtkWidget *widget, cairo_t *cr)
        }
 
        /* graph background */
-       egg_graph_widget_draw_bounding_box (cr, priv->box_x, priv->box_y,
-                                    priv->box_width, priv->box_height);
+       egg_graph_widget_draw_bounding_box (graph, cr, priv->box_x, priv->box_y,
+                                           priv->box_width, priv->box_height);
        if (priv->use_grid)
                egg_graph_widget_draw_grid (graph, cr);
 
        /* solid outline box */
        cairo_rectangle (cr, priv->box_x + 0.5f, priv->box_y + 0.5f,
                         priv->box_width - 1, priv->box_height - 1);
-       cairo_set_source_rgb (cr, 0.6f, 0.6f, 0.6f);
+       egg_graph_widget_set_color (cr, priv->outline_color);
        cairo_set_line_width (cr, 1);
        cairo_stroke (cr);
 
diff --git a/src/egg-graph-widget.h b/src/egg-graph-widget.h
index 6d1b0070..ee8dcdaa 100644
--- a/src/egg-graph-widget.h
+++ b/src/egg-graph-widget.h
@@ -61,6 +61,9 @@ void           egg_graph_widget_set_use_legend        (EggGraphWidget         *graph,
                                                         gboolean                use_legend);
 gboolean        egg_graph_widget_get_use_legend        (EggGraphWidget         *graph);
 
+void            egg_graph_widget_set_dark_colors       (EggGraphWidget         *graph,
+                                                        gboolean                dark_colours);
+
 gchar          *egg_graph_widget_export_to_svg         (EggGraphWidget         *graph,
                                                         guint                   width,
                                                         guint                   height);
diff --git a/src/gpm-statistics.c b/src/gpm-statistics.c
index dce87689..034cc17b 100644
--- a/src/gpm-statistics.c
+++ b/src/gpm-statistics.c
@@ -40,6 +40,7 @@
 #define GPM_SETTINGS_INFO_STATS_GRAPH_POINTS           "info-stats-graph-points"
 #define GPM_SETTINGS_INFO_PAGE_NUMBER                  "info-page-number"
 #define GPM_SETTINGS_INFO_LAST_DEVICE                  "info-last-device"
+#define GPM_SETTINGS_INFO_COLORS                       "info-graph-colors"
 
 static GtkBuilder *builder = NULL;
 static GtkListStore *list_store_info = NULL;
@@ -112,6 +113,10 @@ enum {
 #define GPM_UP_TIME_PRECISION                  5*60 /* seconds */
 #define GPM_UP_TEXT_MIN_TIME                   120 /* seconds */
 
+#define GPM_STATS_COLOR_DARK           "dark"
+#define GPM_STATS_COLOR_LIGHT          "light"
+#define GPM_STATS_COLOR_AUTO           "auto"
+
 /**
  * gpm_stats_get_device_icon_suffix:
  * @device: The UpDevice
@@ -716,6 +721,33 @@ gpm_color_from_rgb (guint8 red, guint8 green, guint8 blue)
        return color;
 }
 
+static gboolean
+gpm_stats_is_dark_mode (GtkWidget *widget)
+{
+       g_autofree gchar *colors_preference;
+       GtkStyleContext *style_context;
+       GdkRGBA color;
+
+       colors_preference = g_settings_get_string (settings, GPM_SETTINGS_INFO_COLORS);
+       if (colors_preference == NULL)
+               colors_preference = GPM_STATS_COLOR_AUTO;
+
+       if ((g_strcmp0 (colors_preference, GPM_STATS_COLOR_AUTO) == 0))
+       {
+               style_context = gtk_widget_get_style_context (widget);
+               gtk_style_context_get_color (style_context, GTK_STATE_FLAG_PRELIGHT, &color);
+
+               if (color.red + color.blue + color.green > 1.5f)
+                       return TRUE;
+       }
+       else if ((g_strcmp0 (colors_preference, GPM_STATS_COLOR_LIGHT) == 0))
+               return FALSE;
+       else if ((g_strcmp0 (colors_preference, GPM_STATS_COLOR_DARK) == 0))
+               return TRUE;
+       else
+               return FALSE;
+}
+
 static void
 gpm_stats_update_info_page_history (UpDevice *device)
 {
@@ -774,6 +806,10 @@ gpm_stats_update_info_page_history (UpDevice *device)
                goto out;
        }
 
+       g_object_set (graph_history,
+                         "dark-mode", gpm_stats_is_dark_mode(widget),
+                         NULL);
+
        /* hide no data and show graph */
        gtk_widget_hide (widget);
        gtk_widget_show (graph_history);
@@ -791,19 +827,37 @@ gpm_stats_update_info_page_history (UpDevice *device)
                point = egg_graph_point_new ();
                point->x = (gint32) up_history_item_get_time (item) - offset;
                point->y = up_history_item_get_value (item);
-               if (up_history_item_get_state (item) == UP_DEVICE_STATE_CHARGING)
-                       point->color = gpm_color_from_rgb (255, 0, 0);
-               else if (up_history_item_get_state (item) == UP_DEVICE_STATE_DISCHARGING)
-                       point->color = gpm_color_from_rgb (0, 0, 255);
-               else if (up_history_item_get_state (item) == UP_DEVICE_STATE_PENDING_CHARGE)
-                       point->color = gpm_color_from_rgb (200, 0, 0);
-               else if (up_history_item_get_state (item) == UP_DEVICE_STATE_PENDING_DISCHARGE)
-                       point->color = gpm_color_from_rgb (0, 0, 200);
-               else {
-                       if (g_strcmp0 (history_type, GPM_HISTORY_RATE_VALUE) == 0)
-                               point->color = gpm_color_from_rgb (255, 255, 255);
-                       else
-                               point->color = gpm_color_from_rgb (0, 255, 0);
+               if (gpm_stats_is_dark_mode (widget))
+               {
+                       if (up_history_item_get_state (item) == UP_DEVICE_STATE_CHARGING)
+                               point->color = gpm_color_from_rgb (255,0,0)
+                       else if (up_history_item_get_state (item) == UP_DEVICE_STATE_DISCHARGING)
+                               point->color = gpm_color_from_rgb (0, 0, 255);
+                       else if (up_history_item_get_state (item) == UP_DEVICE_STATE_PENDING_CHARGE)
+                               point->color = gpm_color_from_rgb (200, 0, 0);
+                       else if (up_history_item_get_state (item) == UP_DEVICE_STATE_PENDING_DISCHARGE)
+                               point->color = gpm_color_from_rgb (0, 0, 200);
+                       else {
+                               if (g_strcmp0 (history_type, GPM_HISTORY_RATE_VALUE) == 0)
+                                       point->color = gpm_color_from_rgb (255, 255, 255);
+                               else
+                                       point->color = gpm_color_from_rgb (0, 255, 0);
+                       }
+               } else {
+                       if (up_history_item_get_state (item) == UP_DEVICE_STATE_CHARGING)
+                               point->color = gpm_color_from_rgb (255, 0, 0);
+                       else if (up_history_item_get_state (item) == UP_DEVICE_STATE_DISCHARGING)
+                               point->color = gpm_color_from_rgb (0, 130, 255);
+                       else if (up_history_item_get_state (item) == UP_DEVICE_STATE_PENDING_CHARGE)
+                               point->color = gpm_color_from_rgb (200, 0, 0);
+                       else if (up_history_item_get_state (item) == UP_DEVICE_STATE_PENDING_DISCHARGE)
+                               point->color = gpm_color_from_rgb (0, 0, 200);
+                       else {
+                               if (g_strcmp0 (history_type, GPM_HISTORY_RATE_VALUE) == 0)
+                                       point->color = gpm_color_from_rgb (255, 255, 255);
+                               else
+                                       point->color = gpm_color_from_rgb (0, 255, 0);
+                       }
                }
                g_ptr_array_add (new, point);
        }
@@ -882,6 +936,10 @@ gpm_stats_update_info_page_stats (UpDevice *device)
                goto out;
        }
 
+       g_object_set (graph_statistics,
+                         "dark-mode", gpm_stats_is_dark_mode (widget),
+                         NULL);
+
        /* hide no data and show graph */
        gtk_widget_hide (widget);
        gtk_widget_show (graph_statistics);


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