summaryrefslogtreecommitdiff
path: root/baobab/src/baobab-cell-renderer-progress.c
diff options
context:
space:
mode:
Diffstat (limited to 'baobab/src/baobab-cell-renderer-progress.c')
-rw-r--r--baobab/src/baobab-cell-renderer-progress.c265
1 files changed, 265 insertions, 0 deletions
diff --git a/baobab/src/baobab-cell-renderer-progress.c b/baobab/src/baobab-cell-renderer-progress.c
new file mode 100644
index 00000000..753d8b0a
--- /dev/null
+++ b/baobab/src/baobab-cell-renderer-progress.c
@@ -0,0 +1,265 @@
+/* baobab-cell-renderer-progress.c
+ *
+ * Copyright (C) 2006 Paolo Borelli
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * 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.
+ */
+
+#include "config.h"
+#include <stdlib.h>
+
+#include "baobab-cell-renderer-progress.h"
+
+#define BAOBAB_CELL_RENDERER_PROGRESS_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), \
+ BAOBAB_TYPE_CELL_RENDERER_PROGRESS, \
+ BaobabCellRendererProgressPrivate))
+
+enum
+{
+ PROP_0,
+ PROP_PERC
+};
+
+struct _BaobabCellRendererProgressPrivate
+{
+ double perc;
+};
+
+G_DEFINE_TYPE (BaobabCellRendererProgress, baobab_cell_renderer_progress, GTK_TYPE_CELL_RENDERER)
+
+static void
+baobab_cell_renderer_progress_init (BaobabCellRendererProgress *cellprogress)
+{
+ cellprogress->priv = BAOBAB_CELL_RENDERER_PROGRESS_GET_PRIVATE (cellprogress);
+ cellprogress->priv->perc = 0;
+
+ gtk_cell_renderer_set_padding (GTK_CELL_RENDERER (cellprogress), 4, 4);
+}
+
+GtkCellRenderer*
+baobab_cell_renderer_progress_new (void)
+{
+ return g_object_new (BAOBAB_TYPE_CELL_RENDERER_PROGRESS, NULL);
+}
+
+static void
+baobab_cell_renderer_progress_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ BaobabCellRendererProgress *cellprogress = BAOBAB_CELL_RENDERER_PROGRESS (object);
+
+ switch (param_id)
+ {
+ case PROP_PERC:
+ g_value_set_double (value, cellprogress->priv->perc);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ }
+}
+
+static void
+baobab_cell_renderer_progress_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ BaobabCellRendererProgress *cellprogress = BAOBAB_CELL_RENDERER_PROGRESS (object);
+
+ switch (param_id)
+ {
+ case PROP_PERC:
+ cellprogress->priv->perc = g_value_get_double (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ }
+}
+
+/* we simply have a fixed size */
+
+#define FIXED_WIDTH 70
+#define FIXED_HEIGHT 8
+
+static void
+baobab_cell_renderer_progress_get_size (GtkCellRenderer *cell,
+ GtkWidget *widget,
+ GdkRectangle *cell_area,
+ gint *x_offset,
+ gint *y_offset,
+ gint *width,
+ gint *height)
+{
+ gint calc_width;
+ gint calc_height;
+ gint xpad;
+ gint ypad;
+ gfloat xalign;
+ gfloat yalign;
+
+ gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
+ calc_width = (gint) xpad * 2 + FIXED_WIDTH;
+ calc_height = (gint) ypad * 2 + FIXED_HEIGHT;
+
+ if (width)
+ *width = calc_width;
+
+ if (height)
+ *height = calc_height;
+
+ if (cell_area)
+ {
+ gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);
+ if (x_offset)
+ {
+ *x_offset = xalign * (cell_area->width - calc_width);
+ *x_offset = MAX (*x_offset, 0);
+ }
+
+ if (y_offset)
+ {
+ *y_offset = yalign * (cell_area->height - calc_height);
+ *y_offset = MAX (*y_offset, 0);
+ }
+ }
+}
+
+static void
+set_color_according_to_perc (cairo_t *cr, double value)
+{
+ static GdkColor red;
+ static GdkColor yellow;
+ static GdkColor green;
+ static gboolean colors_initialized = FALSE;
+
+ if (!colors_initialized)
+ {
+ /* hardcoded tango colors */
+ gdk_color_parse ("#cc0000", &red);
+ gdk_color_parse ("#edd400", &yellow);
+ gdk_color_parse ("#73d216", &green);
+
+ colors_initialized = TRUE;
+ }
+
+ if (value <= 0)
+ {
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ return;
+ }
+ else if (value <= 33.33)
+ {
+ gdk_cairo_set_source_color (cr, &green);
+ return;
+ }
+ else if (value <= 66.66)
+ {
+ gdk_cairo_set_source_color (cr, &yellow);
+ return;
+ }
+ else if (value <= 100.0)
+ {
+ gdk_cairo_set_source_color (cr, &red);
+ return;
+ }
+ else
+ g_assert_not_reached ();
+}
+
+static void
+baobab_cell_renderer_progress_render (GtkCellRenderer *cell,
+ GdkWindow *window,
+ GtkWidget *widget,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GdkRectangle *expose_area,
+ guint flags)
+{
+ BaobabCellRendererProgress *cellprogress = BAOBAB_CELL_RENDERER_PROGRESS (cell);
+ gint x, y, w, h, perc_w;
+ gboolean is_rtl;
+ cairo_t *cr;
+ gint xpad;
+ gint ypad;
+ GtkStyle *style;
+
+ is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+
+ cr = gdk_cairo_create (window);
+
+ gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
+
+ x = cell_area->x + xpad;
+ y = cell_area->y + ypad;
+
+ w = cell_area->width - xpad * 2;
+ h = cell_area->height - ypad * 2;
+
+ /*
+ * we always use a white bar with black
+ * border and green/yellow/red progress...
+ * I know it's not theme friendly, but we don't
+ * want a plain progress bar
+ */
+
+ cairo_rectangle (cr, x, y, w, h);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_fill (cr);
+
+ style = gtk_widget_get_style (widget);
+ x += style->xthickness;
+ y += style->ythickness;
+ w -= style->xthickness * 2;
+ h -= style->ythickness * 2;
+
+ cairo_rectangle (cr, x, y, w, h);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_fill (cr);
+
+ perc_w = w * MAX (0, cellprogress->priv->perc) / 100;
+
+ cairo_rectangle (cr, is_rtl ? (x + w - perc_w) : x, y, perc_w, h);
+ set_color_according_to_perc (cr, cellprogress->priv->perc);
+ cairo_fill (cr);
+
+ cairo_destroy (cr);
+}
+
+static void
+baobab_cell_renderer_progress_class_init (BaobabCellRendererProgressClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
+
+ object_class->get_property = baobab_cell_renderer_progress_get_property;
+ object_class->set_property = baobab_cell_renderer_progress_set_property;
+
+ cell_class->get_size = baobab_cell_renderer_progress_get_size;
+ cell_class->render = baobab_cell_renderer_progress_render;
+
+ g_object_class_install_property (object_class,
+ PROP_PERC,
+ g_param_spec_double ("perc",
+ "percentage",
+ "precentage",
+ -1, 100, 0,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (object_class,
+ sizeof (BaobabCellRendererProgressPrivate));
+}