Author: llipka
Date: Thu Feb 14 22:35:28 2008
New Revision: 4481
URL: http://svn.gnome.org/viewvc/beagle?rev=4481&view=rev

Log:
Because I love you guys, you will get the delicious cairo rounded corners on 
selections.

Added:
   trunk/beagle/search/Beagle.Search/CairoFu.cs
Modified:
   trunk/beagle/search/Beagle.Search.Tiles/Tile.cs
   trunk/beagle/search/Makefile.am

Modified: trunk/beagle/search/Beagle.Search.Tiles/Tile.cs
==============================================================================
--- trunk/beagle/search/Beagle.Search.Tiles/Tile.cs     (original)
+++ trunk/beagle/search/Beagle.Search.Tiles/Tile.cs     Thu Feb 14 22:35:28 2008
@@ -138,24 +138,22 @@
                        if (!IsDrawable)
                                return false;
 
-                       GdkWindow.DrawRectangle (Style.BaseGC (State), true,
-                                                evt.Area.X, evt.Area.Y,
-                                                evt.Area.Width, 
evt.Area.Height);
+                       Cairo.Context gr = Gdk.CairoHelper.Create (evt.Window);
 
-                       if (base.OnExposeEvent (evt))
-                               return true;
+                       Gdk.Color fill = Style.BaseColors 
[(int)StateType.Normal];
 
-                       if (HasFocus) {
-                               Gdk.Rectangle alloc = Allocation;
-                               int focusPad = (int)StyleGetProperty 
("focus-padding");
-
-                               int x = focusPad + Style.Xthickness;
-                               int y = focusPad + Style.Ythickness;
-                               int width = alloc.Width - 2 * (focusPad + 
Style.Xthickness);
-                               int height = alloc.Height - 2 * (focusPad + 
Style.Ythickness);
-                               Style.PaintFocus (Style, GdkWindow, State, 
evt.Area, this,
-                                                 null, x, y, width, height);
+                       gr.Rectangle (evt.Area.X, evt.Area.Y, evt.Area.Width, 
evt.Area.Height);
+                       gr.Color = CairoFu.GdkColorToCairoColor (fill);
+                       gr.Fill ();
+
+                       if (State == StateType.Selected || HasFocus) {
+                               CairoFu.RoundedSelection (gr, this, 0, 0, 
Allocation.Width, Allocation.Height);
                        }
+                       
+                       CairoFu.DisposeContext (gr);
+
+                       if (base.OnExposeEvent (evt))
+                               return true;
 
                        return false;
                }

Added: trunk/beagle/search/Beagle.Search/CairoFu.cs
==============================================================================
--- (empty file)
+++ trunk/beagle/search/Beagle.Search/CairoFu.cs        Thu Feb 14 22:35:28 2008
@@ -0,0 +1,300 @@
+//
+// CairoFu.cs
+//
+// Copyright (C) 2007 Novell, Inc.
+// Copyright (C) 2008 Lukas Lipka <[EMAIL PROTECTED]>
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+using Gdk;
+using Cairo;
+
+namespace Beagle.Search {
+    
+       public static class CairoFu {        
+
+               public static Cairo.Color GdkColorToCairoColor (Gdk.Color color)
+               {
+                       return GdkColorToCairoColor (color, 1.0);
+               }
+        
+               public static Cairo.Color GdkColorToCairoColor (Gdk.Color 
color, double alpha)
+               {
+                       return new Cairo.Color ((double)(color.Red >> 8) / 
255.0,
+                                               (double)(color.Green >> 8) / 
255.0,
+                                               (double)(color.Blue >> 8) / 
255.0,
+                                               alpha);
+               }
+        
+               public static void HsbFromColor (Cairo.Color color, out double 
hue, out double saturation, out double brightness)
+               {
+                       double min, max, delta;
+                       double red = color.R, green = color.G, blue = color.B;
+                       
+                       hue = 0;
+                       saturation = 0;
+                       brightness = 0;
+                       
+                       if (red > green) {
+                               max = Math.Max (red, blue);
+                               min = Math.Min (green, blue);
+                       } else {
+                               max = Math.Max (green, blue);
+                               min = Math.Min (red, blue);
+                       }
+                       
+                       brightness = (max + min) / 2;
+                       
+                       if (Math.Abs (max - min) < 0.0001) {
+                               hue = 0;
+                               saturation = 0;
+                       } else {
+                               saturation = brightness <= 0.5 ? (max - min) / 
(max + min) : (max - min) / (2 - max - min);
+                               delta = max - min;
+                               
+                               if (red == max) {
+                                       hue = (green - blue) / delta;
+                               } else if (green == max) {
+                                       hue = 2 + (blue - red) / delta;
+                               } else if (blue == max) {
+                                       hue = 4 + (red - green) / delta;
+                               }
+                               
+                               hue *= 60;
+
+                               if(hue < 0)
+                                       hue += 360;
+                       }
+               }
+               
+               private static double Modula (double number, double divisor)
+               {
+                       return ((int)number % divisor) + (number - (int)number);
+               }
+               
+               public static Cairo.Color ColorFromHsb (double hue, double 
saturation, double brightness)
+               {
+                       double [] hue_shift = { 0, 0, 0 };
+                       double [] color_shift = { 0, 0, 0 };
+                       double m1, m2, m3;
+                       int i;
+                       
+                       m2 = brightness <= 0.5 ? brightness * (1 + saturation) 
: brightness + saturation - brightness * saturation;
+                       m1 = 2 * brightness - m2;
+                       
+                       hue_shift[0] = hue + 120;
+                       hue_shift[1] = hue;
+                       hue_shift[2] = hue - 120;
+                       
+                       color_shift[0] = color_shift[1] = color_shift[2] = 
brightness;
+                       
+                       i = saturation == 0 ? 3 : 0;
+                       
+                       while (i < 3) {
+                               m3 = hue_shift[i];
+                               
+                               if(m3 > 360) {
+                                       m3 = Modula (m3, 360);
+                               } else if (m3 < 0) {
+                                       m3 = 360 - Modula (Math.Abs (m3), 360);
+                               }
+                               
+                               if (m3 < 60) {
+                                       color_shift[i] = m1 + (m2 - m1) * m3 / 
60;
+                               } else if (m3 < 180) {
+                                       color_shift[i] = m2;
+                               } else if (m3 < 240) {
+                                       color_shift[i] = m1 + (m2 - m1) * (240 
- m3) / 60;
+                               } else {
+                                       color_shift[i] = m1;
+                               }
+
+                               i++;
+                       }
+                       
+                       return new Cairo.Color (color_shift[0], color_shift[1], 
color_shift[2]);
+               }
+               
+               public static Cairo.Color ColorShade (Cairo.Color @base, double 
ratio)
+               {
+                       double h, s, b;
+                       
+                       HsbFromColor (@base, out h, out s, out b);
+                       
+                       b = Math.Max (Math.Min (b * ratio, 1), 0);
+                       s = Math.Max (Math.Min (s * ratio, 1), 0);
+                       
+                       return ColorFromHsb (h, s, b);
+               }
+               
+               public static Cairo.Color ColorAdjustBrightness (Cairo.Color 
@base, double brightness)
+               {
+                       double h, s, b;
+
+                       HsbFromColor (@base, out h, out s, out b);
+                       b = Math.Max (Math.Min (brightness, 1), 0);
+
+                       return ColorFromHsb (h, s, b);
+               }
+               
+               public static string ColorGetHex (Cairo.Color color, bool 
has_alpha)
+               {
+                       if (has_alpha) {
+                               return String.Format 
("#{0:x2}{1:x2}{2:x2}{3:x2}", (byte)(color.R * 255), (byte)(color.G * 255), 
+                                                     (byte)(color.B * 255), 
(byte)(color.A * 255));
+                       }
+
+                       return String.Format ("#{0:x2}{1:x2}{2:x2}", 
(byte)(color.R * 255), (byte)(color.G * 255), 
+                                             (byte)(color.B * 255));
+               }
+               
+               public static void RoundedRectangle (Cairo.Context cr, double 
x, double y, double w, double h, double r)
+               {
+                       RoundedRectangle (cr, x, y, w, h, r, CairoCorners.All);
+               }
+               
+               public static void RoundedRectangle (Cairo.Context cr, double 
x, double y, double w, double h, 
+                                                    double r, CairoCorners 
corners)
+               {
+                       if (r < 0.0001 || corners == CairoCorners.None) {
+                               cr.Rectangle (x, y, w, h);
+                               return;
+                       }
+                       
+                       if ((corners & CairoCorners.TopLeft) != 0) {
+                               cr.MoveTo (x + r, y);
+                       } else {
+                               cr.MoveTo (x, y);
+                       }
+                       
+                       if ((corners & CairoCorners.TopRight) != 0) {
+                               cr.Arc (x + w - r, y + r, r, Math.PI * 1.5, 
Math.PI * 2);
+                       } else {
+                               cr.LineTo (x + w, y);
+                       }
+                       
+                       if ((corners & CairoCorners.BottomRight) != 0) {
+                               cr.Arc (x + w - r, y + h - r, r, 0, Math.PI * 
0.5);
+                       } else {
+                               cr.LineTo (x + w, y + h);
+                       }
+                       
+                       if ((corners & CairoCorners.BottomLeft) != 0) {
+                               cr.Arc (x + r, y + h - r, r, Math.PI * 0.5, 
Math.PI);
+                       } else {
+                               cr.LineTo (x, y + h);
+                       }
+                       
+                       if ((corners & CairoCorners.TopLeft) != 0) {
+                               cr.Arc (x + r, y + r, r, Math.PI, Math.PI * 
1.5);
+                       } else {
+                               cr.LineTo (x, y);
+                       }
+               }
+
+               public static void RoundedSelection (Cairo.Context cr, 
Gtk.Widget widget, double x, double y, double w, double h, double a)
+               {
+                       Cairo.Color selection_color = 
CairoFu.GdkColorToCairoColor (widget.Style.Backgrounds 
[(int)Gtk.StateType.Selected]);
+
+                       Cairo.Color selection_stroke = CairoFu.ColorShade 
(selection_color, 0.85);
+                       Cairo.Color selection_fill_light = CairoFu.ColorShade 
(selection_color, 1.1);
+                       Cairo.Color selection_fill_dark = CairoFu.ColorShade 
(selection_color, 0.90);
+                       selection_stroke.A = selection_fill_light.A = 
selection_fill_dark.A = a;
+                       
+                       Cairo.LinearGradient pattern = new Cairo.LinearGradient 
(x, y, x, y + h);
+                       pattern.AddColorStop (0, selection_fill_light);
+                       pattern.AddColorStop (1, selection_fill_dark);
+                       
+                       RoundedRectangle (cr, x, y, w, h, 3);
+                       cr.Pattern = pattern;
+                       cr.Fill ();
+                       
+                       RoundedRectangle (cr, x + 0.5, y + 0.5, w - 0.5, h - 
0.5, 3);
+                       cr.Color = selection_stroke;
+                       cr.LineWidth = 1.0;
+                       cr.Stroke ();
+               }
+
+               public static void RoundedSelection (Cairo.Context cr, 
Gtk.Widget widget, double x, double y, double w, double h)
+               {
+                       RoundedSelection (cr, widget, x, y, w, h, 1.0);
+               }
+
+               public static void DisposeContext (Cairo.Context cr)
+               {
+                       ((IDisposable)cr.Target).Dispose ();
+                       ((IDisposable)cr).Dispose ();
+               }
+               
+               private struct CairoInteropCall
+               {
+                       public string Name;
+                       public MethodInfo ManagedMethod;
+                       public bool CallNative;
+                       
+                       public CairoInteropCall (string name)
+                       {
+                               Name = name;
+                               ManagedMethod = null;
+                               CallNative = false;
+                       }
+               }
+               
+               private static bool CallCairoMethod (Cairo.Context cr, ref 
CairoInteropCall call)
+               {
+                       if (call.ManagedMethod == null && !call.CallNative) {
+                               MemberInfo [] members = typeof 
(Cairo.Context).GetMember (call.Name, MemberTypes.Method, 
+                                                                               
          BindingFlags.InvokeMethod | BindingFlags.Instance | 
BindingFlags.Public);
+                               
+                               if (members != null && members.Length > 0 && 
members[0] is MethodInfo) {
+                                       call.ManagedMethod = 
(MethodInfo)members[0];
+                               } else {
+                                       call.CallNative = true;
+                               }
+                       }
+                       
+                       if (call.ManagedMethod != null) {
+                               call.ManagedMethod.Invoke (cr, null);
+                               return true;
+                       }
+                       
+                       return false;
+               }
+               
+               [DllImport ("libcairo.so.2")]
+               private static extern void cairo_push_group (IntPtr ptr);
+               private static CairoInteropCall cairo_push_group_call = new 
CairoInteropCall ("PushGroup");
+        
+               public static void PushGroup (Cairo.Context cr)
+               {
+                       if (!CallCairoMethod (cr, ref cairo_push_group_call)) {
+                               cairo_push_group (cr.Handle);
+                       }
+               }
+        
+               [DllImport ("libcairo.so.2")]
+               private static extern void cairo_pop_group_to_source (IntPtr 
ptr);
+               private static CairoInteropCall cairo_pop_group_to_source_call 
= new CairoInteropCall ("PopGroupToSource");
+               
+               public static void PopGroupToSource (Cairo.Context cr)
+               {
+                       if (!CallCairoMethod (cr, ref 
cairo_pop_group_to_source_call)) {
+                               cairo_pop_group_to_source (cr.Handle);
+                       }
+               }
+       }
+
+       [Flags]
+       public enum CairoCorners
+       {
+               None = 0,
+               TopLeft = 1,
+               TopRight = 2,
+               BottomLeft = 4,
+               BottomRight = 8,
+               All = 15
+       }
+}

Modified: trunk/beagle/search/Makefile.am
==============================================================================
--- trunk/beagle/search/Makefile.am     (original)
+++ trunk/beagle/search/Makefile.am     Thu Feb 14 22:35:28 2008
@@ -70,6 +70,7 @@
        $(srcdir)/Beagle.Search.Tiles/WebHistory.cs             \
        $(srcdir)/Beagle.Search.Tray/NotificationArea.cs        \
        $(srcdir)/Beagle.Search.Tray/TrayIcon.cs                \
+       $(srcdir)/Beagle.Search/CairoFu.cs                      \
        $(srcdir)/Beagle.Search/Category.cs                     \
        $(srcdir)/Beagle.Search/DetailsPane.cs                  \
        $(srcdir)/Beagle.Search/Driver.cs                       \
@@ -101,7 +102,8 @@
        $(LOCAL_ASSEMBLIES:%=-r:%)      \
        $(NDESK_DBUS_LIBS)              \
        $(NDESK_DBUS_GLIB_LIBS)         \
-       -r:Mono.Posix
+       -r:Mono.Posix                   \
+       -r:Mono.Cairo
 
 pkglib_DATA = $(ASSEMBLY) $(ASSEMBLY).mdb
 
_______________________________________________
SVN-commits-list mailing list (read only)
http://mail.gnome.org/mailman/listinfo/svn-commits-list

Want to limit the commits to a few modules? Go to above URL, log in to edit 
your options and select the modules ('topics') you want.
Module maintainer? It is possible to set the reply-to to your development 
mailing list. Email [EMAIL PROTECTED] if interested.

Reply via email to