From 274bf55b5239035f2b9e32c4e42b2561721534c5 Mon Sep 17 00:00:00 2001 From: Curtis Wensley Date: Wed, 21 Jun 2023 12:52:46 -0700 Subject: [PATCH] Mac: Fix setting Tree/GridView.BackgroundColor --- .../Forms/Controls/GridColumnHandler.cs | 9 +- src/Eto.Mac/Forms/Controls/GridHandler.cs | 94 +++++++++++++++++-- src/Eto.Mac/Forms/MacBase.cs | 23 +++-- 3 files changed, 110 insertions(+), 16 deletions(-) diff --git a/src/Eto.Mac/Forms/Controls/GridColumnHandler.cs b/src/Eto.Mac/Forms/Controls/GridColumnHandler.cs index c848af74a4..2dad15c79b 100644 --- a/src/Eto.Mac/Forms/Controls/GridColumnHandler.cs +++ b/src/Eto.Mac/Forms/Controls/GridColumnHandler.cs @@ -162,7 +162,14 @@ public nfloat GetPreferredWidth(NSRange? range = null) public string HeaderText { get { return Control.HeaderCell.StringValue; } - set { Control.HeaderCell.StringValue = value; } + set + { + if (value != HeaderText) + { + Control.HeaderCell.StringValue = value; + Control.TableView?.HeaderView?.SetNeedsDisplay(); + } + } } public bool Resizable diff --git a/src/Eto.Mac/Forms/Controls/GridHandler.cs b/src/Eto.Mac/Forms/Controls/GridHandler.cs index f446adbfb2..2708b1cf26 100644 --- a/src/Eto.Mac/Forms/Controls/GridHandler.cs +++ b/src/Eto.Mac/Forms/Controls/GridHandler.cs @@ -47,7 +47,7 @@ public EtoTableHeaderView() public EtoTableHeaderView(IntPtr handle) : base(handle) { } - + public override void MouseDown(NSEvent theEvent) { var h = Handler; @@ -75,6 +75,60 @@ public override void MouseDown(NSEvent theEvent) h.TriggerMouseDown(this, sel, theEvent); } } + + class EtoTableHeaderViewWithBackground : EtoTableHeaderView + { + public NSColor BackgroundColor { get; set; } + + public override void DrawRect(CGRect dirtyRect) + { + if (BackgroundColor == null) + { + base.DrawRect(dirtyRect); + return; + } + + // gotta draw header cells manually to get a custom background color without tinting... + var bounds = Bounds; + BackgroundColor.SetFill(); + NSBezierPath.FillRect(bounds); + + NSBezierPath path; + nfloat? position = null; + var dividerSize = ConvertSizeToBacking(new CGSize(1, 1)); + var spacing = TableView.IntercellSpacing.Width; + var columns = TableView.TableColumns(); + for (int i = 0; i < columns.Length; i++) + { + var cellFrame = GetHeaderRect(i); + var col = columns[i]; + var cell = col.HeaderCell; + if (col.Hidden || cell == null) + continue; + cell.DrawWithFrame(cellFrame, this); + if (position == null) + { + // draw separator up to first column + NSColor.Separator.Set(); + path = new NSBezierPath(); + path.MoveTo(new CGPoint(bounds.X, bounds.Bottom)); + path.LineTo(new CGPoint(cellFrame.X, bounds.Bottom)); + path.LineWidth = dividerSize.Height; + path.Stroke(); + path.Dispose(); + } + position = cellFrame.Right; + } + // draw separator from last column + NSColor.Separator.Set(); + path = new NSBezierPath(); + path.MoveTo(new CGPoint(position ?? bounds.X, bounds.Bottom)); + path.LineTo(new CGPoint(bounds.Right, bounds.Bottom)); + path.LineWidth = dividerSize.Height; + path.Stroke(); + path.Dispose(); + } + } class MacCellFormatArgs : GridCellFormatEventArgs { @@ -298,15 +352,15 @@ public override void AttachEvent(string id) // handled in delegates break; case Eto.Forms.Control.MouseDownEvent: - AddMethod(MacView.selMouseDown, MacView.TriggerMouseDown_Delegate, "v@:@", Control.HeaderView); - AddMethod(MacView.selRightMouseDown, MacView.TriggerMouseDown_Delegate, "v@:@", Control.HeaderView); - AddMethod(MacView.selOtherMouseDown, MacView.TriggerMouseDown_Delegate, "v@:@", Control.HeaderView); + AddMethod(MacView.selMouseDown, MacView.TriggerMouseDown_Delegate, "v@:@", typeof(EtoTableHeaderView)); + AddMethod(MacView.selRightMouseDown, MacView.TriggerMouseDown_Delegate, "v@:@", typeof(EtoTableHeaderView)); + AddMethod(MacView.selOtherMouseDown, MacView.TriggerMouseDown_Delegate, "v@:@", typeof(EtoTableHeaderView)); base.AttachEvent(id); break; case Eto.Forms.Control.MouseUpEvent: - AddMethod(MacView.selMouseUp, MacView.TriggerMouseUp_Delegate, "v@:@", Control.HeaderView); - AddMethod(MacView.selRightMouseUp, MacView.TriggerMouseUp_Delegate, "v@:@", Control.HeaderView); - AddMethod(MacView.selOtherMouseUp, MacView.TriggerMouseUp_Delegate, "v@:@", Control.HeaderView); + AddMethod(MacView.selMouseUp, MacView.TriggerMouseUp_Delegate, "v@:@", typeof(EtoTableHeaderView)); + AddMethod(MacView.selRightMouseUp, MacView.TriggerMouseUp_Delegate, "v@:@", typeof(EtoTableHeaderView)); + AddMethod(MacView.selOtherMouseUp, MacView.TriggerMouseUp_Delegate, "v@:@", typeof(EtoTableHeaderView)); base.AttachEvent(id); break; default: @@ -473,7 +527,11 @@ public bool ShowHeader { if (value && Control.HeaderView == null) { - Control.HeaderView = headerView = new EtoTableHeaderView { Handler = this, Menu = ContextMenu.ToNS() }; + if (HasBackgroundColor && !UseNSBoxBackgroundColor) + headerView = new EtoTableHeaderViewWithBackground { Handler = this, BackgroundColor = BackgroundColor.ToNSUI(), Menu = ContextMenu.ToNS() }; + else + headerView = new EtoTableHeaderView { Handler = this, Menu = ContextMenu.ToNS() }; + Control.HeaderView = headerView; } else if (!value && Control.HeaderView != null) { @@ -898,6 +956,26 @@ internal int DisplayIndexToColumnIndex(int displayIndex) return -1; return Widget.Columns.IndexOf(col); } + + protected override void SetBackgroundColor(Color? color) + { + var bg = color?.ToNSUI() ?? NSColor.ControlBackground; + Control.BackgroundColor = bg; + if (!UseNSBoxBackgroundColor) + { + var currentHeader = Control.HeaderView; + if (currentHeader is EtoTableHeaderViewWithBackground backgroundHeaderView) + { + backgroundHeaderView.BackgroundColor = bg; + backgroundHeaderView.SetNeedsDisplay(); + } + else if (currentHeader != null) + { + headerView = new EtoTableHeaderViewWithBackground { Handler = this, BackgroundColor = bg, Menu = ContextMenu.ToNS() }; + Control.HeaderView = headerView; + } + } + } } } diff --git a/src/Eto.Mac/Forms/MacBase.cs b/src/Eto.Mac/Forms/MacBase.cs index 6793fd1f79..c61a263e79 100644 --- a/src/Eto.Mac/Forms/MacBase.cs +++ b/src/Eto.Mac/Forms/MacBase.cs @@ -176,13 +176,22 @@ protected override void Initialize() public bool AddMethod(IntPtr selector, Delegate action, string arguments, object control) { - var type = control.GetType(); -#if OSX - if (!typeof(IMacControl).IsAssignableFrom(type)) - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Control '{0}' does not inherit from IMacControl", type)); - if (((IMacControl)control).WeakHandler?.Target == null) - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Control '{0}' has a null handler", type)); -#endif + if (control is Type type) + { + if (!typeof(IMacControl).IsAssignableFrom(type)) + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Control '{0}' does not inherit from IMacControl", type)); + } + else + { + type = control.GetType(); + + if (!typeof(IMacControl).IsAssignableFrom(type)) + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Control '{0}' does not inherit from IMacControl", type)); + if (((IMacControl)control).WeakHandler?.Target == null) + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Control '{0}' has a null handler", type)); + } + + var classHandle = Class.GetHandle(type); return ObjCExtensions.AddMethod(classHandle, selector, action, arguments);