Skip to content

Commit

Permalink
Merge pull request #2559 from cwensley/curtis/mac-fix-autosizing-grid…
Browse files Browse the repository at this point in the history
…view

Mac: Fix autosizing of GridView based on content
  • Loading branch information
cwensley authored Oct 11, 2023
2 parents 12c0a04 + 3e3c606 commit 6d3d858
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 191 deletions.
3 changes: 1 addition & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"omnisharp.defaultLaunchSolution": "Eto.Core.sln",
"editor.insertSpaces": false,
"editor.detectIndentation": false,
"files.exclude": {
Expand All @@ -14,6 +13,6 @@
"src",
"samples"
],
"dotnet.defaultSolution": "Eto.Core.sln"
"dotnet.defaultSolution": "src/Eto.sln"

}
125 changes: 0 additions & 125 deletions src/Eto.Core.sln

This file was deleted.

20 changes: 14 additions & 6 deletions src/Eto.Mac/Forms/Controls/GridColumnHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public interface IDataColumnHandler : GridColumn.IHandler
public class GridColumnHandler : MacObject<NSTableColumn, GridColumn, GridColumn.ICallback>, GridColumn.IHandler, IDataColumnHandler
{
Cell dataCell;
bool autoSize;

static readonly object Font_Key = new object();
static readonly object WidthAdjust_Key = new object();
Expand Down Expand Up @@ -120,11 +121,10 @@ public nfloat GetPreferredWidth(NSRange? range = null)
var outlineView = handler.Table as NSOutlineView;
bool isOutlineColumn = outlineView != null && Column == 0;
if (handler.ShowHeader)
{
width = (nfloat)Math.Max(Control.HeaderCell.CellSizeForBounds(new CGRect(0, 0, int.MaxValue, int.MaxValue)).Width, width);
if (isOutlineColumn)
width += (float)outlineView.IndentationPerLevel;
}

if (isOutlineColumn)
width += (float)outlineView.IndentationPerLevel;

if (dataCell != null)
{
Expand Down Expand Up @@ -186,8 +186,16 @@ public bool Resizable

public bool AutoSize
{
get;
set;
get => autoSize;
set
{
if (autoSize != value)
{
autoSize = value;
if (autoSize && !IsLoaded)
Control.Width = Control.MinWidth;
}
}
}

public bool Sortable { get; set; }
Expand Down
25 changes: 18 additions & 7 deletions src/Eto.Mac/Forms/Controls/GridHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ public abstract class GridHandler<TControl, TWidget, TCallback> : MacControl<TCo
where TCallback : Grid.ICallback
{
ColumnCollection columns;
bool loadComplete;

public override NSView DragControl => Control;

Expand Down Expand Up @@ -391,6 +392,13 @@ public override void OnLoadComplete(EventArgs e)
var row = Widget.Properties.Get<int>(GridHandler.ScrolledToRow_Key, 0);
// Yosemite bug: hides first row when DataStore is set before control is visible, so we always call this
Control.ScrollRowToVisible(row);
loadComplete = true;
}

public override void OnUnLoad(EventArgs e)
{
base.OnUnLoad(e);
loadComplete = false;
}

NSRange autoSizeRange;
Expand Down Expand Up @@ -692,21 +700,24 @@ public CGRect GetVisibleRect()

protected override SizeF GetNaturalSize(SizeF availableSize)
{
EnsureAutoSizedColumns();
var width = ColumnHandlers.Sum(r => r.Control.Width);
var rowCount = RowCount;
var range = new NSRange(0, rowCount);
var loaded = loadComplete;
var width = ColumnHandlers.Sum(r => loaded ? r.Control.Width : r.GetPreferredWidth(range));
if (width == 0)
width = 100;

if (Border != BorderType.None)
width += 2;
width += ScrollView.FrameSizeForContentSize(new CGSize(0, 0), false, false).Width;

var intercellSpacing = Control.IntercellSpacing;
width += Control.ColumnCount * intercellSpacing.Width;
width += (Control.ColumnCount - 1) * intercellSpacing.Width;
width += GetTableRowInsets();

// it's okay to the hide last divider, it won't cause the control to scroll horizontally
width -= (int)Math.Round(intercellSpacing.Width / 3) - 1;
if (ScrollView.HasVerticalScroller && ScrollView.VerticalScroller.ScrollerStyle == NSScrollerStyle.Legacy)
width += NSScroller.GetScrollerWidth(ScrollView.VerticalScroller.ControlSize, ScrollView.VerticalScroller.ScrollerStyle);

var height = (int)((RowHeight + intercellSpacing.Height) * RowCount);
var height = (int)((RowHeight + intercellSpacing.Height) * rowCount);
if (ShowHeader)
height += 2 + (int)Control.HeaderView.Frame.Height;
return new SizeF((float)width, height);
Expand Down
59 changes: 46 additions & 13 deletions test/Eto.Test.Mac/UnitTests/GridViewTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace Eto.Test.Mac.UnitTests
public abstract class GridTests<T> : TestBase
where T: Grid, new()
{
protected abstract Test.UnitTests.Forms.Controls.GridTests<T> BaseGridTests { get; }

class GridTestItem : TreeGridItem
{
public string Text { get; set; }
Expand Down Expand Up @@ -35,35 +37,28 @@ public IEnumerable<object> CreateDataStore(int rows = 40)
[TestCase(NSTableViewStyle.FullWidth, -1, 1)]
[TestCase(NSTableViewStyle.FullWidth, -1, 3)]
[TestCase(NSTableViewStyle.FullWidth, 3, 3)]
[TestCase(NSTableViewStyle.FullWidth, 0, 3)]
[TestCase(NSTableViewStyle.Inset, -1, 1)]
[TestCase(NSTableViewStyle.Inset, -1, 3)]
[TestCase(NSTableViewStyle.Inset, 3, 3)]
[TestCase(NSTableViewStyle.Inset, 0, 3)]
[TestCase(NSTableViewStyle.SourceList, -1, 1)]
[TestCase(NSTableViewStyle.SourceList, -1, 3)]
[TestCase(NSTableViewStyle.SourceList, 3, 3)]
[TestCase(NSTableViewStyle.SourceList, 0, 3)]
[TestCase(NSTableViewStyle.Plain, -1, 1)]
[TestCase(NSTableViewStyle.Plain, -1, 3)]
[TestCase(NSTableViewStyle.Plain, 20, 3)]
[TestCase(NSTableViewStyle.Plain, 3, 3)]
[TestCase(NSTableViewStyle.Plain, 0, 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);
}
SetParameters(style, intercellSpacing, grid);

SetDataStore(grid, CreateDataStore());

Expand All @@ -78,17 +73,55 @@ public void ScrollingExpandedColumnShouldKeepItsSize(NSTableViewStyle style, int
return grid;
});
}

private static void SetParameters(NSTableViewStyle style, int intercellSpacing, T grid)
{
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);
}
}

[ManualTest]
[TestCase(NSTableViewStyle.FullWidth, -1, "Some Text", 100)]
[TestCase(NSTableViewStyle.FullWidth, -1, "Some Much Longer Text That Should Still Work", 100)]
[TestCase(NSTableViewStyle.Inset, -1, "Some Text", 100)]
[TestCase(NSTableViewStyle.Inset, -1, "Some Much Longer Text That Should Still Work", 100)]
[TestCase(NSTableViewStyle.SourceList, -1, "Some Text", 100)]
[TestCase(NSTableViewStyle.SourceList, -1, "Some Much Longer Text That Should Still Work", 100)]
[TestCase(NSTableViewStyle.Plain, -1, "Some Text", 100)]
[TestCase(NSTableViewStyle.Plain, -1, "Some Much Longer Text That Should Still Work", 100)]
[TestCase(NSTableViewStyle.Plain, 20, "Some Text", 100)]
[TestCase(NSTableViewStyle.Plain, 3, "Some Text", 100)]
[TestCase(NSTableViewStyle.Plain, 0, "Some Much Longer Text That Should Still Work", 100)]
public void AutoSizedColumnShouldChangeSizeOfControl(NSTableViewStyle style, int intercellSpacing, string text, int rows)
{
BaseGridTests.AutoSizedColumnShouldChangeSizeOfControl(text, rows, grid => {
SetParameters(style, intercellSpacing, grid);
});
}
}

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

[TestFixture]
public class TreeGridViewTests : GridTests<TreeGridView>
{
protected override Test.UnitTests.Forms.Controls.GridTests<TreeGridView> BaseGridTests => new Test.UnitTests.Forms.Controls.TreeGridViewTests();
protected override void SetDataStore(TreeGridView grid, IEnumerable<object> dataStore) => grid.DataStore = (ITreeGridStore<ITreeGridItem>)dataStore;
}
}
Loading

0 comments on commit 6d3d858

Please sign in to comment.