Contents of /trunk/src/custom_type_renderer.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 205 - (hide annotations)
Mon Nov 23 20:12:22 2009 UTC (14 years, 5 months ago) by harbaum
File MIME type: text/plain
File size: 12373 byte(s)
Map/cache icon handling
1 harbaum 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 harbaum 189 #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 harbaum 1 /* 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 harbaum 189 GdkPixbuf *pixbuf = icon_get(CUSTOM_ICON_TYPE, celltype->type>>8);
235 harbaum 1
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 harbaum 189 GdkPixbuf *pixbuf = icon_get(CUSTOM_ICON_TYPE, celltype->type>>8);
274 harbaum 1 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 harbaum 205 /* add "special" addon. the order of these test results in */
301     /* a priority */
302 harbaum 1 GdkPixbuf *addon = NULL;
303 harbaum 205 if(celltype->type & 8) // mine is set
304     addon = icon_get(CUSTOM_ICON_TYPE, 14);
305     else if(celltype->type & 2) // solved is set
306     addon = icon_get(CUSTOM_ICON_TYPE, 12);
307     else if(celltype->type & 1) // override is set
308     addon = icon_get(CUSTOM_ICON_TYPE, 11);
309     else if(celltype->type & 4) // note is set
310 harbaum 189 addon = icon_get(CUSTOM_ICON_TYPE, 13);
311 harbaum 1
312     /* if override (and not found) is set */
313     if(addon) {
314     gdk_cairo_set_source_pixbuf(cr, addon,
315 harbaum 120 all_rect.x + (all_rect.width - pix_width)/2, all_rect.y);
316 harbaum 1 gdk_cairo_rectangle(cr, &draw_rect);
317     cairo_fill(cr);
318     }
319    
320     cairo_destroy(cr);
321     }