[Xfce4-commits] <xfce4-panel:master> Fix various size allocation issues in clock (bug #5219, #3960).

Nick Schermer noreply at xfce.org
Tue Dec 21 21:08:01 CET 2010


Updating branch refs/heads/master
         to f24985be06d4e5f78dac7cf3f607acf6215478c6 (commit)
       from 5056f2d6c85aaad73f588ddc7b87a058b158bc72 (commit)

commit f24985be06d4e5f78dac7cf3f607acf6215478c6
Author: Nick Schermer <nick at xfce.org>
Date:   Tue Dec 21 21:05:29 2010 +0100

    Fix various size allocation issues in clock (bug #5219, #3960).
    
    Also change the way the lcd clock draws it's segments, so the spacing
    between the segments looks better in different panel sizes.

 plugins/clock/clock-binary.c |    4 -
 plugins/clock/clock-lcd.c    |  142 ++++++++++++++++++++++++++----------------
 plugins/clock/clock.c        |   26 ++++++--
 3 files changed, 108 insertions(+), 64 deletions(-)

diff --git a/plugins/clock/clock-binary.c b/plugins/clock/clock-binary.c
index 9580263..dbb49e1 100644
--- a/plugins/clock/clock-binary.c
+++ b/plugins/clock/clock-binary.c
@@ -27,10 +27,6 @@
 #include <math.h>
 #endif
 
-#ifndef M_PI
-#define M_PI 3.141592654
-#endif
-
 #include <gtk/gtk.h>
 #include <cairo/cairo.h>
 
diff --git a/plugins/clock/clock-lcd.c b/plugins/clock/clock-lcd.c
index 3f9f6d1..99633a2 100644
--- a/plugins/clock/clock-lcd.c
+++ b/plugins/clock/clock-lcd.c
@@ -31,7 +31,7 @@
 #include "clock-lcd.h"
 
 #define RELATIVE_SPACE (0.10)
-#define RELATIVE_DIGIT (0.50)
+#define RELATIVE_DIGIT (5 * RELATIVE_SPACE)
 #define RELATIVE_DOTS  (3 * RELATIVE_SPACE)
 
 
@@ -89,6 +89,13 @@ struct _XfceClockLcd
   guint               flash_separators : 1;
 };
 
+typedef struct
+{
+  gdouble x;
+  gdouble y;
+}
+LcdPoint;
+
 
 
 XFCE_PANEL_DEFINE_TYPE (XfceClockLcd, xfce_clock_lcd, GTK_TYPE_IMAGE)
@@ -283,11 +290,8 @@ xfce_clock_lcd_expose_event (GtkWidget      *widget,
   /* get the width:height ratio */
   ratio = xfce_clock_lcd_get_ratio (XFCE_CLOCK_LCD (widget));
 
-  /* size of a digit should be a fraction of 10 */
-  size = widget->allocation.height - widget->allocation.height % 10;
-
   /* make sure we also fit on small vertical panels */
-  size = MIN (rint ((gdouble) widget->allocation.width / ratio), size);
+  size = MIN ((gdouble) widget->allocation.width / ratio, widget->allocation.height);
 
   /* begin offsets */
   offset_x = rint ((widget->allocation.width - (size * ratio)) / 2.00);
@@ -299,13 +303,16 @@ xfce_clock_lcd_expose_event (GtkWidget      *widget,
 
   /* get the cairo context */
   cr = gdk_cairo_create (widget->window);
-  gdk_cairo_set_source_color (cr, &widget->style->fg[GTK_WIDGET_STATE (widget)]);
 
   if (G_LIKELY (cr != NULL))
     {
-      /* clip the drawing region */
+      gdk_cairo_set_source_color (cr, &widget->style->fg[GTK_WIDGET_STATE (widget)]);
       gdk_cairo_rectangle (cr, &event->area);
       cairo_clip (cr);
+      cairo_push_group (cr);
+
+      /* width of the clear line */
+      cairo_set_line_width (cr, MAX (size * 0.05, 1.5));
 
       /* get the local time */
       clock_plugin_get_localtime (&tm);
@@ -317,6 +324,9 @@ xfce_clock_lcd_expose_event (GtkWidget      *widget,
       if (!lcd->show_military && ticks > 12)
         ticks -= 12;
 
+      if (ticks == 1 || (ticks >= 10 && ticks < 20))
+        offset_x -= size * (RELATIVE_SPACE * 4);
+
       /* queue a resize when the number of hour digits changed,
        * because we might miss the exact second (due to slightly delayed
        * timeout) we queue a resize the first 3 seconds or anything in
@@ -374,7 +384,9 @@ xfce_clock_lcd_expose_event (GtkWidget      *widget,
           offset_x = xfce_clock_lcd_draw_digit (cr, ticks, size, offset_x, offset_y);
         }
 
-      /* cleanup */
+      /* drop the pushed group */
+      cairo_pop_group_to_source (cr);
+      cairo_paint (cr);
       cairo_destroy (cr);
     }
 
@@ -393,7 +405,7 @@ xfce_clock_lcd_get_ratio (XfceClockLcd *lcd)
   /* get the local time */
   clock_plugin_get_localtime (&tm);
 
-  /* 8:88 */
+  /* 8:8(space)8 */
   ratio = (3 * RELATIVE_DIGIT) + RELATIVE_DOTS + RELATIVE_SPACE;
 
   ticks = tm.tm_hour;
@@ -401,9 +413,14 @@ xfce_clock_lcd_get_ratio (XfceClockLcd *lcd)
   if (!lcd->show_military && ticks > 12)
     ticks -= 12;
 
-  if (ticks >= 10)
+  if (ticks == 1)
+    ratio -= RELATIVE_SPACE * 4; /* only show 1 */
+  else if (ticks >= 10 && ticks < 20)
+    ratio += RELATIVE_SPACE * 2; /* 1 + space */
+  else if (ticks >= 20)
     ratio += RELATIVE_DIGIT + RELATIVE_SPACE;
 
+  /* (space):88 */
   if (lcd->show_seconds)
     ratio += (2 * RELATIVE_DIGIT) + RELATIVE_SPACE + RELATIVE_DOTS;
 
@@ -446,6 +463,15 @@ xfce_clock_lcd_draw_dots (cairo_t *cr,
 
 
 
+/*
+ * number:
+ *
+ * ##1##
+ * 6   2
+ * ##7##
+ * 5   3
+ * ##4##
+ */
 static gdouble
 xfce_clock_lcd_draw_digit (cairo_t *cr,
                            guint    number,
@@ -453,47 +479,43 @@ xfce_clock_lcd_draw_digit (cairo_t *cr,
                            gdouble  offset_x,
                            gdouble  offset_y)
 {
-  gint    i, j;
+  guint   i, j;
   gint    segment;
   gdouble x, y;
   gdouble rel_x, rel_y;
 
-  /* ##1##
-   * 6   2
-   * ##7##
-   * 5   3
-   * ##4##
-   */
-
   /* coordicates to draw for each segment */
-  gdouble segments_x[][6] = { { 0.02, 0.48,  0.38,  0.12,  -1.0,  0.00 },   /* 1x */
-                              { 0.40, 0.505, 0.505, 0.40,  -1.0,  0.00 },   /* 2x */
-                              { 0.40, 0.505, 0.505, 0.40,  -1.0,  0.00 },   /* 3x */
-                              { 0.12, 0.38,  0.48,  0.02,  -1.0,  0.00 },   /* 4x */
-                              { 0.00, 0.105, 0.105, 0.00,  -1.0,  0.00 },   /* 5x */
-                              { 0.00, 0.105, 0.105, 0.00,  -1.0,  0.00 },   /* 6x */
-                              { 0.00, 0.10,  0.40,  0.50,   0.40, 0.10 } }; /* 7x */
-  gdouble segments_y[][6] = { { 0.00, 0.00,  0.105, 0.105, -1.0,  0.00 },   /* 1y */
-                              { 0.12, 0.02,  0.48,  0.43,  -1.0,  0.00 },   /* 2y */
-                              { 0.57, 0.52,  0.98,  0.88,  -1.0,  0.00 },   /* 3y */
-                              { 0.90, 0.90,  1.00,  1.00,  -1.0,  0.00 },   /* 4y */
-                              { 0.52, 0.57,  0.88,  0.98,  -1.0,  0.00 },   /* 5y */
-                              { 0.02, 0.12,  0.43,  0.48,  -1.0,  0.00 },   /* 6y */
-                              { 0.50, 0.445, 0.445, 0.50,   0.55, 0.55 } }; /* 7y */
+  const LcdPoint segment_points[][6] = {
+    /* 1 */ { { 0, 0 }, { 0.5, 0 }, { 0.4, 0.1 }, { 0.1, 0.1 }, { -1, }, { -1, } },
+    /* 2 */ { { 0.4, 0.1 }, { 0.5, 0.0 }, { 0.5, 0.5 }, { 0.4, 0.45 }, { -1, },  { -1, } },
+    /* 3 */ { { 0.4, 0.55 }, { 0.5, 0.5 }, { 0.5, 1 }, { 0.4, 0.9 }, { -1, },  { -1, } },
+    /* 4 */ { { 0.1, 0.9 }, { 0.4, 0.9 }, { 0.5, 1 }, { 0.0, 1 }, { -1, },  { -1, } },
+    /* 5 */ { { 0.0, 0.5 }, { 0.1, 0.55 }, { 0.1, 0.90 }, { 0.0, 1}, { -1, },  { -1, } },
+    /* 6 */ { { 0.0, 0.0 }, { 0.1, 0.1 }, { 0.1, 0.45 }, { 0.0, 0.5 }, { -1, },  { -1, } },
+    /* 7 */ { { 0.0, 0.5 }, { 0.1, 0.45 }, { 0.4, 0.45 }, { 0.5, 0.5 }, { 0.4, 0.55 }, { 0.1, 0.55 } },
+  };
+
+  /* space line, mirrored to other side */
+  const LcdPoint clear_points[] = {
+    { 0, 0 }, { 0.25, 0.25 }, { 0.25, 0.375 }, { 0, 0.5 },
+    { 0.25, 0.625 }, { 0.25, 0.75 }, { 0, 1 }
+  };
 
   /* segment to draw for each number: 0, 1, ..., 9, A, P */
-  gint    numbers[][8] = { { 0, 1, 2, 3, 4, 5, -1 },
-                           { 1, 2, -1 },
-                           { 0, 1, 6, 4, 3, -1 },
-                           { 0, 1, 6, 2, 3, -1 },
-                           { 5, 6, 1, 2, -1 },
-                           { 0, 5, 6, 2, 3, -1 },
-                           { 0, 5, 4, 3, 2, 6, -1 },
-                           { 0, 1, 2, -1 },
-                           { 0, 1, 2, 3, 4, 5, 6, -1 },
-                           { 3, 2, 1, 0, 5, 6, -1 },
-                           { 4, 5, 0, 1, 2, 6, -1 },
-                           { 4, 5, 0, 1, 6, -1 } };
+  const gint numbers[][8] = {
+    { 0, 1, 2, 3, 4, 5, -1 },
+    { 1, 2, -1 },
+    { 0, 1, 6, 4, 3, -1 },
+    { 0, 1, 6, 2, 3, -1 },
+    { 5, 6, 1, 2, -1 },
+    { 0, 5, 6, 2, 3, -1 },
+    { 0, 5, 4, 3, 2, 6, -1 },
+    { 0, 1, 2, -1 },
+    { 0, 1, 2, 3, 4, 5, 6, -1 },
+    { 3, 2, 1, 0, 5, 6, -1 },
+    { 4, 5, 0, 1, 2, 6, -1 },
+    { 4, 5, 0, 1, 6, -1 }
+  };
 
   panel_return_val_if_fail (number <= 11, offset_x);
 
@@ -510,8 +532,8 @@ xfce_clock_lcd_draw_digit (cairo_t *cr,
       for (j = 0; j < 6; j++)
         {
           /* get the relative sizes */
-          rel_x = segments_x[segment][j];
-          rel_y = segments_y[segment][j];
+          rel_x = segment_points[segment][j].x;
+          rel_y = segment_points[segment][j].y;
 
           /* leave when there are no valid coordinates */
           if (rel_x == -1.00 || rel_y == -1.00)
@@ -521,26 +543,36 @@ xfce_clock_lcd_draw_digit (cairo_t *cr,
           x = rel_x * size + offset_x;
           y = rel_y * size + offset_y;
 
-          /* when 0.01 * size is larger then 1, round the numbers */
-          if (size >= 10)
-            {
-              x = rint (x);
-              y = rint (y);
-            }
-
           if (G_UNLIKELY (j == 0))
             cairo_move_to (cr, x, y);
           else
             cairo_line_to (cr, x, y);
         }
 
-      /* close the line */
       cairo_close_path (cr);
     }
 
-  /* fill the segments */
   cairo_fill (cr);
 
+  /* clear the space between the segments to get the lcd look */
+  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+  for (j = 0; j < 2; j++)
+    {
+      for (i = 0; i < G_N_ELEMENTS (clear_points); i++)
+        {
+          x = (j == 0 ? clear_points[i].x : 0.5 - clear_points[i].x) * size + offset_x;
+          y = clear_points[i].y * size + offset_y;
+
+          if (G_UNLIKELY (i == 0))
+            cairo_move_to (cr, x, y);
+          else
+            cairo_line_to (cr, x, y);
+        }
+
+      cairo_stroke (cr);
+    }
+  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
   return (offset_x + size * (RELATIVE_DIGIT + RELATIVE_SPACE));
 }
 
diff --git a/plugins/clock/clock.c b/plugins/clock/clock.c
index e76e655..a21ec57 100644
--- a/plugins/clock/clock.c
+++ b/plugins/clock/clock.c
@@ -467,6 +467,7 @@ clock_plugin_size_changed (XfcePanelPlugin *panel_plugin,
   gdouble      ratio;
   gint         ratio_size;
   gint         border = 0;
+  gint         offset;
 
   if (plugin->clock == NULL)
     return TRUE;
@@ -478,20 +479,35 @@ clock_plugin_size_changed (XfcePanelPlugin *panel_plugin,
 
   /* get the width:height ratio */
   g_object_get (G_OBJECT (plugin->clock), "size-ratio", &ratio, NULL);
-  ratio_size = ratio > 0 ? size : -1;
+  if (ratio > 0)
+    {
+      offset = MAX (plugin->frame->style->xthickness, plugin->frame->style->ythickness) + border;
+      offset *= 2;
+      ratio_size = size - offset;
+    }
+  else
+    {
+      ratio_size = -1;
+    }
 
   /* set the clock size */
   if (xfce_panel_plugin_get_orientation (panel_plugin) == GTK_ORIENTATION_HORIZONTAL)
     {
-      if (ratio > 0 && ratio != 1.0)
-        ratio_size = ceil (size * ratio);
+      if (ratio > 0)
+        {
+          ratio_size = ceil (ratio_size * ratio);
+          ratio_size += offset;
+        }
 
       gtk_widget_set_size_request (GTK_WIDGET (panel_plugin), ratio_size, size);
     }
   else
     {
-      if (ratio > 0 && ratio != 1.0)
-        ratio_size = ceil (size / ratio);
+      if (ratio > 0)
+        {
+          ratio_size = ceil (ratio_size / ratio);
+          ratio_size += offset;
+        }
 
       gtk_widget_set_size_request (GTK_WIDGET (panel_plugin), size, ratio_size);
     }



More information about the Xfce4-commits mailing list