Esempio n. 1
0
        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();
        }
Esempio n. 2
0
        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();
        }