[hyena] ListView: Rework rendering of header to follow GTK theme (bgo#709619)



commit e82be473c5591cef07ab7d368cb71b951a786e7c
Author: Bertrand Lorentz <bertrand lorentz gmail com>
Date:   Sat Jun 7 18:52:12 2014 +0200

    ListView: Rework rendering of header to follow GTK theme (bgo#709619)
    
    We now use the StyleContext to draw the frame and background of the
    header cells. By setting the correct region and flags, the result should
    follow the GTK+ theme, giving us the same appearance a a standard
    treeview.
    
    But themes do not always account for custom widgets in their CSS
    definitions. For example, with Adwaita the last header is not supposed
    to have a right border, but for the ListView it still does, because of
    an incorrect CSS selector (see bgo#731463).

 .../Hyena.Data.Gui/ListView/ListView_Rendering.cs  |   53 +++++++++----
 Hyena.Gui/Hyena.Gui.Theming/GtkTheme.cs            |   86 --------------------
 Hyena.Gui/Hyena.Gui.Theming/Theme.cs               |    6 --
 3 files changed, 37 insertions(+), 108 deletions(-)
---
diff --git a/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Rendering.cs 
b/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Rendering.cs
index e15f813..218eb91 100644
--- a/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Rendering.cs
+++ b/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Rendering.cs
@@ -173,8 +173,6 @@ namespace Hyena.Data.Gui
             cr.Rectangle (clip.X, clip.Y, clip.Width, clip.Height);
             cr.Clip ();
 
-            Theme.DrawHeaderBackground (cr, header_rendering_alloc);
-
             Rectangle cell_area = new Rectangle ();
             cell_area.Y = header_rendering_alloc.Y;
             cell_area.Height = header_rendering_alloc.Height;
@@ -183,8 +181,6 @@ namespace Hyena.Data.Gui
             cell_context.Opaque = true;
             cell_context.TextAsForeground = true;
 
-            bool have_drawn_separator = false;
-
             for (int ci = 0; ci < column_cache.Length; ci++) {
                 if (pressed_column_is_dragging && pressed_column_index == ci) {
                     continue;
@@ -192,25 +188,54 @@ namespace Hyena.Data.Gui
 
                 cell_area.X = column_cache[ci].X1 + Theme.TotalBorderWidth + header_rendering_alloc.X - 
HadjustmentValue;
                 cell_area.Width = column_cache[ci].Width;
-                PaintHeaderCell (cr, cell_area, ci, false, ref have_drawn_separator);
+                PaintHeaderCell (cr, cell_area, ci, false);
             }
 
             if (pressed_column_is_dragging && pressed_column_index >= 0) {
                 cell_area.X = pressed_column_x_drag - HadjustmentValue;
                 cell_area.Width = column_cache[pressed_column_index].Width;
-                PaintHeaderCell (cr, cell_area, pressed_column_index, true, ref have_drawn_separator);
+                PaintHeaderCell (cr, cell_area, pressed_column_index, true);
             }
 
             cr.ResetClip ();
         }
 
-        private void PaintHeaderCell (Cairo.Context cr, Rectangle area, int ci, bool dragging, ref bool 
have_drawn_separator)
+        private void PaintHeaderCell (Cairo.Context cr, Rectangle area, int ci, bool dragging)
         {
             if (ci < 0 || column_cache.Length <= ci)
                 return;
 
+            var column_flags = new RegionFlags ();
+            if (ci == sort_column_index) {
+                column_flags |= RegionFlags.Sorted;
+            }
+            if (ci == 0) {
+                column_flags |= RegionFlags.First;
+            }
+            if (ci == (column_cache.Length - 1)) {
+                column_flags |= RegionFlags.Last;
+            }
+            // First column should be odd, but ci starts at 0
+            if ((ci + 1) % 2 == 0) {
+                column_flags |= RegionFlags.Even;
+            } else {
+                column_flags |= RegionFlags.Odd;
+            }
+
+            cell_context.Widget.StyleContext.Save ();
+            // RegionFlags.Last is not applied, see https://bugzilla.gnome.org/show_bug.cgi?id=731463
+            cell_context.Widget.StyleContext.AddRegion ("column-header", column_flags);
+            cell_context.Widget.StyleContext.AddClass ("button");
+            cell_context.Widget.StyleContext.RenderBackground (cr, area.X, area.Y, area.Width, area.Height);
+            cell_context.Widget.StyleContext.RenderFrame (cr, area.X, area.Y, area.Width, area.Height);
+
             if (ci == ActiveColumn && HasFocus && HeaderFocused) {
-                Theme.DrawColumnHeaderFocus (cr, area);
+                var border = cell_context.Widget.StyleContext.GetBorder (StyleContext.State);
+                var f_x = area.X + border.Left;
+                var f_y = area.Y + border.Top;
+                var f_width = area.Width - border.Left - border.Right;
+                var f_height = area.Height - border.Top - border.Bottom;
+                cell_context.Widget.StyleContext.RenderFocus (cr, f_x, f_y, f_width, f_height);
             }
 
             if (dragging) {
@@ -219,10 +244,10 @@ namespace Hyena.Data.Gui
 
                 Theme.DrawColumnHighlight (cr, area, dark_color);
 
-                StyleContext.Save ();
-                StyleContext.AddClass ("entry");
+                cell_context.Widget.StyleContext.Save ();
+                cell_context.Widget.StyleContext.AddClass ("entry");
                 Cairo.Color base_color = CairoExtensions.GdkRGBAToCairoColor 
(StyleContext.GetBackgroundColor (StateFlags.Normal));
-                StyleContext.Restore ();
+                cell_context.Widget.StyleContext.Restore ();
 
                 Cairo.Color stroke_color = CairoExtensions.ColorShade (base_color, 0.0);
                 stroke_color.A = 0.3;
@@ -246,11 +271,7 @@ namespace Hyena.Data.Gui
                 cr.Restore ();
             }
 
-            if (!dragging && ci < column_cache.Length - 1 && (have_drawn_separator ||
-                column_cache[ci].MaxWidth != column_cache[ci].MinWidth)) {
-                have_drawn_separator = true;
-                Theme.DrawHeaderSeparator (cr, area, area.Right);
-            }
+            cell_context.Widget.StyleContext.Restore ();
         }
 
 #endregion
diff --git a/Hyena.Gui/Hyena.Gui.Theming/GtkTheme.cs b/Hyena.Gui/Hyena.Gui.Theming/GtkTheme.cs
index 760e759..2dd5938 100644
--- a/Hyena.Gui/Hyena.Gui.Theming/GtkTheme.cs
+++ b/Hyena.Gui/Hyena.Gui.Theming/GtkTheme.cs
@@ -184,92 +184,6 @@ namespace Hyena.Gui.Theming
             }
         }
 
-        public override void DrawHeaderBackground (Cairo.Context cr, Gdk.Rectangle alloc)
-        {
-            Cairo.Color gtk_background_color =
-                CairoExtensions.GdkRGBAToCairoColor (Widget.StyleContext.GetBackgroundColor 
(StateFlags.Normal));
-            Cairo.Color light_color = CairoExtensions.ColorShade (gtk_background_color, 1.1);
-            Cairo.Color dark_color = CairoExtensions.ColorShade (gtk_background_color, 0.95);
-
-            CairoCorners corners = CairoCorners.TopLeft | CairoCorners.TopRight;
-
-            using (var grad = new LinearGradient (alloc.X, alloc.Y, alloc.X, alloc.Bottom)) {
-                grad.AddColorStop (0, light_color);
-                grad.AddColorStop (0.75, dark_color);
-                grad.AddColorStop (0, light_color);
-
-                cr.SetSource (grad);
-                CairoExtensions.RoundedRectangle (cr, alloc.X, alloc.Y, alloc.Width, alloc.Height, 
Context.Radius, corners);
-                cr.Fill ();
-
-                cr.SetSourceColor (border_color);
-                cr.Rectangle (alloc.X, alloc.Bottom, alloc.Width, BorderWidth);
-                cr.Fill ();
-            }
-        }
-
-        public override void DrawColumnHeaderFocus (Cairo.Context cr, Gdk.Rectangle alloc)
-        {
-            double top_offset = 2.0;
-            double right_offset = 2.0;
-
-            double margin = 0.5;
-            double line_width = 0.7;
-
-            Cairo.Color stroke_color = CairoExtensions.ColorShade (
-                CairoExtensions.GdkRGBAToCairoColor (
-                    Widget.StyleContext.GetBackgroundColor (StateFlags.Selected)), 0.8);
-
-            stroke_color.A = 0.1;
-            cr.SetSourceColor (stroke_color);
-
-            CairoExtensions.RoundedRectangle (cr,
-                alloc.X + margin + line_width + right_offset,
-                alloc.Y + margin + line_width + top_offset,
-                alloc.Width - (margin + line_width)*2.0 - right_offset,
-                alloc.Height - (margin + line_width)*2.0 - top_offset,
-                Context.Radius/2.0, CairoCorners.None);
-
-            cr.Fill ();
-
-            stroke_color.A = 1.0;
-            cr.LineWidth = line_width;
-            cr.SetSourceColor (stroke_color);
-            CairoExtensions.RoundedRectangle (cr,
-                alloc.X + margin + line_width + right_offset,
-                alloc.Y + margin + line_width + top_offset,
-                alloc.Width - (line_width + margin)*2.0 - right_offset,
-                alloc.Height - (line_width + margin)*2.0 - right_offset,
-                Context.Radius/2.0, CairoCorners.All);
-            cr.Stroke ();
-        }
-
-        public override void DrawHeaderSeparator (Cairo.Context cr, Gdk.Rectangle alloc, int x)
-        {
-            Cairo.Color gtk_background_color = CairoExtensions.GdkRGBAToCairoColor (
-                Widget.StyleContext.GetBackgroundColor (StateFlags.Normal));
-            Cairo.Color dark_color = CairoExtensions.ColorShade (gtk_background_color, 0.80);
-            Cairo.Color light_color = CairoExtensions.ColorShade (gtk_background_color, 1.1);
-
-            int y_1 = alloc.Top + 4;
-            int y_2 = alloc.Bottom - 3;
-
-            cr.LineWidth = 1;
-            cr.Antialias = Cairo.Antialias.None;
-
-            cr.SetSourceColor (dark_color);
-            cr.MoveTo (x, y_1);
-            cr.LineTo (x, y_2);
-            cr.Stroke ();
-
-            cr.SetSourceColor (light_color);
-            cr.MoveTo (x + 1, y_1);
-            cr.LineTo (x + 1, y_2);
-            cr.Stroke ();
-
-            cr.Antialias = Cairo.Antialias.Default;
-        }
-
         public override void DrawListBackground (Context cr, Gdk.Rectangle alloc, Color color)
         {
             color.A = Context.FillAlpha;
diff --git a/Hyena.Gui/Hyena.Gui.Theming/Theme.cs b/Hyena.Gui/Hyena.Gui.Theming/Theme.cs
index f9adfd6..7848d96 100644
--- a/Hyena.Gui/Hyena.Gui.Theming/Theme.cs
+++ b/Hyena.Gui/Hyena.Gui.Theming/Theme.cs
@@ -134,12 +134,6 @@ namespace Hyena.Gui.Theming
 
         public abstract void DrawFrameBorder (Cairo.Context cr, Gdk.Rectangle alloc);
 
-        public abstract void DrawHeaderBackground (Cairo.Context cr, Gdk.Rectangle alloc);
-
-        public abstract void DrawColumnHeaderFocus (Cairo.Context cr, Gdk.Rectangle alloc);
-
-        public abstract void DrawHeaderSeparator (Cairo.Context cr, Gdk.Rectangle alloc, int x);
-
         public void DrawListBackground (Cairo.Context cr, Gdk.Rectangle alloc, bool baseColor)
         {
             Cairo.Color fill_color;


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