1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3 * arch-tag: Implementation of functions shared by the rating widget and cell renderer.
5 * Copyright (C) 2004 Christophe Fergeau <teuf@gnome.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "rb-cut-and-paste-code.h"
24 #include "rb-rating-helper.h"
25 #include "rb-stock-icons.h"
27 struct _RBRatingPixbufs
{
34 rb_rating_pixbufs_free (RBRatingPixbufs
*pixbufs
)
36 if (pixbufs
->pix_star
)
37 g_object_unref (G_OBJECT (pixbufs
->pix_star
));
39 g_object_unref (G_OBJECT (pixbufs
->pix_dot
));
40 if (pixbufs
->pix_blank
)
41 g_object_unref (G_OBJECT (pixbufs
->pix_blank
));
45 rb_rating_install_rating_property (GObjectClass
*klass
, gulong prop
)
47 g_object_class_install_property (klass
, prop
,
48 g_param_spec_double ("rating",
51 0.0, (double)RB_RATING_MAX_SCORE
,
52 (double)RB_RATING_MAX_SCORE
/2.0,
58 rb_rating_pixbufs_new (void)
61 RBRatingPixbufs
*pixbufs
;
63 pixbufs
= g_new0 (RBRatingPixbufs
, 1);
64 if (pixbufs
== NULL
) {
68 dummy
= gtk_label_new (NULL
);
69 pixbufs
->pix_star
= gtk_widget_render_icon (dummy
,
73 if (pixbufs
->pix_star
== NULL
) {
77 pixbufs
->pix_dot
= gtk_widget_render_icon (dummy
,
81 if (pixbufs
->pix_dot
== NULL
) {
85 pixbufs
->pix_blank
= gtk_widget_render_icon (dummy
,
89 if (pixbufs
->pix_blank
== NULL
) {
93 gtk_widget_destroy (dummy
);
97 if (pixbufs
->pix_star
!= NULL
) {
98 g_object_unref (G_OBJECT (pixbufs
->pix_star
));
100 if (pixbufs
->pix_dot
!= NULL
) {
101 g_object_unref (G_OBJECT (pixbufs
->pix_dot
));
103 if (pixbufs
->pix_blank
!= NULL
) {
104 g_object_unref (G_OBJECT (pixbufs
->pix_blank
));
106 gtk_widget_destroy (dummy
);
112 rb_rating_render_stars (GtkWidget
*widget
,
114 RBRatingPixbufs
*pixbufs
,
125 g_return_val_if_fail (widget
!= NULL
, FALSE
);
126 g_return_val_if_fail (window
!= NULL
, FALSE
);
127 g_return_val_if_fail (pixbufs
!= NULL
, FALSE
);
129 rtl
= (gtk_widget_get_direction (widget
) == GTK_TEXT_DIR_RTL
);
130 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU
, &icon_width
, NULL
);
132 for (i
= 0; i
< RB_RATING_MAX_SCORE
; i
++) {
138 if (selected
== TRUE
) {
140 if (GTK_WIDGET_HAS_FOCUS (widget
))
141 state
= GTK_STATE_SELECTED
;
143 state
= GTK_STATE_ACTIVE
;
146 if (GTK_WIDGET_STATE (widget
) == GTK_STATE_INSENSITIVE
)
147 state
= GTK_STATE_INSENSITIVE
;
149 state
= GTK_STATE_NORMAL
;
153 buf
= pixbufs
->pix_star
;
154 else if (i
>= rating
&& i
< RB_RATING_MAX_SCORE
)
155 buf
= pixbufs
->pix_dot
;
157 buf
= pixbufs
->pix_blank
;
163 buf
= eel_create_colorized_pixbuf (buf
,
164 (widget
->style
->text
[state
].red
+ offset
) >> 8,
165 (widget
->style
->text
[state
].green
+ offset
) >> 8,
166 (widget
->style
->text
[state
].blue
+ offset
) >> 8);
172 star_offset
= (RB_RATING_MAX_SCORE
- i
- 1) * icon_width
;
174 star_offset
= i
* icon_width
;
177 gdk_pixbuf_render_to_drawable_alpha (buf
,
180 x_offset
+ star_offset
,
184 GDK_PIXBUF_ALPHA_FULL
,
186 GDK_RGB_DITHER_NORMAL
,
188 g_object_unref (G_OBJECT (buf
));
195 rb_rating_get_rating_from_widget (GtkWidget
*widget
,
198 double current_rating
)
201 double rating
= -1.0;
203 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU
, &icon_width
, NULL
);
205 /* ensure the user clicks within the good cell */
206 if (widget_x
>= 0 && widget_x
<= widget_width
) {
209 rating
= (int) (widget_x
/ icon_width
) + 1;
211 rtl
= (gtk_widget_get_direction (widget
) == GTK_TEXT_DIR_RTL
);
213 rating
= RB_RATING_MAX_SCORE
- rating
+ 1;
219 if (rating
> RB_RATING_MAX_SCORE
)
220 rating
= RB_RATING_MAX_SCORE
;
222 if (rating
== current_rating
) {
223 /* Make it possible to give a 0 rating to a song */