diff --git a/MatterControlLib/Utilities/MarkdigAgg/AggParagraphRenderer.cs b/MatterControlLib/Utilities/MarkdigAgg/AggParagraphRenderer.cs
index 92cf608ed..db3965477 100644
--- a/MatterControlLib/Utilities/MarkdigAgg/AggParagraphRenderer.cs
+++ b/MatterControlLib/Utilities/MarkdigAgg/AggParagraphRenderer.cs
@@ -20,12 +20,17 @@ namespace Markdig.Renderers.Agg
public class ParagraphX : FlowLeftRightWithWrapping, IHardBreak
{
public ParagraphX(bool bottomMargin)
- {
+ {
+ // Adding HAnchor and initial fixed width properties to resolve excess vertical whitespace added during collapse to width 0
+ //
+ // TODO: Revise impact to FlowLeftRightWithWrapping
+ this.HAnchor = HAnchor.Stretch;
+ this.Width = 5000;
if (bottomMargin)
{
Margin = new BorderDouble(0, 0, 0, 12);
}
- }
+ }
}
//public class ParagraphRenderer :
diff --git a/MatterControlLib/Utilities/MarkdigAgg/AggTableRenderer.cs b/MatterControlLib/Utilities/MarkdigAgg/AggTableRenderer.cs
deleted file mode 100644
index 58810d34b..000000000
--- a/MatterControlLib/Utilities/MarkdigAgg/AggTableRenderer.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) Nicolas Musset. All rights reserved.
-// Copyright (c) 2022, John Lewin
-// This file is licensed under the MIT license.
-// See the LICENSE.md file in the project root for more information.
-
-using System;
-using Markdig.Extensions.Tables;
-using MatterHackers.Agg;
-using MatterHackers.Agg.Platform;
-using MatterHackers.Agg.UI;
-using MatterHackers.MatterControl;
-
-namespace Markdig.Renderers.Agg
-{
- public class AggTableRenderer : AggObjectRenderer
- {
- protected override void Write(AggRenderer renderer, Table table)
- {
- if (renderer == null) throw new ArgumentNullException(nameof(renderer));
- if (table == null) throw new ArgumentNullException(nameof(table));
-
- var aggTable = new FlowLayoutWidget(FlowDirection.TopToBottom)
- {
- HAnchor = HAnchor.Fit,
- VAnchor = VAnchor.Fit,
- Margin = new BorderDouble(top: 12),
- };
-
- // TODO: Use Markdig parser data to drive column/cell widths
- //foreach (var tableColumnDefinition in table.ColumnDefinitions)
- // Width = (tableColumnDefinition?.Width ?? 0) != 0 ? tableColumnDefinition.Width :
-
- renderer.Push(aggTable);
-
- foreach (var rowObj in table)
- {
- var row = (TableRow)rowObj;
-
- var aggRow = new AggTableRow()
- {
- IsHeadingRow = row.IsHeader,
- };
-
- renderer.Push(aggRow);
-
- if (row.IsHeader)
- {
- // Update to desired header row styling and/or moving into AggTableRow for consistency
- aggRow.BackgroundColor = MatterHackers.MatterControl.AppContext.Theme.TabBarBackground;
- }
-
- for (var i = 0; i < row.Count; i++)
- {
- var cellObj = row[i];
- var cell = (TableCell)cellObj;
-
- // Fixed width cells just to get something initially on screen
- var aggCellBox = new GuiWidget()
- {
- Width = 200,
- Height = 25,
- };
-
- // TODO: Cell Width - implement next, might be easy to track and perform in AggTableRow
- /* (Spec)
- * If any line of the markdown source is longer than the column width (see --columns), then the
- * table will take up the full text width and the cell contents will wrap, with the relative cell
- * widths determined by the number of dashes in the line separating the table header from the table
- * body. (For example ---|- would make the first column 3/4 and the second column 1/4 of the full
- * text width.) On the other hand, if no lines are wider than column width, then cell contents will
- * not be wrapped, and the cells will be sized to their contents.
- */
-
- // Cell box above enforces boundaries, use flow for layout
- var aggCellFlow = new FlowLayoutWidget()
- {
- HAnchor = HAnchor.Stretch,
- };
-
- if (table.ColumnDefinitions.Count > 0)
- {
- // TODO: Ideally we'd be driving column width from metadata rather than hard-coded
- // See example below from WPF implementation
- //
- // Grab the column definition, or fall back to a default
- var columnIndex = cell.ColumnIndex < 0 || cell.ColumnIndex >= table.ColumnDefinitions.Count
- ? i
- : cell.ColumnIndex;
- columnIndex = columnIndex >= table.ColumnDefinitions.Count ? table.ColumnDefinitions.Count - 1 : columnIndex;
-
- // TODO: revise alignment via Agg types that produce aligned text
- var columnDefinition = table.ColumnDefinitions[columnIndex];
- var alignment = columnDefinition.Alignment;
- if (alignment.HasValue)
- {
- switch (alignment)
- {
- case TableColumnAlign.Center:
- aggCellFlow.HAnchor |= HAnchor.Center;
- break;
- case TableColumnAlign.Right:
- aggCellFlow.HAnchor |= HAnchor.Right;
- break;
- case TableColumnAlign.Left:
- aggCellFlow.HAnchor |= HAnchor.Left;
- break;
- }
- }
- }
-
- renderer.Push(aggCellBox);
- renderer.Push(aggCellFlow);
- renderer.Write(cell);
- renderer.Pop();
- renderer.Pop();
- }
-
- // Pop row
- renderer.Pop();
- }
-
- // Pop table
- renderer.Pop();
- }
- }
-}
\ No newline at end of file
diff --git a/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTable.cs b/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTable.cs
new file mode 100644
index 000000000..21b71f531
--- /dev/null
+++ b/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTable.cs
@@ -0,0 +1,38 @@
+// Copyright (c) Nicolas Musset. All rights reserved.
+// Copyright (c) 2022, John Lewin
+// This file is licensed under the MIT license.
+// See the LICENSE.md file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Linq;
+using Markdig.Extensions.Tables;
+using MatterHackers.Agg.UI;
+
+namespace Markdig.Renderers.Agg
+{
+ public class AggTable : FlowLayoutWidget
+ {
+
+ public List Columns { get; }
+
+ public List Rows { get; }
+
+ public AggTable(Table table) : base(FlowDirection.TopToBottom)
+ {
+ this.Columns = table.ColumnDefinitions.Select(c => new AggTableColumn(c)).ToList();
+ }
+
+ public override void OnLayout(LayoutEventArgs layoutEventArgs)
+ {
+ if (this.Columns?.Count > 0)
+ {
+ foreach (var column in this.Columns)
+ {
+ column.SetCellWidths();
+ }
+ }
+
+ base.OnLayout(layoutEventArgs);
+ }
+ }
+}
\ No newline at end of file
diff --git a/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableCell.cs b/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableCell.cs
new file mode 100644
index 000000000..096c31dd0
--- /dev/null
+++ b/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableCell.cs
@@ -0,0 +1,53 @@
+// Copyright (c) 2016-2017 Nicolas Musset. All rights reserved.
+// Copyright (c) 2022, John Lewin
+// This file is licensed under the MIT license.
+// See the LICENSE.md file in the project root for more information.
+
+using System;
+using System.Linq;
+using MatterHackers.Agg.UI;
+
+namespace Markdig.Renderers.Agg
+{
+ // Parent container to restrict bounds
+ public class AggTableCell : GuiWidget
+ {
+ public AggTableCell()
+ {
+ // TODO: drive from column once width calculation is performed
+ Width = 300;
+
+ Height = 25;
+
+ // Use event rather than OnLayout as it only seems to produce the desired effect
+ this.Layout += AggTableCell_Layout;
+ }
+
+ // TODO: Investigate. Without this solution, child content is wrapped and clipped, leaving only the last text block visible
+ private void AggTableCell_Layout(object sender, EventArgs e)
+ {
+ Console.WriteLine(Parent?.Name);
+ if (this.Children.Count > 0 && this.Children.First() is FlowLeftRightWithWrapping wrappedChild
+ && wrappedChild.Height != this.Height)
+ {
+ //using (this.LayoutLock())
+ {
+ //// Set height to ensure bounds grow to content after reflow
+ //this.Height = wrappedChild.Height;
+
+ if (this.Parent is AggTableRow parentRow)
+ {
+ parentRow.CellHeightChanged(wrappedChild.Height);
+ }
+ }
+
+ this.ContentWidth = wrappedChild.ContentWidth;
+ }
+ }
+
+ public double ContentWidth { get; private set; }
+
+ // TODO: Use to align child content when bounds are less than current
+ public HAnchor FlowHAnchor { get; set; }
+ }
+}
diff --git a/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableColumn.cs b/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableColumn.cs
new file mode 100644
index 000000000..b42d7b7f0
--- /dev/null
+++ b/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableColumn.cs
@@ -0,0 +1,59 @@
+// Copyright (c) Nicolas Musset. All rights reserved.
+// Copyright (c) 2022, John Lewin
+// This file is licensed under the MIT license.
+// See the LICENSE.md file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Linq;
+using Markdig.Extensions.Tables;
+
+namespace Markdig.Renderers.Agg
+{
+ public class AggTableColumn
+ {
+ private TableColumnDefinition ColumnDefinition;
+
+ public AggTableColumn(TableColumnDefinition definition)
+ {
+ this.ColumnDefinition = definition;
+ }
+
+ public List Cells { get; } = new List();
+
+ public void SetCellWidths()
+ {
+ double cellPadding = 10;
+
+ if (this.Cells.Count == 0)
+ {
+ return;
+ }
+
+ // TODO: Column/cell width theortically is:
+ //
+ // Case A. Expanding to the maximum content width of cells in column to grow each
+ // cell to a minimum value.
+ //
+ // Case B. Contracting when the aggregate column widths exceed the bounds
+ // of the parent container.
+ //
+ // Case C. Distributing percentages across fixed bounds of the parent container
+ //
+ // Other cases...
+
+ // This block attempts to implement Case A by finding the max content width per cells in each column
+ //
+ // Collect max content widths from each cell in this column
+ double maxCellWidth = this.Cells.Select(c => c.ContentWidth).Max() + cellPadding * 2;
+
+ // Apply max width to cells in this column
+ foreach (var cell in this.Cells)
+ {
+ if (cell.Width != maxCellWidth)
+ {
+ cell.Width = maxCellWidth;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableRenderer.cs b/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableRenderer.cs
new file mode 100644
index 000000000..4b95e50fb
--- /dev/null
+++ b/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableRenderer.cs
@@ -0,0 +1,91 @@
+// Copyright (c) Nicolas Musset. All rights reserved.
+// Copyright (c) 2022, John Lewin
+// This file is licensed under the MIT license.
+// See the LICENSE.md file in the project root for more information.
+
+using System;
+using Markdig.Extensions.Tables;
+using MatterHackers.Agg;
+using MatterHackers.Agg.UI;
+
+namespace Markdig.Renderers.Agg
+{
+ public class AggTableRenderer : AggObjectRenderer
+ {
+ protected override void Write(AggRenderer renderer, Table mdTable)
+ {
+ if (renderer == null) throw new ArgumentNullException(nameof(renderer));
+ if (mdTable == null) throw new ArgumentNullException(nameof(mdTable));
+
+ var aggTable = new AggTable(mdTable)
+ {
+ Margin = new BorderDouble(top: 12),
+ };
+
+ renderer.Push(aggTable);
+
+ foreach (var rowObj in mdTable)
+ {
+ var mdRow = (TableRow)rowObj;
+
+ var aggRow = new AggTableRow()
+ {
+ IsHeadingRow = mdRow.IsHeader,
+ };
+
+ renderer.Push(aggRow);
+
+ if (mdRow.IsHeader)
+ {
+ // Update to desired header row styling and/or move into AggTableRow for consistency
+ aggRow.BackgroundColor = MatterHackers.MatterControl.AppContext.Theme.TabBarBackground;
+ }
+
+ for (var i = 0; i < mdRow.Count; i++)
+ {
+ var mdCell = (TableCell)mdRow[i];
+
+ var aggCell = new AggTableCell();
+ aggRow.Cells.Add(aggCell);
+
+ if (mdTable.ColumnDefinitions.Count > 0)
+ {
+ // Grab the column definition, or fall back to a default
+ var columnIndex = mdCell.ColumnIndex < 0 || mdCell.ColumnIndex >= mdTable.ColumnDefinitions.Count
+ ? i
+ : mdCell.ColumnIndex;
+ columnIndex = columnIndex >= mdTable.ColumnDefinitions.Count ? mdTable.ColumnDefinitions.Count - 1 : columnIndex;
+
+ aggTable.Columns[columnIndex].Cells.Add(aggCell);
+
+ if (mdTable.ColumnDefinitions[columnIndex].Alignment.HasValue)
+ {
+ switch (mdTable.ColumnDefinitions[columnIndex].Alignment)
+ {
+ case TableColumnAlign.Center:
+ aggCell.FlowHAnchor |= HAnchor.Center;
+ break;
+ case TableColumnAlign.Right:
+ aggCell.FlowHAnchor |= HAnchor.Right;
+ break;
+ case TableColumnAlign.Left:
+ aggCell.FlowHAnchor |= HAnchor.Left;
+ break;
+ }
+ }
+ }
+
+ renderer.Push(aggCell);
+ renderer.Write(mdCell);
+ renderer.Pop();
+ }
+
+ // Pop row
+ renderer.Pop();
+ }
+
+ // Pop table
+ renderer.Pop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/MatterControlLib/Utilities/MarkdigAgg/AggTableRow.cs b/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableRow.cs
similarity index 56%
rename from MatterControlLib/Utilities/MarkdigAgg/AggTableRow.cs
rename to MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableRow.cs
index 1258993bf..7f9fc607d 100644
--- a/MatterControlLib/Utilities/MarkdigAgg/AggTableRow.cs
+++ b/MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableRow.cs
@@ -3,6 +3,8 @@
// This file is licensed under the MIT license.
// See the LICENSE.md file in the project root for more information.
+using System;
+using System.Collections.Generic;
using System.Linq;
using Markdig.Renderers.Agg.Inlines;
using MatterHackers.Agg;
@@ -10,19 +12,19 @@ using MatterHackers.Agg.UI;
namespace Markdig.Renderers.Agg
{
- public class AggTableRow: FlowLayoutWidget
+ public class AggTableRow : FlowLayoutWidget
{
public AggTableRow()
{
- this.VAnchor = VAnchor.Fit;
- this.Margin = new BorderDouble(3, 4, 0, 12);
-
- // Hack to force content on-screen (seemingly not working when set late/after constructor)
- VAnchor = VAnchor.Absolute;
- Height = 25;
+ this.Margin = new BorderDouble(10, 4);
+ this.VAnchor = VAnchor.Absolute;
+ this.Height = 25;
}
- public bool IsHeadingRow { get; set; }
+ public bool IsHeadingRow { get; set; }
+
+ public List Cells { get; } = new List();
+ public double RowHeight { get; private set; }
// Override AddChild to push styles to child elements when table rows are resolved to the tree
public override GuiWidget AddChild(GuiWidget childToAdd, int indexInChildrenList = -1)
@@ -48,5 +50,29 @@ namespace Markdig.Renderers.Agg
return base.AddChild(childToAdd, indexInChildrenList);
}
+
+ internal void CellHeightChanged(double newHeight)
+ {
+ double cellPadding = 2;
+ double height = newHeight + 2 * cellPadding;
+
+ //double maxChildHeight = this.Cells.Select(c => c.Height).Max();
+
+ if (this.RowHeight != height)
+ {
+ foreach (var cell in this.Cells)
+ {
+ using (cell.LayoutLock())
+ {
+ cell.Height = height;
+ }
+ }
+
+ using (this.LayoutLock())
+ {
+ this.Height = this.RowHeight = height;
+ }
+ }
+ }
}
}
diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp
index 2cfd64bde..ae83bc8ff 160000
--- a/Submodules/agg-sharp
+++ b/Submodules/agg-sharp
@@ -1 +1 @@
-Subproject commit 2cfd64bdeacd33f5be83556f54757b15101af146
+Subproject commit ae83bc8ff30bc77e0cc3c2596beeda0c560d5e36