commit
e1eadd99d6
12 changed files with 306 additions and 141 deletions
|
|
@ -763,7 +763,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
bottomRow.AddChild(timeContainer);
|
||||
|
||||
// we can only reslice on 64 bit, because in 64 bit we always have the gcode loaded
|
||||
if (IntPtr.Size == 8 || ApplicationController.Instance.Allow32BitReSlice)
|
||||
if ((IntPtr.Size == 8 || ApplicationController.Instance.Allow32BitReSlice)
|
||||
// Reslice is not applicable on standalone gcode files
|
||||
&& !printer.Bed.EditContext.FreezeGCode)
|
||||
{
|
||||
var resliceButton = new ThemedTextButton("Re-Slice", theme)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -335,8 +335,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
UiThread.RunOnIdle(async () =>
|
||||
{
|
||||
// Save any pending changes before starting print operation
|
||||
await ApplicationController.Instance.Tasks.Execute("Saving Changes".Localize(), printer, printer.Bed.SaveChanges);
|
||||
// For non-gcode files, save pending changes before starting print operation
|
||||
if (!printer.Bed.EditContext.IsGGCodeSource)
|
||||
{
|
||||
await ApplicationController.Instance.Tasks.Execute("Saving Changes".Localize(), printer, printer.Bed.SaveChanges);
|
||||
}
|
||||
|
||||
await ApplicationController.Instance.PrintPart(
|
||||
printer.Bed.EditContext,
|
||||
|
|
|
|||
|
|
@ -56,10 +56,16 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
// Register listeners
|
||||
printer.Connection.CommunicationStateChanged += Connection_CommunicationStateChanged;
|
||||
printer.Bed.SceneLoaded += Scene_Loaded;
|
||||
|
||||
SetButtonStates();
|
||||
}
|
||||
|
||||
private void Scene_Loaded(object sender, EventArgs e)
|
||||
{
|
||||
this.SetButtonStates();
|
||||
}
|
||||
|
||||
protected override async void OnClick(MouseEventArgs mouseEvent)
|
||||
{
|
||||
base.OnClick(mouseEvent);
|
||||
|
|
@ -70,6 +76,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
// Unregister listeners
|
||||
printer.Connection.CommunicationStateChanged -= Connection_CommunicationStateChanged;
|
||||
printer.Bed.SceneLoaded -= Scene_Loaded;
|
||||
|
||||
base.OnClosed(e);
|
||||
}
|
||||
|
|
@ -81,6 +88,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
private void SetButtonStates()
|
||||
{
|
||||
// Slicing disabled when loaded content is stand-alone GCODE file
|
||||
if (printer.Bed.EditContext.IsGGCodeSource)
|
||||
{
|
||||
this.Enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (printer.Connection.CommunicationState)
|
||||
{
|
||||
case CommunicationStates.PreparingToPrint:
|
||||
|
|
|
|||
|
|
@ -2166,7 +2166,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
sceneContext.Scene.UndoBuffer.ClearHistory();
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
this.SelectAll();
|
||||
SceneActions.DeleteSelection(Scene);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 :
|
||||
|
|
|
|||
|
|
@ -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<Table>
|
||||
{
|
||||
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 : <or auto>
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
38
MatterControlLib/Utilities/MarkdigAgg/Tables/AggTable.cs
Normal file
38
MatterControlLib/Utilities/MarkdigAgg/Tables/AggTable.cs
Normal file
|
|
@ -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<AggTableColumn> Columns { get; }
|
||||
|
||||
public List<AggTableRow> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableCell.cs
Normal file
53
MatterControlLib/Utilities/MarkdigAgg/Tables/AggTableCell.cs
Normal file
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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<AggTableCell> Cells { get; } = new List<AggTableCell>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Table>
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<AggTableCell> Cells { get; } = new List<AggTableCell>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit b702f66317da46a93343be83f1cda51bb29913c8
|
||||
Subproject commit b3a8fa67d718452ba630b40155b414868b3f6378
|
||||
Loading…
Add table
Add a link
Reference in a new issue