[gnome-calendar/wip/pandusonu/week-view] event-widget: implement GtkOrientable



commit 4074bee50e6919d094934424c92c897f11951e6b
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Thu Dec 15 17:02:51 2016 -0200

    event-widget: implement GtkOrientable
    
    So that we can control how much information, and how this
    information is displayed, depending on the widget orientation.

 src/gcal-event-widget.c |  104 ++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 90 insertions(+), 14 deletions(-)
---
diff --git a/src/gcal-event-widget.c b/src/gcal-event-widget.c
index 16410f4..bf193b3 100644
--- a/src/gcal-event-widget.c
+++ b/src/gcal-event-widget.c
@@ -17,10 +17,13 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <string.h>
+
 #include "gcal-event-widget.h"
 #include "gcal-utils.h"
 
 #define INTENSITY(c) ((c->red) * 0.30 + (c->green) * 0.59 + (c->blue) * 0.11)
+#define ICON_SIZE    16
 
 struct _GcalEventWidget
 {
@@ -40,6 +43,8 @@ struct _GcalEventWidget
   /* Drag n' Drop icon */
   GdkPixbuf     *dnd_pixbuf;
 
+  GtkOrientation orientation;
+
   GdkWindow     *event_window;
   gboolean       button_pressed;
 };
@@ -50,6 +55,7 @@ enum
   PROP_DATE_END,
   PROP_DATE_START,
   PROP_EVENT,
+  PROP_ORIENTATION,
   NUM_PROPS
 };
 
@@ -61,7 +67,8 @@ enum
 
 static guint signals[NUM_SIGNALS] = { 0, };
 
-G_DEFINE_TYPE (GcalEventWidget, gcal_event_widget, GTK_TYPE_WIDGET)
+G_DEFINE_TYPE_WITH_CODE (GcalEventWidget, gcal_event_widget, GTK_TYPE_WIDGET,
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL));
 
 static void
 gcal_event_widget_update_style (GcalEventWidget *self)
@@ -191,6 +198,7 @@ gcal_event_widget_init (GcalEventWidget *self)
 
   widget = GTK_WIDGET (self);
   self->clock_format_24h = is_clock_format_24h ();
+  self->orientation = GTK_ORIENTATION_HORIZONTAL;
 
   gtk_widget_set_has_window (widget, FALSE);
   gtk_widget_set_can_focus (widget, TRUE);
@@ -227,6 +235,12 @@ gcal_event_widget_set_property (GObject      *object,
       gcal_event_widget_set_event_internal (self, g_value_get_object (value));
       break;
 
+    case PROP_ORIENTATION:
+      self->orientation = g_value_get_enum (value);
+      gtk_widget_queue_draw (GTK_WIDGET (object));
+      g_object_notify (object, "orientation");
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
     }
@@ -254,6 +268,10 @@ gcal_event_widget_get_property (GObject      *object,
       g_value_set_object (value, self->event);
       break;
 
+    case PROP_ORIENTATION:
+      g_value_set_enum (value, self->orientation);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
     }
@@ -307,11 +325,14 @@ gcal_event_widget_get_preferred_height (GtkWidget *widget,
                                         gint      *minimum,
                                         gint      *natural)
 {
+  GcalEventWidget *self;
   GtkBorder border, padding;
   GtkStyleContext *context;
   PangoLayout *layout;
   gint layout_height;
+  gint factor;
 
+  self = GCAL_EVENT_WIDGET (widget);
   context = gtk_widget_get_style_context (widget);
   layout = gtk_widget_create_pango_layout (widget, NULL);
   pango_layout_get_pixel_size (layout, NULL, &layout_height);
@@ -320,10 +341,12 @@ gcal_event_widget_get_preferred_height (GtkWidget *widget,
   gtk_style_context_get_border (context, gtk_style_context_get_state (context), &border);
   gtk_style_context_get_padding (context, gtk_style_context_get_state (context), &padding);
 
+  factor = self->orientation == GTK_ORIENTATION_HORIZONTAL ? 1 : 2;
+
   if (minimum != NULL)
-    *minimum = layout_height + padding.top + padding.bottom + border.top + border.bottom;
+    *minimum = (factor * layout_height) + padding.top + padding.bottom + border.top + border.bottom;
   if (natural != NULL)
-    *natural = layout_height + padding.top + padding.bottom + border.top + border.bottom;
+    *natural = (factor * layout_height) + padding.top + padding.bottom + border.top + border.bottom;
 }
 
 static void
@@ -487,10 +510,22 @@ gcal_event_widget_draw (GtkWidget *widget,
       else
         start_time = g_date_time_format (local_start_time, "%I:%M %P");
 
-      if (is_ltr)
-        display_text = g_strdup_printf ("(%s) %s", start_time, gcal_event_get_summary (self->event));
+      /*
+       * When in horizontal, draw the elements sequentially; otherwise,
+       * draw the time in the first line, and the title in subsequent
+       * lines.
+       */
+      if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
+        {
+          if (is_ltr)
+            display_text = g_strdup_printf ("(%s) %s", start_time, gcal_event_get_summary (self->event));
+          else
+            display_text = g_strdup_printf ("%s (%s)", gcal_event_get_summary (self->event), start_time);
+        }
       else
-        display_text = g_strdup_printf ("%s (%s)", gcal_event_get_summary (self->event), start_time);
+        {
+          display_text = g_strdup_printf ("<b>%s</b>\n%s", start_time, gcal_event_get_summary (self->event));
+        }
 
       g_clear_pointer (&local_start_time, g_date_time_unref);
       g_clear_pointer (&start_time, g_free);
@@ -498,16 +533,13 @@ gcal_event_widget_draw (GtkWidget *widget,
 
   /* Retrieve the font description */
   gtk_style_context_get (context, state, "font", &font_desc, NULL);
-  layout = gtk_widget_create_pango_layout (widget, display_text);
+  layout = gtk_widget_create_pango_layout (widget, "");
+  pango_layout_set_markup (layout, display_text, -1);
   pango_layout_set_font_description (layout, font_desc);
   pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
-  pango_layout_set_width (layout, (width - (padding.left + padding.right) ) * PANGO_SCALE);
-  pango_cairo_update_layout (cr, layout);
 
   /* Icon size */
-  pango_layout_get_pixel_size (layout, NULL, &layout_height);
-  icon_size = 4 * (layout_height / 4);
-
+  icon_size = ICON_SIZE;
   end_gap = 0;
 
   if (gcal_event_has_alarms (self->event))
@@ -519,8 +551,36 @@ gcal_event_widget_draw (GtkWidget *widget,
   x = is_ltr ? padding.left : padding.left + end_gap;
 
   pango_layout_set_width (layout, (width - (padding.left + padding.right + end_gap)) * PANGO_SCALE);
+  pango_layout_get_pixel_size (layout, NULL, &layout_height);
   gtk_render_layout (context, cr, x, padding.top, layout);
 
+#if 0
+  /* TODO: find out a good way to handle this */
+  /*
+   * On vertical event widgets, we assume we might have space to draw the
+   * event's detail (or at least part of it).
+   */
+  if (self->orientation == GTK_ORIENTATION_VERTICAL &&
+      2 * padding.top + layout_height + padding.bottom < height &&
+      strlen (gcal_event_get_description (self->event)) > 0)
+    {
+      g_autofree gchar *description;
+
+      description = g_strdup_printf ("<small>%s</small>", gcal_event_get_description (self->event));
+      pango_layout_set_markup (layout, description, -1);
+      pango_layout_set_width (layout, (width - (padding.left + padding.right) ) * PANGO_SCALE);
+      pango_layout_set_height (layout, (height - (2 * padding.top + layout_height + padding.bottom) ) * 
PANGO_SCALE);
+      pango_layout_set_font_description (layout, font_desc);
+      pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
+
+      gtk_render_layout (context,
+                         cr,
+                         x,
+                         2 * padding.top + layout_height + padding.bottom,
+                         layout);
+    }
+#endif
+
   x += is_ltr ? (width - end_gap - padding.left - padding.right) : (- padding.right - padding.left - 
icon_size);
 
   /* render reminder icon */
@@ -541,7 +601,11 @@ gcal_event_widget_draw (GtkWidget *widget,
                                                         &was_symbolic,
                                                         NULL);
 
-      gdk_cairo_set_source_pixbuf (cr, pixbuf, x + padding.left, padding.top);
+      gtk_render_icon (context,
+                       cr,
+                       pixbuf,
+                       x + padding.left,
+                       padding.top);
 
       x += is_ltr ? (padding.left + icon_size) : (- padding.right - icon_size);
 
@@ -567,7 +631,12 @@ gcal_event_widget_draw (GtkWidget *widget,
                                                         &was_symbolic,
                                                         NULL);
 
-      gdk_cairo_set_source_pixbuf (cr, pixbuf, x + padding.left, padding.top);
+      gtk_render_icon (context,
+                       cr,
+                       pixbuf,
+                       x + padding.left,
+                       padding.top);
+
       g_object_unref (pixbuf);
       cairo_paint (cr);
     }
@@ -710,6 +779,13 @@ gcal_event_widget_class_init(GcalEventWidgetClass *klass)
                                                         GCAL_TYPE_EVENT,
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
+  /**
+   * GcalEventWidget::orientation:
+   *
+   * The orientation of the event widget.
+   */
+  g_object_class_override_property (object_class, PROP_ORIENTATION, "orientation");
+
   signals[ACTIVATE] = g_signal_new ("activate",
                                      GCAL_TYPE_EVENT_WIDGET,
                                      G_SIGNAL_RUN_LAST,


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