Skip to content

Commit

Permalink
Merge pull request #2367 from cwensley/curtis/grid-column-autosizing-…
Browse files Browse the repository at this point in the history
…take-two

Mac: Fix grid column auto sizing when reusing the same control
  • Loading branch information
cwensley authored Dec 10, 2022
2 parents a54bbf4 + be6ddd8 commit a642cd2
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 65 deletions.
10 changes: 7 additions & 3 deletions src/Eto.Mac/Forms/Controls/GridColumnHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public interface IDataColumnHandler : GridColumn.IHandler
void SetObjectValue(object dataItem, NSObject val);
new GridColumn Widget { get; }
IDataViewHandler DataViewHandler { get; }
void AutoSizeColumn(NSRange? rowRange, bool force = false);
bool AutoSizeColumn(NSRange? rowRange, bool force = false);
void EnabledChanged(bool value);
nfloat GetPreferredWidth(NSRange? range = null);
void SizeToFit();
Expand Down Expand Up @@ -93,18 +93,22 @@ protected override void Initialize()
base.Initialize();
}

public void AutoSizeColumn(NSRange? rowRange, bool force = false)
public bool AutoSizeColumn(NSRange? rowRange, bool force = false)
{
var handler = DataViewHandler;
if (handler == null)
return;
return false;

if (AutoSize)
{
var width = GetPreferredWidth(rowRange);
if (force || width > Control.Width)
{
Control.Width = (nfloat)Math.Ceiling(width);
return true;
}
}
return false;
}

public nfloat GetPreferredWidth(NSRange? range = null)
Expand Down
129 changes: 73 additions & 56 deletions src/Eto.Mac/Forms/Controls/GridHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -331,20 +331,14 @@ protected override void Initialize()
public override void OnLoad(EventArgs e)
{
base.OnLoad(e);
ResetAutoSizedColumns();
UpdateColumns();
}

public override void OnLoadComplete(EventArgs e)
{
base.OnLoadComplete(e);

if (Widget.Columns.Any(r => r.Expand))
{
// expanded columns need readjustment after initial size
AutoSizeColumns(true, false);
Control.SizeToFit();
}

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);
Expand Down Expand Up @@ -379,66 +373,92 @@ nfloat GetTableRowInsets()
}
}

int lastAutoSizeWidth;

public bool AutoSizeColumns(bool force, bool forceNewSize = false)
{
if (Widget.Loaded)
if (!Widget.Loaded)
return false;

var rect = Table.VisibleRect();
if (rect.Width <= 0)
return false;

bool resizeExpanded = forceNewSize;
bool changed = false;
var newRange = rect.IsEmpty ? null : (NSRange?)Table.RowsInRect(rect);

if (lastAutoSizeWidth != (int)rect.Width)
{
resizeExpanded = true;
lastAutoSizeWidth = (int)rect.Width;
}

if (force
|| newRange == null
|| (autoSizeRange.Location != newRange.Value.Location || autoSizeRange.Length != newRange.Value.Length))
{
var rect = Table.VisibleRect();
var newRange = rect.IsEmpty ? null : (NSRange?)Table.RowsInRect(rect);
if (force
|| newRange == null
|| (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)
{
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();
changed |= col.AutoSizeColumn(newRange, forceNewSize && !col.Expand);

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

resizeExpanded |= changed;

if (expandCount > 0 && resizeExpanded)
{
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 = remaining / expandCount;

foreach (var col in ColumnHandlers)
{
var each = remaining / expandCount;

foreach (var col in ColumnHandlers)
if (col.Expand)
{
if (col.Expand)
{
var existingWidth = col.Control.Width;
var weightedWidth = existingWidth / expandedWidth * remaining;
col.Control.Width = weightedWidth;
}
var existingWidth = col.Control.Width;
var weightedWidth = expandedWidth > 0 ? existingWidth / expandedWidth * remaining : each;

changed |= existingWidth != weightedWidth;

col.Control.Width = weightedWidth;
}
}
}
}

if (newRange != null)
autoSizeRange = newRange.Value;
IsAutoSizingColumns = false;
if (newRange != null)
autoSizeRange = newRange.Value;

IsAutoSizingColumns = false;

if (forceNewSize && changed)
{
InvalidateMeasure();
return true;
}
return true;
}
return false;
}
Expand Down Expand Up @@ -723,11 +743,8 @@ public void ResetAutoSizedColumns()

void EnsureAutoSizedColumns()
{
if (hasAutoSizedColumns != true && !Table.VisibleRect().IsEmpty)
{
AutoSizeColumns(true, hasAutoSizedColumns == null);
hasAutoSizedColumns = true;
}
AutoSizeColumns(true, hasAutoSizedColumns == null);
hasAutoSizedColumns = true;
}

public void PerformLayout()
Expand Down
5 changes: 1 addition & 4 deletions src/Eto.Mac/Forms/Controls/GridViewHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,8 @@ public NSDragOperation DraggingSessionSourceOperationMask(NSDraggingSession sess

public override void Layout()
{
if (MacView.NewLayout)
base.Layout();
Handler?.PerformLayout();
if (!MacView.NewLayout)
base.Layout();
base.Layout();
}

public override bool ValidateProposedFirstResponder(NSResponder responder, NSEvent forEvent)
Expand Down
4 changes: 3 additions & 1 deletion test/Eto.Test.Mac/UnitTests/GridViewTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ class GridTestItem : TreeGridItem
public IEnumerable<object> CreateDataStore(int rows = 40)
{
var list = new TreeGridItemCollection();
Image logo = TestIcons.Logo;
Image testImage = TestIcons.TestImage;
for (int i = 0; i < rows; i++)
{
Image image = i % 2 == 0 ? (Image)TestIcons.Logo : (Image)TestIcons.TestImage;
Image image = i % 2 == 0 ? logo : 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;
Expand Down
2 changes: 1 addition & 1 deletion test/Eto.Test/Sections/Controls/GridViewSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ void CreateGrid()
LogEvents(grid);

var dropDown = MyDropDown("DropDownKey");
grid.Columns.Add(SetColumnState(0, new GridColumn { HeaderText = "ImageText", DataCell = new ImageTextCell("Image", "Text") }));
grid.Columns.Add(SetColumnState(0, new GridColumn { HeaderText = "ImageText", DataCell = new ImageTextCell("Image", "Text"), Expand = true }));
grid.Columns.Add(SetColumnState(1, new GridColumn { DataCell = new CheckBoxCell("Check"), AutoSize = true, Resizable = false }));
grid.Columns.Add(SetColumnState(2, new GridColumn { HeaderText = "Image", DataCell = new ImageViewCell("Image"), Resizable = false, HeaderToolTip = null }));
grid.Columns.Add(SetColumnState(3, new GridColumn { HeaderText = "Text", DataCell = new TextBoxCell("Text"), Sortable = true, HeaderToolTip = "Some Tooltip", CellToolTipBinding = Binding.Property((MyGridItem i) => i.ToolTip) }));
Expand Down

0 comments on commit a642cd2

Please sign in to comment.