Contents of /trunk/src/custom_type_renderer.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 120 - (hide 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 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     /* 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 harbaum 120 all_rect.x + (all_rect.width - pix_width)/2, all_rect.y);
307 harbaum 1 gdk_cairo_rectangle(cr, &draw_rect);
308     cairo_fill(cr);
309     }
310    
311     cairo_destroy(cr);
312     }