[gnome-todo/wip/priority-icons] task-row: render a small circle representing task priority



commit e7ef81bf4d34ba5bd8ff1932ac93d6a80002de50
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Thu Jun 25 09:04:05 2015 -0300

    task-row: render a small circle representing task priority

 data/theme/Adwaita.css |   13 ++++++
 data/ui/task-row.ui    |   40 ++++++++++-------
 src/gtd-task-row.c     |  111 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 148 insertions(+), 16 deletions(-)
---
diff --git a/data/theme/Adwaita.css b/data/theme/Adwaita.css
index e19afc4..22e6c12 100644
--- a/data/theme/Adwaita.css
+++ b/data/theme/Adwaita.css
@@ -41,3 +41,16 @@ GtdArrowFrame:dir(rtl) {
 GtkLabel.main-title {
     font-size: 28px;
 }
+
+/* priority icons */
+GtkImage.priority-low {
+    background-color: green;
+}
+
+GtkImage.priority-medium {
+    background-color: yellow;
+}
+
+GtkImage.priority-hight {
+    background-color: red;
+}
diff --git a/data/ui/task-row.ui b/data/ui/task-row.ui
index 0fbb6fe..b38ea9a 100644
--- a/data/ui/task-row.ui
+++ b/data/ui/task-row.ui
@@ -48,12 +48,32 @@
                     <property name="hexpand">False</property>
                     <property name="halign">start</property>
                     <child>
-                      <object class="GtkLabel" id="title_label">
+                      <object class="GtkBox" id="title_label_box">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="hexpand">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" bind-source="title_entry" bind-property="text" />
+                        <property name="spacing">12</property>
+                        <child>
+                          <object class="GtkLabel" id="title_label">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label" bind-source="title_entry" bind-property="text" />
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkImage" id="priority_icon">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkSpinner" id="task_loading_spinner">
+                            <property name="visible">False</property>
+                            <property name="can_focus">False</property>
+                            <property name="active">True</property>
+                            <property name="halign">start</property>
+                          </object>
+                        </child>
                       </object>
                       <packing>
                         <property name="name">label</property>
@@ -76,18 +96,6 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkSpinner" id="task_loading_spinner">
-                    <property name="visible">False</property>
-                    <property name="can_focus">False</property>
-                    <property name="active">True</property>
-                    <property name="halign">start</property>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                  </packing>
-                </child>
-                <child>
                   <object class="GtkBox" id="stub_expander">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
diff --git a/src/gtd-task-row.c b/src/gtd-task-row.c
index 333dc5f..633a764 100644
--- a/src/gtd-task-row.c
+++ b/src/gtd-task-row.c
@@ -23,6 +23,8 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
+#include <math.h>
+
 typedef struct
 {
   GtkRevealer               *revealer;
@@ -34,6 +36,7 @@ typedef struct
   GtkStack                  *new_task_stack;
 
   /* task widgets */
+  GtkImage                  *priority_icon;
   GtkEntry                  *title_entry;
   GtkLabel                  *task_date_label;
   GtkLabel                  *task_list_label;
@@ -53,6 +56,8 @@ struct _GtdTaskRow
   GtdTaskRowPrivate *priv;
 };
 
+#define PRIORITY_ICON_SIZE         16
+
 G_DEFINE_TYPE_WITH_PRIVATE (GtdTaskRow, gtd_task_row, GTK_TYPE_LIST_BOX_ROW)
 
 enum {
@@ -72,6 +77,101 @@ enum {
 
 static guint signals[NUM_SIGNALS] = { 0, };
 
+/*
+ * Code partially stolen from GNOME Calendar (gcal-utils.c)
+ */
+GdkPixbuf*
+generate_priority_icon (GtdTaskRow *row)
+{
+  GtdTaskRowPrivate *priv;
+  GtkStyleContext *context;
+  cairo_surface_t *surface;
+  GdkPixbuf *pix;
+  cairo_t *cr;
+
+  g_return_val_if_fail (GTD_IS_TASK_ROW (row), NULL);
+
+  priv = row->priv;
+  context = gtk_widget_get_style_context (GTK_WIDGET (priv->priority_icon));
+
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                        PRIORITY_ICON_SIZE,
+                                        PRIORITY_ICON_SIZE);
+  cr = cairo_create (surface);
+
+  cairo_arc (cr,
+             PRIORITY_ICON_SIZE / 2.0,
+             PRIORITY_ICON_SIZE / 2.0,
+             PRIORITY_ICON_SIZE / 2.0,
+             0.,
+             2 * M_PI);
+  cairo_clip (cr);
+
+  /* Use the given GtkContext to draw the background */
+  gtk_render_background (context,
+                         cr,
+                         0,
+                         0,
+                         PRIORITY_ICON_SIZE,
+                         PRIORITY_ICON_SIZE);
+
+  cairo_destroy (cr);
+  pix = gdk_pixbuf_get_from_surface (surface,
+                                     0,
+                                     0,
+                                     PRIORITY_ICON_SIZE,
+                                     PRIORITY_ICON_SIZE);
+  cairo_surface_destroy (surface);
+  return pix;
+}
+
+static void
+gtd_task_row__priority_changed_cb (GtdTaskRow *row,
+                                   GParamSpec *spec,
+                                   GObject    *object)
+{
+  GtdTaskRowPrivate *priv;
+  GtkStyleContext *context;
+  GdkPixbuf *icon;
+  gint priority;
+
+  g_return_if_fail (GTD_IS_TASK_ROW (row));
+
+  priv = row->priv;
+  context = gtk_widget_get_style_context (GTK_WIDGET (priv->priority_icon));
+  priority = gtd_task_get_priority (GTD_TASK (object));
+
+  gtk_style_context_save (context);
+
+  switch (priority)
+    {
+    case 1:
+      gtk_style_context_add_class (context, "priority-low");
+      break;
+
+    case 2:
+      gtk_style_context_add_class (context, "priority-medium");
+      break;
+
+    case 3:
+      gtk_style_context_add_class (context, "priority-hight");
+      break;
+
+    default:
+      break;
+    }
+
+  /* Set the new icon */
+  icon = generate_priority_icon (row);
+
+  gtk_image_set_from_pixbuf (priv->priority_icon, icon);
+  gtk_widget_set_visible (GTK_WIDGET (priv->priority_icon), priority != 0);
+
+  gtk_style_context_restore (context);
+
+  g_object_unref (icon);
+}
+
 static gboolean
 gtd_task_row__date_changed_binding (GBinding     *binding,
                                     const GValue *from_value,
@@ -412,6 +512,7 @@ gtd_task_row_class_init (GtdTaskRowClass *klass)
   gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, stack);
   gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, new_task_entry);
   gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, new_task_stack);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, priority_icon);
   gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, revealer);
   gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, task_date_label);
   gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, task_list_label);
@@ -543,6 +644,16 @@ gtd_task_row_set_task (GtdTaskRow *row,
                                        NULL,
                                        row,
                                        NULL);
+
+          /*
+           * Here we generate a false callback call just to reuse the method to
+           * sync the initial state of the priority icon.
+           */
+          gtd_task_row__priority_changed_cb (row, NULL, G_OBJECT (task));
+          g_signal_connect_swapped (task,
+                                    "notify::priority",
+                                    G_CALLBACK (gtd_task_row__priority_changed_cb),
+                                    row);
         }
 
       g_object_notify (G_OBJECT (row), "task");


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