Skip to content

Commit

Permalink
Merge pull request #2359 from cwensley/curtis/grid-column-autosizing
Browse files Browse the repository at this point in the history
Mac: Fix issues autosizing columns in some cases
  • Loading branch information
cwensley authored Dec 2, 2022
2 parents 4f012a3 + a3589c1 commit d51ed9c
Show file tree
Hide file tree
Showing 16 changed files with 206 additions and 64 deletions.
2 changes: 1 addition & 1 deletion lib/monomac
Submodule monomac updated 2 files
+11 −0 src/AppKit/Enums.cs
+256 −8 src/appkit.cs
2 changes: 1 addition & 1 deletion src/Eto.Mac/Drawing/EtoFontManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public EtoFontManager()
{
}

public EtoFontManager(IntPtr handle)
public EtoFontManager(NativeHandle handle)
: base(handle)
{
}
Expand Down
46 changes: 40 additions & 6 deletions src/Eto.Mac/Forms/Controls/GridHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,33 @@ public override void OnLoadComplete(EventArgs e)

NSRange autoSizeRange;

static Lazy<bool> supportsTableStyle = new Lazy<bool>(() => ObjCExtensions.InstancesRespondToSelector<NSTableView>(Selector.GetHandle("effectiveStyle")));

nfloat GetTableRowInsets()
{
// oh I love magic numbers, but there doesn't seem to be any APIs that will return these..
// https://developer.apple.com/documentation/macos-release-notes/appkit-release-notes-for-macos-12
if (supportsTableStyle.Value)
{
switch (Control.EffectiveStyle)
{
case NSTableViewStyle.Inset:
return 32;
case NSTableViewStyle.FullWidth:
return 12;
case NSTableViewStyle.SourceList:
return 32;
case NSTableViewStyle.Plain:
default:
return Control.IntercellSpacing.Width;
}
}
else
{
return Control.IntercellSpacing.Width;
}
}

public bool AutoSizeColumns(bool force, bool forceNewSize = false)
{
if (Widget.Loaded)
Expand All @@ -363,37 +390,44 @@ public bool AutoSizeColumns(bool force, bool forceNewSize = false)
|| (autoSizeRange.Location != newRange.Value.Location || autoSizeRange.Length != newRange.Value.Length))
{
IsAutoSizingColumns = true;

int expandCount = 0;
nfloat requiredWidth = 0;
nfloat expandedWidth = 0;

// remove all spacing that isn't part of column widths
var intercellSpacingWidth = Table.IntercellSpacing.Width;
rect.Width -= intercellSpacingWidth * (Table.ColumnCount - 1);
rect.Width -= GetTableRowInsets();

foreach (var col in ColumnHandlers)
{
col.AutoSizeColumn(newRange, forceNewSize);
if (col.Expand)
{
expandCount++;
expandedWidth += col.Control.Width + intercellSpacingWidth;
expandedWidth += col.Control.Width;
}
else
{
requiredWidth += col.Control.Width + intercellSpacingWidth;
requiredWidth += col.Control.Width;
}
}
if (expandCount > 0 && !forceNewSize)
{
var remaining = (nfloat)Math.Max(0, rect.Width - requiredWidth + (int)Math.Round(intercellSpacingWidth / 3) - 1);
var remaining = (nfloat)Math.Max(0, rect.Width - requiredWidth);
// System.Diagnostics.Debug.WriteLine($"Remaining: {remaining}, Required: {requiredWidth}, Width: {rect.Width}");
if (remaining > 0)
{
var each = (nfloat)Math.Max(0, (remaining / expandCount) - intercellSpacingWidth);
var each = remaining / expandCount;

foreach (var col in ColumnHandlers)
{
if (col.Expand)
{
var existingWidth = col.Control.Width + intercellSpacingWidth;
var existingWidth = col.Control.Width;
var weightedWidth = existingWidth / expandedWidth * remaining;
col.Control.Width = (nfloat)Math.Max(0, weightedWidth - intercellSpacingWidth);
col.Control.Width = weightedWidth;
}
}
}
Expand Down
20 changes: 20 additions & 0 deletions test/Eto.Test.Mac/Eto.Test.Mac64.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

<RuntimeIdentifiers>osx-x64;osx-arm64</RuntimeIdentifiers>
<DefineConstants>MONOMAC</DefineConstants>
<LangVersion>10.0</LangVersion>
</PropertyGroup>

<PropertyGroup Condition="$([MSBuild]::IsOsPlatform(OSX)) AND $(Configuration) == 'Release'">
Expand All @@ -19,6 +20,25 @@
<EnableNotarization Condition="$(EnableNotarizationBuild) == 'True' AND $(TargetFramework.StartsWith('net4')) == 'False'">True</EnableNotarization>
</PropertyGroup>

<ItemGroup>
<Using Include="MonoMac.AppKit" />
<Using Include="MonoMac.Foundation" />
<Using Include="MonoMac.CoreGraphics" />
<Using Include="MonoMac.ObjCRuntime" />
<Using Include="MonoMac.CoreAnimation" />
<Using Include="MonoMac.CoreImage" />
<Using Include="MonoMac.MobileCoreServices" />
<Using Include="MonoMac.CoreFoundation" />
<Using Include="MonoMac.ImageIO" />
<Using Include="MonoMac.CoreText" />
<Using Include="MonoMac.Constants" Alias="Constants" />
<Using Include="MonoMac.AppKit.NSRectEdge" Alias="NSRectEdge" />
<Using Include="System.Double" Alias="nfloat" />
<Using Include="System.Int64" Alias="nint" />
<Using Include="System.UInt64" Alias="nuint" />
<Using Include="System.IntPtr" Alias="NativeHandle" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Eto\Eto.csproj" />
<ProjectReference Include="..\..\src\Eto.Mac\Eto.Mac64.csproj" />
Expand Down
15 changes: 15 additions & 0 deletions test/Eto.Test.Mac/Eto.Test.XamMac2.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,27 @@
<DefineConstants>XAMMAC;XAMMAC2</DefineConstants>
<SupportedOSPlatformVersion>10.15</SupportedOSPlatformVersion>
<NoWarn>CA1416</NoWarn>
<LangVersion>10</LangVersion>
</PropertyGroup>

<PropertyGroup Condition="$(TargetFramework) == 'xamarinmac20'">
<LinkMode Condition="$(Configuration) == 'Release'">SdkOnly</LinkMode>
</PropertyGroup>

<ItemGroup>
<Using Include="AppKit" />
<Using Include="Foundation" />
<Using Include="CoreGraphics" />
<Using Include="ObjCRuntime" />
<Using Include="CoreAnimation" />
<Using Include="CoreImage" />
<Using Include="MobileCoreServices" />
<Using Include="CoreFoundation" />
<Using Include="ImageIO" />
<Using Include="CoreText" />
<Using Include="System.IntPtr" Alias="NativeHandle" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Eto.Test\Eto.Test.csproj" />
<ProjectReference Include="..\..\src\Eto\Eto.csproj" />
Expand Down
13 changes: 13 additions & 0 deletions test/Eto.Test.Mac/Eto.Test.macOS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@
<LinkMode Condition="$(Configuration) == 'Release'">SdkOnly</LinkMode>
</PropertyGroup>

<ItemGroup>
<Using Include="AppKit" />
<Using Include="Foundation" />
<Using Include="CoreGraphics" />
<Using Include="ObjCRuntime" />
<Using Include="CoreAnimation" />
<Using Include="CoreImage" />
<Using Include="MobileCoreServices" />
<Using Include="CoreFoundation" />
<Using Include="ImageIO" />
<Using Include="CoreText" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Eto.Test\Eto.Test.csproj" />
<ProjectReference Include="..\..\src\Eto\Eto.csproj" />
Expand Down
15 changes: 9 additions & 6 deletions test/Eto.Test.Mac/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@
using Eto.Mac.Forms.ToolBar;
using Eto.Forms;

#if MONOMAC
using MonoMac.AppKit;
#else
using AppKit;
#endif

namespace Eto.Test.Mac
{
class Startup
Expand Down Expand Up @@ -77,7 +71,16 @@ static void AddStyles()
//handler.Control.DisplayMode = NSToolbarDisplayMode.Icon;
});

Style.Add<TreeGridViewHandler>(null, c => StyleGrid(c.Control));
Style.Add<GridViewHandler>(null, c => StyleGrid(c.Control));
}

private static void StyleGrid(NSTableView control)
{
// macOS Big Sur changed default from 3,2 to 17,0. This appears to be more sane for our purposes.
// control.IntercellSpacing = new CGSize(3, 2);
}

}
}

8 changes: 0 additions & 8 deletions test/Eto.Test.Mac/UnitTests/BitmapTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@
using Eto.Test.UnitTests;
using NUnit.Framework;

#if MONOMAC
using MonoMac.AppKit;
using MonoMac.CoreGraphics;
#else
using AppKit;
using CoreGraphics;
#endif

namespace Eto.Test.Mac.UnitTests
{
[TestFixture]
Expand Down
7 changes: 0 additions & 7 deletions test/Eto.Test.Mac/UnitTests/ButtonTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@
using System.Threading.Tasks;
using Eto.Mac;

#if MONOMAC
using MonoMac.AppKit;
using MonoMac.CoreGraphics;
#else
using AppKit;
using CoreGraphics;
#endif
namespace Eto.Test.Mac.UnitTests
{
[TestFixture]
Expand Down
8 changes: 0 additions & 8 deletions test/Eto.Test.Mac/UnitTests/CheckBoxTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,6 @@
using Eto.Test.UnitTests;
using NUnit.Framework;

#if MONOMAC
using MonoMac.AppKit;
using MonoMac.CoreGraphics;
#else
using AppKit;
using CoreGraphics;
#endif

namespace Eto.Test.Mac.UnitTests
{
[TestFixture]
Expand Down
98 changes: 98 additions & 0 deletions test/Eto.Test.Mac/UnitTests/GridViewTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Eto.Drawing;
using Eto.Forms;
using Eto.Mac;
using Eto.Test.UnitTests;
using NUnit.Framework;

namespace Eto.Test.Mac.UnitTests
{
public abstract class GridTests<T> : TestBase
where T: Grid, new()
{
class GridTestItem : TreeGridItem
{
public string Text { get; set; }

public Image Image { get; set; }

public override string ToString() => Text ?? base.ToString();
}

protected abstract void SetDataStore(T grid, IEnumerable<object> dataStore);

public IEnumerable<object> CreateDataStore(int rows = 40)
{
var list = new TreeGridItemCollection();
for (int i = 0; i < rows; i++)
{
Image image = i % 2 == 0 ? (Image)TestIcons.Logo : (Image)TestIcons.TestImage;
list.Add(new GridTestItem { Text = $"Item {i}", Image = image, Values = new[] { $"col {i}.2", $"col {i}.3", $"col {i}.4", $"col {i}.5" } });
}
return list;
}

[ManualTest]
[TestCase(NSTableViewStyle.FullWidth, -1, 1)]
[TestCase(NSTableViewStyle.FullWidth, -1, 3)]
[TestCase(NSTableViewStyle.FullWidth, 3, 3)]
[TestCase(NSTableViewStyle.Inset, -1, 1)]
[TestCase(NSTableViewStyle.Inset, -1, 3)]
[TestCase(NSTableViewStyle.Inset, 3, 3)]
[TestCase(NSTableViewStyle.SourceList, -1, 1)]
[TestCase(NSTableViewStyle.SourceList, -1, 3)]
[TestCase(NSTableViewStyle.SourceList, 3, 3)]
[TestCase(NSTableViewStyle.Plain, -1, 1)]
[TestCase(NSTableViewStyle.Plain, -1, 3)]
[TestCase(NSTableViewStyle.Plain, 3, 3)]
public void ScrollingExpandedColumnShouldKeepItsSize(NSTableViewStyle style, int intercellSpacing, int numColumns)
{
ManualForm("Scrolling should not cause the widths of the columns to go beyond the width of the grid,\nso the horizontal scrollbar should never show up.", form =>
{
form.Title = $"TesNSTableViewStyle: {style}";
var grid = new T();
grid.Height = 200;
if (grid.ControlObject is NSTableView tableView)
{
if (ObjCExtensions.InstancesRespondToSelector<NSTableView>(Selector.GetHandle("style")))
tableView.Style = style;
else
{
// macos 10.15 and older
if (style == NSTableViewStyle.SourceList)
tableView.SelectionHighlightStyle = NSTableViewSelectionHighlightStyle.SourceList;
}
if (intercellSpacing >= 0)
tableView.IntercellSpacing = new CGSize(intercellSpacing, 2);
}

SetDataStore(grid, CreateDataStore());

grid.Columns.Add(new GridColumn { DataCell = new ImageTextCell { TextBinding = Binding.Property((GridTestItem m) => m.Text), ImageBinding = Binding.Property((GridTestItem m) => m.Image) } });
for (int i = 0; i < numColumns; i++)
grid.Columns.Add(new GridColumn { DataCell = new TextBoxCell(i) });

var expandColumn = grid.Columns[0];
expandColumn.HeaderText = "Expanded";
expandColumn.Expand = true;

return grid;
});
}
}

[TestFixture]
public class GridViewTests : GridTests<GridView>
{
protected override void SetDataStore(GridView grid, IEnumerable<object> dataStore) => grid.DataStore = dataStore;
}

[TestFixture]
public class TreeGridViewTests : GridTests<TreeGridView>
{
protected override void SetDataStore(TreeGridView grid, IEnumerable<object> dataStore) => grid.DataStore = (ITreeGridStore<ITreeGridItem>)dataStore;
}
}
8 changes: 0 additions & 8 deletions test/Eto.Test.Mac/UnitTests/IconTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,6 @@
using NUnit.Framework;
using Eto.Mac;

#if MONOMAC
using MonoMac.AppKit;
using MonoMac.CoreGraphics;
#else
using AppKit;
using CoreGraphics;
#endif

namespace Eto.Test.Mac64.UnitTests
{
[TestFixture]
Expand Down
8 changes: 0 additions & 8 deletions test/Eto.Test.Mac/UnitTests/NativeParentWindowTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@
using Eto.Forms;
using System.Threading;

#if MONOMAC
using MonoMac.AppKit;
using MonoMac.CoreGraphics;
#else
using AppKit;
using CoreGraphics;
#endif

namespace Eto.Test.Mac.UnitTests
{
[TestFixture]
Expand Down
8 changes: 0 additions & 8 deletions test/Eto.Test.Mac/UnitTests/RadioButtonTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,6 @@
using Eto.Test.UnitTests;
using NUnit.Framework;

#if MONOMAC
using MonoMac.AppKit;
using MonoMac.CoreGraphics;
#else
using AppKit;
using CoreGraphics;
#endif

namespace Eto.Test.Mac.UnitTests
{
[TestFixture]
Expand Down
Loading

0 comments on commit d51ed9c

Please sign in to comment.