Contents of /trunk/src/custom_type_renderer.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 189 - (show annotations)
Tue Nov 17 09:07:17 2009 UTC (14 years, 5 months ago) by harbaum
File MIME type: text/plain
File size: 12248 byte(s)
Various adjustments
1 /*
2 * Copyright (C) 2008 Till Harbaum <till@harbaum.org>.
3 *
4 * This file is part of GPXView.
5 *
6 * GPXView is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GPXView is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GPXView. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "gpxview.h"
21 #include "custom_type_renderer.h"
22
23 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
24 #define CUSTOM_ICON_TYPE ICON_CACHE_TYPE_1_5X
25 #else
26 #define CUSTOM_ICON_TYPE ICON_CACHE_TYPE
27 #endif
28
29 /* http://scentric.net/tutorial/sec-custom-cell-renderers.html */
30 /* https://stage.maemo.org/svn/maemo/projects/haf/trunk/gtk+/gtk/gtkcellrendererpixbuf.c */
31 /* https://stage.maemo.org/svn/maemo/projects/haf/trunk/gtk+/gtk/gtkcellrenderertext.c */
32
33 /* This is based mainly on GtkCellRendererProgress
34 * in GAIM, written and (c) 2002 by Sean Egan
35 * (Licensed under the GPL), which in turn is
36 * based on Gtk's GtkCellRenderer[Text|Toggle|Pixbuf]
37 * implementation by Jonathan Blandford */
38
39 /* Some boring function declarations: GObject type system stuff */
40
41 static void custom_cell_renderer_type_init (CustomCellRendererType *celltype);
42 static void custom_cell_renderer_type_class_init (CustomCellRendererTypeClass *klass);
43 static void custom_cell_renderer_type_get_property (GObject *object,
44 guint param_id,
45 GValue *value,
46 GParamSpec *pspec);
47 static void custom_cell_renderer_type_set_property (GObject *object,
48 guint param_id,
49 const GValue *value,
50 GParamSpec *pspec);
51 static void custom_cell_renderer_type_finalize (GObject *gobject);
52
53
54 /* These functions are the heart of our custom cell renderer: */
55
56 static void custom_cell_renderer_type_get_size (GtkCellRenderer *cell,
57 GtkWidget *widget,
58 GdkRectangle *cell_area,
59 gint *x_offset,
60 gint *y_offset,
61 gint *width,
62 gint *height);
63
64 static void custom_cell_renderer_type_render (GtkCellRenderer *cell,
65 GdkWindow *window,
66 GtkWidget *widget,
67 GdkRectangle *background_area,
68 GdkRectangle *cell_area,
69 GdkRectangle *expose_area,
70 guint flags);
71
72
73 enum { PROP_TYPE = 1, };
74
75 static gpointer parent_class;
76
77 GType custom_cell_renderer_type_get_type (void) {
78 static GType cell_type_type = 0;
79
80 if (cell_type_type == 0)
81 {
82 static const GTypeInfo cell_type_info =
83 {
84 sizeof (CustomCellRendererTypeClass),
85 NULL, /* base_init */
86 NULL, /* base_finalize */
87 (GClassInitFunc) custom_cell_renderer_type_class_init,
88 NULL, /* class_finalize */
89 NULL, /* class_data */
90 sizeof (CustomCellRendererType),
91 0, /* n_preallocs */
92 (GInstanceInitFunc) custom_cell_renderer_type_init,
93 };
94
95 /* Derive from GtkCellRenderer */
96 cell_type_type = g_type_register_static (GTK_TYPE_CELL_RENDERER,
97 "CustomCellRendererType",
98 &cell_type_info,
99 0);
100 }
101 return cell_type_type;
102 }
103
104
105 /***************************************************************************
106 *
107 * custom_cell_renderer_type_init: set some default properties of the
108 * parent (GtkCellRenderer).
109 *
110 ***************************************************************************/
111
112 static void
113 custom_cell_renderer_type_init (CustomCellRendererType *cellrenderertype)
114 {
115 GTK_CELL_RENDERER(cellrenderertype)->mode = GTK_CELL_RENDERER_MODE_INERT;
116 GTK_CELL_RENDERER(cellrenderertype)->xpad = 0;
117 GTK_CELL_RENDERER(cellrenderertype)->ypad = 0;
118 }
119
120
121 /***************************************************************************
122 *
123 * custom_cell_renderer_type_class_init:
124 *
125 * set up our own get_property and set_property functions, and
126 * override the parent's functions that we need to implement.
127 * And make our new "size" property known to the type system.
128 * If you want cells that can be activated on their own (ie. not
129 * just the whole row selected) or cells that are editable, you
130 * will need to override 'activate' and 'start_editing' as well.
131 *
132 ***************************************************************************/
133
134 static void
135 custom_cell_renderer_type_class_init (CustomCellRendererTypeClass *klass) {
136 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(klass);
137 GObjectClass *object_class = G_OBJECT_CLASS(klass);
138
139 parent_class = g_type_class_peek_parent (klass);
140 object_class->finalize = custom_cell_renderer_type_finalize;
141
142 /* Hook up functions to set and get our
143 * custom cell renderer properties */
144 object_class->get_property = custom_cell_renderer_type_get_property;
145 object_class->set_property = custom_cell_renderer_type_set_property;
146
147 /* Override the two crucial functions that are the heart
148 * of a cell renderer in the parent class */
149 cell_class->get_size = custom_cell_renderer_type_get_size;
150 cell_class->render = custom_cell_renderer_type_render;
151
152 /* Install our very own properties */
153 g_object_class_install_property (object_class, PROP_TYPE,
154 g_param_spec_int ("type", "Type", "Container type", -256,
155 (CACHE_TYPE_MAX<<8)+255, 0, G_PARAM_READWRITE));
156 }
157
158
159 /***************************************************************************
160 *
161 * custom_cell_renderer_type_finalize: free any resources here
162 *
163 ***************************************************************************/
164
165 static void custom_cell_renderer_type_finalize (GObject *object) {
166 (* G_OBJECT_CLASS (parent_class)->finalize) (object);
167 }
168
169
170 /***************************************************************************
171 *
172 * custom_cell_renderer_type_get_property: as it says
173 *
174 ***************************************************************************/
175
176 static void
177 custom_cell_renderer_type_get_property (GObject *object,
178 guint param_id,
179 GValue *value,
180 GParamSpec *psec) {
181 CustomCellRendererType *celltype = CUSTOM_CELL_RENDERER_TYPE(object);
182
183 switch (param_id) {
184 case PROP_TYPE:
185 g_value_set_int(value, celltype->type);
186 break;
187
188 default:
189 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, psec);
190 break;
191 }
192 }
193
194
195 /***************************************************************************
196 *
197 * custom_cell_renderer_type_set_property: as it says
198 *
199 ***************************************************************************/
200
201 static void
202 custom_cell_renderer_type_set_property (GObject *object,
203 guint param_id,
204 const GValue *value,
205 GParamSpec *pspec) {
206 CustomCellRendererType *celltype = CUSTOM_CELL_RENDERER_TYPE (object);
207
208 switch (param_id) {
209 case PROP_TYPE:
210 celltype->type = g_value_get_int(value);
211 break;
212
213 default:
214 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
215 break;
216 }
217 }
218
219 /***************************************************************************
220 *
221 * custom_cell_renderer_type_new: return a new cell renderer instance
222 *
223 ***************************************************************************/
224
225 GtkCellRenderer *custom_cell_renderer_type_new (void) {
226 return g_object_new(CUSTOM_TYPE_CELL_RENDERER_TYPE, NULL);
227 }
228
229 static void
230 custom_cell_renderer_type_get_size (GtkCellRenderer *cell,
231 GtkWidget *widget, GdkRectangle *cell_area, gint *x_offset,
232 gint *y_offset, gint *width, gint *height) {
233 CustomCellRendererType *celltype = CUSTOM_CELL_RENDERER_TYPE (cell);
234 GdkPixbuf *pixbuf = icon_get(CUSTOM_ICON_TYPE, celltype->type>>8);
235
236 if(!pixbuf) return;
237
238 gint calc_width = (gint) gdk_pixbuf_get_width(pixbuf);
239 gint calc_height = (gint) gdk_pixbuf_get_height(pixbuf);
240
241 if (x_offset) *x_offset = 0;
242 if (y_offset) *y_offset = 0;
243
244 if (cell_area) {
245 if (x_offset)
246 *x_offset = (cell_area->width - calc_width)/2;
247
248 if (y_offset)
249 *y_offset = (cell_area->height - calc_height)/2;
250 }
251
252 if (width) *width = calc_width;
253 if (height) *height = calc_height;
254 }
255
256
257 /***************************************************************************
258 *
259 * custom_cell_renderer_type_render: crucial - do the rendering.
260 *
261 ***************************************************************************/
262
263 static void
264 custom_cell_renderer_type_render (GtkCellRenderer *cell,
265 GdkWindow *window,
266 GtkWidget *widget,
267 GdkRectangle *background_area,
268 GdkRectangle *cell_area,
269 GdkRectangle *expose_area,
270 guint flags)
271 {
272 CustomCellRendererType *celltype = CUSTOM_CELL_RENDERER_TYPE (cell);
273 GdkPixbuf *pixbuf = icon_get(CUSTOM_ICON_TYPE, celltype->type>>8);
274 GdkRectangle all_rect;
275 GdkRectangle draw_rect;
276
277 if(!pixbuf) return;
278
279 gint pix_width = gdk_pixbuf_get_width(pixbuf);
280
281 custom_cell_renderer_type_get_size (cell, widget, cell_area,
282 &all_rect.x, &all_rect.y,
283 &all_rect.width, &all_rect.height);
284
285 all_rect.x += cell_area->x;
286 all_rect.y += cell_area->y;
287
288 if (!gdk_rectangle_intersect (cell_area, &all_rect, &draw_rect) ||
289 !gdk_rectangle_intersect (expose_area, &draw_rect, &draw_rect))
290 return;
291
292 /* draw the bitmap */
293 cairo_t *cr = gdk_cairo_create(window);
294
295 gdk_cairo_set_source_pixbuf(cr, pixbuf,
296 all_rect.x + (all_rect.width - pix_width)/2, all_rect.y);
297 gdk_cairo_rectangle(cr, &draw_rect);
298 cairo_fill(cr);
299
300 /* just a note, nothing else */
301 GdkPixbuf *addon = NULL;
302 if((celltype->type & 7) == 4) // only note is set
303 addon = icon_get(CUSTOM_ICON_TYPE, 13);
304 if((celltype->type & 7) == 5) // only note and override are set
305 addon = icon_get(CUSTOM_ICON_TYPE, 11);
306 if(celltype->type & 2) // solved is set
307 addon = icon_get(CUSTOM_ICON_TYPE, 12);
308
309 /* if override (and not found) is set */
310 if(addon) {
311 gdk_cairo_set_source_pixbuf(cr, addon,
312 all_rect.x + (all_rect.width - pix_width)/2, all_rect.y);
313 gdk_cairo_rectangle(cr, &draw_rect);
314 cairo_fill(cr);
315 }
316
317 cairo_destroy(cr);
318 }