[f-spot] Base rating widget on Hyena RatingEntry



commit b0824dd43d209f7aebea5d6d87a4e385a7e026e7
Author: Mike Gemünde <mike gemuende de>
Date:   Mon Aug 23 20:09:52 2010 +0200

    Base rating widget on Hyena RatingEntry
    
    https://bugzilla.gnome.org/show_bug.cgi?id=627835

 build/build.environment.mk                         |    2 +-
 icons/rating-blank-16.png                          |  Bin 199 -> 457 bytes
 .../MainApp/FSpot.Extensions/PopupCommands.cs      |    2 +-
 .../MainApp/FSpot.UI.Dialog/RatingFilterDialog.cs  |   35 ++-
 src/Clients/MainApp/FSpot.Widgets/IconView.cs      |   12 +-
 src/Clients/MainApp/FSpot.Widgets/InfoBox.cs       |    6 +-
 .../MainApp/FSpot.Widgets/RatingMenuItem.cs        |  151 ++-------
 src/Clients/MainApp/FSpot/PhotoView.cs             |    9 +-
 src/Core/FSpot.Gui/FSpot.Gui.csproj                |    8 +-
 src/Core/FSpot.Gui/FSpot.Widgets/Rating.cs         |  365 --------------------
 src/Core/FSpot.Gui/FSpot.Widgets/RatingEntry.cs    |   27 ++
 src/Core/FSpot.Gui/FSpot.Widgets/RatingRenderer.cs |  255 ++++++++++++++
 src/Core/FSpot.Gui/Makefile.am                     |    3 +-
 13 files changed, 363 insertions(+), 512 deletions(-)
---
diff --git a/build/build.environment.mk b/build/build.environment.mk
index 3739498..8980bf5 100644
--- a/build/build.environment.mk
+++ b/build/build.environment.mk
@@ -118,7 +118,7 @@ LINK_FSPOT_PLATFORM = -r:$(DIR_BIN)/FSpot.Platform.dll
 LINK_FSPOT_PLATFORM_DEPS = $(REF_FSPOT_PLATFORM) $(LINK_FSPOT_PLATFORM)
 
 # FSpot.Gui
-REF_FSPOT_GUI = $(LINK_FSPOT_CORE_DEPS) $(LINK_FSPOT_BLING_DEPS)
+REF_FSPOT_GUI = $(LINK_FSPOT_CORE_DEPS) $(LINK_FSPOT_BLING_DEPS) $(LINK_HYENA_GUI_DEPS)
 LINK_FSPOT_GUI = -r:$(DIR_BIN)/FSpot.Gui.dll
 LINK_FSPOT_GUI_DEPS = $(REF_FSPOT_GUI) $(LINK_FSPOT_GUI) $(LINK_HENA_GUI_DEPS)
 
diff --git a/icons/rating-blank-16.png b/icons/rating-blank-16.png
index cd6d36e..5734aa9 100644
Binary files a/icons/rating-blank-16.png and b/icons/rating-blank-16.png differ
diff --git a/src/Clients/MainApp/FSpot.Extensions/PopupCommands.cs b/src/Clients/MainApp/FSpot.Extensions/PopupCommands.cs
index e4f1640..1ad338c 100644
--- a/src/Clients/MainApp/FSpot.Extensions/PopupCommands.cs
+++ b/src/Clients/MainApp/FSpot.Extensions/PopupCommands.cs
@@ -91,7 +91,7 @@ namespace FSpot.Extensions
 	{
 		public void Run (object o, EventArgs e)
 		{
-			App.Instance.Organizer.HandleRatingMenuSelected ((o as Widgets.Rating).Value);
+			App.Instance.Organizer.HandleRatingMenuSelected ((o as FSpot.Widgets.RatingMenuItem).Value);
 		}
 	}
 }
diff --git a/src/Clients/MainApp/FSpot.UI.Dialog/RatingFilterDialog.cs b/src/Clients/MainApp/FSpot.UI.Dialog/RatingFilterDialog.cs
index 1092063..37e7bbb 100644
--- a/src/Clients/MainApp/FSpot.UI.Dialog/RatingFilterDialog.cs
+++ b/src/Clients/MainApp/FSpot.UI.Dialog/RatingFilterDialog.cs
@@ -23,10 +23,11 @@ namespace FSpot.UI.Dialog
 
 		private int minrating_value = 4;
 		private int maxrating_value = 5;
-		private Rating minrating;
-		private Rating maxrating;
+		private RatingEntry minrating;
+		private RatingEntry maxrating;
 
-		public RatingFilterDialog (FSpot.PhotoQuery query, Gtk.Window parent_window) : base ("RatingFilterDialog.ui", "rating_filter_dialog")
+		public RatingFilterDialog (FSpot.PhotoQuery query, Gtk.Window parent_window)
+            : base ("RatingFilterDialog.ui", "rating_filter_dialog")
 		{
 			TransientFor = parent_window;
 			DefaultResponse = ResponseType.Ok;
@@ -36,11 +37,17 @@ namespace FSpot.UI.Dialog
 				minrating_value = (int) query.RatingRange.MinRating;
 				maxrating_value = (int) query.RatingRange.MaxRating;
 			}
-			minrating = new Rating (minrating_value);
-			maxrating = new Rating (maxrating_value);
+			minrating = new RatingEntry (minrating_value);
+			maxrating = new RatingEntry (maxrating_value);
 			minrating_hbox.PackStart (minrating, false, false, 0);
 			maxrating_hbox.PackStart (maxrating, false, false, 0);
 
+            minrating.Show ();
+            maxrating.Show ();
+
+            minrating.Changed += HandleMinratingChanged;
+            maxrating.Changed += HandleMaxratingChanged;
+
 			ResponseType response = (ResponseType) Run ();
 
 			if (response == ResponseType.Ok) {
@@ -49,5 +56,23 @@ namespace FSpot.UI.Dialog
 
 			Destroy ();
 		}
+
+        void HandleMinratingChanged (object sender, System.EventArgs e)
+        {
+            if (minrating.Value > maxrating.Value) {
+                maxrating.Changed -= HandleMaxratingChanged;
+                maxrating.Value = minrating.Value;
+                maxrating.Changed += HandleMaxratingChanged;
+            }
+        }
+
+        void HandleMaxratingChanged (object sender, System.EventArgs e)
+        {
+            if (maxrating.Value < minrating.Value) {
+                minrating.Changed -= HandleMinratingChanged;
+                minrating.Value = maxrating.Value;
+                minrating.Changed += HandleMinratingChanged;
+            }
+        }
 	}
 }
diff --git a/src/Clients/MainApp/FSpot.Widgets/IconView.cs b/src/Clients/MainApp/FSpot.Widgets/IconView.cs
index 8f30dda..225c110 100644
--- a/src/Clients/MainApp/FSpot.Widgets/IconView.cs
+++ b/src/Clients/MainApp/FSpot.Widgets/IconView.cs
@@ -968,11 +968,13 @@ namespace FSpot.Widgets
 				thumbnail.Dispose ();
 			}
 			if (DisplayRatings && photo.Rating > 0 && region.X == draw.X && region.X != 0) {
-				FSpot.Widgets.RatingSmall rating;
-				rating = new FSpot.Widgets.RatingSmall ((int) photo.Rating, false);
-				rating.DisplayPixbuf.RenderToDrawable (BinWindow, Style.WhiteGC,
-						0, 0, region.X, region.Y, -1, -1, RgbDither.None, 0, 0);
-
+                var rating = new RatingRenderer () {
+                    Value = (int) photo.Rating
+                };
+                using (var rating_pixbuf = rating.RenderPixbuf ()) {
+                    rating_pixbuf.RenderToDrawable (BinWindow, Style.WhiteGC,
+                                                    0, 0, region.X, region.Y, -1, -1, RgbDither.None, 0, 0);
+                }
 			}
 			Gdk.Rectangle layout_bounds = Gdk.Rectangle.Zero;
 			if (DisplayDates) {
diff --git a/src/Clients/MainApp/FSpot.Widgets/InfoBox.cs b/src/Clients/MainApp/FSpot.Widgets/InfoBox.cs
index 451d59f..6cb47b5 100644
--- a/src/Clients/MainApp/FSpot.Widgets/InfoBox.cs
+++ b/src/Clients/MainApp/FSpot.Widgets/InfoBox.cs
@@ -130,7 +130,7 @@ namespace FSpot.Widgets
 		private Label file_size_value_label;
 
 		private Label rating_label;
-		private RatingSmall rating_view;
+		private RatingEntry rating_view;
 
 		private TagView tag_view;
 		private string default_exposure_string;
@@ -145,7 +145,7 @@ namespace FSpot.Widgets
 
 		private void HandleRatingChanged (object o, EventArgs e)
 		{
-			App.Instance.Organizer.HandleRatingMenuSelected ((o as Widgets.Rating).Value);
+			App.Instance.Organizer.HandleRatingMenuSelected ((o as Widgets.RatingEntry).Value);
 		}
 
 		private Label CreateRightAlignedLabel (string text)
@@ -271,7 +271,7 @@ namespace FSpot.Widgets
 			Gtk.Alignment rating_align = new Gtk.Alignment( 0, 0, 0, 0);
 			info_table.Attach (rating_align, 1, 2, 8, 9, AttachOptions.Fill, AttachOptions.Fill, TABLE_XPADDING, TABLE_YPADDING);
 
-			rating_view = new RatingSmall ();
+			rating_view = new RatingEntry () { HasFrame = false };
 			rating_view.Visible = false;
 			rating_view.Changed += HandleRatingChanged;
 			rating_align.Add (rating_view);
diff --git a/src/Clients/MainApp/FSpot.Widgets/RatingMenuItem.cs b/src/Clients/MainApp/FSpot.Widgets/RatingMenuItem.cs
index 6116a36..74d786e 100644
--- a/src/Clients/MainApp/FSpot.Widgets/RatingMenuItem.cs
+++ b/src/Clients/MainApp/FSpot.Widgets/RatingMenuItem.cs
@@ -3,8 +3,10 @@
 //
 // Author:
 //   Aaron Bockover <abockover novell com>
+//   Mike Gemuende <mike gemuende de>
 //
 // Copyright (C) 2007 Novell, Inc.
+// Copyright (C) 2010 Mike Gemuende
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -27,134 +29,31 @@
 //
 
 using System;
-using Gtk;
-using Mono.Unix;
 
-using Hyena;
-using Hyena.Widgets;
 
 namespace FSpot.Widgets
 {
-	public class RatingMenuItem : ComplexMenuItem
-	{
-		private Rating entry;
-		private bool pressing;
-		private bool can_activate = true;
-
-		protected RatingMenuItem (IntPtr raw) : base (raw)
-		{
-		}
-
-		public RatingMenuItem () : this (null)
-		{
-		}
-
-		public RatingMenuItem (object parent) : base ()
-		{
-			HBox box = new HBox ();
-			box.Spacing = 5;
-
-			Label label = new Label ();
-			label.Markup = String.Format ("<i>{0}</i>",
-					GLib.Markup.EscapeText (Catalog.GetString ("Rating:")));
-			box.PackStart (label, false, false, 0);
-
-			if (parent is FullScreenView) {
-				Log.Debug ("PARENT IS FSVIEW");
-				FullScreenView fsview = parent as FullScreenView;
-				entry = new Rating ((int)fsview.View.Item.Current.Rating, true);
-			} else if (App.Instance.Organizer.Selection.Count == 1)
-				entry = new Rating ((int)App.Instance.Organizer.Selection[0].Rating, true);
-			else
-				entry = new Rating (-1, true);
-			entry.Changed += OnEntryChanged;
-			box.PackStart (entry, false, false, 0);
-
-			box.ShowAll ();
-			Add (box);
-		}
-
-		protected override void OnRealized ()
-		{
-			entry.ModifyBg (Gtk.StateType.Prelight, entry.Style.BaseColors [(int)Gtk.StateType.Selected]);
-			base.OnRealized();
-
-		}
-
-		private int TransformX (double inx)
-		{
-			int x = (int)inx - entry.Allocation.X;
-
-			if (x < 0) {
-				x = 0;
-			} else if (x > entry.Allocation.Width) {
-				x = entry.Allocation.Width;
-			}
-
-			return x;
-		}
-
-		protected override bool OnButtonPressEvent (Gdk.EventButton evnt)
-		{
-			pressing = true;
-			entry.SetValueFromPosition (TransformX (evnt.X));
-			return true;
-		}
-
-		protected override bool OnButtonReleaseEvent (Gdk.EventButton evnt)
-		{
-			pressing = false;
-			return true;
-		}
-
-		protected override bool OnMotionNotifyEvent (Gdk.EventMotion evnt)
-		{
-			if (!pressing) {
-				return false;
-			}
-
-			entry.SetValueFromPosition (TransformX (evnt.X));
-			return true;
-		}
-
-		protected override bool OnLeaveNotifyEvent (Gdk.EventCrossing evnt)
-		{
-			pressing = false;
-			return true;
-		}
-
-		protected override bool OnScrollEvent (Gdk.EventScroll evnt)
-		{
-			return entry.HandleScroll (evnt);
-		}
-
-		protected override bool OnKeyPressEvent (Gdk.EventKey evnt)
-		{
-			return entry.HandleKeyPress (evnt);
-		}
-
-		private void OnEntryChanged (object o, EventArgs args)
-		{
-			if (can_activate) {
-				Activate ();
-				OnSelected ();
-			}
-		}
-
-		public void Reset (int value)
-		{
-			can_activate = false;
-			Value = value;
-			can_activate = true;
-		}
-
-		public int Value {
-			get { return entry.Value; }
-			set { entry.Value = value; }
-		}
-
-		public Rating RatingEntry {
-			get { return entry; }
-		}
-	}
+    public class RatingMenuItem : Hyena.Widgets.RatingMenuItem
+    {
+        private RatingEntry entry;
+
+        public RatingMenuItem () : base (new FSpot.Widgets.RatingEntry ())
+        {
+            entry = this.RatingEntry as FSpot.Widgets.RatingEntry;
+        }
+
+        public RatingMenuItem (object parent) : this ()
+        {
+            if (parent is FullScreenView) {
+                entry.Value = (int)(parent as FullScreenView).View.Item.Current.Rating;
+
+            } else if (App.Instance.Organizer.Selection.Count == 1) {
+                entry.Value = (int)App.Instance.Organizer.Selection[0].Rating;
+            }
+        }
+
+        protected RatingMenuItem (IntPtr raw) : base (raw)
+        {
+        }
+    }
 }
diff --git a/src/Clients/MainApp/FSpot/PhotoView.cs b/src/Clients/MainApp/FSpot/PhotoView.cs
index 8557024..2c9627d 100644
--- a/src/Clients/MainApp/FSpot/PhotoView.cs
+++ b/src/Clients/MainApp/FSpot/PhotoView.cs
@@ -39,7 +39,7 @@ namespace FSpot {
 		private Widgets.TagView tag_view;
 
 		private Entry description_entry;
-		private Widgets.Rating rating;
+		private RatingEntry rating;
 
 		// Public events.
 
@@ -192,7 +192,7 @@ namespace FSpot {
 			if (!Item.IsValid)
 				return;
 
-			((Photo)Item.Current).Rating = (uint)(o as Widgets.Rating).Value;
+			((Photo)Item.Current).Rating = (uint)(o as Widgets.RatingEntry).Value;
 
 			if (commit_delay.IsPending)
 				if (changed_photo == Item.Index)
@@ -340,7 +340,10 @@ namespace FSpot {
 			lower_hbox.PackStart (description_entry, true, true, 0);
 			description_entry.Changed += HandleDescriptionChanged;
 
-			rating = new Widgets.Rating();
+            rating = new RatingEntry () {
+                HasFrame = false,
+                AlwaysShowEmptyStars = true
+            };
 			lower_hbox.PackStart (rating, false, false, 0);
 			rating.Changed += HandleRatingChanged;
 
diff --git a/src/Core/FSpot.Gui/FSpot.Gui.csproj b/src/Core/FSpot.Gui/FSpot.Gui.csproj
index 3f32b9d..7ca8491 100644
--- a/src/Core/FSpot.Gui/FSpot.Gui.csproj
+++ b/src/Core/FSpot.Gui/FSpot.Gui.csproj
@@ -35,7 +35,6 @@
     <Compile Include="FSpot.Widgets\ApplicationActivatedEventArgs.cs" />
     <Compile Include="FSpot.Widgets\BuilderWindow.cs" />
     <Compile Include="FSpot.Widgets\CheckPattern.cs" />
-    <Compile Include="FSpot.Widgets\ComplexMenuItem.cs" />
     <Compile Include="FSpot.Widgets\Curve.cs" />
     <Compile Include="FSpot.Widgets\CurveType.cs" />
     <Compile Include="FSpot.Widgets\CustomPrintWidget.cs" />
@@ -47,7 +46,6 @@
     <Compile Include="FSpot.Widgets\MenuButton.cs" />
     <Compile Include="FSpot.Widgets\OpenWithMenu.cs" />
     <Compile Include="FSpot.Widgets\PointerMode.cs" />
-    <Compile Include="FSpot.Widgets\Rating.cs" />
     <Compile Include="FSpot.Widgets\SaneTreeView.cs" />
     <Compile Include="FSpot.Widgets\ScrolledView.cs" />
     <Compile Include="FSpot.Transitions\CairoTransition.cs" />
@@ -59,6 +57,8 @@
     <Compile Include="FSpot.Gui\WindowOpacityFader.cs" />
     <Compile Include="FSpot.Gui\CompositeUtils.cs" />
     <Compile Include="FSpot.Widgets\ToolTipWindow.cs" />
+    <Compile Include="FSpot.Widgets\RatingEntry.cs" />
+    <Compile Include="FSpot.Widgets\RatingRenderer.cs" />
   </ItemGroup>
   <ProjectExtensions>
     <MonoDevelop>
@@ -116,6 +116,10 @@
       <Project>{9D66BC1B-4390-4B8D-8468-19D5A862EC23}</Project>
       <Name>FSpot.Cms</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\..\lib\Hyena\Hyena.Gui\Hyena.Gui.csproj">
+      <Project>{C856EFD8-E812-4E61-8B76-E3583D94C233}</Project>
+      <Name>Hyena.Gui</Name>
+    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
     <Folder Include="FSpot.Transitions\" />
diff --git a/src/Core/FSpot.Gui/FSpot.Widgets/RatingEntry.cs b/src/Core/FSpot.Gui/FSpot.Widgets/RatingEntry.cs
new file mode 100644
index 0000000..ad50706
--- /dev/null
+++ b/src/Core/FSpot.Gui/FSpot.Widgets/RatingEntry.cs
@@ -0,0 +1,27 @@
+/*
+ * RatingEntry.cs
+ *
+ * Author(s)
+ *  Mike Gemuende <mike gemuende de>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+using System;
+
+namespace FSpot.Widgets
+{
+    public class RatingEntry : Hyena.Widgets.RatingEntry
+    {
+        public RatingEntry (int rating) : base (rating, new RatingRenderer ())
+        {
+            MaxRating = 5;
+            MinRating = 0;
+        }
+
+        public RatingEntry () : this (0)
+        {
+        }
+    }
+}
+
diff --git a/src/Core/FSpot.Gui/FSpot.Widgets/RatingRenderer.cs b/src/Core/FSpot.Gui/FSpot.Widgets/RatingRenderer.cs
new file mode 100644
index 0000000..d64e2fd
--- /dev/null
+++ b/src/Core/FSpot.Gui/FSpot.Widgets/RatingRenderer.cs
@@ -0,0 +1,255 @@
+/*
+ * RatingRenderer.cs
+ *
+ * Author(s)
+ *  Mike Gemuende <mike gemuende de>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+using System;
+
+using Gdk;
+using Cairo;
+
+using Hyena.Gui;
+
+using FSpot.Utils;
+
+
+namespace FSpot.Widgets
+{
+    public class RatingRenderer : Hyena.Gui.RatingRenderer
+    {
+        private static int REQUESTED_ICON_SIZE = 16;
+
+#region Shared Pixbufs
+
+        // cache the unscaled pixbufs for all instances
+        private static Pixbuf icon_rated;
+        private static Pixbuf icon_blank;
+        private static Pixbuf icon_hover;
+
+#endregion
+
+#region Access Rating Pixbufs
+
+        protected static Pixbuf IconRated {
+            get {
+                if (icon_rated == null)
+                    icon_rated =
+                        GtkUtil.TryLoadIcon (FSpot.Core.Global.IconTheme,
+                                             "rating-rated",
+                                             REQUESTED_ICON_SIZE, (Gtk.IconLookupFlags)0);
+
+                return icon_rated;
+            }
+        }
+
+        protected static Pixbuf IconBlank {
+            get {
+                if (icon_blank == null)
+                    icon_blank =
+                        GtkUtil.TryLoadIcon (FSpot.Core.Global.IconTheme,
+                                             "rating-blank",
+                                             REQUESTED_ICON_SIZE, (Gtk.IconLookupFlags)0);
+
+                return icon_blank;
+            }
+        }
+
+        protected static Pixbuf IconHover {
+            get {
+                if (icon_hover == null)
+                    icon_hover =
+                        GtkUtil.TryLoadIcon (FSpot.Core.Global.IconTheme,
+                                             "rating-rated-gray",
+                                             REQUESTED_ICON_SIZE, (Gtk.IconLookupFlags)0);
+
+                return icon_hover;
+            }
+        }
+
+#endregion
+
+#region Cache and Access Scaled Rating Pixbufs
+
+        // cache the scaled pixbufs for every instance
+        private int scaled_icon_size;
+        private Pixbuf scaled_icon_rated;
+        private Pixbuf scaled_icon_blank;
+        private Pixbuf scaled_icon_hover;
+
+        protected Pixbuf ScaledIconRated {
+            get {
+                if (scaled_icon_size == Size && scaled_icon_rated != null)
+                    return scaled_icon_rated;
+
+                if (scaled_icon_size != Size)
+                    ResetCachedPixbufs ();
+
+                scaled_icon_rated = ScaleIcon (IconRated);
+                scaled_icon_size = Size;
+
+                return scaled_icon_rated;
+            }
+        }
+
+        protected Pixbuf ScaledIconBlank {
+            get {
+                if (scaled_icon_size == Size && scaled_icon_blank != null)
+                    return scaled_icon_blank;
+
+                if (scaled_icon_size != Size)
+                    ResetCachedPixbufs ();
+
+                scaled_icon_blank = ScaleIcon (IconBlank);
+                scaled_icon_size = Size;
+
+                return scaled_icon_blank;
+            }
+        }
+
+        protected Pixbuf ScaledIconHover {
+            get {
+                if (scaled_icon_size == Size && scaled_icon_hover != null)
+                    return scaled_icon_hover;
+
+                if (scaled_icon_size != Size)
+                    ResetCachedPixbufs ();
+
+                scaled_icon_hover = ScaleIcon (IconHover);
+                scaled_icon_size = Size;
+
+                return scaled_icon_hover;
+            }
+        }
+
+        private void ResetCachedPixbufs ()
+        {
+            if (scaled_icon_rated != null) {
+                scaled_icon_rated.Dispose ();
+                scaled_icon_rated = null;
+            }
+
+            if (scaled_icon_blank != null) {
+                scaled_icon_blank.Dispose ();
+                scaled_icon_blank = null;
+            }
+
+            if (scaled_icon_hover != null) {
+                scaled_icon_hover.Dispose ();
+                scaled_icon_hover = null;
+            }
+        }
+
+        private Pixbuf ScaleIcon (Pixbuf icon)
+        {
+            if (icon.Width > Size) {
+                return icon.ScaleSimple (Size, Size, InterpType.Bilinear);
+            }
+
+            var scaled_icon = new Pixbuf (Colorspace.Rgb, true, 8, Size, Size);
+            scaled_icon.Fill (0xffffff00);
+
+            int x_offset = (Size - icon.Width) / 2;
+            int y_offset = (Size - icon.Height) / 2;
+
+            icon.CopyArea (0, 0, icon.Width, icon.Height, scaled_icon, x_offset, y_offset);
+            return scaled_icon;
+        }
+
+#endregion
+
+#region Constructors / Destructor
+
+        public RatingRenderer ()
+        {
+        }
+
+        ~RatingRenderer ()
+        {
+            ResetCachedPixbufs ();
+        }
+
+#endregion
+
+#region Drawing Code
+
+        public Pixbuf RenderPixbuf ()
+        {
+            return RenderPixbuf (false);
+        }
+
+        public Pixbuf RenderPixbuf (bool showEmptyStars)
+        {
+            return RenderPixbuf (showEmptyStars, false, MinRating - 1, 0.0, 0.0, 1.0);
+        }
+
+        public Pixbuf RenderPixbuf (bool showEmptyStars, bool isHovering, int hoverValue, double fillOpacity,
+                                    double hoverFillOpacity, double strokeOpacity)
+        {
+            var pixbuf = new Pixbuf (Colorspace.Rgb, true, 8, MaxRating * Size, Size);
+            pixbuf.Fill (0xffffff00);
+
+            int x = 0;
+            for (int i = MinRating + 1, s = isHovering || showEmptyStars ? MaxRating : Value; i <= s; i++, x += Size) {
+
+                Pixbuf icon = null;
+
+                bool rated = (i <= Value && Value > MinRating);
+                bool hover = isHovering &&
+                    rated ? (i > hoverValue && hoverValue < Value) : (i <= hoverValue && hoverValue > MinRating);
+
+                // hover
+                if (hover) {
+                    icon = ScaledIconHover;
+
+                // rated
+                } else if (rated) {
+                    icon = ScaledIconRated;
+
+                // empty 'star'
+                } else {
+                    icon = ScaledIconBlank;
+
+                }
+
+                icon.CopyArea (0, 0, icon.Width, icon.Height, pixbuf, x, 0);
+            }
+
+            return pixbuf;
+        }
+
+#endregion
+
+#region Override Render Code
+
+        public override void Render (Cairo.Context cr, Gdk.Rectangle area, Cairo.Color color, bool showEmptyStars,
+                                     bool isHovering, int hoverValue, double fillOpacity, double hoverFillOpacity,
+                                     double strokeOpacity)
+        {
+            if (Value == MinRating && !isHovering && !showEmptyStars) {
+                return;
+            }
+
+            double x, y;
+            ComputePosition (area, out x, out y);
+
+            cr.Translate (0.5, 0.5);
+
+            using (var pixbuf = RenderPixbuf (showEmptyStars, isHovering, hoverValue,
+                                              fillOpacity, hoverFillOpacity, strokeOpacity)) {
+                using (var surface = CairoExtensions.CreateSurfaceForPixbuf (cr, pixbuf)) {
+                    cr.Rectangle (x, y, pixbuf.Width, pixbuf.Height);
+                    cr.SetSource (surface, x, y);
+                    cr.Fill ();
+                }
+            }
+        }
+
+#endregion
+
+    }
+}
+
diff --git a/src/Core/FSpot.Gui/Makefile.am b/src/Core/FSpot.Gui/Makefile.am
index bc26a2f..2ed4df7 100644
--- a/src/Core/FSpot.Gui/Makefile.am
+++ b/src/Core/FSpot.Gui/Makefile.am
@@ -25,7 +25,8 @@ SOURCES =  \
 	FSpot.Widgets/MenuButton.cs \
 	FSpot.Widgets/OpenWithMenu.cs \
 	FSpot.Widgets/PointerMode.cs \
-	FSpot.Widgets/Rating.cs \
+	FSpot.Widgets/RatingEntry.cs \
+	FSpot.Widgets/RatingRenderer.cs \
 	FSpot.Widgets/SaneTreeView.cs \
 	FSpot.Widgets/ScrolledView.cs \
 	FSpot.Widgets/ToolTipWindow.cs



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]