private void PaintList(Cairo.Context cr, Rectangle clip) { if (ChildSize.Height <= 0) { return; } // TODO factor this out? // Render the sort effect to the GdkWindow. if (sort_column_index != -1 && (!pressed_column_is_dragging || pressed_column_index != sort_column_index)) { CachedColumn col = column_cache[sort_column_index]; StyleContext.AddRegion("column", RegionFlags.Sorted); StyleContext.RenderBackground(cr, list_rendering_alloc.X + col.X1 - HadjustmentValue, header_rendering_alloc.Bottom + Theme.BorderWidth, col.Width, list_rendering_alloc.Height + Theme.InnerBorderWidth * 2); StyleContext.RemoveRegion("column"); } clip.Intersect(list_rendering_alloc); cr.Rectangle(clip.X, clip.Y, clip.Width, clip.Height); cr.Clip(); cell_context.Clip = clip; cell_context.TextAsForeground = false; int vadjustment_value = VadjustmentValue; int first_row = vadjustment_value / ChildSize.Height; int last_row = Math.Min(model.Count, first_row + RowsInView); int offset = list_rendering_alloc.Y - vadjustment_value % ChildSize.Height; Rectangle selected_focus_alloc = Rectangle.Zero; Rectangle single_list_alloc = new Rectangle(); single_list_alloc.X = list_rendering_alloc.X - HadjustmentValue; single_list_alloc.Y = offset; single_list_alloc.Width = list_rendering_alloc.Width + HadjustmentValue; single_list_alloc.Height = ChildSize.Height; int selection_height = 0; int selection_y = 0; selected_rows.Clear(); for (int ri = first_row; ri < last_row; ri++) { if (Selection != null && Selection.Contains(ri)) { if (selection_height == 0) { selection_y = single_list_alloc.Y; } selection_height += single_list_alloc.Height; selected_rows.Add(ri); if (Selection.FocusedIndex == ri) { selected_focus_alloc = single_list_alloc; } } else { StyleContext.AddClass("cell"); if (rules_hint) // TODO: check also gtk_widget_style_get(widget,"allow-rules",&allow_rules,NULL); { StyleContext.AddRegion("row", ri % 2 != 0 ? RegionFlags.Odd : RegionFlags.Even); } StyleContext.RenderBackground(cr, single_list_alloc.X, single_list_alloc.Y, single_list_alloc.Width, single_list_alloc.Height); StyleContext.RemoveRegion("row"); StyleContext.RemoveClass("cell"); PaintReorderLine(cr, ri, single_list_alloc); if (Selection != null && Selection.FocusedIndex == ri && !Selection.Contains(ri) && HasFocus) { CairoCorners corners = CairoCorners.All; if (Selection.Contains(ri - 1)) { corners &= ~(CairoCorners.TopLeft | CairoCorners.TopRight); } if (Selection.Contains(ri + 1)) { corners &= ~(CairoCorners.BottomLeft | CairoCorners.BottomRight); } if (HasFocus && !HeaderFocused) // Cursor out of selection. { Theme.DrawRowCursor(cr, single_list_alloc.X, single_list_alloc.Y, single_list_alloc.Width, single_list_alloc.Height, CairoExtensions.ColorShade(CairoExtensions.GdkRGBAToCairoColor(StyleContext.GetBackgroundColor(StateFlags.Selected)), 0.85)); } } if (selection_height > 0) { StyleContext.AddClass("cell"); var bg_selected_color = StyleContext.GetBackgroundColor(StateFlags.Selected); if (bg_selected_color.Equals(StyleContext.GetBackgroundColor(StateFlags.Normal))) { // see https://bugs.launchpad.net/bugs/1211831 Hyena.Log.Warning("Buggy CSS theme: same background-color for .cell:selected and .cell"); StyleContext.RemoveClass("cell"); bg_selected_color = StyleContext.GetBackgroundColor(StateFlags.Selected); StyleContext.AddClass("cell"); } Cairo.Color selection_color = CairoExtensions.GdkRGBAToCairoColor(bg_selected_color); if (!HasFocus || HeaderFocused) { selection_color = CairoExtensions.ColorShade(selection_color, 1.1); } Theme.DrawRowSelection(cr, list_rendering_alloc.X, selection_y, list_rendering_alloc.Width, selection_height, true, true, selection_color, CairoCorners.All); StyleContext.RemoveClass("cell"); selection_height = 0; } PaintRow(cr, ri, single_list_alloc, StateFlags.Normal); } single_list_alloc.Y += single_list_alloc.Height; } // In case the user is dragging to the end of the list PaintReorderLine(cr, last_row, single_list_alloc); if (selection_height > 0) { Theme.DrawRowSelection(cr, list_rendering_alloc.X, selection_y, list_rendering_alloc.Width, selection_height); } if (Selection != null && Selection.Count > 1 && !selected_focus_alloc.Equals(Rectangle.Zero) && HasFocus && !HeaderFocused) // Cursor inside selection. // Use entry to get text color { StyleContext.Save(); StyleContext.AddClass("entry"); Cairo.Color text_color = CairoExtensions.GdkRGBAToCairoColor(StyleContext.GetColor(StateFlags.Selected)); StyleContext.Restore(); Theme.DrawRowCursor(cr, selected_focus_alloc.X, selected_focus_alloc.Y, selected_focus_alloc.Width, selected_focus_alloc.Height, text_color); } foreach (int ri in selected_rows) { single_list_alloc.Y = offset + ((ri - first_row) * single_list_alloc.Height); PaintRow(cr, ri, single_list_alloc, StateFlags.Selected); } cr.ResetClip(); }
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; } StyleContext.Save(); // RegionFlags.Last is not applied, see https://bugzilla.gnome.org/show_bug.cgi?id=731463 StyleContext.AddRegion("column-header", column_flags); StyleContext.AddClass("button"); if (dragging) { // This is not applied in Adwaita, see https://bugzilla.gnome.org/show_bug.cgi?id=731663 StyleContext.AddClass("dnd"); } StyleContext.RenderBackground(cr, area.X, area.Y, area.Width, area.Height); StyleContext.RenderFrame(cr, area.X, area.Y, area.Width, area.Height); if (ci == ActiveColumn && HasFocus && HeaderFocused) { var border = 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; StyleContext.RenderFocus(cr, f_x, f_y, f_width, f_height); } ColumnCell cell = column_cache[ci].Column.HeaderCell; if (cell != null) { cr.Save(); cr.Translate(area.X, area.Y); cell_context.Area = area; cell_context.Selected = false; cell.Render(cell_context, area.Width, area.Height); cr.Restore(); } StyleContext.Restore(); }