[gtk+/extended-layout-jhs: 55/64] Pimped the test for better demonstration. Correctly calulate layout width



commit 027b916cddb3eb4e929e49da5897c9187beabe89
Author: Mathias Hasselmann <mathias hasselmann gmx de>
Date:   Sun Aug 12 23:16:36 2007 +0000

    Pimped the test for better demonstration. Correctly calulate layout width
    
    2007-08-13  Mathias Hasselmann  <mathias hasselmann gmx de>
    
    	* tests/testellipsise.c: Pimped the test for better demonstration.
    	* gtk/gtklabel.c: Correctly calulate layout width for rotated
    	text when ellipses are used.
    
    svn path=/branches/extended-layout/; revision=18607

 ChangeLog.gtk-extended-layout |    6 ++
 gtk/gtklabel.c                |   65 ++++++++++++++++++++++----
 tests/testellipsise.c         |  105 +++++++++++++++++++++++++++++++++++++---
 3 files changed, 159 insertions(+), 17 deletions(-)
---
diff --git a/ChangeLog.gtk-extended-layout b/ChangeLog.gtk-extended-layout
index a1262e8..3d5d362 100644
--- a/ChangeLog.gtk-extended-layout
+++ b/ChangeLog.gtk-extended-layout
@@ -1,3 +1,9 @@
+2007-08-13  Mathias Hasselmann  <mathias hasselmann gmx de>
+
+	* tests/testellipsise.c: Pimped the test for better demonstration. 
+	* gtk/gtklabel.c: Correctly calulate layout width for rotated
+	text when ellipses are used.
+
 2007-08-12  Mathias Hasselmann  <mathias hasselmann gmx de>
 
 	* gtk/gtkbin.c: Filter feature set returned by the child to match
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index 2f94db1..58e15cd 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -50,6 +50,10 @@
 
 #define GTK_LABEL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_LABEL, GtkLabelPrivate))
 
+#ifndef INFINITY /* Why don't we use C99 again? */
+#define INFINITY HUGE_VAL
+#endif
+
 typedef struct
 {
   gint wrap_width;
@@ -2197,12 +2201,6 @@ gtk_label_size_request (GtkWidget      *widget,
     {
       PangoContext *context = pango_layout_get_context (label->layout);
       const PangoMatrix *matrix = pango_context_get_matrix (context);
-      PangoRectangle rect;
-
-      pango_layout_get_extents (label->layout, NULL, &rect);
-      pango_matrix_transform_rectangle (matrix, &rect);
-      pango_extents_to_pixels (&rect, NULL);
-
       pango_matrix_transform_pixel_rectangle (matrix, &required_rect);
     }
 
@@ -2238,10 +2236,59 @@ gtk_label_size_allocate (GtkWidget     *widget,
             {
               PangoContext *context = gtk_widget_get_pango_context (widget);
               const PangoMatrix *matrix = pango_context_get_matrix (context);
-              pango_matrix_transform_pixel_rectangle (matrix, &bounds);
-            }
 
-	  if (logical.width > bounds.width)
+              const gdouble dx = matrix->xx; /* cos (M_PI * angle / 180) */
+              const gdouble dy = matrix->xy; /* sin (M_PI * angle / 180) */
+
+              if (fabs (dy) < 0.01)
+                {
+                  if (logical.width > bounds.width)
+	            pango_layout_set_width (label->layout, bounds.width * PANGO_SCALE);
+                }
+              else if (fabs (dx) < 0.01)
+                {
+                  if (logical.width > bounds.height)
+	            pango_layout_set_width (label->layout, bounds.height * PANGO_SCALE);
+                }
+              else
+                {
+                  gdouble x0, y0, x1, y1, length;
+                  gboolean vertical;
+                  gint cy;
+
+                  x0 = bounds.width / 2;
+                  y0 = dx ? x0 * dy / dx : dy * INFINITY;
+                  vertical = fabs (y0) > bounds.height / 2;
+
+                  if (vertical)
+                    {
+                      y0 = bounds.height/2;
+                      x0 = dy ? y0 * dx / dy : dx * INFINITY;
+                    }
+
+                  length = 2 * sqrt (x0 * x0 + y0 * y0);
+                  pango_layout_set_width (label->layout, rint (length * PANGO_SCALE));
+                  pango_layout_get_pixel_size (label->layout, NULL, &cy);
+
+                  x1 = +dy * cy/2;
+                  y1 = -dx * cy/2;
+
+                  if (vertical)
+                    {
+                      y0 = bounds.height/2 + y1 - y0;
+                      x0 = -y0 * dx/dy;
+                    }
+                  else
+                    {
+                      x0 = bounds.width/2 + x1 - x0;
+                      y0 = -x0 * dy/dx;
+                    }
+                  
+                  length = length - sqrt (x0 * x0 + y0 * y0) * 2;
+                  pango_layout_set_width (label->layout, rint (length * PANGO_SCALE));
+                }
+            }
+	  else if (logical.width > bounds.width)
 	    pango_layout_set_width (label->layout, bounds.width * PANGO_SCALE);
 	}
     }
diff --git a/tests/testellipsise.c b/tests/testellipsise.c
index 591cbdb..26f5304 100644
--- a/tests/testellipsise.c
+++ b/tests/testellipsise.c
@@ -26,6 +26,21 @@
 #include <gtk/gtk.h>
 
 static void
+redraw_event_box (GtkWidget *widget)
+{
+  while (widget)
+    {
+      if (GTK_IS_EVENT_BOX (widget))
+        {
+          gtk_widget_queue_draw (widget);
+          break;
+        }
+
+      widget = gtk_widget_get_parent (widget);
+    }
+}
+
+static void
 combo_changed_cb (GtkWidget *combo,
 		  gpointer   data)
 {
@@ -33,49 +48,123 @@ combo_changed_cb (GtkWidget *combo,
   gint active;
 
   active = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
-  
   gtk_label_set_ellipsize (GTK_LABEL (label), (PangoEllipsizeMode)active);
+  redraw_event_box (label);
 }
 
 static void
 scale_changed_cb (GtkRange *range,
 		  gpointer   data)
 {
-  GtkWidget *label = GTK_WIDGET (data);
   double angle = gtk_range_get_value (range);
+  GtkWidget *label = GTK_WIDGET (data);
   
   gtk_label_set_angle (GTK_LABEL (label), angle);
+  redraw_event_box (label);
+}
+
+static gboolean
+ebox_expose_event_cb (GtkWidget      *widget,
+                      GdkEventExpose *event,
+                      gpointer        data)
+{
+  PangoLayout *layout;
+  const double dashes[] = { 6, 18 };
+  GtkRequisition natural_size;
+  GtkWidget *label = data;
+  cairo_t *cr;
+  gint x, y;
+
+  cr = gdk_cairo_create (widget->window);
+  cairo_translate (cr, -0.5, -0.5);
+  cairo_set_line_width (cr, 1);
+
+  cairo_set_source_rgb (cr, 1, 1, 1);
+  cairo_rectangle (cr, 0, 0, widget->allocation.width, widget->allocation.height);
+  cairo_fill (cr);
+
+  gtk_widget_translate_coordinates (label, widget, 0, 0, &x, &y);
+  layout = gtk_widget_create_pango_layout (widget, "");
+
+  pango_layout_set_markup (layout,
+    "<span color='#c33'>\342\227\217 requisition</span>\n"
+    "<span color='#3c3'>\342\227\217 natural size</span>\n"
+    "<span color='#33c'>\342\227\217 allocation</span>", -1);
+
+  pango_cairo_show_layout (cr, layout);
+  g_object_unref (layout);
+
+  cairo_rectangle (cr,
+                   x + 0.5 * (label->allocation.width - label->requisition.width),
+                   y + 0.5 * (label->allocation.height - label->requisition.height),
+                   label->requisition.width, label->requisition.height);
+  cairo_set_source_rgb (cr, 0.8, 0.2, 0.2);
+  cairo_set_dash (cr, NULL, 0, 0);
+  cairo_stroke (cr);
+
+  cairo_rectangle (cr, x, y, label->allocation.width, label->allocation.height);
+  cairo_set_source_rgb (cr, 0.2, 0.2, 0.8);
+  cairo_set_dash (cr, dashes, 2, 0.5);
+  cairo_stroke (cr);
+
+  gtk_extended_layout_get_natural_size (GTK_EXTENDED_LAYOUT (label),
+                                        &natural_size);
+
+  cairo_rectangle (cr,
+                   x + 0.5 * (label->allocation.width - natural_size.width),
+                   y + 0.5 * (label->allocation.height - natural_size.height),
+                   natural_size.width, natural_size.height);
+  cairo_set_source_rgb (cr, 0.2, 0.8, 0.2);
+  cairo_set_dash (cr, dashes, 2, 12.5);
+  cairo_stroke (cr);
+
+  cairo_destroy (cr);
+
+  return FALSE;
 }
 
 int
 main (int argc, char *argv[])
 {
-  GtkWidget *window, *vbox, *label, *combo, *scale;
+  GtkWidget *window, *vbox, *label;
+  GtkWidget *combo, *scale, *align, *ebox;
 
   gtk_init (&argc, &argv);
 
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_container_set_border_width (GTK_CONTAINER (window), 12);
+  gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
   g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
 
   vbox = gtk_vbox_new (FALSE, 6);
   gtk_container_add (GTK_CONTAINER (window), vbox);
 
+  combo = gtk_combo_box_new_text ();
+  scale = gtk_hscale_new_with_range (0, 360, 1);
   label = gtk_label_new ("This label may be ellipsized\nto make it fit.");
-  gtk_box_pack_end (GTK_BOX (vbox), label, TRUE, TRUE, 0);
 
-  combo = gtk_combo_box_new_text ();
   gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "NONE");
   gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "START");
   gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "MIDDLE");
   gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "END");
   gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+
+  align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
+  gtk_container_add (GTK_CONTAINER (align), label);
+
+  ebox = gtk_event_box_new ();
+  gtk_widget_set_app_paintable (ebox, TRUE);
+  gtk_container_add (GTK_CONTAINER (ebox), align);
+
   gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, TRUE, 0);
-  g_signal_connect (combo, "changed", G_CALLBACK (combo_changed_cb), label);
+  gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (vbox), ebox, TRUE, TRUE, 0);
 
-  scale = gtk_hscale_new_with_range (0, 360, 1);
+  g_object_set_data (G_OBJECT (label), "combo", combo);
+
+  g_signal_connect (combo, "changed", G_CALLBACK (combo_changed_cb), label);
   g_signal_connect (scale, "value-changed", G_CALLBACK (scale_changed_cb), label);
-  gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, TRUE, 0);
+  g_signal_connect (ebox, "expose-event", G_CALLBACK (ebox_expose_event_cb), label);
 
   gtk_widget_show_all (window);
 



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