~ubuntu-branches/ubuntu/utopic/rhythmbox/utopic-proposed

« back to all changes in this revision

Viewing changes to widgets/rb-rating.c

Tags: upstream-0.9.2
ImportĀ upstreamĀ versionĀ 0.9.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include <gtk/gtkiconfactory.h>
26
26
 
27
27
#include "rb-rating.h"
 
28
#include "rb-rating-helper.h"
28
29
#include "rb-stock-icons.h"
29
30
#include "rb-cut-and-paste-code.h"
30
31
 
31
32
/* Offset at the beggining of the widget */
32
 
#define X_OFFSET 4
 
33
#define X_OFFSET 0
33
34
 
34
35
/* Vertical offset */
35
36
#define Y_OFFSET 2
60
61
 
61
62
struct RBRatingPrivate
62
63
{
63
 
        double score;
64
 
 
65
 
        GdkPixbuf *pix_star;
66
 
        GdkPixbuf *pix_dot;
67
 
        GdkPixbuf *pix_blank;
 
64
        double rating;
 
65
        RBRatingPixbufs *pixbufs;
68
66
};
69
67
 
70
68
enum
71
69
{
72
70
        PROP_0,
73
 
        PROP_SCORE
 
71
        PROP_RATING
74
72
};
75
73
 
76
74
enum
125
123
        widget_class->expose_event = rb_rating_expose;
126
124
        widget_class->size_request = rb_rating_size_request;
127
125
 
128
 
        g_object_class_install_property (object_class,
129
 
                                         PROP_SCORE,
130
 
                                         g_param_spec_double ("score",
131
 
                                                              "Rating score",
132
 
                                                              "Rating score",
133
 
                                                              0.0, 5.0, 2.5,
134
 
                                                              G_PARAM_READWRITE));
 
126
        rb_rating_install_rating_property (object_class, PROP_RATING);
135
127
 
136
128
        rb_rating_signals[RATED] = 
137
129
                g_signal_new ("rated",
148
140
static void
149
141
rb_rating_init (RBRating *rating)
150
142
{
151
 
        GtkWidget *dummy;
152
 
        GdkPixbuf *pixbuf;
153
 
 
154
143
        rating->priv = g_new0 (RBRatingPrivate, 1);
155
144
 
156
145
        /* create the needed icons */
157
 
        dummy = gtk_label_new (NULL);
158
 
        pixbuf = gtk_widget_render_icon (dummy,
159
 
                                         RB_STOCK_SET_STAR,
160
 
                                         GTK_ICON_SIZE_MENU,
161
 
                                         NULL);
162
 
        rating->priv->pix_star = eel_create_colorized_pixbuf 
163
 
                                        (pixbuf,
164
 
                                         dummy->style->text[GTK_STATE_NORMAL].red + COLOR_OFFSET,
165
 
                                         dummy->style->text[GTK_STATE_NORMAL].green + COLOR_OFFSET,
166
 
                                         dummy->style->text[GTK_STATE_NORMAL].blue + COLOR_OFFSET);
167
 
        g_object_unref (G_OBJECT (pixbuf));
168
 
 
169
 
        pixbuf = gtk_widget_render_icon (dummy,
170
 
                                         RB_STOCK_NO_STAR,
171
 
                                         GTK_ICON_SIZE_MENU,
172
 
                                         NULL);
173
 
        rating->priv->pix_blank = eel_create_colorized_pixbuf 
174
 
                                        (pixbuf,
175
 
                                         dummy->style->text[GTK_STATE_NORMAL].red,
176
 
                                         dummy->style->text[GTK_STATE_NORMAL].green,
177
 
                                         dummy->style->text[GTK_STATE_NORMAL].blue);
178
 
        g_object_unref (G_OBJECT (pixbuf));
179
 
 
180
 
        pixbuf = gtk_widget_render_icon (dummy,
181
 
                                         RB_STOCK_UNSET_STAR,
182
 
                                         GTK_ICON_SIZE_MENU,
183
 
                                         NULL);
184
 
        rating->priv->pix_dot = eel_create_colorized_pixbuf (pixbuf,
185
 
                                                             dummy->style->text[GTK_STATE_NORMAL].red,
186
 
                                                             dummy->style->text[GTK_STATE_NORMAL].green,
187
 
                                                             dummy->style->text[GTK_STATE_NORMAL].blue);
188
 
        g_object_unref (G_OBJECT (pixbuf));
189
 
 
190
 
        gtk_widget_destroy (dummy);
 
146
        rating->priv->pixbufs = rb_rating_pixbufs_new ();
191
147
 
192
148
        /* register some signals */
193
149
        g_signal_connect_object (G_OBJECT (rating),
202
158
        RBRating *rating;
203
159
 
204
160
        rating = RB_RATING (object);
205
 
 
206
 
        g_object_unref (G_OBJECT (rating->priv->pix_star));
207
 
        g_object_unref (G_OBJECT (rating->priv->pix_dot));
208
 
        g_object_unref (G_OBJECT (rating->priv->pix_blank));
 
161
        rb_rating_pixbufs_free (rating->priv->pixbufs);
209
162
        g_free (rating->priv);
210
163
 
211
164
        G_OBJECT_CLASS (parent_class)->finalize (object);
220
173
        RBRating *rating = RB_RATING (object);
221
174
  
222
175
        switch (param_id) {
223
 
        case PROP_SCORE:
224
 
                g_value_set_double (value, rating->priv->score);
 
176
        case PROP_RATING:
 
177
                g_value_set_double (value, rating->priv->rating);
225
178
                break;
226
179
        default:
227
180
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
239
192
        RBRating *rating= RB_RATING (object);
240
193
  
241
194
        switch (param_id) {
242
 
        case PROP_SCORE:
243
 
                rating->priv->score = g_value_get_double (value);
 
195
        case PROP_RATING:
 
196
                rating->priv->rating = g_value_get_double (value);
244
197
                gtk_widget_queue_draw (GTK_WIDGET (rating));
245
198
                break;
246
199
        default:
254
207
{
255
208
        RBRating *rating;
256
209
  
257
 
        rating = g_object_new (RB_TYPE_RATING, NULL);
 
210
        rating = g_object_new (RB_TYPE_RATING, NULL, NULL);
258
211
 
259
212
        g_return_val_if_fail (rating->priv != NULL, NULL);
260
213
  
271
224
 
272
225
        gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_size, NULL);
273
226
 
274
 
        requisition->width = 5 * icon_size + X_OFFSET;
 
227
        requisition->width = RB_RATING_MAX_SCORE * icon_size + X_OFFSET;
275
228
        requisition->height = icon_size + Y_OFFSET * 2;
276
229
}
277
230
 
280
233
                  GdkEventExpose *event)
281
234
{
282
235
        int icon_size;
283
 
        gboolean rtl;
284
236
 
285
237
        g_return_val_if_fail (RB_IS_RATING (widget), FALSE);
286
238
 
287
 
        rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
288
 
 
289
239
        gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_size, NULL);
290
240
 
291
241
        if (GTK_WIDGET_DRAWABLE (widget) == TRUE) {
292
 
                int i;
293
242
                RBRating *rating = RB_RATING (widget);
294
243
 
295
244
                /* make the widget prettier */
305
254
                                  widget->allocation.width,
306
255
                                  widget->allocation.height);
307
256
 
308
 
                /* draw a blank area at the beggining, this lets the user click
309
 
                 * in this area to unset the rating */
310
 
                gdk_pixbuf_render_to_drawable_alpha (rating->priv->pix_blank,
311
 
                                                     widget->window,
312
 
                                                     0, 0,
313
 
                                                     0, Y_OFFSET,
314
 
                                                     X_OFFSET, icon_size,
315
 
                                                     GDK_PIXBUF_ALPHA_FULL, 0,
316
 
                                                     GDK_RGB_DITHER_NORMAL, 0, 0);
317
 
 
318
257
 
319
258
                /* draw the stars */
320
 
                for (i = 0; i < MAX_SCORE; i++) {
321
 
                        GdkPixbuf *pixbuf;
322
 
                        gint icon_x_offset;
323
 
 
324
 
                        if (i < rating->priv->score)
325
 
                                pixbuf = rating->priv->pix_star;
326
 
                        else
327
 
                                pixbuf = rating->priv->pix_dot;
328
 
 
329
 
                        if (pixbuf == NULL)
330
 
                                return FALSE;
331
 
 
332
 
                        if (rtl) {
333
 
                                icon_x_offset = X_OFFSET + (MAX_SCORE-i-1) * icon_size;
334
 
                        } else {
335
 
                                icon_x_offset = X_OFFSET + i * icon_size;
336
 
                        }
337
 
                        gdk_pixbuf_render_to_drawable_alpha (pixbuf,
338
 
                                                             widget->window,
339
 
                                                             0, 0,
340
 
                                                             icon_x_offset, Y_OFFSET,
341
 
                                                             icon_size, icon_size,
342
 
                                                             GDK_PIXBUF_ALPHA_FULL, 0,
343
 
                                                             GDK_RGB_DITHER_NORMAL, 0, 0);
344
 
                }
345
 
 
346
 
 
347
 
                return TRUE;
 
259
                return rb_rating_render_stars (widget, widget->window, 
 
260
                                               rating->priv->pixbufs, 0, 0, 
 
261
                                               X_OFFSET, Y_OFFSET,
 
262
                                               rating->priv->rating, FALSE);
348
263
        }
349
264
 
350
265
        return FALSE;
355
270
                           GdkEventButton *event,
356
271
                           RBRating *rating)
357
272
{
358
 
        int mouse_x, mouse_y, icon_size;
359
 
        double score = 0;
 
273
        int mouse_x, mouse_y;
 
274
        double new_rating;
360
275
 
361
276
        g_return_val_if_fail (widget != NULL, FALSE);
362
277
        g_return_val_if_fail (RB_IS_RATING (rating), FALSE);
363
278
 
364
 
        gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_size, NULL);
365
279
        gtk_widget_get_pointer (widget, &mouse_x, &mouse_y);
366
280
 
367
 
        /* ensure the user clicks within the good area */
368
 
        if (mouse_x >= 0 && mouse_x <= widget->allocation.width) {
369
 
                gboolean rtl;
370
 
                
371
 
                if (mouse_x <= X_OFFSET)
372
 
                        score = 0;
373
 
                else
374
 
                        score = ((mouse_x - X_OFFSET) / icon_size) + 1;
375
 
 
376
 
                rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
377
 
                if (rtl) {
378
 
                        score = MAX_SCORE - score + 1;
379
 
                }
380
 
 
381
 
                if (score > 5) score = 5;
382
 
                if (score < 0) score = 0;
383
 
 
 
281
        new_rating = rb_rating_get_rating_from_widget (widget, mouse_x, 
 
282
                                                       widget->allocation.width, 
 
283
                                                       rating->priv->rating);
 
284
 
 
285
        if (new_rating == -1.0) {
 
286
                return FALSE;
 
287
        } else {
384
288
                g_signal_emit (G_OBJECT (rating), 
385
289
                               rb_rating_signals[RATED], 
386
 
                               0, score);
387
 
 
 
290
                               0, new_rating);
388
291
                return TRUE;
389
292
        }
390
 
 
391
 
        return FALSE;
392
293
}