Skip to content

Commit

Permalink
Merge pull request #2503 from cwensley/curtis/mac-grid-background-colors
Browse files Browse the repository at this point in the history
Mac: Fix setting Tree/GridView.BackgroundColor
  • Loading branch information
cwensley authored Jun 21, 2023
2 parents 72a7b07 + 274bf55 commit ee410fd
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 16 deletions.
9 changes: 8 additions & 1 deletion src/Eto.Mac/Forms/Controls/GridColumnHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
94 changes: 86 additions & 8 deletions src/Eto.Mac/Forms/Controls/GridHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public EtoTableHeaderView()
public EtoTableHeaderView(IntPtr handle) : base(handle)
{
}

public override void MouseDown(NSEvent theEvent)
{
var h = Handler;
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
}
}
}

}
}
Expand Down
23 changes: 16 additions & 7 deletions src/Eto.Mac/Forms/MacBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit ee410fd

Please sign in to comment.