summaryrefslogtreecommitdiff
path: root/gtk/gtkcellrendererprogress.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2007-01-02 04:11:15 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2007-01-02 04:11:15 +0000
commit0dd1afdfca7d6c173cbd30aab28119a65dc87493 (patch)
treec44f6616b03ea6c4fdacc7da4d4b45ca28a2ad31 /gtk/gtkcellrendererprogress.c
parent29282c6ec90a7592323b919e746e204d12e01419 (diff)
downloadgtk+-0dd1afdfca7d6c173cbd30aab28119a65dc87493.tar.gz
Implement activity mode for GtkCellRendererProgress. (#377851, Brad
2007-01-01 Matthias Clasen <mclasen@redhat.com> * gtk/gtkcellrendererprogress.c: Implement activity mode for GtkCellRendererProgress. (#377851, Brad Taylor) svn path=/trunk/; revision=17004
Diffstat (limited to 'gtk/gtkcellrendererprogress.c')
-rw-r--r--gtk/gtkcellrendererprogress.c227
1 files changed, 167 insertions, 60 deletions
diff --git a/gtk/gtkcellrendererprogress.c b/gtk/gtkcellrendererprogress.c
index ce930e5225..a4afff66db 100644
--- a/gtk/gtkcellrendererprogress.c
+++ b/gtk/gtkcellrendererprogress.c
@@ -19,7 +19,7 @@
* Boston, MA 02111-1307, USA.
*/
/*
- * Modified by the GTK+ Team and others 1997-2004. See the AUTHORS
+ * Modified by the GTK+ Team and others 1997-2007. 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/.
@@ -41,7 +41,8 @@ enum
{
PROP_0,
PROP_VALUE,
- PROP_TEXT
+ PROP_TEXT,
+ PROP_PULSE
};
struct _GtkCellRendererProgressPrivate
@@ -51,6 +52,8 @@ struct _GtkCellRendererProgressPrivate
gchar *label;
gint min_h;
gint min_w;
+ gint pulse;
+ gint offset;
};
static void gtk_cell_renderer_progress_finalize (GObject *object);
@@ -66,6 +69,8 @@ static void gtk_cell_renderer_progress_set_value (GtkCellRendererProgress *ce
gint value);
static void gtk_cell_renderer_progress_set_text (GtkCellRendererProgress *cellprogress,
const gchar *text);
+static void gtk_cell_renderer_progress_set_pulse (GtkCellRendererProgress *cellprogress,
+ gint pulse);
static void compute_dimensions (GtkCellRenderer *cell,
GtkWidget *widget,
const gchar *text,
@@ -136,6 +141,30 @@ gtk_cell_renderer_progress_class_init (GtkCellRendererProgressClass *klass)
NULL,
GTK_PARAM_READWRITE));
+ /**
+ * GtkCellRendererProgress:pulse:
+ *
+ * Setting this to a non-negative value causes the cell renderer to
+ * enter "activity mode", where a block bounces back and forth to
+ * indicate that some progress is made, with specifying exactly how
+ * much.
+ *
+ * Each increment of the property causes the block to move by a little
+ * bit.
+ *
+ * To indicate that the activity has not started yet, set the property
+ * to zero. To indicate completion, set the property to %G_MAXINT.
+ *
+ * Since: 2.12
+ */
+ g_object_class_install_property (object_class,
+ PROP_PULSE,
+ g_param_spec_int ("pulse",
+ P_("Pulse"),
+ P_("Set this to positive values to indicate that some progress is made, but you don't know how much."),
+ -1, G_MAXINT, -1,
+ GTK_PARAM_READWRITE));
+
g_type_class_add_private (object_class,
sizeof (GtkCellRendererProgressPrivate));
}
@@ -143,12 +172,17 @@ gtk_cell_renderer_progress_class_init (GtkCellRendererProgressClass *klass)
static void
gtk_cell_renderer_progress_init (GtkCellRendererProgress *cellprogress)
{
- cellprogress->priv = GTK_CELL_RENDERER_PROGRESS_GET_PRIVATE (cellprogress);
- cellprogress->priv->value = 0;
- cellprogress->priv->text = NULL;
- cellprogress->priv->label = NULL;
- cellprogress->priv->min_w = -1;
- cellprogress->priv->min_h = -1;
+ GtkCellRendererProgressPrivate *priv = GTK_CELL_RENDERER_PROGRESS_GET_PRIVATE (cellprogress);
+
+ priv->value = 0;
+ priv->text = NULL;
+ priv->label = NULL;
+ priv->min_w = -1;
+ priv->min_h = -1;
+ priv->pulse = -1;
+ priv->offset = 0;
+
+ cellprogress->priv = priv;
}
@@ -171,9 +205,10 @@ static void
gtk_cell_renderer_progress_finalize (GObject *object)
{
GtkCellRendererProgress *cellprogress = GTK_CELL_RENDERER_PROGRESS (object);
+ GtkCellRendererProgressPrivate *priv = cellprogress->priv;
- g_free (cellprogress->priv->text);
- g_free (cellprogress->priv->label);
+ g_free (priv->text);
+ g_free (priv->label);
G_OBJECT_CLASS (gtk_cell_renderer_progress_parent_class)->finalize (object);
}
@@ -185,14 +220,18 @@ gtk_cell_renderer_progress_get_property (GObject *object,
GParamSpec *pspec)
{
GtkCellRendererProgress *cellprogress = GTK_CELL_RENDERER_PROGRESS (object);
+ GtkCellRendererProgressPrivate *priv = cellprogress->priv;
switch (param_id)
{
case PROP_VALUE:
- g_value_set_int (value, cellprogress->priv->value);
+ g_value_set_int (value, priv->value);
break;
case PROP_TEXT:
- g_value_set_string (value, cellprogress->priv->text);
+ g_value_set_string (value, priv->text);
+ break;
+ case PROP_PULSE:
+ g_value_set_int (value, priv->pulse);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -217,28 +256,40 @@ gtk_cell_renderer_progress_set_property (GObject *object,
gtk_cell_renderer_progress_set_text (cellprogress,
g_value_get_string (value));
break;
+ case PROP_PULSE:
+ gtk_cell_renderer_progress_set_pulse (cellprogress,
+ g_value_get_int (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
}
}
static void
+recompute_label (GtkCellRendererProgress *cellprogress)
+{
+ GtkCellRendererProgressPrivate *priv = cellprogress->priv;
+ gchar *label;
+
+ if (priv->text)
+ label = g_strdup (priv->text);
+ else if (priv->pulse < 0)
+ /* do not translate the part before the | */
+ label = g_strdup_printf (Q_("progress bar label|%d %%"), priv->value);
+ else
+ label = NULL;
+
+ g_free (priv->label);
+ priv->label = label;
+}
+
+static void
gtk_cell_renderer_progress_set_value (GtkCellRendererProgress *cellprogress,
gint value)
{
- gchar *text;
-
cellprogress->priv->value = value;
- if (cellprogress->priv->text)
- text = g_strdup (cellprogress->priv->text);
- else
- /* do not translate the part before the | */
- text = g_strdup_printf (Q_("progress bar label|%d %%"),
- cellprogress->priv->value);
-
- g_free (cellprogress->priv->label);
- cellprogress->priv->label = text;
+ recompute_label (cellprogress);
}
static void
@@ -251,8 +302,26 @@ gtk_cell_renderer_progress_set_text (GtkCellRendererProgress *cellprogress,
g_free (cellprogress->priv->text);
cellprogress->priv->text = new_text;
- /* Update the label */
- gtk_cell_renderer_progress_set_value (cellprogress, cellprogress->priv->value);
+ recompute_label (cellprogress);
+}
+
+static void
+gtk_cell_renderer_progress_set_pulse (GtkCellRendererProgress *cellprogress,
+ gint pulse)
+{
+ GtkCellRendererProgressPrivate *priv = cellprogress->priv;
+
+ if (pulse != priv->pulse)
+ {
+ if (priv->pulse <= 0)
+ priv->offset = 0;
+ else
+ priv->offset++;
+ }
+
+ priv->pulse = pulse;
+
+ recompute_label (cellprogress);
}
static void
@@ -287,25 +356,26 @@ gtk_cell_renderer_progress_get_size (GtkCellRenderer *cell,
gint *height)
{
GtkCellRendererProgress *cellprogress = GTK_CELL_RENDERER_PROGRESS (cell);
+ GtkCellRendererProgressPrivate *priv = cellprogress->priv;
gint w, h;
gchar *text;
- if (cellprogress->priv->min_w < 0)
+ if (priv->min_w < 0)
{
text = g_strdup_printf (Q_("progress bar label|%d %%"), 100);
compute_dimensions (cell, widget, text,
- &cellprogress->priv->min_w,
- &cellprogress->priv->min_h);
+ &priv->min_w,
+ &priv->min_h);
g_free (text);
}
- compute_dimensions (cell, widget, cellprogress->priv->label, &w, &h);
+ compute_dimensions (cell, widget, priv->label, &w, &h);
if (width)
- *width = MAX (cellprogress->priv->min_w, w);
+ *width = MAX (priv->min_w, w);
if (height)
- *height = MIN (cellprogress->priv->min_h, h);
+ *height = MIN (priv->min_h, h);
/* FIXME: at the moment cell_area is only set when we are requesting
* the size for drawing the focus rectangle. We now just return
@@ -334,9 +404,10 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
guint flags)
{
GtkCellRendererProgress *cellprogress = GTK_CELL_RENDERER_PROGRESS (cell);
+ GtkCellRendererProgressPrivate *priv= cellprogress->priv;
PangoLayout *layout;
PangoRectangle logical_rect;
- gint x, y, w, h, perc_w, pos;
+ gint x, y, w, h, x_pos, y_pos, bar_x, bar_width;
GdkRectangle clip;
gboolean is_rtl;
@@ -357,11 +428,31 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
NULL, widget, NULL,
x, y, w, h);
- perc_w = w * MAX (0, cellprogress->priv->value) / 100;
- clip.x = is_rtl ? (x + w - perc_w) : x;
clip.y = y;
- clip.width = perc_w;
clip.height = h;
+ if (priv->pulse < 0)
+ {
+ clip.width = w * MAX (0, priv->value) / 100;
+ clip.x = is_rtl ? (x + w - clip.width) : x;
+ }
+ else if (priv->pulse == 0)
+ {
+ clip.x = x;
+ clip.width = 0;
+ }
+ else if (priv->pulse == G_MAXINT)
+ {
+ clip.x = x;
+ clip.width = w;
+ }
+ else
+ {
+ clip.width = MAX (2, w / 5);
+ x_pos = (is_rtl ? priv->offset + 12 : priv->offset) % 24;
+ if (x_pos > 12)
+ x_pos = 24 - x_pos;
+ clip.x = x + w * x_pos / 15;
+ }
gtk_paint_box (widget->style,
window,
@@ -370,32 +461,48 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
clip.x, clip.y,
clip.width, clip.height);
- 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);
+ if (priv->label)
+ {
+ layout = gtk_widget_create_pango_layout (widget, priv->label);
+ pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
+
+ x_pos = x + (w - logical_rect.width) / 2;
+ y_pos = y + (h - logical_rect.height) / 2;
- g_object_unref (layout);
+ gtk_paint_layout (widget->style, window,
+ GTK_STATE_SELECTED,
+ FALSE, &clip, widget, "progressbar",
+ x_pos, y_pos,
+ layout);
+
+ bar_x = clip.x;
+ bar_width = clip.width;
+ if (bar_x > x)
+ {
+ clip.x = x;
+ clip.width = bar_x - x;
+
+ gtk_paint_layout (widget->style, window,
+ GTK_STATE_NORMAL,
+ FALSE, &clip, widget, "progressbar",
+ x_pos, y_pos,
+ layout);
+ }
+
+ if (bar_x + bar_width < x + w)
+ {
+ clip.x = bar_x + bar_width;
+ clip.width = x + w - (bar_x + bar_width);
+
+ gtk_paint_layout (widget->style, window,
+ GTK_STATE_NORMAL,
+ FALSE, &clip, widget, "progressbar",
+ x_pos, y_pos,
+ layout);
+ }
+
+ g_object_unref (layout);
+ }
}
#define __GTK_CELL_RENDERER_PROGRESS_C__