diff options
Diffstat (limited to 'lib/widgets/ephy-cell-renderer-progress.c')
-rw-r--r-- | lib/widgets/ephy-cell-renderer-progress.c | 526 |
1 files changed, 300 insertions, 226 deletions
diff --git a/lib/widgets/ephy-cell-renderer-progress.c b/lib/widgets/ephy-cell-renderer-progress.c index 0d012dce8..2f89e459d 100644 --- a/lib/widgets/ephy-cell-renderer-progress.c +++ b/lib/widgets/ephy-cell-renderer-progress.c @@ -1,4 +1,4 @@ -/* gtkcellrenderer.c +/* gtkcellrendererprogress.c * Copyright (C) 2002 Naba Kumar <kh_naba@users.sourceforge.net> * heavily modified by Jörgen Scheibengruber <mfcn@gmx.de> * heavily modified by Marco Pesenti Gritti <marco@gnome.org> @@ -17,296 +17,370 @@ * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. - * - * $Id$ */ +/* + * Modified by the GTK+ Team and others 1997-2004. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* KEEP IN SYNC with the original in gtk+ (HEAD branch) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> -#include <glib/gi18n.h> - #include "ephy-cell-renderer-progress.h" +#include <glib/gi18n.h> -static void ephy_cell_renderer_progress_init (EphyCellRendererProgress *celltext); -static void ephy_cell_renderer_progress_class_init (EphyCellRendererProgressClass *class); - -#define EPHY_CELL_RENDERER_PROGRESS_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_CELL_RENDERER_PROGRESS, EphyCellRendererProgressPrivate)) +#define EPHY_CELL_RENDERER_PROGRESS_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), \ + EPHY_TYPE_CELL_RENDERER_PROGRESS, \ + EphyCellRendererProgressPrivate)) #define XPAD 4 #define YPAD 8 -#define UNKNOWN_STRING _("Unknown") enum { PROP_0, - PROP_VALUE + PROP_VALUE, + PROP_TEXT }; struct _EphyCellRendererProgressPrivate { - int value; - char *text; - int min_h; - int min_w; + gint value; + gchar *text; + gchar *label; + gint min_h; + gint min_w; }; -static gpointer parent_class; +static void ephy_cell_renderer_progress_finalize (GObject *object); +static void ephy_cell_renderer_progress_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void ephy_cell_renderer_progress_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); +static void ephy_cell_renderer_progress_set_value (EphyCellRendererProgress *cellprogress, + gint value); +static void ephy_cell_renderer_progress_set_text (EphyCellRendererProgress *cellprogress, + const gchar *text); +static void compute_dimensions (GtkWidget *widget, + const gchar *text, + gint *width, + gint *height); +static void ephy_cell_renderer_progress_get_size (GtkCellRenderer *cell, + GtkWidget *widget, + GdkRectangle *cell_area, + gint *x_offset, + gint *y_offset, + gint *width, + gint *height); +static void ephy_cell_renderer_progress_render (GtkCellRenderer *cell, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *background_area, + GdkRectangle *cell_area, + GdkRectangle *expose_area, + guint flags); + + +G_DEFINE_TYPE (EphyCellRendererProgress, ephy_cell_renderer_progress, GTK_TYPE_CELL_RENDERER); -GtkType -ephy_cell_renderer_progress_get_type (void) +static void +ephy_cell_renderer_progress_class_init (EphyCellRendererProgressClass *klass) { - static GtkType cell_progress_type = 0; - - if (!cell_progress_type) - { - static const GTypeInfo cell_progress_info = - { - sizeof (EphyCellRendererProgressClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) ephy_cell_renderer_progress_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EphyCellRendererProgress), - 0, /* n_preallocs */ - (GInstanceInitFunc) ephy_cell_renderer_progress_init, - }; - cell_progress_type = g_type_register_static (GTK_TYPE_CELL_RENDERER, - "EphyCellRendererProgress", - &cell_progress_info, 0); - } - - return cell_progress_type; + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass); + + object_class->finalize = ephy_cell_renderer_progress_finalize; + object_class->get_property = ephy_cell_renderer_progress_get_property; + object_class->set_property = ephy_cell_renderer_progress_set_property; + + cell_class->get_size = ephy_cell_renderer_progress_get_size; + cell_class->render = ephy_cell_renderer_progress_render; + + /** + * EphyCellRendererProgress:value: + * + * The "value" property determines the percentage to which the + * progress bar will be "filled in". + * + * Since: 2.6 + **/ + g_object_class_install_property (object_class, + PROP_VALUE, + g_param_spec_int ("value", + "Value", + "Value of the progress bar", + -2, 100, 0, + G_PARAM_READWRITE)); + + /** + * EphyCellRendererProgress:text: + * + * The "text" property determines the label which will be drawn + * over the progress bar. Setting this property to %NULL causes the default + * label to be displayed. Setting this property to an empty string causes + * no label to be displayed. + * + * Since: 2.6 + **/ + g_object_class_install_property (object_class, + PROP_TEXT, + g_param_spec_string ("text", + "Text", + "Text on the progress bar", + NULL, + G_PARAM_READWRITE)); + + g_type_class_add_private (object_class, + sizeof (EphyCellRendererProgressPrivate)); } static void ephy_cell_renderer_progress_init (EphyCellRendererProgress *cellprogress) { - cellprogress->priv = EPHY_CELL_RENDERER_PROGRESS_GET_PRIVATE (cellprogress); - cellprogress->priv->value = 0; - cellprogress->priv->text = NULL; - cellprogress->priv->min_w = -1; + cellprogress->priv = EPHY_CELL_RENDERER_PROGRESS_GET_PRIVATE (cellprogress); + cellprogress->priv->value = 0; + cellprogress->priv->text = NULL; + cellprogress->priv->label = NULL; + cellprogress->priv->min_w = -1; } -static void -ephy_cell_renderer_progress_set_value (EphyCellRendererProgress *cellprogress, int value) -{ - char *text; - - cellprogress->priv->value = value; - if (cellprogress->priv->value == EPHY_PROGRESS_CELL_FAILED) - { - text = g_strdup (_("Failed")); - } - else if (cellprogress->priv->value == EPHY_PROGRESS_CELL_UNKNOWN) - { - text = g_strdup (UNKNOWN_STRING); - } - else - { - text = g_strdup_printf ("%d %%", cellprogress->priv->value); - } +/** + * ephy_cell_renderer_progress_new: + * + * Creates a new #EphyCellRendererProgress. + * + * Return value: the new cell renderer + * + * Since: 2.6 + **/ +GtkCellRenderer* +ephy_cell_renderer_progress_new (void) +{ + return GTK_CELL_RENDERER (g_object_new (EPHY_TYPE_CELL_RENDERER_PROGRESS, NULL)); +} - g_free (cellprogress->priv->text); - cellprogress->priv->text = text; +static void +ephy_cell_renderer_progress_finalize (GObject *object) +{ + EphyCellRendererProgress *cellprogress = EPHY_CELL_RENDERER_PROGRESS (object); + + g_free (cellprogress->priv->text); + g_free (cellprogress->priv->label); + + G_OBJECT_CLASS (ephy_cell_renderer_progress_parent_class)->finalize (object); } static void ephy_cell_renderer_progress_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) + guint param_id, + GValue *value, + GParamSpec *pspec) { - EphyCellRendererProgress *cellprogress = EPHY_CELL_RENDERER_PROGRESS (object); - - switch (param_id) - { - case PROP_VALUE: - g_value_set_int (value, cellprogress->priv->value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - } + EphyCellRendererProgress *cellprogress = EPHY_CELL_RENDERER_PROGRESS (object); + + switch (param_id) + { + case PROP_VALUE: + g_value_set_int (value, cellprogress->priv->value); + break; + case PROP_TEXT: + g_value_set_string (value, cellprogress->priv->text); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + } } static void ephy_cell_renderer_progress_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) + guint param_id, + const GValue *value, + GParamSpec *pspec) { - EphyCellRendererProgress *cellprogress = EPHY_CELL_RENDERER_PROGRESS (object); - - switch (param_id) - { - case PROP_VALUE: - ephy_cell_renderer_progress_set_value - (cellprogress, g_value_get_int (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - } + EphyCellRendererProgress *cellprogress = EPHY_CELL_RENDERER_PROGRESS (object); + + switch (param_id) + { + case PROP_VALUE: + ephy_cell_renderer_progress_set_value (cellprogress, + g_value_get_int (value)); + break; + case PROP_TEXT: + ephy_cell_renderer_progress_set_text (cellprogress, + g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + } } static void -compute_dimensions (GtkWidget *widget, const char *text, int *width, int *height) +ephy_cell_renderer_progress_set_value (EphyCellRendererProgress *cellprogress, + gint value) { - PangoRectangle logical_rect; - PangoLayout *layout; - - layout = gtk_widget_create_pango_layout (widget, text); - pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - - if (width) - { - *width = logical_rect.width + XPAD * 2 + - widget->style->xthickness * 2; - } - - if (height) - { - *height = logical_rect.height + YPAD * 2 + - widget->style->ythickness * 2; - } - - g_object_unref (G_OBJECT (layout)); + gchar *text; + + cellprogress->priv->value = value; + + if (cellprogress->priv->text) + text = g_strdup (cellprogress->priv->text); + else if (cellprogress->priv->value == EPHY_PROGRESS_CELL_FAILED) + /* Translator hint: this is a label on progress bars inside a tree view. + */ + text = g_strdup (_("Failed")); + else if (cellprogress->priv->value == EPHY_PROGRESS_CELL_UNKNOWN) + /* Translator hint: this is a label on progress bars inside a tree view. + */ + text = g_strdup (_("Unknown")); + else + /* Translator hint: this is the default label on progress bars + * inside a tree view. %d will be replaced by the percentage + */ + text = g_strdup_printf (_("%d %%"), cellprogress->priv->value); + + g_free (cellprogress->priv->label); + cellprogress->priv->label = text; } static void -ephy_cell_renderer_progress_get_size (GtkCellRenderer *cell, - GtkWidget *widget, - GdkRectangle *cell_area, - gint *x_offset, - gint *y_offset, - gint *width, - gint *height) +ephy_cell_renderer_progress_set_text (EphyCellRendererProgress *cellprogress, + const gchar *text) { - EphyCellRendererProgress *cellprogress = EPHY_CELL_RENDERER_PROGRESS (cell); - int w, h; - - if (cellprogress->priv->min_w < 0) - { - compute_dimensions (widget, UNKNOWN_STRING, - &cellprogress->priv->min_w, - &cellprogress->priv->min_h); - } - - compute_dimensions (widget, cellprogress->priv->text, &w, &h); - - if (width) - { - *width = MAX (cellprogress->priv->min_w, w); - } + gchar *new_text; - if (height) - { - *height = MIN (cellprogress->priv->min_h, h); - } -} + new_text = g_strdup (text); + g_free (cellprogress->priv->text); + cellprogress->priv->text = new_text; -GtkCellRenderer* -ephy_cell_renderer_progress_new (void) -{ - return GTK_CELL_RENDERER (g_object_new (ephy_cell_renderer_progress_get_type (), NULL)); + /* Update the label */ + ephy_cell_renderer_progress_set_value (cellprogress, cellprogress->priv->value); } static void -ephy_cell_renderer_progress_render (GtkCellRenderer *cell, - GdkWindow *window, - GtkWidget *widget, - GdkRectangle *background_area, - GdkRectangle *cell_area, - GdkRectangle *expose_area, - guint flags) +compute_dimensions (GtkWidget *widget, + const gchar *text, + gint *width, + gint *height) { - EphyCellRendererProgress *cellprogress = (EphyCellRendererProgress *) cell; - GdkGC *gc; - PangoLayout *layout; - PangoRectangle logical_rect; - GtkStateType state; - int x, y, w, h, perc_w, pos; - - gc = gdk_gc_new (window); - - x = cell_area->x + XPAD; - y = cell_area->y + YPAD; - - w = cell_area->width - XPAD * 2; - h = cell_area->height - YPAD * 2; - - gdk_gc_set_rgb_fg_color (gc, &widget->style->fg[GTK_STATE_NORMAL]); - gdk_draw_rectangle (window, gc, TRUE, x, y, w, h); - - x += widget->style->xthickness; - y += widget->style->ythickness; - w -= widget->style->xthickness * 2; - h -= widget->style->ythickness * 2; - gdk_gc_set_rgb_fg_color (gc, &widget->style->bg[GTK_STATE_NORMAL]); - gdk_draw_rectangle (window, gc, TRUE, x, y, w, h); - - gdk_gc_set_rgb_fg_color (gc, &widget->style->bg[GTK_STATE_SELECTED]); - perc_w = w * cellprogress->priv->value / 100; - gdk_draw_rectangle (window, gc, TRUE, x, y, perc_w, h); - - layout = gtk_widget_create_pango_layout (widget, cellprogress->priv->text); - pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - - pos = (w - logical_rect.width)/2; - - if (perc_w < pos + logical_rect.width/2) - { - state = GTK_STATE_NORMAL; - } - else - { - state = GTK_STATE_SELECTED; - } - - gtk_paint_layout (widget->style, window, state, - FALSE, cell_area, widget, "progressbar", - x + pos, y + (h - logical_rect.height)/2, - layout); - - g_object_unref (G_OBJECT (layout)); - g_object_unref (G_OBJECT (gc)); + PangoRectangle logical_rect; + PangoLayout *layout; + + layout = gtk_widget_create_pango_layout (widget, text); + pango_layout_get_pixel_extents (layout, NULL, &logical_rect); + + if (width) + *width = logical_rect.width + XPAD * 2 + widget->style->xthickness * 2; + + if (height) + *height = logical_rect.height + YPAD * 2 + widget->style->ythickness * 2; + + g_object_unref (G_OBJECT (layout)); } static void -ephy_cell_renderer_progress_finalize (GObject *object) +ephy_cell_renderer_progress_get_size (GtkCellRenderer *cell, + GtkWidget *widget, + GdkRectangle *cell_area, + gint *x_offset, + gint *y_offset, + gint *width, + gint *height) { - EphyCellRendererProgress *cellprogress = EPHY_CELL_RENDERER_PROGRESS (object); - - g_free (cellprogress->priv->text); - - G_OBJECT_CLASS (parent_class)->finalize (object); + EphyCellRendererProgress *cellprogress = EPHY_CELL_RENDERER_PROGRESS (cell); + gint w, h; + + if (cellprogress->priv->min_w < 0) + compute_dimensions (widget, _("Unknown"), + &cellprogress->priv->min_w, + &cellprogress->priv->min_h); + + compute_dimensions (widget, cellprogress->priv->label, &w, &h); + + if (width) + *width = MAX (cellprogress->priv->min_w, w); + + if (height) + *height = MIN (cellprogress->priv->min_h, h); } static void -ephy_cell_renderer_progress_class_init (EphyCellRendererProgressClass *class) +ephy_cell_renderer_progress_render (GtkCellRenderer *cell, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *background_area, + GdkRectangle *cell_area, + GdkRectangle *expose_area, + guint flags) { - GObjectClass *object_class = G_OBJECT_CLASS (class); - GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class); - - parent_class = g_type_class_peek_parent (class); + EphyCellRendererProgress *cellprogress = EPHY_CELL_RENDERER_PROGRESS (cell); + GdkGC *gc; + PangoLayout *layout; + PangoRectangle logical_rect; + gint x, y, w, h, perc_w, pos; + GdkRectangle clip; + gboolean is_rtl; + + is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL; - object_class->finalize = ephy_cell_renderer_progress_finalize; - object_class->get_property = ephy_cell_renderer_progress_get_property; - object_class->set_property = ephy_cell_renderer_progress_set_property; - - cell_class->get_size = ephy_cell_renderer_progress_get_size; - cell_class->render = ephy_cell_renderer_progress_render; + gc = gdk_gc_new (window); - g_object_class_install_property (object_class, - PROP_VALUE, - g_param_spec_int ("value", - "Value", - "Value of the progress bar.", - -2, 100, 0, - G_PARAM_READWRITE)); - - g_type_class_add_private (object_class, sizeof (EphyCellRendererProgressPrivate)); + x = cell_area->x + XPAD; + y = cell_area->y + YPAD; + + w = cell_area->width - XPAD * 2; + h = cell_area->height - YPAD * 2; + + gdk_gc_set_rgb_fg_color (gc, &widget->style->fg[GTK_STATE_NORMAL]); + gdk_draw_rectangle (window, gc, TRUE, x, y, w, h); + + x += widget->style->xthickness; + y += widget->style->ythickness; + w -= widget->style->xthickness * 2; + h -= widget->style->ythickness * 2; + gdk_gc_set_rgb_fg_color (gc, &widget->style->bg[GTK_STATE_NORMAL]); + gdk_draw_rectangle (window, gc, TRUE, x, y, w, h); + + gdk_gc_set_rgb_fg_color (gc, &widget->style->bg[GTK_STATE_SELECTED]); + perc_w = w * cellprogress->priv->value / 100; + gdk_draw_rectangle (window, gc, TRUE, is_rtl ? (x + w - perc_w) : x, y, perc_w, h); + + layout = gtk_widget_create_pango_layout (widget, cellprogress->priv->label); + pango_layout_get_pixel_extents (layout, NULL, &logical_rect); + + pos = (w - logical_rect.width)/2; + + clip.x = x; + clip.y = y; + clip.width = is_rtl ? w - perc_w : perc_w; + clip.height = h; + + gtk_paint_layout (widget->style, window, + is_rtl ? GTK_STATE_NORMAL : GTK_STATE_SELECTED, + FALSE, &clip, widget, "progressbar", + x + pos, y + (h - logical_rect.height)/2, + layout); + + clip.x = clip.x + clip.width; + clip.width = w - clip.width; + + gtk_paint_layout (widget->style, window, + is_rtl ? GTK_STATE_SELECTED : GTK_STATE_NORMAL, + FALSE, &clip, widget, "progressbar", + x + pos, y + (h - logical_rect.height)/2, + layout); + + g_object_unref (G_OBJECT (layout)); + g_object_unref (G_OBJECT (gc)); } + |