Updated Vietnamese translation
[rhythmbox.git] / widgets / rb-cell-renderer-rating.c
blob030ff45d499333f35f106eea738af0b6c6d28b5c
1 /* rb-cell-renderer-rating.c
3 * arch-tag: Implementation of star rating GtkTreeView cell renderer
5 * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
6 * Copyright (C) 2002 Olivier Martin <oleevye@wanadoo.fr>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
22 * $ Id $
25 #include <config.h>
26 #include <stdlib.h>
27 #include <libgnome/gnome-i18n.h>
28 #include <gtk/gtklabel.h>
29 #include <gtk/gtkwidget.h>
30 #include <gtk/gtktreeview.h>
31 #include <gtk/gtkiconfactory.h>
33 #include "rb-cell-renderer-rating.h"
34 #include "rb-marshal.h"
35 #include "rb-rating-helper.h"
37 static void rb_cell_renderer_rating_get_property (GObject *object,
38 guint param_id,
39 GValue *value,
40 GParamSpec *pspec);
41 static void rb_cell_renderer_rating_set_property (GObject *object,
42 guint param_id,
43 const GValue *value,
44 GParamSpec *pspec);
45 static void rb_cell_renderer_rating_init (RBCellRendererRating *celltext);
46 static void rb_cell_renderer_rating_class_init (RBCellRendererRatingClass *class);
47 static void rb_cell_renderer_rating_get_size (GtkCellRenderer *cell,
48 GtkWidget *widget,
49 GdkRectangle *rectangle,
50 gint *x_offset,
51 gint *y_offset,
52 gint *width,
53 gint *height);
54 static void rb_cell_renderer_rating_render (GtkCellRenderer *cell,
55 GdkWindow *window,
56 GtkWidget *widget,
57 GdkRectangle *background_area,
58 GdkRectangle *cell_area,
59 GdkRectangle *expose_area,
60 GtkCellRendererState flags);
61 static gboolean rb_cell_renderer_rating_activate (GtkCellRenderer *cell,
62 GdkEvent *event,
63 GtkWidget *widget,
64 const gchar *path,
65 GdkRectangle *background_area,
66 GdkRectangle *cell_area,
67 GtkCellRendererState flags);
68 static void rb_cell_renderer_rating_finalize (GObject *object);
70 struct RBCellRendererRatingPrivate
72 double rating;
75 struct RBCellRendererRatingClassPrivate
77 RBRatingPixbufs *pixbufs;
81 enum
83 PROP_0,
84 PROP_RATING
87 enum
89 RATED,
90 LAST_SIGNAL
93 static GObjectClass *parent_class = NULL;
95 static guint rb_cell_renderer_rating_signals[LAST_SIGNAL] = { 0 };
97 GtkType
98 rb_cell_renderer_rating_get_type (void)
100 static GtkType cell_rating_type = 0;
102 if (!cell_rating_type) {
103 static const GTypeInfo cell_rating_info =
105 sizeof (RBCellRendererRatingClass),
106 NULL, /* base_init */
107 NULL, /* base_finalize */
108 (GClassInitFunc) rb_cell_renderer_rating_class_init,
109 NULL, /* class_finalize */
110 NULL, /* class_data */
111 sizeof (RBCellRendererRating),
112 0, /* n_preallocs */
113 (GInstanceInitFunc) rb_cell_renderer_rating_init,
116 cell_rating_type = g_type_register_static (GTK_TYPE_CELL_RENDERER,
117 "RBCellRendererRating",
118 &cell_rating_info,
122 return cell_rating_type;
125 static void
126 rb_cell_renderer_rating_init (RBCellRendererRating *cellrating)
129 cellrating->priv = g_new0 (RBCellRendererRatingPrivate, 1);
131 /* set the renderer able to be activated */
132 GTK_CELL_RENDERER (cellrating)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
134 /* create the needed icons */
137 static void
138 rb_cell_renderer_rating_class_init (RBCellRendererRatingClass *class)
140 GObjectClass *object_class = G_OBJECT_CLASS (class);
141 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
143 parent_class = g_type_class_peek_parent (class);
144 object_class->finalize = rb_cell_renderer_rating_finalize;
146 object_class->get_property = rb_cell_renderer_rating_get_property;
147 object_class->set_property = rb_cell_renderer_rating_set_property;
149 cell_class->get_size = rb_cell_renderer_rating_get_size;
150 cell_class->render = rb_cell_renderer_rating_render;
151 cell_class->activate = rb_cell_renderer_rating_activate;
153 class->priv = g_new0 (RBCellRendererRatingClassPrivate, 1);
154 class->priv->pixbufs = rb_rating_pixbufs_new ();
156 rb_rating_install_rating_property (object_class, PROP_RATING);
158 rb_cell_renderer_rating_signals[RATED] =
159 g_signal_new ("rated",
160 G_OBJECT_CLASS_TYPE (object_class),
161 G_SIGNAL_RUN_LAST,
162 G_STRUCT_OFFSET (RBCellRendererRatingClass, rated),
163 NULL, NULL,
164 rb_marshal_VOID__STRING_DOUBLE,
165 G_TYPE_NONE,
167 G_TYPE_STRING,
168 G_TYPE_DOUBLE);
171 static void
172 rb_cell_renderer_rating_finalize (GObject *object)
174 RBCellRendererRating *cellrating;
176 cellrating = RB_CELL_RENDERER_RATING (object);
178 g_free (cellrating->priv);
180 G_OBJECT_CLASS (parent_class)->finalize (object);
183 static void
184 rb_cell_renderer_rating_get_property (GObject *object,
185 guint param_id,
186 GValue *value,
187 GParamSpec *pspec)
189 RBCellRendererRating *cellrating = RB_CELL_RENDERER_RATING (object);
191 switch (param_id) {
192 case PROP_RATING:
193 g_value_set_double (value, cellrating->priv->rating);
194 break;
195 default:
196 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
197 break;
202 static void
203 rb_cell_renderer_rating_set_property (GObject *object,
204 guint param_id,
205 const GValue *value,
206 GParamSpec *pspec)
208 RBCellRendererRating *cellrating= RB_CELL_RENDERER_RATING (object);
210 switch (param_id) {
211 case PROP_RATING:
212 cellrating->priv->rating = g_value_get_double (value);
213 if (cellrating->priv->rating < 0)
214 cellrating->priv->rating = 0;
215 break;
216 default:
217 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
218 break;
223 * rb_cell_renderer_rating_new: create a cell renderer that will
224 * display some pixbufs for representing the rating of a song.
225 * It is also able to update the rating.
227 * Return value: the new cell renderer
230 GtkCellRenderer *
231 rb_cell_renderer_rating_new ()
233 return GTK_CELL_RENDERER (gtk_type_new (rb_cell_renderer_rating_get_type ()));
236 static void
237 rb_cell_renderer_rating_get_size (GtkCellRenderer *cell,
238 GtkWidget *widget,
239 GdkRectangle *cell_area,
240 gint *x_offset,
241 gint *y_offset,
242 gint *width,
243 gint *height)
245 int icon_width;
246 RBCellRendererRating *cellrating = (RBCellRendererRating *) cell;
248 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, NULL);
250 if (x_offset)
251 *x_offset = 0;
253 if (y_offset)
254 *y_offset = 0;
256 if (width)
257 *width = (gint) GTK_CELL_RENDERER (cellrating)->xpad * 2 + icon_width * RB_RATING_MAX_SCORE;
259 if (height)
260 *height = (gint) GTK_CELL_RENDERER (cellrating)->ypad * 2 + icon_width;
263 static void
264 rb_cell_renderer_rating_render (GtkCellRenderer *cell,
265 GdkWindow *window,
266 GtkWidget *widget,
267 GdkRectangle *background_area,
268 GdkRectangle *cell_area,
269 GdkRectangle *expose_area,
270 GtkCellRendererState flags)
273 gboolean selected;
274 GdkRectangle pix_rect, draw_rect;
275 RBCellRendererRating *cellrating = (RBCellRendererRating *) cell;
276 RBCellRendererRatingClass *cell_class;
278 cellrating = RB_CELL_RENDERER_RATING (cell);
279 cell_class = RB_CELL_RENDERER_RATING_GET_CLASS (cellrating);
280 rb_cell_renderer_rating_get_size (cell, widget, cell_area,
281 &pix_rect.x,
282 &pix_rect.y,
283 &pix_rect.width,
284 &pix_rect.height);
286 pix_rect.x += cell_area->x;
287 pix_rect.y += cell_area->y;
288 pix_rect.width -= cell->xpad * 2;
289 pix_rect.height -= cell->ypad * 2;
292 if (gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect) == FALSE)
293 return;
297 selected = (flags & GTK_CELL_RENDERER_SELECTED);
299 rb_rating_render_stars (widget, window, cell_class->priv->pixbufs,
300 draw_rect.x - pix_rect.x,
301 draw_rect.y - pix_rect.y,
302 draw_rect.x, draw_rect.y,
303 cellrating->priv->rating, selected);
306 static gboolean
307 rb_cell_renderer_rating_activate (GtkCellRenderer *cell,
308 GdkEvent *event,
309 GtkWidget *widget,
310 const gchar *path,
311 GdkRectangle *background_area,
312 GdkRectangle *cell_area,
313 GtkCellRendererState flags)
315 int mouse_x, mouse_y;
316 double rating;
318 RBCellRendererRating *cellrating = (RBCellRendererRating *) cell;
320 g_return_val_if_fail (RB_IS_CELL_RENDERER_RATING (cellrating), FALSE);
322 gtk_widget_get_pointer (widget, &mouse_x, &mouse_y);
323 gtk_tree_view_widget_to_tree_coords (GTK_TREE_VIEW (widget),
324 mouse_x,
325 mouse_y,
326 &mouse_x,
327 &mouse_y);
329 rating = rb_rating_get_rating_from_widget (widget,
330 mouse_x - cell_area->x,
331 cell_area->width,
332 cellrating->priv->rating);
334 if (rating != -1.0) {
335 g_signal_emit (G_OBJECT (cellrating),
336 rb_cell_renderer_rating_signals[RATED],
337 0, path, rating);
340 return TRUE;