コード例 #1
0
 public void ValueIsFormatted()
 {
     var format = new ColumnFormat("Num", Simple.NumberProp.PropertyType);
     format.SetActualWidth(5);
     var col = new CachedColumn(Simple.NumberProp, 50);
     Assert.That(col.Format(format), Is.EqualTo("50"));
 }
コード例 #2
0
        private void PaintDraggingColumn(Cairo.Context cr)
        {
            if (!pressed_column_is_dragging || pressed_column_index < 0)
            {
                return;
            }

            CachedColumn column = column_cache[pressed_column_index];

            int x = pressed_column_x_drag + 1 - HadjustmentValue;

            StyleContext.Save();
            StyleContext.AddClass("entry");
            Cairo.Color fill_color = CairoExtensions.GdkRGBAToCairoColor(StyleContext.GetBackgroundColor(StateFlags.Normal));

            Cairo.Color stroke_color = CairoExtensions.ColorShade(fill_color, 0.0);
            fill_color.A   = 0.45;
            stroke_color.A = 0.3;
            StyleContext.Restore();

            cr.Rectangle(x, header_rendering_alloc.Bottom + 1, column.Width - 2,
                         list_rendering_alloc.Bottom - header_rendering_alloc.Bottom - 1);
            cr.Color = fill_color;
            cr.Fill();

            cr.MoveTo(x - 0.5, header_rendering_alloc.Bottom + 0.5);
            cr.LineTo(x - 0.5, list_rendering_alloc.Bottom + 0.5);
            cr.LineTo(x + column.Width - 1.5, list_rendering_alloc.Bottom + 0.5);
            cr.LineTo(x + column.Width - 1.5, header_rendering_alloc.Bottom + 0.5);

            cr.Color     = stroke_color;
            cr.LineWidth = 1.0;
            cr.Stroke();
        }
コード例 #3
0
        private void PaintDraggingColumn(Rectangle clip)
        {
            if (!pressed_column_is_dragging || pressed_column_index < 0)
            {
                return;
            }

            CachedColumn column = column_cache [pressed_column_index];

            int x = pressed_column_x_drag + Allocation.X + 1 - (int)hadjustment.Value;

            Cairo.Color fill_color = Theme.Colors.GetWidgetColor(GtkColorClass.Base, StateType.Normal);
            fill_color.A = 0.45;

            Cairo.Color stroke_color = Theme.Colors.GetWidgetColor(
                GtkColorClass.Base, StateType.Normal).ColorShade(0.0);
            stroke_color.A = 0.3;

            cairo_context.Rectangle(x, header_rendering_alloc.Bottom + 1, column.Width - 2,
                                    list_rendering_alloc.Bottom - header_rendering_alloc.Bottom - 1);
            cairo_context.Color = fill_color;
            cairo_context.Fill();

            cairo_context.MoveTo(x - 0.5, header_rendering_alloc.Bottom + 0.5);
            cairo_context.LineTo(x - 0.5, list_rendering_alloc.Bottom + 0.5);
            cairo_context.LineTo(x + column.Width - 1.5, list_rendering_alloc.Bottom + 0.5);
            cairo_context.LineTo(x + column.Width - 1.5, header_rendering_alloc.Bottom + 0.5);

            cairo_context.Color     = stroke_color;
            cairo_context.LineWidth = 1.0;
            cairo_context.Stroke();
        }
コード例 #4
0
        private void GenerateColumnCache()
        {
            column_cache = new CachedColumn[column_controller.Count];

            int    i     = 0;
            double total = 0.0;

            foreach (Column column in column_controller)
            {
                if (!column.Visible)
                {
                    continue;
                }

                // If we don't already have a MinWidth set, use the width of our Title text
                column.CalculateWidths(column_layout, HeaderVisible, HeaderHeight);
                column_cache[i]        = new CachedColumn();
                column_cache[i].Column = column;
                column_cache[i].Index  = i;

                total += column.Width;
                i++;
            }

            Array.Resize(ref column_cache, i);

            double scale_factor = 1.0 / total;

            for (i = 0; i < column_cache.Length; i++)
            {
                column_cache[i].Column.Width *= scale_factor;
            }

            RecalculateColumnSizes();
        }
コード例 #5
0
        void RenderDarkBackgroundInSortedColumn()
        {
            if (pressed_column_is_dragging && pressed_column_index == sort_column_index)
            {
                return;
            }

            CachedColumn col = column_cache [sort_column_index];

            Theme.DrawRowRule(cairo_context,
                              list_rendering_alloc.X + col.X1 - HadjustmentValue,
                              header_rendering_alloc.Bottom + Theme.BorderWidth,
                              col.Width,
                              list_rendering_alloc.Height + Theme.InnerBorderWidth * 2);
        }
コード例 #6
0
        private bool OnMotionNotifyEvent(int x)
        {
            if (!pressed_column_is_dragging)
            {
                return(false);
            }

            OnDragScroll(OnDragHScrollTimeout, header_interaction_alloc.Width * 0.1, header_interaction_alloc.Width, x);

            GdkWindow.Cursor = drag_cursor;

            Column swap_column = GetColumnAt(x);

            if (swap_column != null)
            {
                CachedColumn swap_column_c = GetCachedColumnForColumn(swap_column);
                bool         reorder       = false;

                if (swap_column_c.Index < pressed_column_index)
                {
                    // Moving from right to left
                    reorder = pressed_column_x_drag <= swap_column_c.X1 + swap_column_c.Width / 2;
                }
                else if (swap_column_c.Index > pressed_column_index)
                {
                    if (column_cache.Length > pressed_column_index && pressed_column_index >= 0)
                    {
                        // Moving from left to right
                        reorder = pressed_column_x_drag + column_cache[pressed_column_index].Width >=
                                  swap_column_c.X1 + swap_column_c.Width / 2;
                    }
                }

                if (reorder)
                {
                    int actual_pressed_index = ColumnController.IndexOf(column_cache[pressed_column_index].Column);
                    int actual_swap_index    = ColumnController.IndexOf(swap_column_c.Column);
                    ColumnController.Reorder(actual_pressed_index, actual_swap_index);
                    pressed_column_index = swap_column_c.Index;
                    RegenerateColumnCache();
                }
            }

            pressed_column_x_drag = x - pressed_column_x_offset - (pressed_column_x_start_hadjustment - HadjustmentValue);

            QueueDraw();
            return(true);
        }
コード例 #7
0
        private void OnQueryTooltip(object o, Gtk.QueryTooltipArgs args)
        {
            if (cell_context != null && cell_context.Layout != null && !args.KeyboardTooltip)
            {
                ITooltipCell cell;
                Column       column;
                int          row_index;

                if (GetEventCell <ITooltipCell> (args.X, args.Y, out cell, out column, out row_index))
                {
                    CachedColumn cached_column = GetCachedColumnForColumn(column);

                    string markup = cell.GetTooltipMarkup(cell_context, cached_column.Width);
                    if (!String.IsNullOrEmpty(markup))
                    {
                        Gdk.Rectangle rect = new Gdk.Rectangle();
                        rect.X = list_interaction_alloc.X + cached_column.X1;

                        // get the y of the event in list coords
                        rect.Y = args.Y - list_interaction_alloc.Y;

                        // get the top of the cell pointed to by list_y
                        rect.Y -= VadjustmentValue % RowHeight;
                        rect.Y -= rect.Y % RowHeight;

                        // convert back to widget coords
                        rect.Y += list_interaction_alloc.Y;

                        // TODO is this right even if the list is wide enough to scroll horizontally?
                        rect.Width = cached_column.Width;

                        // TODO not right - could be smaller if at the top/bottom and only partially showing
                        rect.Height = RowHeight;

                        args.Tooltip.Markup  = markup;
                        args.Tooltip.TipArea = rect;
                        args.RetVal          = true;
                    }
                }
            }

            // Work around ref counting SIGSEGV, see http://bugzilla.gnome.org/show_bug.cgi?id=478519#c9
            if (args.Tooltip != null)
            {
                args.Tooltip.Dispose();
            }
        }
コード例 #8
0
        private bool OnHeaderButtonPressEvent(Gdk.EventButton evnt)
        {
            int x = (int)evnt.X - header_interaction_alloc.X;
            int y = (int)evnt.Y - header_interaction_alloc.Y;

            if (evnt.Button == 3 && ColumnController.EnableColumnMenu)
            {
                Column menu_column = GetColumnAt(x);
                if (menu_column != null)
                {
                    OnColumnRightClicked(menu_column, x + Allocation.X, y + Allocation.Y);
                }
                return(true);
            }
            else if (evnt.Button != 1)
            {
                return(true);
            }

            Gtk.Drag.SourceUnset(this);

            Column column = GetColumnForResizeHandle(x);

            if (column != null)
            {
                resizing_column_index = GetCachedColumnForColumn(column).Index;
            }
            else
            {
                column = GetColumnAt(x);
                if (column != null)
                {
                    CachedColumn column_c = GetCachedColumnForColumn(column);
                    pressed_column_index               = column_c.Index;
                    pressed_column_x_start             = x;
                    pressed_column_x_offset            = pressed_column_x_start - column_c.X1;
                    pressed_column_x_start_hadjustment = HadjustmentValue;
                }
            }

            return(true);
        }
コード例 #9
0
        private void GenerateColumnCache()
        {
            column_cache = new CachedColumn [column_controller.Count];

            int    i     = 0;
            double total = 0.0;

            // Calculate the total relative width and the minimal column widths
            foreach (Column column in column_controller)
            {
                int w;
                int h;
                column_layout.SetText(column.HeaderText);
                column_layout.GetPixelSize(out w, out h);

                column_cache [i]        = new CachedColumn();
                column_cache [i].Column = column;
                column_cache [i].Index  = i;
                column.MinWidth         = Math.Max(column.MinWidth, w);

                if (column.Visible)
                {
                    total += column.Width;
                }
                i++;
            }

            // Normalize the relative column widths
            double scale_factor = 1.0 / total;

            for (i = 0; i < column_cache.Length; i++)
            {
                if (!column_cache [i].Column.Visible)
                {
                    continue;
                }

                column_cache [i].Column.Width *= scale_factor;
            }

            AutoCalculateColumnSizes();
        }
コード例 #10
0
        public void GetCellAtPoint(int x, int y, Atk.CoordType coord_type, out int row, out int col)
        {
            int origin_x = 0;
            int origin_y = 0;

            if (coord_type == Atk.CoordType.Screen)
            {
                GdkWindow.GetPosition(out origin_x, out origin_y);
            }

            x = x - ListAllocation.X - origin_x;
            y = y - ListAllocation.Y - origin_y;

            Column column = GetColumnAt(x);

            CachedColumn cached_column = GetCachedColumnForColumn(column);

            row = GetModelRowAt(x, y);
            col = cached_column.Index;
        }
コード例 #11
0
        void GenerateColumnCache()
        {
            column_cache = new CachedColumn[column_controller.Count];

            int    i     = 0;
            double total = 0.0;

            foreach (var column in column_controller)
            {
                if (!column.Visible)
                {
                    continue;
                }

                // If we don't already have a MinWidth set, use the width of our Title text
                column.CalculateWidths(column_layout, HeaderVisible, HeaderHeight);
                column_cache[i] = new CachedColumn {
                    Column = column,
                    Index  = i
                };

                total += column.Width;
                i++;
            }

            Array.Resize(ref column_cache, i);

            double scale_factor = 1.0 / total;

            for (i = 0; i < column_cache.Length; i++)
            {
                column_cache[i].Column.Width *= scale_factor;
                if (column_cache[i].Column.Width <= 0)
                {
                    Hyena.Log.Warning("Overriding 0-computed column cache width");
                    column_cache[i].Column.Width = 0.01;
                }
            }

            RecalculateColumnSizes();
        }
コード例 #12
0
        private void UpdateColumnCache()
        {
            if (column_controller == null)
            {
                return;
            }

            if (column_cache == null)
            {
                GenerateColumnCache();
            }

            CachedColumn lastColumn = CachedColumn.Zero;

            for (int i = 0; i < column_cache.Length; i++)
            {
                if (!column_cache [i].Column.Visible)
                {
                    continue;
                }

                column_cache [i].Width    = (int)Math.Round(header_width * column_cache [i].Column.Width, MidpointRounding.AwayFromZero);
                column_cache [i].X1       = lastColumn.X2;
                column_cache [i].X2       = column_cache [i].X1 + column_cache [i].Width;
                column_cache [i].ResizeX1 = column_cache [i].X2;
                column_cache [i].ResizeX2 = column_cache [i].ResizeX1 + 2;

                lastColumn = column_cache [i];
            }

            // TODO handle max width
            if (lastColumn.Index < 0)
            {
                return;
            }

            column_cache [lastColumn.Index].X2    = header_width;
            column_cache [lastColumn.Index].Width = lastColumn.X2 - lastColumn.X1;
        }
コード例 #13
0
        public void AllignToH(int col_index)
        {
            if (column_cache == null || col_index >= column_cache.Length)
            {
                return;
            }

            CachedColumn column = column_cache [col_index];

            autoAligning = true;
            try {
                if (column.X1 < hadjustment.Value)
                {
                    ScrollToH((double)column.X1);
                }
                else if ((column.X1 + column.Width) > (hadjustment.Value + hadjustment.PageSize))
                {
                    ScrollToH(column.X1 + column.Width - hadjustment.PageSize);
                }
            } finally {
                autoAligning = false;
            }
        }
コード例 #14
0
        protected int GetColumnWidth(int column_index)
        {
            CachedColumn cached_column = column_cache[column_index];

            return(cached_column.Width);
        }
コード例 #15
0
        private void OnQueryTooltip(object o, Gtk.QueryTooltipArgs args)
        {
            if (!args.KeyboardTooltip)
            {
                if (ViewLayout != null)
                {
                    var pt    = new Point(args.X - list_interaction_alloc.X, args.Y - list_interaction_alloc.Y);
                    var child = ViewLayout.FindChildAtPoint(pt);
                    if (child != null)
                    {
                        string markup;
                        Rect   area;
                        pt.Offset(ViewLayout.ActualAllocation.Point);
                        if (child.GetTooltipMarkupAt(pt, out markup, out area))
                        {
                            area.Offset(-ViewLayout.ActualAllocation.X, -ViewLayout.ActualAllocation.Y);
                            area.Offset(list_interaction_alloc.X, list_interaction_alloc.Y);
                            args.Tooltip.Markup  = markup;
                            args.Tooltip.TipArea = (Gdk.Rectangle)area;

                            /*if (!area.Contains (args.X, args.Y)) {
                             *  Log.WarningFormat ("Tooltip rect {0} does not contain tooltip point {1},{2} -- this will cause excessive requerying", area, args.X, args.Y);
                             * }*/
                            args.RetVal = true;
                        }
                    }
                }
                else if (cell_context != null && cell_context.Layout != null)
                {
                    ITooltipCell cell;
                    Column       column;
                    int          row_index;

                    if (GetEventCell <ITooltipCell> (args.X, args.Y, out cell, out column, out row_index))
                    {
                        CachedColumn cached_column = GetCachedColumnForColumn(column);

                        string markup = cell.GetTooltipMarkup(cell_context, cached_column.Width);
                        if (!String.IsNullOrEmpty(markup))
                        {
                            Gdk.Rectangle rect = new Gdk.Rectangle();
                            rect.X = list_interaction_alloc.X + cached_column.X1;

                            // get the y of the event in list coords
                            rect.Y = args.Y - list_interaction_alloc.Y;

                            // get the top of the cell pointed to by list_y
                            rect.Y -= VadjustmentValue % ChildSize.Height;
                            rect.Y -= rect.Y % ChildSize.Height;

                            // convert back to widget coords
                            rect.Y += list_interaction_alloc.Y;

                            // TODO is this right even if the list is wide enough to scroll horizontally?
                            rect.Width = cached_column.Width;

                            // TODO not right - could be smaller if at the top/bottom and only partially showing
                            rect.Height = ChildSize.Height;

                            /*if (!rect.Contains (args.X, args.Y)) {
                             *  Log.WarningFormat ("ListView tooltip rect {0} does not contain tooltip point {1},{2} -- this will cause excessive requerying", rect, args.X, args.Y);
                             * }*/

                            args.Tooltip.Markup  = markup;
                            args.Tooltip.TipArea = rect;
                            args.RetVal          = true;
                        }
                    }
                }
            }

            // Work around ref counting SIGSEGV, see http://bugzilla.gnome.org/show_bug.cgi?id=478519#c9
            if (args.Tooltip != null)
            {
                args.Tooltip.Dispose();
            }
        }
コード例 #16
0
        private void ResizeColumn(double x)
        {
            CachedColumn resizingColumn = column_cache [resizing_column_index];
            double       resizeDelta    = x - resizingColumn.ResizeX2;

            resizeDelta = Math.Max(resizeDelta, resizingColumn.Column.MinWidth - resizingColumn.Width);
            resizeDelta = Math.Min(resizeDelta, resizingColumn.Column.MaxWidth - resizingColumn.Width);

            if (resizeDelta == 0)
            {
                return;
            }

            int sign = Math.Sign(resizeDelta);

            resizeDelta = Math.Abs(resizeDelta);
            double total_elastic_width = 0.0;

            for (int i = resizing_column_index + 1; i < column_cache.Length; i++)
            {
                column_cache [i].CalculatedWidth = sign == 1
                    ? column_cache [i].Width - column_cache [i].Column.MinWidth
                    : column_cache [i].Column.MaxWidth - column_cache [i].Width;

                total_elastic_width += column_cache [i].CalculatedWidth;
            }

            if (total_elastic_width != 0 && sign == -1 && header_width > header_interaction_alloc.Width)
            {
                total_elastic_width = 0;
            }

            if (total_elastic_width > 0)
            {
                double resizeFactor = Math.Min(resizeDelta, total_elastic_width);
                resizeFactor = sign * resizeFactor / header_width;

                for (int i = resizing_column_index + 1; i < column_cache.Length; i++)
                {
                    column_cache [i].Column.Width += -resizeFactor * column_cache [i].CalculatedWidth / total_elastic_width;
                }
            }

            resizingColumn.Column.Width += sign * resizeDelta / header_width;

            System.Diagnostics.Debug.Write("Columns: ");
            double total_width = 0;

            for (int i = 0; i < column_cache.Length; i++)
            {
                if (!column_cache [i].Column.Visible)
                {
                    continue;
                }

                double col_width = column_cache [i].Column.Width * header_width;
                // Do a range check on the column size
                col_width = Math.Max(col_width, column_cache [i].Column.MinWidth);
                col_width = Math.Min(col_width, column_cache [i].Column.MaxWidth);
                // Save the possible modifications back
                column_cache [i].Column.Width = col_width / header_width;

                System.Diagnostics.Debug.Write(((int)col_width).ToString().PadLeft(3, ' '));
                System.Diagnostics.Debug.Write(", ");
                total_width += col_width;
            }
            System.Diagnostics.Debug.WriteLine("Total: " + total_width);

            if (header_width != (int)total_width)
            {
                double scale_factor = header_width / total_width;
                for (int i = 0; i < column_cache.Length; i++)
                {
                    if (!column_cache [i].Column.Visible)
                    {
                        continue;
                    }

                    column_cache [i].Column.Width *= scale_factor;
                }
                header_width = (int)total_width;
            }

            UpdateColumnCache();
            UpdateAdjustments(null, null);
            QueueDraw();
        }
コード例 #17
0
        private void ResizeColumn(double x)
        {
            CachedColumn resizing_column = column_cache[resizing_column_index];
            double       resize_delta    = x - resizing_column.ResizeX2;

            // If this column cannot be resized, check the columns to the left.
            int real_resizing_column_index = resizing_column_index;

            while (resizing_column.MinWidth == resizing_column.MaxWidth)
            {
                if (real_resizing_column_index == 0)
                {
                    return;
                }
                resizing_column = column_cache[--real_resizing_column_index];
            }

            // Make sure the resize_delta won't make us smaller than the min
            if (resizing_column.Width + resize_delta < resizing_column.MinWidth)
            {
                resize_delta = resizing_column.MinWidth - resizing_column.Width;
            }

            // Make sure the resize_delta won't make us bigger than the max
            if (resizing_column.Width + resize_delta > resizing_column.MaxWidth)
            {
                resize_delta = resizing_column.MaxWidth - resizing_column.Width;
            }

            if (resize_delta == 0)
            {
                return;
            }

            int sign = Math.Sign(resize_delta);

            resize_delta = Math.Abs(resize_delta);
            double total_elastic_width = 0.0;

            for (int i = real_resizing_column_index + 1; i < column_cache.Length; i++)
            {
                total_elastic_width += column_cache[i].ElasticWidth = sign == 1
                    ? column_cache[i].Width - column_cache[i].MinWidth
                    : column_cache[i].MaxWidth - column_cache[i].Width;
            }

            if (total_elastic_width == 0)
            {
                return;
            }

            if (resize_delta > total_elastic_width)
            {
                resize_delta = total_elastic_width;
            }

            // Convert to a proprotional width
            resize_delta = sign * resize_delta / (double)header_width;

            for (int i = real_resizing_column_index + 1; i < column_cache.Length; i++)
            {
                column_cache[i].Column.Width += -resize_delta * (column_cache[i].ElasticWidth / total_elastic_width);
            }

            resizing_column.Column.Width += resize_delta;

            RegenerateColumnCache();
            QueueDraw();
        }
コード例 #18
0
 static CachedColumn()
 {
     Zero       = new CachedColumn();
     Zero.Index = -1;
 }
コード例 #19
0
        private bool ProxyEventToCell(Gdk.Event evnt, bool press,
                                      out IInteractiveCell icell, out Gdk.Rectangle icell_area)
        {
            icell      = null;
            icell_area = Gdk.Rectangle.Zero;

            int evnt_x, evnt_y;
            int x, y, row_index;

            x = y = row_index = 0;

            var evnt_button = evnt as Gdk.EventButton;
            var evnt_motion = evnt as Gdk.EventMotion;

            if (evnt_motion != null)
            {
                evnt_x = (int)evnt_motion.X;
                evnt_y = (int)evnt_motion.Y;
            }
            else if (evnt_button != null)
            {
                evnt_x = (int)evnt_button.X;
                evnt_y = (int)evnt_button.Y;
            }
            else
            {
                // Possibly EventCrossing, for the leave event
                icell = last_icell;
                return(false);
            }

            Column column;

            if (!GetEventCell <IInteractiveCell> (evnt_x, evnt_y, out icell, out column, out row_index))
            {
                return(false);
            }

            x = evnt_x - list_interaction_alloc.X;
            y = evnt_y - list_interaction_alloc.Y;

            // Turn the view-absolute coordinates into cell-relative coordinates
            CachedColumn cached_column = GetCachedColumnForColumn(column);

            x -= cached_column.X1 - HadjustmentValue;
            int page_offset = VadjustmentValue % ChildSize.Height;

            y = (y + page_offset) % ChildSize.Height;

            var view_point = GetViewPointForModelRow(row_index);

            icell_area.Y      = (int)view_point.Y + list_interaction_alloc.Y + Allocation.Y;
            icell_area.X      = cached_column.X1 + list_rendering_alloc.X;
            icell_area.Width  = cached_column.Width;
            icell_area.Height = ChildSize.Height;

            // Send the cell a synthesized input event
            if (evnt_motion != null)
            {
                return(icell.CursorMotionEvent(new Hyena.Gui.Canvas.Point(x, y)));
            }
            else
            {
                return(icell.ButtonEvent(new Hyena.Gui.Canvas.Point(x, y), press, evnt_button.Button));
            }
        }
コード例 #20
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();
        }
コード例 #21
0
        private void PaintRows(Rectangle clip)
        {
            // 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];
                Theme.DrawRowRule(cairo_context,
                                  list_rendering_alloc.X + col.X1 - HadjustmentValue,
                                  header_rendering_alloc.Bottom + Theme.BorderWidth,
                                  col.Width, list_rendering_alloc.Height + Theme.InnerBorderWidth * 2);
            }

            clip.Intersect(list_rendering_alloc);
            cairo_context.Rectangle(clip.X, clip.Y, clip.Width, clip.Height);
            cairo_context.Clip();

            cell_context.Clip             = clip;
            cell_context.TextAsForeground = false;

            int vadjustment_value = VadjustmentValue;
            int first_row         = vadjustment_value / RowHeight;
            int last_row          = Math.Min(model.Count, first_row + RowsInView);
            int offset            = list_rendering_alloc.Y - vadjustment_value % RowHeight;

            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 = RowHeight;

            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
                {
                    if (rules_hint && ri % 2 != 0)
                    {
                        Theme.DrawRowRule(cairo_context, single_list_alloc.X, single_list_alloc.Y,
                                          single_list_alloc.Width, single_list_alloc.Height);
                    }

                    PaintReorderLine(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(cairo_context, single_list_alloc.X, single_list_alloc.Y,
                                                single_list_alloc.Width, single_list_alloc.Height,
                                                CairoExtensions.ColorShade(Theme.Colors.GetWidgetColor(GtkColorClass.Background, StateType.Selected), 0.85));
                        }
                    }

                    if (selection_height > 0)
                    {
                        Cairo.Color selection_color = Theme.Colors.GetWidgetColor(GtkColorClass.Background, StateType.Selected);
                        if (!HasFocus || HeaderFocused)
                        {
                            selection_color = CairoExtensions.ColorShade(selection_color, 1.1);
                        }

                        Theme.DrawRowSelection(cairo_context, list_rendering_alloc.X, selection_y, list_rendering_alloc.Width, selection_height,
                                               true, true, selection_color, CairoCorners.All);
                        selection_height = 0;
                    }

                    PaintRow(ri, single_list_alloc, StateType.Normal);
                }

                single_list_alloc.Y += single_list_alloc.Height;
            }

            // In case the user is dragging to the end of the list
            PaintReorderLine(last_row, single_list_alloc);

            if (selection_height > 0)
            {
                Theme.DrawRowSelection(cairo_context, 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.
            {
                Theme.DrawRowCursor(cairo_context, selected_focus_alloc.X, selected_focus_alloc.Y,
                                    selected_focus_alloc.Width, selected_focus_alloc.Height,
                                    Theme.Colors.GetWidgetColor(GtkColorClass.Text, StateType.Selected));
            }

            foreach (int ri in selected_rows)
            {
                single_list_alloc.Y = offset + ((ri - first_row) * single_list_alloc.Height);
                PaintRow(ri, single_list_alloc, StateType.Selected);
            }

            cairo_context.ResetClip();
        }
コード例 #22
0
        private void PaintRows(Rectangle clip)
        {
            sort_column_index = -1;
            for (int i = 0; i < column_cache.Length; i++)
            {
                if (!column_cache [i].Column.Visible)
                {
                    continue;
                }

                Column column = column_cache [i].Column;
                if (sortModel == null)
                {
                    continue;
                }

                CellTextHeader column_cell = column.HeaderCell as CellTextHeader;
                if (column_cell == null)
                {
                    continue;
                }

                if (column.IsSortable && sortModel.SortColumn == column)
                {
                    sort_column_index = i;
                }
            }

            if (sort_column_index != -1 && (!pressed_column_is_dragging || pressed_column_index != sort_column_index))
            {
                CachedColumn col = column_cache [sort_column_index];
                Theme.DrawRowRule(cairo_context,
                                  list_rendering_alloc.X + col.X1 - (int)hadjustment.Value,
                                  header_rendering_alloc.Bottom + Theme.BorderWidth,
                                  col.Width, list_rendering_alloc.Height + Theme.InnerBorderWidth * 2);
            }

            clip.Intersect(list_rendering_alloc);
            cairo_context.Rectangle(clip.X, clip.Y, clip.Width, clip.Height);
            cairo_context.Clip();

            cell_context.Clip             = clip;
            cell_context.TextAsForeground = false;

            int vadjustment_value = (int)vadjustment.Value;
            int first_row         = vadjustment_value / RowHeight;
            int last_row;

            try {
                last_row = Math.Min(model.Count, first_row + RowsInView);
            } catch (DbConnectionLostException) {
                last_row = first_row + RowsInView;
            }
            int offset = list_rendering_alloc.Y - vadjustment_value % RowHeight;

            Rectangle selected_focus_alloc = Rectangle.Zero;
            Rectangle single_list_alloc    = new Rectangle();

            single_list_alloc.X      = list_rendering_alloc.X - (int)(hadjustment.Value);
            single_list_alloc.Y      = offset;
            single_list_alloc.Width  = list_rendering_alloc.Width;
            single_list_alloc.Height = RowHeight;

            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.FocusedCell.Row == ri)
                    {
                        selected_focus_alloc = single_list_alloc;
                    }
                }
                else
                {
                    if (rules_hint && ri % 2 != 0)
                    {
                        Theme.DrawRowRule(cairo_context, list_rendering_alloc.X, single_list_alloc.Y,
                                          single_list_alloc.Width, single_list_alloc.Height);
                    }

                    if (ri == drag_reorder_row_index && Reorderable)
                    {
                        cairo_context.Save();
                        cairo_context.LineWidth = 1.0;
                        cairo_context.Antialias = Cairo.Antialias.None;
                        cairo_context.MoveTo(single_list_alloc.Left, single_list_alloc.Top);
                        cairo_context.LineTo(single_list_alloc.Right, single_list_alloc.Top);
                        cairo_context.Color = Theme.Colors.GetWidgetColor(GtkColorClass.Text, StateType.Normal);
                        cairo_context.Stroke();
                        cairo_context.Restore();
                    }

                    if (Selection != null && Selection.FocusedCell.Row == ri && !Selection.Contains(ri) && AllowSelect)
                    {
                        CairoCorners corners = CairoCorners.All;

                        if (Selection.Contains(ri - 1))
                        {
                            corners &= ~(CairoCorners.TopLeft | CairoCorners.TopRight);
                        }

                        if (Selection.Contains(ri + 1))
                        {
                            corners &= ~(CairoCorners.BottomLeft | CairoCorners.BottomRight);
                        }

                        Theme.DrawRowSelection(cairo_context, single_list_alloc.X, single_list_alloc.Y,
                                               single_list_alloc.Width, single_list_alloc.Height, false, true,
                                               Theme.Colors.GetWidgetColor(GtkColorClass.Background, StateType.Selected), corners);
                    }

                    if (selection_height > 0)
                    {
                        Theme.DrawRowSelection(cairo_context, list_rendering_alloc.X, selection_y, list_rendering_alloc.Width, selection_height);
                        selection_height = 0;
                    }

                    PaintRow(ri, single_list_alloc, StateType.Normal);
                }

                single_list_alloc.Y += single_list_alloc.Height;
            }

            if (selection_height > 0)
            {
                Theme.DrawRowSelection(cairo_context, 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)
            {
                Theme.DrawRowSelection(cairo_context, selected_focus_alloc.X, selected_focus_alloc.Y,
                                       selected_focus_alloc.Width, selected_focus_alloc.Height, false, true,
                                       Theme.Colors.GetWidgetColor(GtkColorClass.Dark, StateType.Selected));
            }

            foreach (int ri in selected_rows)
            {
                single_list_alloc.Y = offset + ((ri - first_row) * single_list_alloc.Height);
                PaintRow(ri, single_list_alloc, StateType.Selected);
            }

            cairo_context.ResetClip();
        }