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")); }
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(); }
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(); }
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(); }
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); }
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); }
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(); } }
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); }
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(); }
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; }
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(); }
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; }
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; } }
protected int GetColumnWidth(int column_index) { CachedColumn cached_column = column_cache[column_index]; return(cached_column.Width); }
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(); } }
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(); }
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(); }
static CachedColumn() { Zero = new CachedColumn(); Zero.Index = -1; }
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)); } }
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 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(); }
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(); }