Contents of /trunk/src/custom_type_renderer.c

Parent Directory Parent Directory | Revision Log Revision Log


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