Czech translation update (via transifex.net)
[cinaest] / src / rating-widget.vala
1 /* This file is part of Cinaest.
2  *
3  * Copyright (C) 2010 Philipp Zabel
4  *
5  * Cinaest is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Cinaest is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with Cinaest. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 using Gtk;
20
21 public class RatingWidget : DrawingArea {
22         private int _rating;
23         private bool button_pressed;
24         private Gdk.Color active_color;
25         private Gdk.Color disabled_color;
26
27         public int rating {
28                 get {
29                         return _rating;
30                 }
31                 set {
32                         if (_rating == value)
33                                 return;
34
35                         _rating = value;
36
37                         unowned Gdk.Region region = this.window.get_clip_region ();
38                         // redraw the cairo canvas completely by exposing it
39                         this.window.invalidate_region (region, true);
40                         this.window.process_updates (true);
41                 }
42         }
43
44         public RatingWidget () {
45                 var style = Gtk.rc_get_style_by_paths (this.get_settings (), "GtkButton", null, typeof (Gtk.Button));
46                 if (!style.lookup_color ("ActiveTextColor", out active_color))
47                         Gdk.Color.parse ("white", out active_color);
48                 if (!style.lookup_color ("DisabledTextColor", out disabled_color))
49                         Gdk.Color.parse ("black", out disabled_color);
50
51                 add_events (Gdk.EventMask.BUTTON_PRESS_MASK
52                             | Gdk.EventMask.BUTTON_RELEASE_MASK
53                             | Gdk.EventMask.POINTER_MOTION_MASK);
54
55                 set_size_request (640, 70);
56         }
57
58         public override bool expose_event (Gdk.EventExpose event) {
59                 var cr = Gdk.cairo_create (this.window);
60                 var radius = double.min (this.allocation.width / 20,
61                                          this.allocation.height / 2);
62                 cr.rectangle (event.area.x, event.area.y, event.area.width, event.area.height);
63                 cr.clip ();
64
65                 cr.save ();
66                 cr.rectangle (radius * rating / 5.0, 0, this.allocation.width - radius * rating / 5.0, this.allocation.height);
67                 cr.clip ();
68                 for (int i = rating/10; i < 10; i++)
69                         draw_star (cr, i, radius, disabled_color);
70                 cr.restore ();
71
72                 cr.new_path ();
73                 cr.rectangle (0, 0, radius * rating / 5.0, this.allocation.height);
74                 cr.clip ();
75                 for (int i = 0; i < (rating+5)/10; i++)
76                         draw_star (cr, i, radius, active_color);
77
78                 return false;
79         }
80
81         private void draw_star (Cairo.Context cr, int n, double radius, Gdk.Color color) {
82                 var x = radius * (2 * n + 1);
83                 var y = this.allocation.height / 2;
84
85                 cr.set_source_rgb (color.red / 65535.0, color.green / 65535.0, color.blue / 65535.0);
86                 cr.new_path ();
87                 for (int i = 0; i <= 10; i++) {
88                         double r = radius * (5 + 8 * (i % 2)) / 13.0;
89                         double a = x + r * Math.cos (i * 2*Math.PI/10.0 + Math.PI/2.0);
90                         double b = y + r * Math.sin (i * 2*Math.PI/10.0 + Math.PI/2.0);
91                         if (i == 0)
92                                 cr.move_to (a, b);
93                         else
94                                 cr.line_to (a, b);
95                 }
96                 cr.close_path ();
97                 cr.fill_preserve ();
98         }
99
100         public override bool button_press_event (Gdk.EventButton event) {
101                 button_pressed = true;
102                 rate (event.x);
103
104                 return false;
105         }
106
107         public override bool button_release_event (Gdk.EventButton event) {
108                 button_pressed = false;
109
110                 return false;
111         }
112
113         public override bool motion_notify_event (Gdk.EventMotion event) {
114                 if (button_pressed)
115                         rate (event.x);
116
117                 return false;
118         }
119
120         private void rate (double x) {
121                 int r;
122
123                 x = 10 * x / this.allocation.width;
124                 if (x <= 0) {
125                         r = 0;
126                 } else {
127                         int star = (int) x;
128                         r = 10 * (star + 1);
129                         x -= star;
130                         if (x <= 0.333)
131                                 r -= 5;
132                         if (r > 100)
133                                 r = 100;
134                 }
135                 rating = r;
136         }
137 }