]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkcellrenderertext.c
Change FSF Address
[~andy/gtk] / gtk / gtkcellrenderertext.c
index cf58d4dacbde0b7a1514bced623a750948312f4e..e4b5f7248b90466f790765cadc01228636262b52 100644 (file)
@@ -12,9 +12,7 @@
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "config.h"
@@ -30,6 +28,7 @@
 #include "gtkintl.h"
 #include "gtkprivate.h"
 #include "gtktreeprivate.h"
+#include "a11y/gtktextcellaccessible.h"
 
 
 /**
@@ -84,6 +83,13 @@ static void       gtk_cell_renderer_text_get_preferred_height_for_width (GtkCell
                                                                          gint                   width,
                                                                          gint                  *minimum_height,
                                                                          gint                  *natural_height);
+static void       gtk_cell_renderer_text_get_aligned_area               (GtkCellRenderer       *cell,
+                                                                        GtkWidget             *widget,
+                                                                        GtkCellRendererState   flags,
+                                                                        const GdkRectangle    *cell_area,
+                                                                        GdkRectangle          *aligned_area);
+
+
 
 enum {
   EDITED,
@@ -154,18 +160,16 @@ struct _GtkCellRendererTextPrivate
 {
   GtkWidget *entry;
 
-  PangoAlignment        align;
   PangoAttrList        *extra_attrs;
   GdkRGBA               foreground;
   GdkRGBA               background;
+  PangoAlignment        align;
   PangoEllipsizeMode    ellipsize;
   PangoFontDescription *font;
   PangoLanguage        *language;
   PangoUnderline        underline_style;
   PangoWrapMode         wrap_mode;
 
-  gboolean in_entry_menu;
-
   gchar *text;
 
   gdouble font_scale;
@@ -176,6 +180,7 @@ struct _GtkCellRendererTextPrivate
   gint max_width_chars;
   gint wrap_width;
 
+  guint in_entry_menu     : 1;
   guint strikethrough     : 1;
   guint editable          : 1;
   guint scale_set         : 1;
@@ -240,6 +245,7 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
   cell_class->get_preferred_width = gtk_cell_renderer_text_get_preferred_width;
   cell_class->get_preferred_height = gtk_cell_renderer_text_get_preferred_height;
   cell_class->get_preferred_height_for_width = gtk_cell_renderer_text_get_preferred_height_for_width;
+  cell_class->get_aligned_area = gtk_cell_renderer_text_get_aligned_area;
 
   g_object_class_install_property (object_class,
                                    PROP_TEXT,
@@ -282,13 +288,20 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
                                                         NULL,
                                                         GTK_PARAM_WRITABLE));
 
+  /**
+   * GtkCellRendererText:background-gdk:
+   *
+   * Background color as a #GdkColor
+   *
+   * Deprecated: 3.4: Use #GtkCellRendererText:background-rgba instead.
+   */
   g_object_class_install_property (object_class,
                                    PROP_BACKGROUND_GDK,
                                    g_param_spec_boxed ("background-gdk",
                                                        P_("Background color"),
                                                        P_("Background color as a GdkColor"),
                                                        GDK_TYPE_COLOR,
-                                                       GTK_PARAM_READWRITE));  
+                                                       GTK_PARAM_READWRITE | G_PARAM_DEPRECATED));
 
   /**
    * GtkCellRendererText:background-rgba:
@@ -312,13 +325,20 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
                                                         NULL,
                                                         GTK_PARAM_WRITABLE));
 
+  /**
+   * GtkCellRendererText:foreground-gdk:
+   *
+   * Foreground color as a #GdkColor
+   *
+   * Deprecated: 3.4: Use #GtkCellRendererText:foreground-rgba instead.
+   */
   g_object_class_install_property (object_class,
                                    PROP_FOREGROUND_GDK,
                                    g_param_spec_boxed ("foreground-gdk",
                                                        P_("Foreground color"),
                                                        P_("Foreground color as a GdkColor"),
                                                        GDK_TYPE_COLOR,
-                                                       GTK_PARAM_READWRITE));
+                                                       GTK_PARAM_READWRITE | G_PARAM_DEPRECATED));
 
   /**
    * GtkCellRendererText:foreground-rgba:
@@ -693,6 +713,8 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
                  G_TYPE_STRING);
 
   g_type_class_add_private (object_class, sizeof (GtkCellRendererTextPrivate));
+
+  _gtk_cell_renderer_class_set_accessible_type (cell_class, GTK_TYPE_TEXT_CELL_ACCESSIBLE);
 }
 
 static void
@@ -1682,12 +1704,17 @@ get_size (GtkCellRenderer    *cell,
 
   if (priv->calc_fixed_height)
     {
+      GtkStyleContext *style_context;
+      GtkStateFlags state;
       PangoContext *context;
       PangoFontMetrics *metrics;
       PangoFontDescription *font_desc;
       gint row_height;
 
-      font_desc = pango_font_description_copy_static (gtk_widget_get_style (widget)->font_desc);
+      style_context = gtk_widget_get_style_context (widget);
+      state = gtk_widget_get_state_flags (widget);
+
+      font_desc = pango_font_description_copy_static (gtk_style_context_get_font (style_context, state));
       pango_font_description_merge_static (font_desc, priv->font, TRUE);
 
       if (priv->scale_set)
@@ -1728,46 +1755,21 @@ get_size (GtkCellRenderer    *cell,
 
   pango_layout_get_pixel_extents (layout, NULL, &rect);
 
-  if (height)
-    *height = ypad * 2 + rect.height;
-
-  /* The minimum size for ellipsized labels is ~ 3 chars */
-  if (width)
-    {
-      if (priv->ellipsize || priv->width_chars > 0)
-       {
-         PangoContext *context;
-         PangoFontMetrics *metrics;
-         gint char_width;
-
-         context = pango_layout_get_context (layout);
-          metrics = pango_context_get_metrics (context,
-                                               gtk_widget_get_style (widget)->font_desc,
-                                               pango_context_get_language (context));
-
-         char_width = pango_font_metrics_get_approximate_char_width (metrics);
-         pango_font_metrics_unref (metrics);
-         
-         *width = xpad * 2 + (PANGO_PIXELS (char_width) * MAX (priv->width_chars, 3));
-       }
-      else
-       {
-         *width = xpad * 2 + rect.x + rect.width;
-       }         
-    }
-
   if (cell_area)
     {
       gfloat xalign, yalign;
 
       gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);
 
+      rect.height = MIN (rect.height, cell_area->height - 2 * ypad);
+      rect.width  = MIN (rect.width, cell_area->width - 2 * xpad);
+
       if (x_offset)
        {
          if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
-           *x_offset = (1.0 - xalign) * (cell_area->width - (rect.x + rect.width + (2 * xpad)));
+           *x_offset = (1.0 - xalign) * (cell_area->width - (rect.width + (2 * xpad)));
          else 
-           *x_offset = xalign * (cell_area->width - (rect.x + rect.width + (2 * xpad)));
+           *x_offset = xalign * (cell_area->width - (rect.width + (2 * xpad)));
 
          if ((priv->ellipsize_set && priv->ellipsize != PANGO_ELLIPSIZE_NONE) || priv->wrap_width != -1)
            *x_offset = MAX(*x_offset, 0);
@@ -1784,6 +1786,12 @@ get_size (GtkCellRenderer    *cell,
       if (y_offset) *y_offset = 0;
     }
 
+  if (height)
+    *height = ypad * 2 + rect.height;
+
+  if (width)
+    *width = xpad * 2 + rect.width;
+
   g_object_unref (layout);
 }
 
@@ -1798,41 +1806,18 @@ gtk_cell_renderer_text_render (GtkCellRenderer      *cell,
 {
   GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (cell);
   GtkCellRendererTextPrivate *priv = celltext->priv;
+  GtkStyleContext *context;
   PangoLayout *layout;
-  GtkStateType state;
   gint x_offset = 0;
   gint y_offset = 0;
   gint xpad, ypad;
+  PangoRectangle rect;
 
   layout = get_layout (celltext, widget, cell_area, flags);
   get_size (cell, widget, cell_area, layout, &x_offset, &y_offset, NULL, NULL);
+  context = gtk_widget_get_style_context (widget);
 
-  if (!gtk_cell_renderer_get_sensitive (cell))
-    {
-      state = GTK_STATE_INSENSITIVE;
-    }
-  else if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
-    {
-      if (gtk_widget_has_focus (widget))
-       state = GTK_STATE_SELECTED;
-      else
-       state = GTK_STATE_ACTIVE;
-    }
-  else if ((flags & GTK_CELL_RENDERER_PRELIT) == GTK_CELL_RENDERER_PRELIT &&
-          gtk_widget_get_state (widget) == GTK_STATE_PRELIGHT)
-    {
-      state = GTK_STATE_PRELIGHT;
-    }
-  else
-    {
-      if (gtk_widget_get_state (widget) == GTK_STATE_INSENSITIVE)
-       state = GTK_STATE_INSENSITIVE;
-      else
-       state = GTK_STATE_NORMAL;
-    }
-
-  if (priv->background_set && 
-      (flags & GTK_CELL_RENDERER_SELECTED) == 0)
+  if (priv->background_set && (flags & GTK_CELL_RENDERER_SELECTED) == 0)
     {
       gdk_cairo_rectangle (cr, background_area);
       gdk_cairo_set_source_rgba (cr, &priv->background);
@@ -1842,20 +1827,25 @@ gtk_cell_renderer_text_render (GtkCellRenderer      *cell,
   gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
 
   if (priv->ellipsize_set && priv->ellipsize != PANGO_ELLIPSIZE_NONE)
-    pango_layout_set_width (layout, 
+    pango_layout_set_width (layout,
                            (cell_area->width - x_offset - 2 * xpad) * PANGO_SCALE);
   else if (priv->wrap_width == -1)
     pango_layout_set_width (layout, -1);
 
-  gtk_paint_layout (gtk_widget_get_style (widget),
-                          cr,
-                          state,
-                          TRUE,
-                          widget,
-                          "cellrenderertext",
-                          cell_area->x + x_offset + xpad,
-                          cell_area->y + y_offset + ypad,
-                          layout);
+  pango_layout_get_pixel_extents (layout, NULL, &rect);
+  x_offset = x_offset - rect.x;
+
+  cairo_save (cr);
+
+  gdk_cairo_rectangle (cr, cell_area);
+  cairo_clip (cr);
+
+  gtk_render_layout (context, cr,
+                     cell_area->x + x_offset + xpad,
+                     cell_area->y + y_offset + ypad,
+                     layout);
+
+  cairo_restore (cr);
 
   g_object_unref (layout);
 }
@@ -1989,7 +1979,6 @@ gtk_cell_renderer_text_start_editing (GtkCellRenderer      *cell,
                                      const GdkRectangle   *cell_area,
                                      GtkCellRendererState  flags)
 {
-  GtkRequisition requisition;
   GtkCellRendererText *celltext;
   GtkCellRendererTextPrivate *priv;
   gfloat xalign, yalign;
@@ -2013,33 +2002,6 @@ gtk_cell_renderer_text_start_editing (GtkCellRenderer      *cell,
   
   gtk_editable_select_region (GTK_EDITABLE (priv->entry), 0, -1);
 
-  gtk_widget_get_preferred_size (priv->entry, &requisition, NULL);
-  if (requisition.height < cell_area->height)
-    {
-      GtkBorder *style_border;
-      GtkBorder border;
-
-      gtk_widget_style_get (priv->entry,
-                           "inner-border", &style_border,
-                           NULL);
-
-      if (style_border)
-        {
-         border = *style_border;
-         g_boxed_free (GTK_TYPE_BORDER, style_border);
-       }
-      else
-        {
-         /* Since boxed style properties can't have default values ... */
-         border.left = 2;
-         border.right = 2;
-       }
-
-      border.top = (cell_area->height - requisition.height) / 2;
-      border.bottom = (cell_area->height - requisition.height) / 2;
-      gtk_entry_set_inner_border (GTK_ENTRY (priv->entry), &border);
-    }
-
   priv->in_entry_menu = FALSE;
   if (priv->entry_menu_popdown_timeout)
     {
@@ -2110,14 +2072,15 @@ gtk_cell_renderer_text_get_preferred_width (GtkCellRenderer *cell,
                                             gint            *minimum_size,
                                             gint            *natural_size)
 {
-  GtkCellRendererTextPrivate    *priv;
+  GtkCellRendererTextPrivate *priv;
   GtkCellRendererText        *celltext;
-  GtkStyle                   *style;
+  GtkStyleContext            *style_context;
+  const PangoFontDescription *font_desc;
   PangoLayout                *layout;
   PangoContext               *context;
   PangoFontMetrics           *metrics;
   PangoRectangle              rect;
-  gint char_width, digit_width, char_pixels, text_width, ellipsize_chars, guess_width, xpad;
+  gint char_width, text_width, ellipsize_chars, xpad;
   gint min_width, nat_width;
 
   /* "width-chars" Hard-coded minimum width:
@@ -2132,16 +2095,12 @@ gtk_cell_renderer_text_get_preferred_width (GtkCellRenderer *cell,
   celltext = GTK_CELL_RENDERER_TEXT (cell);
   priv = celltext->priv;
 
-  style = gtk_widget_get_style (widget);
+  style_context = gtk_widget_get_style_context (widget);
 
   gtk_cell_renderer_get_padding (cell, &xpad, NULL);
 
   layout = get_layout (celltext, widget, NULL, 0);
 
-  /* Get the layout with the text possibly wrapping at wrap_width */
-  pango_layout_get_pixel_extents (layout, NULL, &rect);
-  guess_width = rect.width;
-
   /* Fetch the length of the complete unwrapped text */
   pango_layout_set_width (layout, -1);
   pango_layout_get_extents (layout, NULL, &rect);
@@ -2149,12 +2108,11 @@ gtk_cell_renderer_text_get_preferred_width (GtkCellRenderer *cell,
 
   /* Fetch the average size of a charachter */
   context = pango_layout_get_context (layout);
-  metrics = pango_context_get_metrics (context, style->font_desc,
-                                      pango_context_get_language (context));
-  
+  font_desc = gtk_style_context_get_font (style_context, 0);
+  metrics = pango_context_get_metrics (context, font_desc,
+                                       pango_context_get_language (context));
+
   char_width = pango_font_metrics_get_approximate_char_width (metrics);
-  digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
-  char_pixels = MAX (char_width, digit_width);
 
   pango_font_metrics_unref (metrics);
   g_object_unref (layout);
@@ -2164,24 +2122,25 @@ gtk_cell_renderer_text_get_preferred_width (GtkCellRenderer *cell,
     ellipsize_chars = 3;
   else
     ellipsize_chars = 0;
-  
+
   if ((priv->ellipsize_set && priv->ellipsize != PANGO_ELLIPSIZE_NONE) || priv->width_chars > 0)
-    min_width = 
-      xpad * 2 + (PANGO_PIXELS (char_width) * MAX (priv->width_chars, ellipsize_chars));
+    min_width = xpad * 2 +
+      MIN (PANGO_PIXELS_CEIL (text_width),
+           (PANGO_PIXELS (char_width) * MAX (priv->width_chars, ellipsize_chars)));
   /* If no width-chars set, minimum for wrapping text will be the wrap-width */
   else if (priv->wrap_width > -1)
-    min_width = xpad * 2 + rect.x + priv->wrap_width;
+    min_width = xpad * 2 + rect.x + MIN (PANGO_PIXELS_CEIL (text_width), priv->wrap_width);
   else
-    min_width = xpad * 2 + rect.x + guess_width;
+    min_width = xpad * 2 + rect.x + PANGO_PIXELS_CEIL (text_width);
 
   if (priv->width_chars > 0)
-    nat_width = xpad * 2 + 
-      MAX ((PANGO_PIXELS (char_width) * priv->width_chars), PANGO_PIXELS (text_width));
+    nat_width = xpad * 2 +
+      MAX ((PANGO_PIXELS (char_width) * priv->width_chars), PANGO_PIXELS_CEIL (text_width));
   else
-    nat_width = xpad * 2 + PANGO_PIXELS (text_width);
+    nat_width = xpad * 2 + PANGO_PIXELS_CEIL (text_width);
 
   nat_width = MAX (nat_width, min_width);
-  
+
   if (priv->max_width_chars > 0)
     {
       gint max_width = xpad * 2 + PANGO_PIXELS (char_width) * priv->max_width_chars;
@@ -2195,7 +2154,6 @@ gtk_cell_renderer_text_get_preferred_width (GtkCellRenderer *cell,
 
   if (natural_size)
     *natural_size = nat_width;
-
 }
 
 static void
@@ -2205,14 +2163,12 @@ gtk_cell_renderer_text_get_preferred_height_for_width (GtkCellRenderer *cell,
                                                        gint            *minimum_height,
                                                        gint            *natural_height)
 {
-  GtkCellRendererTextPrivate    *priv;
-  GtkCellRendererText        *celltext;
-  PangoLayout                *layout;
-  gint                        text_height, xpad, ypad;
+  GtkCellRendererText *celltext;
+  PangoLayout         *layout;
+  gint                 text_height, xpad, ypad;
 
 
   celltext = GTK_CELL_RENDERER_TEXT (cell);
-  priv = celltext->priv;
 
   gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
 
@@ -2250,3 +2206,24 @@ gtk_cell_renderer_text_get_preferred_height (GtkCellRenderer *cell,
                                                          minimum_size, natural_size);
 }
 
+static void
+gtk_cell_renderer_text_get_aligned_area (GtkCellRenderer       *cell,
+                                        GtkWidget             *widget,
+                                        GtkCellRendererState   flags,
+                                        const GdkRectangle    *cell_area,
+                                        GdkRectangle          *aligned_area)
+{
+  GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (cell);
+  PangoLayout *layout;
+  gint x_offset = 0;
+  gint y_offset = 0;
+
+  layout = get_layout (celltext, widget, cell_area, flags);
+  get_size (cell, widget, cell_area, layout, &x_offset, &y_offset, 
+           &aligned_area->width, &aligned_area->height);
+
+  aligned_area->x = cell_area->x + x_offset;
+  aligned_area->y = cell_area->y + y_offset;
+
+  g_object_unref (layout);
+}