Add rating widget
authorPhilipp Zabel <philipp.zabel@gmail.com>
Tue, 9 Feb 2010 20:40:28 +0000 (21:40 +0100)
committerPhilipp Zabel <philipp.zabel@gmail.com>
Wed, 14 Jul 2010 21:34:08 +0000 (23:34 +0200)
Makefile.am
src/rating-widget.vala [new file with mode: 0644]

index 09a2537..aa1f965 100644 (file)
@@ -54,6 +54,7 @@ cinaest_SOURCES = \
        src/orientation.c \
        src/plugin-registrar.c \
        src/poster/movie-poster-factory.c \
+       src/rating-widget.c \
        src/settings-dialog.c \
        src/source-dialog.c \
        src/source-list-menu.c \
@@ -73,6 +74,7 @@ cinaest_VALASOURCES = \
        src/orientation.vala \
        src/plugin-registrar.vala \
        src/poster/movie-poster-factory.vala \
+       src/rating-widget.vala \
        src/settings-dialog.vala \
        src/source-dialog.vala \
        src/source-list-menu.vala \
diff --git a/src/rating-widget.vala b/src/rating-widget.vala
new file mode 100644 (file)
index 0000000..70b27f4
--- /dev/null
@@ -0,0 +1,111 @@
+/* This file is part of Cinaest.
+ *
+ * Copyright (C) 2010 Philipp Zabel
+ *
+ * Cinaest is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Cinaest is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Cinaest. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+using Gtk;
+
+public class RatingWidget : DrawingArea {
+       private int rating;
+       private bool button_pressed;
+       private Gdk.Color active_color;
+       private Gdk.Color disabled_color;
+
+       public RatingWidget () {
+               var style = Gtk.rc_get_style_by_paths (this.get_settings (), "GtkButton", null, typeof (Gtk.Button));
+               if (!style.lookup_color ("ActiveTextColor", out active_color))
+                       Gdk.Color.parse ("white", out active_color);
+               if (!style.lookup_color ("DisabledTextColor", out disabled_color))
+                       Gdk.Color.parse ("black", out disabled_color);
+
+               add_events (Gdk.EventMask.BUTTON_PRESS_MASK
+                           | Gdk.EventMask.BUTTON_RELEASE_MASK
+                           | Gdk.EventMask.POINTER_MOTION_MASK);
+
+               set_size_request (640, 70);
+       }
+
+       public override bool expose_event (Gdk.EventExpose event) {
+               var cr = Gdk.cairo_create (this.window);
+               cr.rectangle (event.area.x, event.area.y, event.area.width, event.area.height);
+               cr.clip ();
+
+               for (int i = 0; i < 10; i++) {
+                       draw_star (cr, i, (i >= rating) ? disabled_color : active_color);
+               }
+
+               return false;
+       }
+
+       private void draw_star (Cairo.Context cr, int n, Gdk.Color color) {
+               var radius = double.min (this.allocation.width / 20,
+                                        this.allocation.height / 2);
+               var x = radius * (2 * n + 1);
+               var y = this.allocation.height / 2;
+
+               cr.set_source_rgb (color.red / 65535.0, color.green / 65535.0, color.blue / 65535.0);
+               cr.new_path ();
+               for (int i = 0; i <= 10; i++) {
+                       double r = radius * (5 + 8 * (i % 2)) / 13.0;
+                       double a = x + r * Math.cos (i * 2*Math.PI/10.0 + Math.PI/2.0);
+                       double b = y + r * Math.sin (i * 2*Math.PI/10.0 + Math.PI/2.0);
+                       if (i == 0)
+                               cr.move_to (a, b);
+                       else
+                               cr.line_to (a, b);
+               }
+               cr.close_path ();
+               cr.fill_preserve ();
+       }
+
+       public override bool button_press_event (Gdk.EventButton event) {
+               button_pressed = true;
+               rate (10 * event.x / this.allocation.width);
+
+               return false;
+       }
+
+       public override bool button_release_event (Gdk.EventButton event) {
+               button_pressed = false;
+
+               return false;
+       }
+
+       public override bool motion_notify_event (Gdk.EventMotion event) {
+               if (button_pressed)
+                       rate (10 * event.x / this.allocation.width);
+
+               return false;
+       }
+
+       private void rate (double r) {
+               if (r <= 0)
+                       rating = 0;
+               else
+                       rating = (int) r + 1;
+               if (rating > 10)
+                       rating = 10;
+
+               unowned Gdk.Region region = this.window.get_clip_region ();
+               // redraw the cairo canvas completely by exposing it
+               this.window.invalidate_region (region, true);
+               this.window.process_updates (true);
+       }
+
+       public int get_rating () {
+               return rating;
+       }
+}