udapted vi.po
[rhythmbox.git] / widgets / rb-cell-renderer-pixbuf.c
blob39cec295fa32f7fddd6d36de9c91f1367f1e3d48
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* rbcellrendererpixbuf.c
4 * arch-tag: Implementation of Rhythmbox pixbuf GtkTreeView cell renderer
6 * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
7 * Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301 USA.
25 #include <config.h>
26 #include <libgnome/gnome-i18n.h>
27 #include <stdlib.h>
28 #include <gtk/gtktreeview.h>
29 #include <gtk/gtkiconfactory.h>
31 #include "rb-cell-renderer-pixbuf.h"
32 #include "rb-cut-and-paste-code.h"
34 static void rb_cell_renderer_pixbuf_get_property (GObject *object,
35 guint param_id,
36 GValue *value,
37 GParamSpec *pspec);
38 static void rb_cell_renderer_pixbuf_set_property (GObject *object,
39 guint param_id,
40 const GValue *value,
41 GParamSpec *pspec);
42 static void rb_cell_renderer_pixbuf_init (RBCellRendererPixbuf *celltext);
43 static void rb_cell_renderer_pixbuf_class_init (RBCellRendererPixbufClass *class);
44 static void rb_cell_renderer_pixbuf_get_size (GtkCellRenderer *cell,
45 GtkWidget *widget,
46 GdkRectangle *rectangle,
47 gint *x_offset,
48 gint *y_offset,
49 gint *width,
50 gint *height);
51 static void rb_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
52 GdkWindow *window,
53 GtkWidget *widget,
54 GdkRectangle *background_area,
55 GdkRectangle *cell_area,
56 GdkRectangle *expose_area,
57 guint flags);
58 static gboolean rb_cell_renderer_pixbuf_activate (GtkCellRenderer *cell,
59 GdkEvent *event,
60 GtkWidget *widget,
61 const gchar *path,
62 GdkRectangle *background_area,
63 GdkRectangle *cell_area,
64 GtkCellRendererState flags);
66 enum {
67 PROP_ZERO,
68 PROP_PIXBUF
71 enum
73 PIXBUF_CLICKED,
74 LAST_SIGNAL
77 G_DEFINE_TYPE (RBCellRendererPixbuf, rb_cell_renderer_pixbuf, GTK_TYPE_CELL_RENDERER)
79 static guint rb_cell_renderer_pixbuf_signals [LAST_SIGNAL] = { 0 };
81 static void
82 rb_cell_renderer_pixbuf_init (RBCellRendererPixbuf *cellpixbuf)
85 /* set the renderer able to be activated */
86 GTK_CELL_RENDERER (cellpixbuf)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
89 static void
90 rb_cell_renderer_pixbuf_class_init (RBCellRendererPixbufClass *class)
92 GObjectClass *object_class = G_OBJECT_CLASS (class);
93 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
95 object_class->get_property = rb_cell_renderer_pixbuf_get_property;
96 object_class->set_property = rb_cell_renderer_pixbuf_set_property;
98 cell_class->get_size = rb_cell_renderer_pixbuf_get_size;
99 cell_class->render = rb_cell_renderer_pixbuf_render;
100 cell_class->activate = rb_cell_renderer_pixbuf_activate;
102 g_object_class_install_property (object_class,
103 PROP_PIXBUF,
104 g_param_spec_object ("pixbuf",
105 _("Pixbuf Object"),
106 _("The pixbuf to render."),
107 GDK_TYPE_PIXBUF,
108 G_PARAM_READABLE |
109 G_PARAM_WRITABLE));
111 rb_cell_renderer_pixbuf_signals[PIXBUF_CLICKED] =
112 g_signal_new ("pixbuf-clicked",
113 G_OBJECT_CLASS_TYPE (object_class),
114 G_SIGNAL_RUN_FIRST,
115 G_STRUCT_OFFSET (RBCellRendererPixbufClass, pixbuf_clicked),
116 NULL, NULL,
117 g_cclosure_marshal_VOID__STRING,
118 G_TYPE_NONE,
120 G_TYPE_STRING);
123 static void
124 rb_cell_renderer_pixbuf_get_property (GObject *object,
125 guint param_id,
126 GValue *value,
127 GParamSpec *pspec)
129 RBCellRendererPixbuf *cellpixbuf = RB_CELL_RENDERER_PIXBUF (object);
131 switch (param_id)
133 case PROP_PIXBUF:
134 g_value_set_object (value,
135 cellpixbuf->pixbuf ? G_OBJECT (cellpixbuf->pixbuf) : NULL);
136 break;
137 default:
138 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
139 break;
143 static void
144 rb_cell_renderer_pixbuf_set_property (GObject *object,
145 guint param_id,
146 const GValue *value,
147 GParamSpec *pspec)
149 GdkPixbuf *pixbuf;
150 RBCellRendererPixbuf *cellpixbuf = RB_CELL_RENDERER_PIXBUF (object);
152 switch (param_id)
154 case PROP_PIXBUF:
155 pixbuf = (GdkPixbuf*) g_value_get_object (value);
156 if (pixbuf)
157 g_object_ref (G_OBJECT (pixbuf));
158 if (cellpixbuf->pixbuf)
159 g_object_unref (G_OBJECT (cellpixbuf->pixbuf));
160 cellpixbuf->pixbuf = pixbuf;
161 break;
162 default:
163 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
164 break;
169 * rb_cell_renderer_pixbuf_new:
171 * Creates a new #RBCellRendererPixbuf. Adjust rendering
172 * parameters using object properties. Object properties can be set
173 * globally (with g_object_set()). Also, with #RBTreeViewColumn, you
174 * can bind a property to a value in a #RBTreeModel. For example, you
175 * can bind the "pixbuf" property on the cell renderer to a pixbuf value
176 * in the model, thus rendering a different image in each row of the
177 * #RBTreeView.
179 * Return value: the new cell renderer
181 GtkCellRenderer *
182 rb_cell_renderer_pixbuf_new (void)
184 return GTK_CELL_RENDERER (gtk_type_new (rb_cell_renderer_pixbuf_get_type ()));
187 static void
188 rb_cell_renderer_pixbuf_get_size (GtkCellRenderer *cell,
189 GtkWidget *widget,
190 GdkRectangle *cell_area,
191 gint *x_offset,
192 gint *y_offset,
193 gint *width,
194 gint *height)
196 RBCellRendererPixbuf *cellpixbuf = (RBCellRendererPixbuf *) cell;
197 gint pixbuf_width = 0;
198 gint pixbuf_height = 0;
199 gint calc_width;
200 gint calc_height;
202 if (cellpixbuf->pixbuf)
204 pixbuf_width = gdk_pixbuf_get_width (cellpixbuf->pixbuf);
205 pixbuf_height = gdk_pixbuf_get_height (cellpixbuf->pixbuf);
208 calc_width = (gint) GTK_CELL_RENDERER (cellpixbuf)->xpad * 2 + pixbuf_width;
209 calc_height = (gint) GTK_CELL_RENDERER (cellpixbuf)->ypad * 2 + pixbuf_height;
211 if (x_offset) *x_offset = 0;
212 if (y_offset) *y_offset = 0;
214 if (cell_area && pixbuf_width > 0 && pixbuf_height > 0)
216 if (x_offset)
218 *x_offset = GTK_CELL_RENDERER (cellpixbuf)->xalign * (cell_area->width - calc_width - (2 * GTK_CELL_RENDERER (cellpixbuf)->xpad));
219 *x_offset = MAX (*x_offset, 0) + GTK_CELL_RENDERER (cellpixbuf)->xpad;
221 if (y_offset)
223 *y_offset = GTK_CELL_RENDERER (cellpixbuf)->yalign * (cell_area->height - calc_height - (2 * GTK_CELL_RENDERER (cellpixbuf)->ypad));
224 *y_offset = MAX (*y_offset, 0) + GTK_CELL_RENDERER (cellpixbuf)->ypad;
228 if (calc_width)
229 *width = calc_width;
231 if (height)
232 *height = calc_height;
235 static void
236 rb_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
237 GdkWindow *window,
238 GtkWidget *widget,
239 GdkRectangle *background_area,
240 GdkRectangle *cell_area,
241 GdkRectangle *expose_area,
242 guint flags)
245 RBCellRendererPixbuf *cellpixbuf = (RBCellRendererPixbuf *) cell;
246 GdkRectangle pix_rect;
247 GdkRectangle draw_rect;
248 GtkStateType state;
250 if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
252 if (GTK_WIDGET_HAS_FOCUS (widget))
253 state = GTK_STATE_SELECTED;
254 else
255 state = GTK_STATE_ACTIVE;
257 else
259 if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE)
260 state = GTK_STATE_INSENSITIVE;
261 else
262 state = GTK_STATE_NORMAL;
265 if (!cellpixbuf->pixbuf)
266 return;
268 rb_cell_renderer_pixbuf_get_size (cell, widget, cell_area,
269 &pix_rect.x,
270 &pix_rect.y,
271 &pix_rect.width,
272 &pix_rect.height);
274 pix_rect.x += cell_area->x;
275 pix_rect.y += cell_area->y;
276 pix_rect.width -= cell->xpad * 2;
277 pix_rect.height -= cell->ypad * 2;
279 if (gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect))
280 gdk_pixbuf_render_to_drawable_alpha (cellpixbuf->pixbuf,
281 window,
282 /* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */
283 draw_rect.x - pix_rect.x,
284 draw_rect.y - pix_rect.y,
285 draw_rect.x,
286 draw_rect.y,
287 draw_rect.width,
288 draw_rect.height,
289 GDK_PIXBUF_ALPHA_FULL,
291 GDK_RGB_DITHER_NORMAL,
292 0, 0);
295 static gboolean
296 rb_cell_renderer_pixbuf_activate (GtkCellRenderer *cell,
297 GdkEvent *event,
298 GtkWidget *widget,
299 const gchar *path,
300 GdkRectangle *background_area,
301 GdkRectangle *cell_area,
302 GtkCellRendererState flags)
304 int mouse_x, mouse_y, icon_width;
305 RBCellRendererPixbuf *cellpixbuf = (RBCellRendererPixbuf *) cell;
307 g_return_val_if_fail (RB_IS_CELL_RENDERER_PIXBUF (cellpixbuf), FALSE);
309 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, NULL);
310 gtk_widget_get_pointer (widget, &mouse_x, &mouse_y);
311 gtk_tree_view_widget_to_tree_coords (GTK_TREE_VIEW (widget),
312 mouse_x,
313 mouse_y,
314 &mouse_x,
315 &mouse_y);
317 /* ensure the user clicks within the good cell */
318 if (mouse_x - cell_area->x >= 0
319 && mouse_x - cell_area->x <= cell_area->width) {
320 g_signal_emit (G_OBJECT (cellpixbuf), rb_cell_renderer_pixbuf_signals [PIXBUF_CLICKED], 0, path);
322 return TRUE;