Fixed bug in reqstat.
[doldaconnect.git] / clients / gtk2 / progressbar.c
CommitLineData
d3372da9 1/* Taken from the GTK TreeView tutorial on gtk.org.
2 * Slightly modified.
3 */
4
5#include "progressbar.h"
6
7/* This is based mainly on GtkCellRendererProgress
8 * in GAIM, written and (c) 2002 by Sean Egan
9 * (Licensed under the GPL), which in turn is
10 * based on Gtk's GtkCellRenderer[Text|Toggle|Pixbuf]
11 * implementation by Jonathan Blandford */
12
13/* Some boring function declarations: GObject type system stuff */
14
15static void custom_cell_renderer_progress_init (CustomCellRendererProgress *cellprogress);
16
17static void custom_cell_renderer_progress_class_init (CustomCellRendererProgressClass *klass);
18
19static void custom_cell_renderer_progress_get_property (GObject *object,
20 guint param_id,
21 GValue *value,
22 GParamSpec *pspec);
23
24static void custom_cell_renderer_progress_set_property (GObject *object,
25 guint param_id,
26 const GValue *value,
27 GParamSpec *pspec);
28
29static void custom_cell_renderer_progress_finalize (GObject *gobject);
30
31
32/* These functions are the heart of our custom cell renderer: */
33
34static void custom_cell_renderer_progress_get_size (GtkCellRenderer *cell,
35 GtkWidget *widget,
36 GdkRectangle *cell_area,
37 gint *x_offset,
38 gint *y_offset,
39 gint *width,
40 gint *height);
41
42static void custom_cell_renderer_progress_render (GtkCellRenderer *cell,
43 GdkWindow *window,
44 GtkWidget *widget,
45 GdkRectangle *background_area,
46 GdkRectangle *cell_area,
47 GdkRectangle *expose_area,
48 guint flags);
49
50
51enum
52{
53 PROP_PERCENTAGE = 1,
54};
55
56static gpointer parent_class;
57
58
59/***************************************************************************
60 *
61 * custom_cell_renderer_progress_get_type: here we register our type with
62 * the GObject type system if we
63 * haven't done so yet. Everything
64 * else is done in the callbacks.
65 *
66 ***************************************************************************/
67
68GType
69custom_cell_renderer_progress_get_type (void)
70{
71 static GType cell_progress_type = 0;
72
73 if (cell_progress_type)
74 return cell_progress_type;
75
76 if (1)
77 {
78 static const GTypeInfo cell_progress_info =
79 {
80 sizeof (CustomCellRendererProgressClass),
81 NULL, /* base_init */
82 NULL, /* base_finalize */
83 (GClassInitFunc) custom_cell_renderer_progress_class_init,
84 NULL, /* class_finalize */
85 NULL, /* class_data */
86 sizeof (CustomCellRendererProgress),
87 0, /* n_preallocs */
88 (GInstanceInitFunc) custom_cell_renderer_progress_init,
89 };
90
91 /* Derive from GtkCellRenderer */
92 cell_progress_type = g_type_register_static (GTK_TYPE_CELL_RENDERER,
93 "CustomCellRendererProgress",
94 &cell_progress_info,
95 0);
96 }
97
98 return cell_progress_type;
99}
100
101
102/***************************************************************************
103 *
104 * custom_cell_renderer_progress_init: set some default properties of the
105 * parent (GtkCellRenderer).
106 *
107 ***************************************************************************/
108
109static void
110custom_cell_renderer_progress_init (CustomCellRendererProgress *cellrendererprogress)
111{
112 GTK_CELL_RENDERER(cellrendererprogress)->mode = GTK_CELL_RENDERER_MODE_INERT;
113 GTK_CELL_RENDERER(cellrendererprogress)->xpad = 2;
114 GTK_CELL_RENDERER(cellrendererprogress)->ypad = 2;
115}
116
117
118/***************************************************************************
119 *
120 * custom_cell_renderer_progress_class_init:
121 *
122 * set up our own get_property and set_property functions, and
123 * override the parent's functions that we need to implement.
124 * And make our new "percentage" property known to the type system.
125 * If you want cells that can be activated on their own (ie. not
126 * just the whole row selected) or cells that are editable, you
127 * will need to override 'activate' and 'start_editing' as well.
128 *
129 ***************************************************************************/
130
131static void
132custom_cell_renderer_progress_class_init (CustomCellRendererProgressClass *klass)
133{
134 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(klass);
135 GObjectClass *object_class = G_OBJECT_CLASS(klass);
136
137 parent_class = g_type_class_peek_parent (klass);
138 object_class->finalize = custom_cell_renderer_progress_finalize;
139
140 /* Hook up functions to set and get our
141 * custom cell renderer properties */
142 object_class->get_property = custom_cell_renderer_progress_get_property;
143 object_class->set_property = custom_cell_renderer_progress_set_property;
144
145 /* Override the two crucial functions that are the heart
146 * of a cell renderer in the parent class */
147 cell_class->get_size = custom_cell_renderer_progress_get_size;
148 cell_class->render = custom_cell_renderer_progress_render;
149
150 /* Install our very own properties */
151 g_object_class_install_property (object_class,
152 PROP_PERCENTAGE,
153 g_param_spec_double ("percentage",
154 "Percentage",
155 "The fractional progress to display",
156 0, 1, 0,
157 G_PARAM_READWRITE));
158}
159
160
161/***************************************************************************
162 *
163 * custom_cell_renderer_progress_finalize: free any resources here
164 *
165 ***************************************************************************/
166
167static void
168custom_cell_renderer_progress_finalize (GObject *object)
169{
170/*
171 CustomCellRendererProgress *cellrendererprogress = CUSTOM_CELL_RENDERER_PROGRESS(object);
172*/
173
174 /* Free any dynamically allocated resources here */
175
176 (* G_OBJECT_CLASS (parent_class)->finalize) (object);
177}
178
179
180/***************************************************************************
181 *
182 * custom_cell_renderer_progress_get_property: as it says
183 *
184 ***************************************************************************/
185
186static void
187custom_cell_renderer_progress_get_property (GObject *object,
188 guint param_id,
189 GValue *value,
190 GParamSpec *psec)
191{
192 CustomCellRendererProgress *cellprogress = CUSTOM_CELL_RENDERER_PROGRESS(object);
193
194 switch (param_id)
195 {
196 case PROP_PERCENTAGE:
197 g_value_set_double(value, cellprogress->progress);
198 break;
199
200 default:
201 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, psec);
202 break;
203 }
204}
205
206
207/***************************************************************************
208 *
209 * custom_cell_renderer_progress_set_property: as it says
210 *
211 ***************************************************************************/
212
213static void
214custom_cell_renderer_progress_set_property (GObject *object,
215 guint param_id,
216 const GValue *value,
217 GParamSpec *pspec)
218{
219 CustomCellRendererProgress *cellprogress = CUSTOM_CELL_RENDERER_PROGRESS (object);
220
221 switch (param_id)
222 {
223 case PROP_PERCENTAGE:
224 cellprogress->progress = g_value_get_double(value);
225 break;
226
227 default:
228 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
229 break;
230 }
231}
232
233/***************************************************************************
234 *
235 * custom_cell_renderer_progress_new: return a new cell renderer instance
236 *
237 ***************************************************************************/
238
239GtkCellRenderer *
240custom_cell_renderer_progress_new (void)
241{
242 return g_object_new(CUSTOM_TYPE_CELL_RENDERER_PROGRESS, NULL);
243}
244
245
246/***************************************************************************
247 *
248 * custom_cell_renderer_progress_get_size: crucial - calculate the size
249 * of our cell, taking into account
250 * padding and alignment properties
251 * of parent.
252 *
253 ***************************************************************************/
254
255#define FIXED_WIDTH 100
256#define FIXED_HEIGHT 12
257
258static void
259custom_cell_renderer_progress_get_size (GtkCellRenderer *cell,
260 GtkWidget *widget,
261 GdkRectangle *cell_area,
262 gint *x_offset,
263 gint *y_offset,
264 gint *width,
265 gint *height)
266{
267 gint calc_width;
268 gint calc_height;
269
270 calc_width = (gint) cell->xpad * 2 + FIXED_WIDTH;
271 calc_height = (gint) cell->ypad * 2 + FIXED_HEIGHT;
272
273 if (width)
274 *width = calc_width;
275
276 if (height)
277 *height = calc_height;
278
279 if (cell_area)
280 {
281 if (x_offset)
282 {
283 *x_offset = cell->xalign * (cell_area->width - calc_width);
284 *x_offset = MAX (*x_offset, 0);
285 }
286
287 if (y_offset)
288 {
289 *y_offset = cell->yalign * (cell_area->height - calc_height);
290 *y_offset = MAX (*y_offset, 0);
291 }
292 }
293}
294
295
296/***************************************************************************
297 *
298 * custom_cell_renderer_progress_render: crucial - do the rendering.
299 *
300 ***************************************************************************/
301
302static void
303custom_cell_renderer_progress_render (GtkCellRenderer *cell,
304 GdkWindow *window,
305 GtkWidget *widget,
306 GdkRectangle *background_area,
307 GdkRectangle *cell_area,
308 GdkRectangle *expose_area,
309 guint flags)
310{
311 CustomCellRendererProgress *cellprogress = CUSTOM_CELL_RENDERER_PROGRESS (cell);
312 GtkStateType state;
313 gint width, height;
314 gint x_offset, y_offset;
315
316 custom_cell_renderer_progress_get_size (cell, widget, cell_area,
317 &x_offset, &y_offset,
318 &width, &height);
319
320 if (GTK_WIDGET_HAS_FOCUS (widget))
321 state = GTK_STATE_ACTIVE;
322 else
323 state = GTK_STATE_NORMAL;
324
325 width -= cell->xpad*2;
326 height -= cell->ypad*2;
327
328 gtk_paint_box (widget->style,
329 window,
330 GTK_STATE_NORMAL, GTK_SHADOW_IN,
331 NULL, widget, "trough",
332 cell_area->x + x_offset + cell->xpad,
333 cell_area->y + y_offset + cell->ypad,
334 width - 1, height - 1);
335
336 gtk_paint_box (widget->style,
337 window,
338 state, GTK_SHADOW_OUT,
339 NULL, widget, "bar",
340 cell_area->x + x_offset + cell->xpad,
341 cell_area->y + y_offset + cell->ypad,
342 width * cellprogress->progress,
343 height - 1);
344}