[planner: 40/61] usage-row: Port to cairo drawing




commit 6553a952c8f7cb5fd1da6f5dca0d58994b6733e2
Author: Mart Raudsepp <leio gentoo org>
Date:   Mon Dec 28 01:00:53 2020 +0200

    usage-row: Port to cairo drawing
    
    The drawing should match what was done before, except for the completed
    percentage indicator, which used to be a 1980's stipple pattern, but now
    is a lighter color slightly narrower bar on top.

 src/planner-usage-row.c | 349 +++++++++++++++++++-----------------------------
 1 file changed, 141 insertions(+), 208 deletions(-)
---
diff --git a/src/planner-usage-row.c b/src/planner-usage-row.c
index f343d92b..92bab9e9 100644
--- a/src/planner-usage-row.c
+++ b/src/planner-usage-row.c
@@ -5,6 +5,7 @@
  * Copyright (C) 2003 Xavier Ordoquy <xordoquy wanadoo fr>
  * Copyright (C) 2006 Alvaro del Castillo <acs barrapunto com>
  * Copyright (C) 2008 Lee Baylis <lee leebaylis co uk>
+ * Copyright (C) 2020 Mart Raudsepp <mart leio tech>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -86,10 +87,6 @@ typedef enum {
 } State;
 
 struct _PlannerUsageRowPriv {
-        GdkGC         *complete_gc;
-        GdkGC         *break_gc;
-        GdkGC         *fill_gc;
-        GdkGC         *frame_gc;
         PangoLayout   *layout;
 
         MrpAssignment *assignment;
@@ -128,8 +125,6 @@ static void     usage_row_update                       (GnomeCanvasItem        *
                                                         double                 *affine,
                                                         ArtSVP                 *clip_path,
                                                         int                     flags);
-static void     usage_row_realize                      (GnomeCanvasItem        *item);
-static void     usage_row_unrealize                    (GnomeCanvasItem        *item);
 static void     usage_row_draw                         (GnomeCanvasItem        *item,
                                                         GdkDrawable            *drawable,
                                                         gint                    x,
@@ -169,26 +164,6 @@ static void     usage_row_resource_assignment_added_cb (MrpResource            *
 
 static GnomeCanvasItemClass *parent_class;
 static guint                 signals[LAST_SIGNAL];
-static GdkBitmap            *complete_stipple = NULL;
-static gchar                 complete_stipple_pattern[] = { 0x02, 0x01 };
-static GdkBitmap            *break_stipple = NULL;
-static gchar                 break_stipple_pattern[] = { 0x03 };
-
-static GdkColor              color_normal;
-static GdkColor              color_normal_light;
-static GdkColor              color_normal_dark;
-
-static GdkColor              color_free;
-static GdkColor              color_free_light;
-static GdkColor              color_free_dark;
-
-static GdkColor              color_underuse;
-static GdkColor              color_underuse_light;
-static GdkColor              color_underuse_dark;
-
-static GdkColor              color_overuse;
-static GdkColor              color_overuse_light;
-static GdkColor              color_overuse_dark;
 
 
 GType
@@ -305,8 +280,6 @@ usage_row_class_init (PlannerUsageRowClass * class)
         object_class->destroy = usage_row_destroy;
 
         item_class->update = usage_row_update;
-        item_class->realize = usage_row_realize;
-        item_class->unrealize = usage_row_unrealize;
         item_class->draw = usage_row_draw;
         item_class->point = usage_row_point;
         item_class->bounds = usage_row_bounds;
@@ -728,101 +701,35 @@ usage_row_update (GnomeCanvasItem *item,
         gnome_canvas_update_bbox (item, x1, y1, x2, y2);
 }
 
-static void
-usage_row_realize (GnomeCanvasItem * item)
-{
-        PlannerUsageRow     *row;
-        PlannerUsageRowPriv *priv;
-
-        row = PLANNER_USAGE_ROW (item);
-        priv = row->priv;
-
-        GNOME_CANVAS_ITEM_CLASS (parent_class)->realize (item);
-
-        if (complete_stipple == NULL) {
-                complete_stipple = gdk_bitmap_create_from_data (NULL,
-                                                                complete_stipple_pattern,
-                                                                2, 2);
-
-                g_object_add_weak_pointer (G_OBJECT (complete_stipple),
-                                           (gpointer) & complete_stipple);
-
-               gnome_canvas_get_color (item->canvas, "LightSkyBlue3", &color_normal);
-               gnome_canvas_get_color (item->canvas, "#9ac7e0", &color_normal_light);
-               gnome_canvas_get_color (item->canvas, "#7da1b5", &color_normal_dark);
-
-               gnome_canvas_get_color (item->canvas, "indian red", &color_overuse);
-               gnome_canvas_get_color (item->canvas, "#de6464", &color_overuse_light);
-               gnome_canvas_get_color (item->canvas, "#ba5454", &color_overuse_dark);
-
-               gnome_canvas_get_color (item->canvas, "grey", &color_underuse);
-               gnome_canvas_get_color (item->canvas, "#d6d6d6", &color_underuse_light);
-               gnome_canvas_get_color (item->canvas, "#a8a8a8", &color_underuse_dark);
-
-               gnome_canvas_get_color (item->canvas, "medium sea green", &color_free);
-               gnome_canvas_get_color (item->canvas, "#43c77e", &color_free_light);
-               gnome_canvas_get_color (item->canvas, "#359e64", &color_free_dark);
-       } else {
-                g_object_ref (complete_stipple);
-        }
-
-        if (break_stipple == NULL) {
-                break_stipple = gdk_bitmap_create_from_data (NULL,
-                                                             break_stipple_pattern,
-                                                             6, 1);
-
-                g_object_add_weak_pointer (G_OBJECT (break_stipple),
-                                           (gpointer) & break_stipple);
-        } else {
-                g_object_ref (break_stipple);
-        }
-
-        priv->complete_gc = gdk_gc_new (item->canvas->layout.bin_window);
-        gdk_gc_set_stipple (priv->complete_gc, complete_stipple);
-        gdk_gc_set_fill (priv->complete_gc, GDK_STIPPLED);
-
-        priv->break_gc = gdk_gc_new (item->canvas->layout.bin_window);
-        gdk_gc_set_stipple (priv->break_gc, break_stipple);
-        gdk_gc_set_fill (priv->break_gc, GDK_STIPPLED);
-
-        priv->fill_gc = gdk_gc_new (item->canvas->layout.bin_window);
-
-        priv->frame_gc = gdk_gc_new (item->canvas->layout.bin_window);
-        gdk_gc_set_line_attributes (priv->frame_gc,
-                                    1,
-                                    GDK_LINE_SOLID,
-                                    GDK_CAP_BUTT, GDK_JOIN_MITER);
-}
-
-static void
-usage_row_unrealize (GnomeCanvasItem * item)
-{
-        PlannerUsageRow *row;
-
-        row = PLANNER_USAGE_ROW (item);
-
-        g_object_unref (row->priv->complete_gc);
-        row->priv->complete_gc = NULL;
-
-        g_object_unref (row->priv->break_gc);
-        row->priv->break_gc = NULL;
-
-        g_object_unref (row->priv->fill_gc);
-        row->priv->fill_gc = NULL;
-
-       g_object_unref (row->priv->frame_gc);
-        row->priv->frame_gc = NULL;
-
-        if (break_stipple) {
-                g_object_unref (break_stipple);
-        }
-
-        if (complete_stipple) {
-                g_object_unref (complete_stipple);
-        }
-
-        GNOME_CANVAS_ITEM_CLASS (parent_class)->unrealize (item);
-}
+/* TODO-GTK3: Move to GdkRGBA + gdk_cairo_set_source_rgba; later to themeing support */
+#define SET_CAIRO_COLOR(r, g, b) cairo_set_source_rgb (cr, r / 255., g / 255., b / 255.)
+
+/* LightSkyBlue3 */
+#define SET_COLOR_NORMAL         SET_CAIRO_COLOR(141, 182, 205)
+/* #9ac7e0 */
+#define SET_COLOR_NORMAL_LIGHT   SET_CAIRO_COLOR(0x9a, 0xc7, 0xe0)
+/* #7da1b5 */
+#define SET_COLOR_NORMAL_DARK    SET_CAIRO_COLOR(0x7d, 0xa1, 0xb5)
+/* indian red */
+#define SET_COLOR_OVERUSE        SET_CAIRO_COLOR(205, 92, 92)
+/* #de6464 */
+#define SET_COLOR_OVERUSE_LIGHT  SET_CAIRO_COLOR(0xde, 0x64, 0x64)
+/* #ba5454 */
+#define SET_COLOR_OVERUSE_DARK   SET_CAIRO_COLOR(0xba, 0x54, 0x54)
+/* grey */
+#define SET_COLOR_UNDERUSE       SET_CAIRO_COLOR(190, 190, 190)
+/* #d6d6d6 */
+#define SET_COLOR_UNDERUSE_LIGHT SET_CAIRO_COLOR(0xd6, 0xd6, 0xd6)
+/* #a8a8a8 */
+#define SET_COLOR_UNDERUSE_DARK  SET_CAIRO_COLOR(0xa8, 0xa8, 0xa8)
+/* medium sea green */
+#define SET_COLOR_FREE           SET_CAIRO_COLOR(60, 179, 113)
+/* #43c77e */
+#define SET_COLOR_FREE_LIGHT     SET_CAIRO_COLOR(0x43, 0xc7, 0x7e)
+/* #359e64 */
+#define SET_COLOR_FREE_DARK      SET_CAIRO_COLOR(0x35, 0x9e, 0x64)
+/* LightSkyBlue1 */
+#define SET_COLOR_COMPLETE       SET_CAIRO_COLOR(176, 226, 255)
 
 typedef enum {
         START_ASSIGN,
@@ -884,6 +791,7 @@ usage_row_draw_resource_ival (mrptime          start,
 {
         PlannerUsageRow     *row;
         PlannerUsageRowPriv *priv;
+        cairo_t             *cr;
 
         /* World coord */
         gdouble               xoffset, yoffset;
@@ -968,109 +876,119 @@ usage_row_draw_resource_ival (mrptime          start,
                 return;
         }
 
+        cr = gdk_cairo_create (drawable);
+        cairo_set_line_width (cr, 1.0);
+        cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+
         if (units == 0) {
-                gdk_gc_set_foreground (priv->fill_gc, &color_free);
+                SET_COLOR_FREE;
         }
        else if (units < 100) {
-                gdk_gc_set_foreground (priv->fill_gc, &color_underuse);
+                SET_COLOR_UNDERUSE;
         }
        else if (units == 100) {
-                gdk_gc_set_foreground (priv->fill_gc, &color_normal);
+                SET_COLOR_NORMAL;
         } else {
-                gdk_gc_set_foreground (priv->fill_gc, &color_overuse);
+                SET_COLOR_OVERUSE;
         }
 
         /* Draw the central part of the chunk */
        if (rr_xend >= rr_xstart && rr_yend >= rr_ystart) {
-               gdk_draw_rectangle (drawable,
-                                   priv->fill_gc,
-                                   TRUE,
-                                   rr_xstart, rr_ystart,
-                                   rr_xend - rr_xstart + 1, rr_yend - rr_ystart + 1);
+               cairo_rectangle (cr,
+                                rr_xstart, rr_ystart,
+                                rr_xend - rr_xstart + 1, rr_yend - rr_ystart + 1);
+               cairo_fill (cr);
        }
 
         if (units == 0) {
-                gdk_gc_set_foreground (priv->fill_gc, &color_free_light);
+                SET_COLOR_FREE_LIGHT;
         }
        else if (units < 100) {
-                gdk_gc_set_foreground (priv->fill_gc, &color_underuse_light);
+                SET_COLOR_UNDERUSE_LIGHT;
         }
        else if (units == 100) {
-                gdk_gc_set_foreground (priv->fill_gc, &color_normal_light);
+                SET_COLOR_NORMAL_LIGHT;
         } else {
-                gdk_gc_set_foreground (priv->fill_gc, &color_overuse_light);
+                SET_COLOR_OVERUSE_LIGHT;
         }
 
-        //gdk_gc_set_foreground (priv->fill_gc, &color_high);
-
+        /* TODO: Simplify drawing with cairo_rel_line_to or cairo_rectangle? */
         /* Top of the shadow. */
         if (cs_ystart == rs_ystart) {
-                gdk_draw_line (drawable, priv->fill_gc, r_xstart, rs_ystart,
-                               r_xend, rs_ystart);
+                cairo_move_to (cr, r_xstart + 0.5, rs_ystart + 0.5);
+                cairo_line_to (cr, r_xend + 0.5, rs_ystart + 0.5);
         }
 
         /* Left of the shadow. */
         if (chunk & ROW_START && cs_xstart == rs_xstart) {
-                gdk_draw_line (drawable, priv->fill_gc, rs_xstart, rs_ystart,
-                               rs_xstart, cs_yend);
+                cairo_move_to (cr, rs_xstart + 0.5, rs_ystart + 0.5);
+                cairo_line_to (cr, rs_xstart + 0.5, cs_yend + 0.5);
         }
 
+        cairo_stroke (cr);
+
        if (units == 0) {
-                gdk_gc_set_foreground (priv->fill_gc, &color_free_dark);
+                SET_COLOR_FREE_DARK;
         }
        else if (units < 100) {
-                gdk_gc_set_foreground (priv->fill_gc, &color_underuse_dark);
+                SET_COLOR_UNDERUSE_DARK;
         }
        else if (units == 100) {
-                gdk_gc_set_foreground (priv->fill_gc, &color_normal_dark);
+                SET_COLOR_NORMAL_DARK;
         } else {
-                gdk_gc_set_foreground (priv->fill_gc, &color_overuse_dark);
+                SET_COLOR_OVERUSE_DARK;
         }
 
-       //gdk_gc_set_foreground (priv->fill_gc, &color_shadow);
-
         /* Bottom of the shadow. */
         if (cs_yend == rs_yend) {
-                gdk_draw_line (drawable, priv->fill_gc, r_xstart, rs_yend,
-                               r_xend, rs_yend);
+                cairo_move_to (cr, r_xstart + 0.5, rs_yend + 0.5);
+                cairo_line_to (cr, r_xend + 0.5, rs_yend + 0.5);
         }
 
         /* Right of the shadow. */
         if (chunk & ROW_END && cs_xend == rs_xend) {
-                gdk_draw_line (drawable, priv->fill_gc, rs_xend, rs_ystart,
-                               rs_xend, cs_yend);
+                cairo_move_to (cr, rs_xend + 0.5, rs_ystart + 0.5);
+                cairo_line_to (cr, rs_xend + 0.5, cs_yend + 0.5);
         }
 
+        cairo_stroke (cr);
+
        /* Interval separator. */
        if (!(chunk & ROW_START)) {
-               gdk_gc_set_foreground (priv->fill_gc, &GTK_WIDGET (item->canvas)->style->white);
-               gdk_draw_line (drawable, priv->fill_gc, c_xstart, rs_ystart, c_xstart,
-                               rr_yend);
+               gdk_cairo_set_source_color (cr, &GTK_WIDGET (item->canvas)->style->white);
+               cairo_move_to (cr, c_xstart + 0.5, rs_ystart + 0.5);
+               cairo_line_to (cr, c_xstart + 0.5, rr_yend + 0.5);
+               cairo_stroke (cr);
        }
 
+        cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+
         /* Top frame. */
         if (c_ystart == r_ystart) {
-                gdk_draw_line (drawable, priv->frame_gc, r_xstart, r_ystart, r_xend,
-                               r_ystart);
+                cairo_move_to (cr, r_xstart + 0.5, r_ystart + 0.5);
+                cairo_line_to (cr, r_xend + 0.5, r_ystart + 0.5);
        }
 
         /* Bottom frame. */
         if (c_yend == r_yend) {
-                gdk_draw_line (drawable, priv->frame_gc, r_xstart, r_yend, r_xend,
-                               r_yend);
+                cairo_move_to (cr, r_xstart + 0.5, r_yend + 0.5);
+                cairo_line_to (cr, r_xend + 0.5, r_yend + 0.5);
        }
 
         /* Left frame. */
         if (chunk & ROW_START && c_xstart == r_xstart) {
-                gdk_draw_line (drawable, priv->frame_gc, r_xstart, r_ystart,
-                               r_xstart, r_yend);
+                cairo_move_to (cr, r_xstart + 0.5, r_ystart + 0.5);
+                cairo_line_to (cr, r_xstart + 0.5, r_yend + 0.5);
        }
 
         /* Right frame. */
         if (chunk & ROW_END && c_xend == r_xend) {
-                gdk_draw_line (drawable, priv->frame_gc, r_xend, r_ystart, r_xend,
-                               r_yend);
+                cairo_move_to (cr, r_xend + 0.5, r_ystart + 0.5);
+                cairo_line_to (cr, r_xend + 0.5, r_yend + 0.5);
        }
+
+        cairo_stroke (cr);
+        cairo_destroy (cr);
 }
 
 static void
@@ -1185,7 +1103,8 @@ usage_row_draw_assignment (PlannerUsageRow *row,
                            gint              width,
                            gint              height)
 {
-        PlannerUsageRowPriv *priv;
+        PlannerUsageRowPriv  *priv;
+        cairo_t              *cr;
         MrpTask              *task;
         gdouble               i2w_dx;
         gdouble               i2w_dy;
@@ -1227,6 +1146,10 @@ usage_row_draw_assignment (PlannerUsageRow *row,
                 return;
         }
 
+        cr = gdk_cairo_create (drawable);
+        cairo_set_line_width (cr, 1.0);
+        cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+
         /* summary_y = floor (priv->y + 2 * 0.15 * priv->height + 0.5) - y; */
 
         /* "Clip" the expose area. */
@@ -1245,75 +1168,85 @@ usage_row_draw_assignment (PlannerUsageRow *row,
         }
 
         if (rx1 <= rx2) {
-                if (complete_width > 0) {
-                        gnome_canvas_set_stipple_origin (item->canvas,
-                                                         priv->complete_gc);
-                }
-
-                gdk_gc_set_foreground (priv->fill_gc, &color_normal);
-
-                gdk_draw_rectangle (drawable,
-                                    priv->fill_gc,
-                                    TRUE,
-                                    rx1, cy1 + 1, rx2 - rx1, cy2 - cy1 - 1);
+                SET_COLOR_NORMAL;
+                cairo_rectangle (cr, rx1, cy1 + 1, rx2 - rx1, cy2 - cy1 - 1);
+                cairo_fill (cr);
 
                 if (rx1 <= complete_x2) {
-                        gdk_draw_rectangle (drawable,
-                                            priv->complete_gc,
-                                            TRUE,
-                                            rx1,
-                                            cy1 + 4,
-                                            complete_x2 - rx1, cy2 - cy1 - 7);
+                        /* TODO: Improve design of completed percentage bar; perhaps add borders? */
+                        SET_COLOR_COMPLETE;
+                        cairo_rectangle (cr,
+                                         rx1, cy1 + 5,
+                                         complete_x2 - rx1, cy2 - cy1 - 9);
+                        cairo_fill (cr);
                 }
 
-                gdk_draw_line (drawable, priv->frame_gc, rx1, cy1, rx2, cy1);
-                gdk_draw_line (drawable, priv->frame_gc, rx1, cy2, rx2, cy2);
+                cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+                cairo_move_to (cr, rx1 + 0.5, cy1 + 0.5);
+                cairo_line_to (cr, rx2 + 0.5, cy1 + 0.5);
+                cairo_move_to (cr, rx1 + 0.5, cy2 + 0.5);
+                cairo_line_to (cr, rx2 + 0.5, cy2 + 0.5);
+                cairo_stroke (cr);
 
-                gdk_gc_set_foreground (priv->fill_gc, &color_normal_light);
-                gdk_draw_line (drawable,
-                               priv->fill_gc,
-                               rx1 + 0, cy1 + 1, rx2 - 0, cy1 + 1);
+                SET_COLOR_NORMAL_LIGHT;
+                cairo_move_to (cr, rx1 + 0 + 0.5, cy1 + 1 + 0.5);
+                cairo_line_to (cr, rx2 - 0 + 0.5, cy1 + 1 + 0.5);
 
                 if (cx1 == rx1) {
-                        gdk_draw_line (drawable,
-                                       priv->fill_gc,
-                                       rx1 + 1, cy1 + 1, rx1 + 1, cy2 - 1);
+                        cairo_move_to (cr, rx1 + 1 + 0.5, cy1 + 1 + 0.5);
+                        cairo_line_to (cr, rx1 + 1 + 0.5, cy2 - 1 + 0.5);
                 }
 
-                gdk_gc_set_foreground (priv->fill_gc, &color_normal_dark);
-                gdk_draw_line (drawable,
-                               priv->fill_gc,
-                               rx1 + 0, cy2 - 1, rx2 - 0, cy2 - 1);
+                cairo_stroke (cr);
+
+                SET_COLOR_NORMAL_DARK;
+                cairo_move_to (cr, rx1 + 0 + 0.5, cy2 - 1 + 0.5);
+                cairo_line_to (cr, rx2 - 0 + 0.5, cy2 - 1 + 0.5);
 
                 if (cx2 == rx2) {
-                        gdk_draw_line (drawable,
-                                       priv->fill_gc,
-                                       rx2 - 1, cy1 + 1, rx2 - 1, cy2 - 1);
+                        cairo_move_to (cr, rx2 - 1 + 0.5, cy1 + 1 + 0.5);
+                        cairo_line_to (cr, rx2 - 1 + 0.5, cy2 - 1 + 0.5);
                 }
 
+                cairo_stroke (cr);
+
+                cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+
                 if (cx1 == rx1) {
-                        gdk_draw_line (drawable,
-                                       priv->frame_gc, rx1, cy1, rx1, cy2);
+                        cairo_move_to (cr, rx1 + 0.5, cy1 + 0.5);
+                        cairo_line_to (cr, rx1 + 0.5, cy2 + 0.5);
                 }
 
                 if (cx2 == rx2) {
-                        gdk_draw_line (drawable,
-                                       priv->frame_gc, rx2, cy1, rx2, cy2);
+                        cairo_move_to (cr, rx2 + 0.5, cy1 + 0.5);
+                        cairo_line_to (cr, rx2 + 0.5, cy2 + 0.5);
                 }
+
+                cairo_stroke (cr);
         }
 
         rx1 = MAX (cx2 + TEXT_PADDING, 0);
         rx2 = MIN (cx2 + TEXT_PADDING + priv->text_width, width);
 
-        if (priv->layout != NULL && rx1 < rx2) {
+       if (priv->layout != NULL && rx1 < rx2) {
+               /* TODO-GTK3: Use the below code for color (double-check about state)
+               GtkStyleContext *context;
+               GtkStateFlags    flags;
+               GdkRGBA rgba;
+
+               context = gtk_widget_get_style_context (GTK_WIDGET (item->canvas))
+               state = gtk_widget_get_state_flags (GTK_WIDGET (item->canvas));
+               gtk_style_context_get_color (context, state, &rgba);
+               gdk_cairo_set_source_rgba (cr, &rgba);
+               */
+               /* Until then, use GtkStyle */
+               gdk_cairo_set_source_color (cr, &GTK_WIDGET (item->canvas)->style->text[GTK_STATE_NORMAL]);
                /* FIXME: Center the text vertically? */
-               gdk_draw_layout (drawable,
-                                GTK_WIDGET (item->canvas)->style->text_gc[GTK_STATE_NORMAL],
-                                cx2 + TEXT_PADDING,
-                                cy1,
-                                priv->layout);
+               cairo_move_to (cr, cx2 + TEXT_PADDING, cy1);
+               pango_cairo_show_layout (cr, priv->layout);
+       }
 
-        }
+        cairo_destroy (cr);
 }
 
 static void


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