commit
eef20b42b8
27 changed files with 413 additions and 328 deletions
|
|
@ -559,15 +559,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
Converter = new AsPercentOrDirectFirst(),
|
||||
},
|
||||
new SliceSettingData()
|
||||
{
|
||||
SlicerConfigName = SettingsKey.fill_pattern,
|
||||
PresentationName = "Fill Pattern".Localize(),
|
||||
HelpText = "The geometric shape of the support structure for the inside of parts.".Localize(),
|
||||
DataEditType = DataEditTypes.LIST,
|
||||
ListValues = "rectilinear,line,grid,concentric,honeycomb,hilbertcurve,achimedeancords,octagramspiral,3dhoneycomb",
|
||||
DefaultValue = "honeycomb"
|
||||
},
|
||||
new SliceSettingData()
|
||||
{
|
||||
SlicerConfigName = SettingsKey.fill_thin_gaps,
|
||||
PresentationName = "Fill Thin Gaps".Localize(),
|
||||
|
|
@ -893,7 +884,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
HelpText = "The geometric shape of the support structure for the inside of parts.".Localize(),
|
||||
DataEditType = DataEditTypes.LIST,
|
||||
ShowIfSet = "!sla_printer",
|
||||
ListValues = "GRID,TRIANGLES,HEXAGON,LINES,CONCENTRIC",
|
||||
ListValues = "GRID,TRIANGLES,HEXAGON,GYROID,LINES,CONCENTRIC",
|
||||
DefaultValue = "TRIANGLES",
|
||||
Converter = new ValueConverter(),
|
||||
},
|
||||
|
|
@ -1657,15 +1648,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
Converter = new AsPercentOfReferenceOrDirect(SettingsKey.perimeter_speed)
|
||||
},
|
||||
new SliceSettingData()
|
||||
{
|
||||
SlicerConfigName = SettingsKey.solid_fill_pattern,
|
||||
PresentationName = "Top/Bottom Fill Pattern".Localize(),
|
||||
HelpText = "The pattern used on the bottom and top layers of the print.".Localize(),
|
||||
DataEditType = DataEditTypes.LIST,
|
||||
ListValues = "rectilinear,concentric,hilbertcurve,achimedeancords,octagramspiral",
|
||||
DefaultValue = "rectilinear"
|
||||
},
|
||||
new SliceSettingData()
|
||||
{
|
||||
SlicerConfigName = SettingsKey.solid_infill_extrusion_width,
|
||||
PresentationName = "Solid Infill".Localize(),
|
||||
|
|
|
|||
|
|
@ -2933,12 +2933,16 @@ namespace MatterHackers.MatterControl
|
|||
|
||||
string settingsFilePath = ProfileManager.Instance.ProfilePath(printer.Settings.ID);
|
||||
|
||||
using (var file = File.OpenWrite(archivePath))
|
||||
using (var zip = new ZipArchive(file, ZipArchiveMode.Create))
|
||||
// if the printer was deleted while printing the path can be null
|
||||
if (settingsFilePath != null)
|
||||
{
|
||||
zip.CreateEntryFromFile(sourcePath, "PrinterPlate.mcx");
|
||||
zip.CreateEntryFromFile(settingsFilePath, printer.Settings.GetValue(SettingsKey.printer_name) + ".printer");
|
||||
zip.CreateEntryFromFile(gcodeFilePath, "sliced.gcode");
|
||||
using (var file = File.OpenWrite(archivePath))
|
||||
using (var zip = new ZipArchive(file, ZipArchiveMode.Create))
|
||||
{
|
||||
zip.CreateEntryFromFile(sourcePath, "PrinterPlate.mcx");
|
||||
zip.CreateEntryFromFile(settingsFilePath, printer.Settings.GetValue(SettingsKey.printer_name) + ".printer");
|
||||
zip.CreateEntryFromFile(gcodeFilePath, "sliced.gcode");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -147,8 +147,8 @@ namespace MatterHackers.MatterControl.ConfigurationPage
|
|||
{
|
||||
HAnchor = HAnchor.Absolute,
|
||||
VAnchor = VAnchor.Absolute,
|
||||
Width = 80,
|
||||
Height = 65,
|
||||
Width = 80 * GuiWidget.DeviceScale,
|
||||
Height = 65 * GuiWidget.DeviceScale,
|
||||
Mode = themeName,
|
||||
Border = 1,
|
||||
BorderColor = theme.BorderColor20,
|
||||
|
|
@ -169,13 +169,14 @@ namespace MatterHackers.MatterControl.ConfigurationPage
|
|||
|
||||
if (themeName == AppContext.ThemeSet.ThemesetID)
|
||||
{
|
||||
var imageBuffer = new ImageBuffer(35, 35);
|
||||
var imageSize = (int)(35 * GuiWidget.DeviceScale);
|
||||
var imageBuffer = new ImageBuffer(imageSize, imageSize);
|
||||
var graphics = imageBuffer.NewGraphics2D();
|
||||
|
||||
previewContainer.BorderColor = AppContext.Theme.AccentMimimalOverlay;
|
||||
previewContainer.Border = 1;
|
||||
|
||||
var arrowHeight = 35;
|
||||
var arrowHeight = 35 * GuiWidget.DeviceScale;
|
||||
|
||||
var upArrow = new VertexStorage();
|
||||
upArrow.MoveTo(0, 0);
|
||||
|
|
@ -183,8 +184,8 @@ namespace MatterHackers.MatterControl.ConfigurationPage
|
|||
upArrow.LineTo(0, -arrowHeight);
|
||||
upArrow.LineTo(0, 0);
|
||||
|
||||
graphics.Render(upArrow, new Vector2(0, 35), AppContext.Theme.PrimaryAccentColor);
|
||||
graphics.Render(this.CheckMark, 4, 17);
|
||||
graphics.Render(upArrow, new Vector2(0, 35 * GuiWidget.DeviceScale), AppContext.Theme.PrimaryAccentColor);
|
||||
graphics.Render(this.CheckMark, 4 * GuiWidget.DeviceScale, 17 * GuiWidget.DeviceScale);
|
||||
|
||||
imageBuffer.SetPreMultiply();
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage
|
|||
HAnchor = HAnchor.Absolute | HAnchor.Left,
|
||||
VAnchor = VAnchor.Stretch,
|
||||
Margin = new BorderDouble(0),
|
||||
Width = 20,
|
||||
Width = 20 * GuiWidget.DeviceScale,
|
||||
BackgroundColor = theme.MinimalShade,
|
||||
};
|
||||
this.AddChild(secondaryBackground);
|
||||
|
|
@ -67,7 +67,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage
|
|||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Absolute | VAnchor.Top,
|
||||
Height = 6,
|
||||
Height = 6 * GuiWidget.DeviceScale,
|
||||
Margin = new BorderDouble(left: 25),
|
||||
BackgroundColor = primaryAccentColor,
|
||||
};
|
||||
|
|
@ -77,8 +77,8 @@ namespace MatterHackers.MatterControl.ConfigurationPage
|
|||
{
|
||||
HAnchor = HAnchor.Absolute | HAnchor.Left,
|
||||
VAnchor = VAnchor.Absolute | VAnchor.Top,
|
||||
Height = 8,
|
||||
Width = 8,
|
||||
Height = 8 * GuiWidget.DeviceScale,
|
||||
Width = 8 * GuiWidget.DeviceScale,
|
||||
Margin = new BorderDouble(left: 6, top: 6),
|
||||
BackgroundColor = primaryAccentColor,
|
||||
};
|
||||
|
|
@ -88,8 +88,8 @@ namespace MatterHackers.MatterControl.ConfigurationPage
|
|||
{
|
||||
HAnchor = HAnchor.Absolute | HAnchor.Left,
|
||||
VAnchor = VAnchor.Absolute | VAnchor.Top,
|
||||
Height = 8,
|
||||
Width = 8,
|
||||
Height = 8 * GuiWidget.DeviceScale,
|
||||
Width = 8 * GuiWidget.DeviceScale,
|
||||
Margin = new BorderDouble(left: 6, top: 20),
|
||||
BackgroundColor = primaryAccentColor,
|
||||
};
|
||||
|
|
@ -99,8 +99,8 @@ namespace MatterHackers.MatterControl.ConfigurationPage
|
|||
{
|
||||
HAnchor = HAnchor.Absolute | HAnchor.Left,
|
||||
VAnchor = VAnchor.Absolute | VAnchor.Top,
|
||||
Height = 8,
|
||||
Width = 8,
|
||||
Height = 8 * GuiWidget.DeviceScale,
|
||||
Width = 8 * GuiWidget.DeviceScale,
|
||||
Margin = new BorderDouble(left: 6, top: 34),
|
||||
BackgroundColor = primaryAccentColor,
|
||||
};
|
||||
|
|
@ -110,7 +110,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage
|
|||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Absolute | VAnchor.Top,
|
||||
Height = 37,
|
||||
Height = 37 * GuiWidget.DeviceScale,
|
||||
Margin = new BorderDouble(left: 25, top: 12),
|
||||
BackgroundColor = theme.SlightShade,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -47,9 +47,14 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
protected FlowLayoutWidget rightPanel;
|
||||
private GuiWidget editButton;
|
||||
private GuiWidget saveButton;
|
||||
private SearchInputBox searchPanel;
|
||||
private TextEditWithInlineCancel textEditWithInlineCancel;
|
||||
|
||||
public InlineStringEdit(string stringValue, ThemeConfig theme, string automationName, bool boldFont = false, bool editable = true)
|
||||
public InlineStringEdit(string stringValue,
|
||||
ThemeConfig theme,
|
||||
string automationName,
|
||||
bool boldFont = false,
|
||||
bool editable = true,
|
||||
string emptyText = null)
|
||||
: base(theme)
|
||||
{
|
||||
this.Padding = theme.ToolbarPadding;
|
||||
|
|
@ -75,27 +80,27 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
Name = automationName + " Save",
|
||||
};
|
||||
|
||||
searchPanel = new SearchInputBox(theme)
|
||||
textEditWithInlineCancel = new TextEditWithInlineCancel(theme, emptyText)
|
||||
{
|
||||
Visible = false,
|
||||
Margin = new BorderDouble(left: 4)
|
||||
};
|
||||
searchPanel.searchInput.ActualTextEditWidget.EnterPressed += (s, e) =>
|
||||
textEditWithInlineCancel.TextEditWidget.ActualTextEditWidget.EnterPressed += (s, e) =>
|
||||
{
|
||||
this.Text = searchPanel.Text;
|
||||
this.Text = textEditWithInlineCancel.Text;
|
||||
this.SetVisibility(showEditPanel: false);
|
||||
this.ValueChanged?.Invoke(this, null);
|
||||
};
|
||||
|
||||
searchPanel.searchInput.Name = automationName + " Field";
|
||||
textEditWithInlineCancel.TextEditWidget.Name = automationName + " Field";
|
||||
|
||||
searchPanel.ResetButton.Name = "Close Title Edit";
|
||||
searchPanel.ResetButton.ToolTipText = "Close".Localize();
|
||||
searchPanel.ResetButton.Click += (s, e) =>
|
||||
textEditWithInlineCancel.ResetButton.Name = "Close Title Edit";
|
||||
textEditWithInlineCancel.ResetButton.ToolTipText = "Close".Localize();
|
||||
textEditWithInlineCancel.ResetButton.Click += (s, e) =>
|
||||
{
|
||||
this.SetVisibility(showEditPanel: false);
|
||||
};
|
||||
this.AddChild(searchPanel);
|
||||
this.AddChild(textEditWithInlineCancel);
|
||||
|
||||
rightPanel = new FlowLayoutWidget();
|
||||
|
||||
|
|
@ -115,7 +120,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
}
|
||||
else
|
||||
{
|
||||
searchPanel.Text = this.Text;
|
||||
textEditWithInlineCancel.Text = this.Text;
|
||||
this.SetVisibility(showEditPanel: true);
|
||||
}
|
||||
};
|
||||
|
|
@ -123,7 +128,11 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
|
||||
saveButton.Click += (s, e) =>
|
||||
{
|
||||
this.Text = searchPanel.Text;
|
||||
if (!string.IsNullOrEmpty(textEditWithInlineCancel.Text))
|
||||
{
|
||||
this.Text = textEditWithInlineCancel.Text;
|
||||
}
|
||||
|
||||
this.SetVisibility(showEditPanel: false);
|
||||
};
|
||||
rightPanel.AddChild(saveButton);
|
||||
|
|
@ -137,7 +146,18 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
|
||||
public override string Text
|
||||
{
|
||||
get => titleText.Text;
|
||||
get
|
||||
{
|
||||
// if the user is still editing the text (has not canceled)
|
||||
// and there is some text there, return the work in progress.
|
||||
if (textEditWithInlineCancel.Visible && !string.IsNullOrEmpty(textEditWithInlineCancel.Text))
|
||||
{
|
||||
return textEditWithInlineCancel.Text;
|
||||
}
|
||||
|
||||
return titleText.Text;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (titleText.Text != value)
|
||||
|
|
@ -154,7 +174,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
titleText.Visible = !showEditPanel;
|
||||
|
||||
saveButton.Visible = showEditPanel;
|
||||
searchPanel.Visible = showEditPanel;
|
||||
textEditWithInlineCancel.Visible = showEditPanel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -325,6 +325,8 @@ namespace MatterHackers.MatterControl.DataStorage
|
|||
|
||||
public bool PrintComplete { get; set; }
|
||||
|
||||
public bool PrintCanceled { get; set; }
|
||||
|
||||
public DateTime PrintEnd { get; set; }
|
||||
|
||||
[Indexed]
|
||||
|
|
|
|||
|
|
@ -66,21 +66,28 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
|
||||
public override void Flatten(UndoBuffer undoBuffer)
|
||||
{
|
||||
// only keep the mesh and get rid of everything else
|
||||
using (RebuildLock())
|
||||
if (Mesh == null)
|
||||
{
|
||||
var meshOnlyItem = new Object3D()
|
||||
{
|
||||
Mesh = this.Mesh.Copy(CancellationToken.None)
|
||||
};
|
||||
|
||||
meshOnlyItem.CopyProperties(this, Object3DPropertyFlags.All);
|
||||
|
||||
// and replace us with the children
|
||||
undoBuffer.AddAndDo(new ReplaceCommand(new[] { this }, new[] { meshOnlyItem }));
|
||||
Remove(undoBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// only keep the mesh and get rid of everything else
|
||||
using (RebuildLock())
|
||||
{
|
||||
var meshOnlyItem = new Object3D()
|
||||
{
|
||||
Mesh = this.Mesh.Copy(CancellationToken.None)
|
||||
};
|
||||
|
||||
Invalidate(InvalidateType.Children);
|
||||
meshOnlyItem.CopyProperties(this, Object3DPropertyFlags.All);
|
||||
|
||||
// and replace us with the children
|
||||
undoBuffer.AddAndDo(new ReplaceCommand(new[] { this }, new[] { meshOnlyItem }));
|
||||
}
|
||||
|
||||
Invalidate(InvalidateType.Children);
|
||||
}
|
||||
}
|
||||
|
||||
public LinearExtrudeObject3D()
|
||||
|
|
|
|||
|
|
@ -77,29 +77,32 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
{
|
||||
if (_image == null)
|
||||
{
|
||||
_image = this.LoadImage();
|
||||
// set a temp image so we don't have any problems with threading
|
||||
var image = this.LoadImage();
|
||||
|
||||
if (_image != null)
|
||||
if (image != null)
|
||||
{
|
||||
if (this.Invert)
|
||||
{
|
||||
_image = InvertLightness.DoInvertLightness(_image);
|
||||
image = InvertLightness.DoInvertLightness(image);
|
||||
}
|
||||
}
|
||||
else // bad load
|
||||
{
|
||||
_image = new ImageBuffer(200, 200);
|
||||
var graphics2D = _image.NewGraphics2D();
|
||||
image = new ImageBuffer(200, 100);
|
||||
var graphics2D = image.NewGraphics2D();
|
||||
graphics2D.Clear(Color.White);
|
||||
graphics2D.DrawString("Bad Load", 100, 100);
|
||||
graphics2D.DrawString("Image Missing".Localize(), image.Width / 2, image.Height / 2, 20, Agg.Font.Justification.Center, Agg.Font.Baseline.BoundsCenter);
|
||||
}
|
||||
|
||||
// we don't want to invalidate on the mesh change
|
||||
using (RebuildLock())
|
||||
{
|
||||
base.Mesh = this.InitMesh() ?? PlatonicSolids.CreateCube(100, 100, 0.2);
|
||||
base.Mesh = this.InitMesh(image) ?? PlatonicSolids.CreateCube(100, 100, 0.2);
|
||||
}
|
||||
|
||||
_image = image;
|
||||
|
||||
// send the invalidate on image change
|
||||
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Image));
|
||||
}
|
||||
|
|
@ -162,7 +165,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
using (this.RebuildLock())
|
||||
{
|
||||
// TODO: Revise fallback mesh
|
||||
base.Mesh = this.InitMesh() ?? PlatonicSolids.CreateCube(100, 100, 0.2);
|
||||
base.Mesh = this.InitMesh(this.Image) ?? PlatonicSolids.CreateCube(100, 100, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -174,16 +177,15 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
|
||||
public override Task Rebuild()
|
||||
{
|
||||
InitMesh();
|
||||
InitMesh(this.Image);
|
||||
|
||||
return base.Rebuild();
|
||||
}
|
||||
|
||||
private Mesh InitMesh()
|
||||
private Mesh InitMesh(ImageBuffer imageBuffer)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(this.AssetPath))
|
||||
{
|
||||
var imageBuffer = this.Image;
|
||||
if (imageBuffer != null)
|
||||
{
|
||||
ScaleMmPerPixels = Math.Min(DefaultSizeMm / imageBuffer.Width, DefaultSizeMm / imageBuffer.Height);
|
||||
|
|
|
|||
|
|
@ -147,6 +147,11 @@ namespace MatterHackers.MatterControl.PrintHistory
|
|||
}
|
||||
}
|
||||
|
||||
if (printTask.PrintCanceled)
|
||||
{
|
||||
timeIndicator.Text += " - Canceled";
|
||||
}
|
||||
|
||||
timeIndicator.Margin = new BorderDouble(right: 6);
|
||||
timeIndicator.TextColor = timeTextColor;
|
||||
|
||||
|
|
@ -196,10 +201,14 @@ namespace MatterHackers.MatterControl.PrintHistory
|
|||
indicator.BackgroundColor = new Color(38, 147, 51, 180);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (printTask.PrintCanceled)
|
||||
{
|
||||
indicator.BackgroundColor = new Color(252, 209, 22, 180);
|
||||
}
|
||||
else
|
||||
{
|
||||
indicator.BackgroundColor = Color.LightGray;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetPrintInfo()
|
||||
|
|
@ -420,6 +429,8 @@ namespace MatterHackers.MatterControl.PrintHistory
|
|||
|
||||
public bool Compleated { get; set; }
|
||||
|
||||
public bool Canceled { get; internal set; }
|
||||
|
||||
public double RecoveryCount { get; set; }
|
||||
|
||||
public string ItemsPrinted { get; set; }
|
||||
|
|
@ -447,6 +458,7 @@ namespace MatterHackers.MatterControl.PrintHistory
|
|||
Start = printTask.PrintStart,
|
||||
End = printTask.PrintEnd,
|
||||
Compleated = printTask.PrintComplete,
|
||||
Canceled = printTask.PrintCanceled,
|
||||
PrintQuality = printTask.PrintQuality,
|
||||
ItemsPrinted = groupNames,
|
||||
Minutes = printTask.PrintTimeMinutes,
|
||||
|
|
|
|||
|
|
@ -98,12 +98,12 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
breadCrumbWidget = new FolderBreadCrumbWidget(libraryContext, theme);
|
||||
navBar.AddChild(breadCrumbWidget);
|
||||
|
||||
var searchPanel = new SearchInputBox(theme)
|
||||
var searchPanel = new TextEditWithInlineCancel(theme)
|
||||
{
|
||||
Visible = false,
|
||||
Margin = new BorderDouble(10, 0, 5, 0),
|
||||
};
|
||||
searchPanel.searchInput.ActualTextEditWidget.EnterPressed += (s, e) =>
|
||||
searchPanel.TextEditWidget.ActualTextEditWidget.EnterPressed += (s, e) =>
|
||||
{
|
||||
this.PerformSearch();
|
||||
};
|
||||
|
|
@ -112,13 +112,13 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
breadCrumbWidget.Visible = true;
|
||||
searchPanel.Visible = false;
|
||||
|
||||
searchPanel.searchInput.Text = "";
|
||||
searchPanel.TextEditWidget.Text = "";
|
||||
|
||||
this.ClearSearch();
|
||||
};
|
||||
|
||||
// Store a reference to the input field
|
||||
this.searchInput = searchPanel.searchInput;
|
||||
this.searchInput = searchPanel.TextEditWidget;
|
||||
|
||||
navBar.AddChild(searchPanel);
|
||||
|
||||
|
|
|
|||
|
|
@ -251,12 +251,12 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
breadCrumbWidget = new FolderBreadCrumbWidget(workspace.LibraryView, theme);
|
||||
navBar.AddChild(breadCrumbWidget);
|
||||
|
||||
var searchPanel = new SearchInputBox(theme)
|
||||
var searchPanel = new TextEditWithInlineCancel(theme)
|
||||
{
|
||||
Visible = false,
|
||||
Margin = new BorderDouble(10, 0, 5, 0),
|
||||
};
|
||||
searchPanel.searchInput.ActualTextEditWidget.EnterPressed += (s, e) =>
|
||||
searchPanel.TextEditWidget.ActualTextEditWidget.EnterPressed += (s, e) =>
|
||||
{
|
||||
this.PerformSearch();
|
||||
};
|
||||
|
|
@ -265,13 +265,13 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
breadCrumbWidget.Visible = true;
|
||||
searchPanel.Visible = false;
|
||||
|
||||
searchPanel.searchInput.Text = "";
|
||||
searchPanel.TextEditWidget.Text = "";
|
||||
|
||||
this.ClearSearch();
|
||||
};
|
||||
|
||||
// Store a reference to the input field
|
||||
this.searchInput = searchPanel.searchInput;
|
||||
this.searchInput = searchPanel.TextEditWidget;
|
||||
|
||||
navBar.AddChild(searchPanel);
|
||||
|
||||
|
|
@ -537,40 +537,42 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
}
|
||||
}
|
||||
|
||||
public class SearchInputBox : GuiWidget
|
||||
public class TextEditWithInlineCancel : GuiWidget
|
||||
{
|
||||
internal MHTextEditWidget searchInput;
|
||||
public MHTextEditWidget TextEditWidget { get; }
|
||||
|
||||
public GuiWidget ResetButton { get; }
|
||||
|
||||
public SearchInputBox(ThemeConfig theme, string emptyText = null)
|
||||
public TextEditWithInlineCancel(ThemeConfig theme, string emptyText = null)
|
||||
{
|
||||
if (emptyText == null)
|
||||
{
|
||||
emptyText = "Search".Localize();
|
||||
}
|
||||
|
||||
this.VAnchor = VAnchor.Center | VAnchor.Fit;
|
||||
this.HAnchor = HAnchor.Stretch;
|
||||
|
||||
searchInput = new MHTextEditWidget("", theme, messageWhenEmptyAndNotSelected: emptyText ?? "Search".Localize())
|
||||
TextEditWidget = new MHTextEditWidget("", theme, messageWhenEmptyAndNotSelected: emptyText)
|
||||
{
|
||||
Name = "Search Library Edit",
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Center
|
||||
};
|
||||
this.AddChild(searchInput);
|
||||
this.AddChild(TextEditWidget);
|
||||
|
||||
var resetButton = theme.CreateSmallResetButton();
|
||||
resetButton.HAnchor |= HAnchor.Right;
|
||||
resetButton.VAnchor |= VAnchor.Center;
|
||||
resetButton.Name = "Close Search";
|
||||
resetButton.ToolTipText = "Clear".Localize();
|
||||
this.ResetButton = theme.CreateSmallResetButton();
|
||||
ResetButton.HAnchor |= HAnchor.Right;
|
||||
ResetButton.VAnchor |= VAnchor.Center;
|
||||
ResetButton.Name = "Close Search";
|
||||
ResetButton.ToolTipText = "Clear".Localize();
|
||||
|
||||
this.AddChild(resetButton);
|
||||
|
||||
this.ResetButton = resetButton;
|
||||
this.AddChild(ResetButton);
|
||||
}
|
||||
|
||||
public override string Text
|
||||
{
|
||||
get => searchInput.ActualTextEditWidget.Text;
|
||||
set => searchInput.ActualTextEditWidget.Text = value;
|
||||
get => TextEditWidget.ActualTextEditWidget.Text;
|
||||
set => TextEditWidget.ActualTextEditWidget.Text = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
{
|
||||
public abstract class SearchableTreePanel : FlowLayoutWidget
|
||||
{
|
||||
protected SearchInputBox searchBox;
|
||||
protected TextEditWithInlineCancel searchBox;
|
||||
protected TreeView treeView;
|
||||
protected Splitter horizontalSplitter;
|
||||
protected ThemeConfig theme;
|
||||
|
|
@ -55,7 +55,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
|
||||
var searchIcon = AggContext.StaticData.LoadIcon("icon_search_24x24.png", 16, 16, theme.InvertIcons).AjustAlpha(0.3);
|
||||
|
||||
searchBox = new SearchInputBox(theme)
|
||||
searchBox = new TextEditWithInlineCancel(theme)
|
||||
{
|
||||
Name = "Search",
|
||||
HAnchor = HAnchor.Stretch,
|
||||
|
|
@ -64,7 +64,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
|
||||
searchBox.ResetButton.Visible = false;
|
||||
|
||||
var searchInput = searchBox.searchInput;
|
||||
var searchInput = searchBox.TextEditWidget;
|
||||
|
||||
searchInput.BeforeDraw += (s, e) =>
|
||||
{
|
||||
|
|
@ -91,7 +91,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
}
|
||||
};
|
||||
|
||||
searchBox.searchInput.ActualTextEditWidget.TextChanged += (s, e) =>
|
||||
searchBox.TextEditWidget.ActualTextEditWidget.TextChanged += (s, e) =>
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(searchBox.Text))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -335,6 +335,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
tabControl.TabBar.ActionArea.AddChild(brandMenu, 0);
|
||||
|
||||
tabControl.TabBar.ActionArea.VAnchor = VAnchor.Absolute;
|
||||
tabControl.TabBar.ActionArea.Height = brandMenu.Height;
|
||||
|
||||
// Restore active workspace tabs
|
||||
foreach (var workspace in ApplicationController.Instance.Workspaces)
|
||||
{
|
||||
|
|
@ -363,7 +366,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Absolute,
|
||||
Padding = 1,
|
||||
Height = 22,
|
||||
Height = 22 * GuiWidget.DeviceScale,
|
||||
BackgroundColor = theme.BackgroundColor,
|
||||
Border = new BorderDouble(top: 1),
|
||||
BorderColor = theme.BorderColor20,
|
||||
|
|
@ -390,17 +393,15 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
Border = new BorderDouble(1),
|
||||
BackgroundColor = theme.MinimalShade.WithAlpha(10),
|
||||
BorderColor = theme.SlightShade,
|
||||
Width = 200
|
||||
Width = 200 * GuiWidget.DeviceScale
|
||||
};
|
||||
statusBar.AddChild(stretchStatusPanel);
|
||||
|
||||
var panelBackgroundColor = theme.MinimalShade.WithAlpha(10);
|
||||
|
||||
statusBar.AddChild(
|
||||
this.CreateThemeStatusPanel(theme, panelBackgroundColor));
|
||||
statusBar.AddChild(this.CreateThemeStatusPanel(theme, panelBackgroundColor));
|
||||
|
||||
statusBar.AddChild(
|
||||
this.CreateNetworkStatusPanel(theme));
|
||||
statusBar.AddChild(this.CreateNetworkStatusPanel(theme));
|
||||
|
||||
this.RenderRunningTasks(theme, ApplicationController.Instance.Tasks);
|
||||
}
|
||||
|
|
@ -584,7 +585,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
Border = new BorderDouble(1),
|
||||
BackgroundColor = theme.MinimalShade.WithAlpha(10),
|
||||
BorderColor = theme.SlightShade,
|
||||
Width = 120
|
||||
Width = 120 * GuiWidget.DeviceScale
|
||||
};
|
||||
if (ApplicationController.ServicesStatusType != null)
|
||||
{
|
||||
|
|
@ -633,7 +634,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
HAnchor = HAnchor.Absolute,
|
||||
VAnchor = VAnchor.Fit,
|
||||
Width = 650,
|
||||
Width = 650 * GuiWidget.DeviceScale,
|
||||
Border = 1,
|
||||
BorderColor = theme.DropList.Open.BackgroundColor,
|
||||
// Padding = theme.DefaultContainerPadding,
|
||||
|
|
@ -818,7 +819,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
private static void EnableReduceWidth(ChromeTab partTab, ThemeConfig theme)
|
||||
{
|
||||
var scale = GuiWidget.DeviceScale;
|
||||
partTab.MinimumSize = new Vector2(80 * scale, theme.TabButtonHeight);
|
||||
partTab.MinimumSize = new Vector2(80 * scale, theme.TabButtonHeight * GuiWidget.DeviceScale);
|
||||
|
||||
var textWidget = partTab.Descendants<TextWidget>().First();
|
||||
var tabPill = partTab.Descendants<SimpleTab.TabPill>().First();
|
||||
|
|
@ -944,7 +945,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
Border = new BorderDouble(1),
|
||||
BorderColor = theme.SlightShade,
|
||||
ProgressBackgroundColor = progressBackgroundColor,
|
||||
Width = 200
|
||||
Width = 200 * GuiWidget.DeviceScale
|
||||
};
|
||||
|
||||
tasksContainer.AddChild(runningTaskPanel);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
BackgroundColor = theme.InteractionLayerOverlayColor,
|
||||
HAnchor = HAnchor.Fit | HAnchor.Left,
|
||||
VAnchor = VAnchor.Fit,
|
||||
MinimumSize = new Vector2(325, 0),
|
||||
MinimumSize = new Vector2(325 * GuiWidget.DeviceScale, 0),
|
||||
Border = new BorderDouble(top: 1),
|
||||
BorderColor = borderColor,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
private ChromeTabs tabControl;
|
||||
private GuiWidget searchButton;
|
||||
private SearchInputBox searchBox;
|
||||
private TextEditWithInlineCancel searchBox;
|
||||
|
||||
public SearchPanel(ChromeTabs tabControl, GuiWidget searchButton, ThemeConfig theme)
|
||||
: base(theme, GrabBarSide.Left)
|
||||
|
|
@ -67,13 +67,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
VAnchor = VAnchor.Stretch
|
||||
};
|
||||
|
||||
searchBox = new SearchInputBox(theme)
|
||||
searchBox = new TextEditWithInlineCancel(theme)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Fit,
|
||||
Margin = new BorderDouble(5, 8, 5, 5)
|
||||
};
|
||||
searchBox.searchInput.ActualTextEditWidget.EnterPressed += async (s2, e2) =>
|
||||
searchBox.TextEditWidget.ActualTextEditWidget.EnterPressed += async (s2, e2) =>
|
||||
{
|
||||
searchResults.CloseAllChildren();
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
var searchHits = await Task.Run(() =>
|
||||
{
|
||||
return HelpIndex.Search(searchBox.searchInput.Text);
|
||||
return HelpIndex.Search(searchBox.TextEditWidget.Text);
|
||||
});
|
||||
|
||||
searchResults.CloseAllChildren();
|
||||
|
|
@ -118,7 +118,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
searchBox.ResetButton.Click += (s2, e2) =>
|
||||
{
|
||||
searchBox.BackgroundColor = Color.Transparent;
|
||||
searchBox.searchInput.Text = "";
|
||||
searchBox.TextEditWidget.Text = "";
|
||||
|
||||
searchResults.CloseAllChildren();
|
||||
};
|
||||
|
|
@ -140,7 +140,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
public override void OnLoad(EventArgs args)
|
||||
{
|
||||
// Set initial focus to input field
|
||||
searchBox.searchInput.Focus();
|
||||
searchBox.TextEditWidget.Focus();
|
||||
|
||||
base.OnLoad(args);
|
||||
}
|
||||
|
|
@ -174,7 +174,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
if (helpDocsTab.TabContent is HelpTreePanel treePanel)
|
||||
{
|
||||
treePanel.MatchingText = searchBox.searchInput.Text;
|
||||
treePanel.MatchingText = searchBox.TextEditWidget.Text;
|
||||
treePanel.ActiveNodePath = (sender as HelpSearchResultRow).SearchResult.Path;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,38 +40,38 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
{
|
||||
public event EventHandler<StringEventArgs> SearchInvoked;
|
||||
|
||||
private SearchInputBox searchPanel;
|
||||
private TextEditWithInlineCancel searchPanel;
|
||||
|
||||
public SearchableSectionWidget(string sectionTitle, GuiWidget sectionContent, ThemeConfig theme, int headingPointSize = -1, bool expandingContent = true, bool expanded = true, string serializationKey = null, bool defaultExpansion = false, bool setContentVAnchor = true, string emptyText = null)
|
||||
: base(sectionTitle, sectionContent, theme, theme.CreateSearchButton(), headingPointSize, expandingContent, expanded, serializationKey, defaultExpansion, setContentVAnchor)
|
||||
{
|
||||
var headerRow = this.Children.First();
|
||||
|
||||
searchPanel = new SearchInputBox(theme, emptyText)
|
||||
searchPanel = new TextEditWithInlineCancel(theme, emptyText)
|
||||
{
|
||||
Visible = false,
|
||||
BackgroundColor = theme.TabBarBackground,
|
||||
MinimumSize = new Vector2(0, headerRow.Height)
|
||||
};
|
||||
|
||||
searchPanel.searchInput.Margin = new BorderDouble(3, 0);
|
||||
searchPanel.TextEditWidget.Margin = new BorderDouble(3, 0);
|
||||
|
||||
searchPanel.searchInput.ActualTextEditWidget.EnterPressed += (s, e) =>
|
||||
searchPanel.TextEditWidget.ActualTextEditWidget.EnterPressed += (s, e) =>
|
||||
{
|
||||
var filter = searchPanel.searchInput.Text.Trim();
|
||||
var filter = searchPanel.TextEditWidget.Text.Trim();
|
||||
|
||||
this.SearchInvoked?.Invoke(this, new StringEventArgs(filter));
|
||||
|
||||
searchPanel.Visible = false;
|
||||
headerRow.Visible = true;
|
||||
searchPanel.searchInput.Text = "";
|
||||
searchPanel.TextEditWidget.Text = "";
|
||||
};
|
||||
|
||||
searchPanel.ResetButton.Click += (s, e) =>
|
||||
{
|
||||
searchPanel.Visible = false;
|
||||
headerRow.Visible = true;
|
||||
searchPanel.searchInput.Text = "";
|
||||
searchPanel.TextEditWidget.Text = "";
|
||||
};
|
||||
|
||||
var searchButton = this.rightAlignedContent as GuiWidget;
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
public class OverflowBar : Toolbar
|
||||
{
|
||||
protected static HashSet<Type> ignoredTypes = new HashSet<Type> { typeof(HorizontalLine), typeof(SearchInputBox) };
|
||||
protected static HashSet<Type> ignoredInMenuTypes = new HashSet<Type> { typeof(VerticalLine), typeof(HorizontalLine), typeof(SearchInputBox), typeof(HorizontalSpacer) };
|
||||
protected static HashSet<Type> ignoredTypes = new HashSet<Type> { typeof(HorizontalLine), typeof(TextEditWithInlineCancel) };
|
||||
protected static HashSet<Type> ignoredInMenuTypes = new HashSet<Type> { typeof(VerticalLine), typeof(HorizontalLine), typeof(TextEditWithInlineCancel), typeof(HorizontalSpacer) };
|
||||
|
||||
public OverflowBar(ThemeConfig theme)
|
||||
: this(null, theme)
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
HAnchor = HAnchor.Fit | HAnchor.Left,
|
||||
VAnchor = VAnchor.Fit,
|
||||
Padding = 5,
|
||||
MinimumSize = new Vector2(400, 65),
|
||||
MinimumSize = new Vector2(400 * GuiWidget.DeviceScale, 65 * GuiWidget.DeviceScale),
|
||||
};
|
||||
printPanel.AddChild(optionsPanel);
|
||||
|
||||
|
|
|
|||
|
|
@ -2268,6 +2268,7 @@ Make sure that your printer is turned on. Some printers will appear to be connec
|
|||
ActivePrintTask.PrintEnd = DateTime.Now;
|
||||
ActivePrintTask.PrintComplete = false;
|
||||
ActivePrintTask.PrintingGCodeFileName = "";
|
||||
ActivePrintTask.PrintCanceled = true;
|
||||
ActivePrintTask.Commit();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
{
|
||||
public static class PrinterSettingsExtensions
|
||||
{
|
||||
private static Dictionary<string, string> blackListSettings = new Dictionary<string, string>()
|
||||
private static readonly Dictionary<string, string> BlackListSettings = new Dictionary<string, string>()
|
||||
{
|
||||
[SettingsKey.spiral_vase] = "0",
|
||||
[SettingsKey.layer_to_pause] = "",
|
||||
|
|
@ -48,7 +48,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
[SettingsKey.filament_1_has_been_loaded] = "0"
|
||||
};
|
||||
|
||||
private static object writeLock = new object();
|
||||
private static readonly object WriteLock = new object();
|
||||
|
||||
public static double XSpeed(this PrinterSettings printerSettings)
|
||||
{
|
||||
|
|
@ -82,7 +82,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
|
||||
public static void ClearBlackList(this PrinterSettings settings)
|
||||
{
|
||||
foreach (var kvp in blackListSettings)
|
||||
foreach (var kvp in BlackListSettings)
|
||||
{
|
||||
if (settings.UserLayer.ContainsKey(kvp.Key))
|
||||
{
|
||||
|
|
@ -101,15 +101,19 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
return;
|
||||
}
|
||||
|
||||
settings.Save(
|
||||
ProfileManager.Instance.ProfilePath(settings.ID),
|
||||
userDrivenChange);
|
||||
var profilePath = ProfileManager.Instance.ProfilePath(settings.ID);
|
||||
|
||||
// it is possible for a profile to get deleted while printing so we have to check for it
|
||||
if (profilePath != null)
|
||||
{
|
||||
settings.Save(profilePath, userDrivenChange);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Save(this PrinterSettings settings, string filePath, bool userDrivenChange = true)
|
||||
{
|
||||
// TODO: Rewrite to be owned by ProfileManager and simply mark as dirty and every n period persist and clear dirty flags
|
||||
lock (writeLock)
|
||||
lock (WriteLock)
|
||||
{
|
||||
string json = settings.ToJson();
|
||||
|
||||
|
|
|
|||
|
|
@ -230,10 +230,17 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
[JsonIgnore]
|
||||
public IEnumerable<PrinterInfo> ActiveProfiles => Profiles.Where(profile => !profile.MarkedForDelete).ToList();
|
||||
|
||||
public static bool DebugPrinterDelete { get; set; } = false;
|
||||
|
||||
public PrinterInfo this[string profileID]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (DebugPrinterDelete)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Profiles.Where(p => p.ID == profileID).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
|
@ -279,7 +286,14 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
|
||||
public string ProfilePath(string printerID)
|
||||
{
|
||||
return ProfilePath(this[printerID]);
|
||||
var printer = this[printerID];
|
||||
if (printer != null)
|
||||
{
|
||||
return ProfilePath(printer);
|
||||
}
|
||||
|
||||
// the printer may have been deleted
|
||||
return null;
|
||||
}
|
||||
|
||||
public string ProfilePath(PrinterInfo printer)
|
||||
|
|
|
|||
|
|
@ -62,11 +62,19 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
|
||||
contentRow.BackgroundColor = Color.Transparent;
|
||||
|
||||
var inlineNameEdit = new InlineStringEdit(presetsContext.PersistenceLayer.Name, theme, presetsContext.LayerType.ToString() + " Name", boldFont: true);
|
||||
var inlineNameEdit = new InlineStringEdit(presetsContext.PersistenceLayer.Name,
|
||||
theme,
|
||||
presetsContext.LayerType.ToString() + " Name",
|
||||
boldFont: true,
|
||||
emptyText: "Setting Name".Localize());
|
||||
inlineNameEdit.ValueChanged += (s, e) =>
|
||||
{
|
||||
printer.Settings.SetValue(SettingsKey.layer_name, inlineNameEdit.Text, presetsContext.PersistenceLayer);
|
||||
};
|
||||
inlineNameEdit.Closed += (s, e) =>
|
||||
{
|
||||
printer.Settings.SetValue(SettingsKey.layer_name, inlineNameEdit.Text, presetsContext.PersistenceLayer);
|
||||
};
|
||||
contentRow.AddChild(inlineNameEdit);
|
||||
|
||||
var sliceSettingsWidget = CreateSliceSettingsWidget(printer, presetsContext.PersistenceLayer);
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
private readonly SettingsContext settingsContext;
|
||||
private readonly bool isPrimarySettingsView;
|
||||
|
||||
private readonly SearchInputBox searchPanel;
|
||||
private readonly TextEditWithInlineCancel settingsNameEdit;
|
||||
private int groupPanelCount = 0;
|
||||
private List<(GuiWidget widget, SliceSettingData settingData)> settingsRows;
|
||||
private TextWidget filteredItemsHeading;
|
||||
|
|
@ -135,17 +135,17 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
|
||||
this.TabBar.Padding = this.TabBar.Margin.Clone(right: theme.ToolbarPadding.Right);
|
||||
|
||||
searchPanel = new SearchInputBox(theme)
|
||||
settingsNameEdit = new TextEditWithInlineCancel(theme, "name".Localize())
|
||||
{
|
||||
Visible = false,
|
||||
BackgroundColor = theme.TabBarBackground,
|
||||
MinimumSize = new Vector2(0, this.TabBar.Height)
|
||||
};
|
||||
|
||||
searchPanel.searchInput.Margin = new BorderDouble(3, 0);
|
||||
searchPanel.searchInput.ActualTextEditWidget.EnterPressed += (s, e) =>
|
||||
settingsNameEdit.TextEditWidget.Margin = new BorderDouble(3, 0);
|
||||
settingsNameEdit.TextEditWidget.ActualTextEditWidget.EnterPressed += (s, e) =>
|
||||
{
|
||||
var filter = searchPanel.searchInput.Text.Trim();
|
||||
var filter = settingsNameEdit.TextEditWidget.Text.Trim();
|
||||
|
||||
foreach (var item in this.settingsRows)
|
||||
{
|
||||
|
|
@ -158,16 +158,17 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
|
||||
this.ShowFilteredView();
|
||||
};
|
||||
searchPanel.ResetButton.Click += (s, e) =>
|
||||
|
||||
settingsNameEdit.ResetButton.Click += (s, e) =>
|
||||
{
|
||||
searchPanel.Visible = false;
|
||||
searchPanel.searchInput.Text = "";
|
||||
settingsNameEdit.Visible = false;
|
||||
settingsNameEdit.TextEditWidget.Text = "";
|
||||
|
||||
this.ClearFilter();
|
||||
};
|
||||
|
||||
// Add heading for My Settings view
|
||||
searchPanel.AddChild(filteredItemsHeading = new TextWidget(justMySettingsTitle, pointSize: theme.DefaultFontSize, textColor: theme.TextColor)
|
||||
settingsNameEdit.AddChild(filteredItemsHeading = new TextWidget(justMySettingsTitle, pointSize: theme.DefaultFontSize, textColor: theme.TextColor)
|
||||
{
|
||||
Margin = new BorderDouble(left: 10),
|
||||
HAnchor = HAnchor.Left,
|
||||
|
|
@ -175,7 +176,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
Visible = false
|
||||
}, 0);
|
||||
|
||||
this.AddChild(searchPanel, 0);
|
||||
this.AddChild(settingsNameEdit, 0);
|
||||
|
||||
var scrollable = new ScrollableWidget(true)
|
||||
{
|
||||
|
|
@ -286,10 +287,10 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
searchButton.Click += (s, e) =>
|
||||
{
|
||||
filteredItemsHeading.Visible = false;
|
||||
searchPanel.searchInput.Visible = true;
|
||||
settingsNameEdit.TextEditWidget.Visible = true;
|
||||
|
||||
searchPanel.Visible = true;
|
||||
searchPanel.searchInput.Focus();
|
||||
settingsNameEdit.Visible = true;
|
||||
settingsNameEdit.TextEditWidget.Focus();
|
||||
this.TabBar.Visible = false;
|
||||
};
|
||||
|
||||
|
|
@ -914,9 +915,9 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
}
|
||||
|
||||
filteredItemsHeading.Visible = true;
|
||||
searchPanel.searchInput.Visible = false;
|
||||
settingsNameEdit.TextEditWidget.Visible = false;
|
||||
this.TabBar.Visible = false;
|
||||
searchPanel.Visible = true;
|
||||
settingsNameEdit.Visible = true;
|
||||
|
||||
this.ShowFilteredView();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit fd058b1fb03b30fc8b5f4a602d585aabc90809f9
|
||||
Subproject commit cdb91e5d4c50fd470a1e40aa2ab5ffdd0221071c
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 04fb5d5d6842ba55940bbfb1ffc5a13d2966a063
|
||||
Subproject commit a3577e13914d8f4cd0875d7848b2049af540fe74
|
||||
|
|
@ -94,14 +94,10 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
{
|
||||
Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count(), "One printer should be defined after add");
|
||||
|
||||
testRunner.OpenPrintPopupMenu();
|
||||
|
||||
testRunner.ClickByName("SetupPrinter");
|
||||
|
||||
testRunner.Complete9StepLeveling();
|
||||
|
||||
// print a part
|
||||
testRunner.AddItemToBedplate();
|
||||
testRunner.OpenPrintPopupMenu()
|
||||
.ClickByName("SetupPrinter")
|
||||
.Complete9StepLeveling()
|
||||
.AddItemToBedplate();
|
||||
|
||||
var printer = testRunner.FirstPrinter();
|
||||
|
||||
|
|
@ -320,6 +316,33 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
}, maxTimeToRun: 90);
|
||||
}
|
||||
|
||||
[Test, Category("Emulator")]
|
||||
public async Task PrinterDeletedWhilePrinting()
|
||||
{
|
||||
await MatterControlUtilities.RunTest((testRunner) =>
|
||||
{
|
||||
using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator())
|
||||
{
|
||||
Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count(), "One printer should exist after add");
|
||||
|
||||
var printer = testRunner.FirstPrinter();
|
||||
|
||||
// print a part
|
||||
testRunner.AddItemToBedplate();
|
||||
testRunner.StartPrint(pauseAtLayers: "2");
|
||||
ProfileManager.DebugPrinterDelete = true;
|
||||
|
||||
// Wait for pause dialog
|
||||
testRunner.ClickResumeButton(printer, true, 1);
|
||||
|
||||
// Wait for done
|
||||
testRunner.WaitForPrintFinished(printer);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}, maxTimeToRun: 180);
|
||||
}
|
||||
|
||||
[Test, Category("Emulator")]
|
||||
public async Task PrinterRecoveryTest()
|
||||
{
|
||||
|
|
@ -333,67 +356,30 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
printer.Settings.SetValue(SettingsKey.recover_is_enabled, "1");
|
||||
printer.Settings.SetValue(SettingsKey.has_hardware_leveling, "0");
|
||||
|
||||
// TODO: Delay needed to work around timing issue in MatterHackers/MCCentral#2415
|
||||
testRunner.Delay(1);
|
||||
|
||||
testRunner.WaitForReloadAll(() => { });
|
||||
|
||||
Assert.IsTrue(printer.Connection.RecoveryIsEnabled);
|
||||
|
||||
// print a part
|
||||
testRunner.AddItemToBedplate();
|
||||
testRunner.StartPrint(pauseAtLayers: "2;4;6");
|
||||
|
||||
// Wait for pause dialog
|
||||
testRunner.WaitForName("Yes Button", 15); // the yes button is 'Resume'
|
||||
|
||||
// validate the current layer
|
||||
Assert.AreEqual(1, printer.Connection.CurrentlyPrintingLayer);
|
||||
|
||||
// Resume
|
||||
testRunner.ClickByName("Yes Button");
|
||||
|
||||
// the printer is now paused
|
||||
// close the pause dialog pop-up do not resume
|
||||
ClickDialogButton(testRunner, printer, "No Button", 3);
|
||||
|
||||
// Disconnect
|
||||
testRunner.ClickByName("Disconnect from printer button");
|
||||
|
||||
// Reconnect
|
||||
testRunner.WaitForName("Connect to printer button", 10);
|
||||
testRunner.ClickByName("Connect to printer button");
|
||||
|
||||
testRunner.WaitFor(() => printer.Connection.CommunicationState == CommunicationStates.Connected);
|
||||
testRunner.AddItemToBedplate()
|
||||
.StartPrint(pauseAtLayers: "2;4;6")
|
||||
.ClickResumeButton(printer, true, 1) // Resume
|
||||
.ClickResumeButton(printer, false, 3) // close the pause dialog pop-up do not resume
|
||||
.ClickByName("Disconnect from printer button")
|
||||
.ClickByName("Connect to printer button") // Reconnect
|
||||
.WaitFor(() => printer.Connection.CommunicationState == CommunicationStates.Connected);
|
||||
|
||||
// Assert that recovery happens
|
||||
Assert.IsTrue(PrintRecovery.RecoveryAvailable(printer), "Recovery should be enabled after Disconnect while printing");
|
||||
|
||||
// Recover the print
|
||||
ClickDialogButton(testRunner, printer, "Yes Button", -1);
|
||||
|
||||
// The first pause that we get after recovery should be layer 6.
|
||||
// wait for the pause and continue
|
||||
ClickDialogButton(testRunner, printer, "Yes Button", 5);
|
||||
|
||||
// Wait for done
|
||||
testRunner.WaitForPrintFinished(printer);
|
||||
testRunner.ClickButton("Yes Button", "Recover Print")
|
||||
.ClickResumeButton(printer, true, 5) // The first pause that we get after recovery should be layer 6.
|
||||
.WaitForPrintFinished(printer);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}, maxTimeToRun: 180);
|
||||
}
|
||||
|
||||
// TODO: convert to extension method
|
||||
private static void ClickDialogButton(AutomationRunner testRunner, PrinterConfig printer, string buttonName, int expectedLayer)
|
||||
{
|
||||
testRunner.WaitForName(buttonName, 90);
|
||||
Assert.AreEqual(expectedLayer, printer.Connection.CurrentlyPrintingLayer);
|
||||
|
||||
testRunner.ClickByName(buttonName);
|
||||
testRunner.WaitFor(() => !testRunner.NameExists(buttonName), 1);
|
||||
}
|
||||
|
||||
[Test, Category("Emulator")]
|
||||
public async Task TuningAdjustmentsDefaultToOneAndPersists()
|
||||
{
|
||||
|
|
@ -421,23 +407,20 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
printFinishedResetEvent.Set();
|
||||
};
|
||||
|
||||
testRunner.StartPrint();
|
||||
|
||||
testRunner.ScrollIntoView("Extrusion Multiplier NumberEdit");
|
||||
testRunner.ScrollIntoView("Feed Rate NumberEdit");
|
||||
testRunner.StartPrint()
|
||||
.ScrollIntoView("Extrusion Multiplier NumberEdit")
|
||||
.ScrollIntoView("Feed Rate NumberEdit");
|
||||
|
||||
// Tuning values should default to 1 when missing
|
||||
ConfirmExpectedSpeeds(testRunner, 1, 1, "Initial case");
|
||||
|
||||
testRunner.Delay();
|
||||
testRunner.ClickByName("Extrusion Multiplier NumberEdit");
|
||||
testRunner.Type(targetExtrusionRate.ToString());
|
||||
|
||||
testRunner.ClickByName("Feed Rate NumberEdit");
|
||||
testRunner.Type(targetFeedRate.ToString());
|
||||
|
||||
// Force focus away from the feed rate field, causing an persisted update
|
||||
testRunner.ClickByName("Extrusion Multiplier NumberEdit");
|
||||
testRunner.Delay()
|
||||
.ClickByName("Extrusion Multiplier NumberEdit")
|
||||
.Type(targetExtrusionRate.ToString())
|
||||
.ClickByName("Feed Rate NumberEdit")
|
||||
.Type(targetFeedRate.ToString())
|
||||
// Force focus away from the feed rate field, causing an persisted update
|
||||
.ClickByName("Extrusion Multiplier NumberEdit");
|
||||
|
||||
ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "After setting TextEdit values");
|
||||
|
||||
|
|
@ -453,17 +436,15 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
// Values should match entered values
|
||||
ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "After print finished");
|
||||
|
||||
testRunner.WaitForPrintFinished(printer);
|
||||
|
||||
// Restart the print
|
||||
testRunner.StartPrint();
|
||||
testRunner.Delay(1);
|
||||
testRunner.WaitForPrintFinished(printer)
|
||||
.StartPrint() // Restart the print
|
||||
.Delay(1);
|
||||
|
||||
// Values should match entered values
|
||||
ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "After print restarted");
|
||||
|
||||
testRunner.CancelPrint();
|
||||
testRunner.Delay(1);
|
||||
testRunner.CancelPrint()
|
||||
.Delay(1);
|
||||
|
||||
// Values should match entered values
|
||||
ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "After canceled print");
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
{
|
||||
private static bool saveImagesForDebug = true;
|
||||
|
||||
private static event EventHandler unregisterEvents;
|
||||
private static event EventHandler UnregisterEvents;
|
||||
|
||||
private static int testID = 0;
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
{
|
||||
// Wire up a block and release mechanism to wait until the sign in process has completed
|
||||
AutoResetEvent resetEvent = new AutoResetEvent(false);
|
||||
ApplicationController.Instance.DoneReloadingAll.RegisterEvent((s, e) => resetEvent.Set(), ref unregisterEvents);
|
||||
ApplicationController.Instance.DoneReloadingAll.RegisterEvent((s, e) => resetEvent.Set(), ref UnregisterEvents);
|
||||
|
||||
// Start the procedure that begins a ReloadAll event in MatterControl
|
||||
reloadAllAction();
|
||||
|
|
@ -127,13 +127,13 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
resetEvent.WaitOne(10 * 1000);
|
||||
|
||||
// Remove our DoneReloadingAll listener
|
||||
unregisterEvents(null, null);
|
||||
UnregisterEvents(null, null);
|
||||
|
||||
// Wait for any post DoneReloadingAll code to finish up and return
|
||||
testRunner.Delay(.2);
|
||||
}
|
||||
|
||||
public static void WaitForPage(this AutomationRunner testRunner, string headerText)
|
||||
public static AutomationRunner WaitForPage(this AutomationRunner testRunner, string headerText)
|
||||
{
|
||||
// Helper methods
|
||||
bool HeaderExists(string text)
|
||||
|
|
@ -147,8 +147,9 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
testRunner.WaitFor(() => HeaderExists(headerText));
|
||||
|
||||
Assert.IsTrue(HeaderExists(headerText), "Expected page not found: " + headerText);
|
||||
}
|
||||
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
public static string PathToExportGcodeFolder
|
||||
{
|
||||
|
|
@ -168,7 +169,8 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
public enum PrepAction
|
||||
{
|
||||
CloseSignInAndPrinterSelect
|
||||
};
|
||||
}
|
||||
;
|
||||
|
||||
public static void ExpandEditTool(this AutomationRunner testRunner, string expandCheckboxButtonName)
|
||||
{
|
||||
|
|
@ -186,6 +188,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
{
|
||||
testRunner.ClickByName("3D View Edit");
|
||||
}
|
||||
|
||||
testRunner.DragDropByName("InteractionLayer", "InteractionLayer", offsetDrop: new Agg.Point2D(10, 15), mouseButtons: MouseButtons.Right);
|
||||
|
||||
testRunner.Delay(1);
|
||||
|
|
@ -252,23 +255,16 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
WaitForTempStream.WaitAfterReachTempTime = config.TempStabilizationTime;
|
||||
|
||||
// Create the printer
|
||||
testRunner.AddAndSelectPrinter(make, model);
|
||||
|
||||
// edit the com port
|
||||
testRunner.SwitchToPrinterSettings();
|
||||
testRunner.AddAndSelectPrinter(make, model)
|
||||
.SwitchToPrinterSettings();
|
||||
|
||||
var serialPortDropDown = testRunner.GetWidgetByName("com_port Field", out _, 1);
|
||||
|
||||
testRunner.WaitFor(() => serialPortDropDown.Enabled); // Wait until the serialPortDropDown is ready to click it. Ensures the printer is loaded.
|
||||
|
||||
testRunner.ClickByName("com_port Field");
|
||||
|
||||
testRunner.ClickByName("Emulator Menu Item");
|
||||
|
||||
// connect to the created printer
|
||||
testRunner.ClickByName("Connect to printer button");
|
||||
|
||||
testRunner.WaitForName("Disconnect from printer button");
|
||||
testRunner.ClickByName("com_port Field")
|
||||
.ClickByName("Emulator Menu Item")
|
||||
.ClickByName("Connect to printer button") // connect to the created printer
|
||||
.WaitForName("Disconnect from printer button");
|
||||
|
||||
// replace the old behavior of clicking the 'Already Loaded' button by setting to filament_has_been_loaded.
|
||||
ApplicationController.Instance.ActivePrinters.First().Settings.SetValue(SettingsKey.filament_has_been_loaded, "1");
|
||||
|
|
@ -279,22 +275,22 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
return Emulator.Instance;
|
||||
}
|
||||
|
||||
public static void CancelPrint(this AutomationRunner testRunner)
|
||||
public static AutomationRunner CancelPrint(this AutomationRunner testRunner)
|
||||
{
|
||||
// If the pause/resume dialog is open, dismiss it before canceling the print
|
||||
if (testRunner.WaitForName("Yes Button", 1))
|
||||
if (testRunner.NamedWidgetExists("Yes Button"))
|
||||
{
|
||||
testRunner.ClickByName("Yes Button");
|
||||
}
|
||||
|
||||
testRunner.WaitForWidgetEnabled("Print Progress Dial", 15);
|
||||
testRunner.WaitForWidgetEnabled("Print Progress Dial", 15)
|
||||
.WaitForWidgetEnabled("Stop Task Button")
|
||||
.ClickByName("Stop Task Button")
|
||||
.WaitForName("Ok Button", 10); // Wait for and dismiss the new PrintCompleted dialog
|
||||
|
||||
testRunner.WaitForWidgetEnabled("Stop Task Button");
|
||||
testRunner.ClickByName("Stop Task Button");
|
||||
|
||||
// Wait for and dismiss the new PrintCompleted dialog
|
||||
testRunner.WaitForName("Ok Button", 10);
|
||||
testRunner.ClickByName("Ok Button");
|
||||
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
public static void WaitForLayer(this Emulator emulator, PrinterSettings printerSettings, int layerNumber, double secondsToWait = 30)
|
||||
|
|
@ -343,16 +339,13 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
testRunner.ClickByName("Yes Button");
|
||||
}
|
||||
|
||||
public static void AddAndSelectPrinter(this AutomationRunner testRunner, string make = "Airwolf 3D", string model = "HD")
|
||||
public static AutomationRunner AddAndSelectPrinter(this AutomationRunner testRunner, string make = "Airwolf 3D", string model = "HD")
|
||||
{
|
||||
testRunner.GetWidgetByName("PartPreviewContent", out SystemWindow systemWindow, 10);
|
||||
|
||||
// make sure we wait for MC to be up and running
|
||||
testRunner.WaitforDraw(systemWindow);
|
||||
testRunner.WaitforDraw(systemWindow) // make sure we wait for MC to be up and running
|
||||
.EnsureWelcomePageClosed(); // close the welcome message
|
||||
|
||||
// close the welcome message
|
||||
testRunner.EnsureWelcomePageClosed();
|
||||
testRunner.Delay();
|
||||
if (testRunner.NamedWidgetExists("Cancel Wizard Button"))
|
||||
{
|
||||
testRunner.ClickByName("Cancel Wizard Button");
|
||||
|
|
@ -388,26 +381,21 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
});
|
||||
|
||||
// Apply filter
|
||||
testRunner.ClickByName("Search");
|
||||
testRunner.Type(model);
|
||||
testRunner.Type("{Enter}");
|
||||
testRunner.ClickByName("Search")
|
||||
.Type(model)
|
||||
.Type("{Enter}")
|
||||
.Delay()
|
||||
.ClickByName($"Node{make}{model}") // Click printer node
|
||||
.ClickByName("Next Button") // Continue to next page
|
||||
.Delay()
|
||||
.WaitFor(() => testRunner.ChildExists<SetupStepComPortOne>());
|
||||
testRunner.ClickByName("Cancel Wizard Button")
|
||||
.WaitFor(() => !testRunner.ChildExists<SetupStepComPortOne>());
|
||||
|
||||
// Click printer node
|
||||
testRunner.Delay();
|
||||
testRunner.ClickByName($"Node{make}{model}");
|
||||
|
||||
// Continue to next page
|
||||
testRunner.ClickByName("Next Button");
|
||||
|
||||
testRunner.Delay();
|
||||
|
||||
testRunner.WaitFor(() => testRunner.ChildExists<SetupStepComPortOne>());
|
||||
testRunner.ClickByName("Cancel Wizard Button");
|
||||
|
||||
testRunner.WaitFor(() => !testRunner.ChildExists<SetupStepComPortOne>());
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
public static void EnsureWelcomePageClosed(this AutomationRunner testRunner)
|
||||
public static AutomationRunner EnsureWelcomePageClosed(this AutomationRunner testRunner)
|
||||
{
|
||||
// Close the WelcomePage window if active
|
||||
if (testRunner.GetWidgetByName("HeaderRow", out _) is GuiWidget headerRow
|
||||
|
|
@ -416,6 +404,10 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
{
|
||||
testRunner.ClickByName("Cancel Wizard Button");
|
||||
}
|
||||
|
||||
testRunner.WaitFor(() => !testRunner.NameExists("Cancel Wizard Button", .1));
|
||||
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
public static void WaitForAndCancelPrinterSetupPage(this AutomationRunner testRunner)
|
||||
|
|
@ -511,6 +503,32 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
testRunner.ClickByName("User Options Menu");
|
||||
}
|
||||
|
||||
public static AutomationRunner ClickButton(this AutomationRunner testRunner, string buttonName, string buttonText, double maxWait = 5)
|
||||
{
|
||||
testRunner.WaitForName(buttonName, maxWait, predicate: (w) => w.Children.FirstOrDefault().Text == buttonText);
|
||||
testRunner.ClickByName(buttonName);
|
||||
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
public static AutomationRunner ClickResumeButton(this AutomationRunner testRunner,
|
||||
PrinterConfig printer,
|
||||
bool resume,
|
||||
int expectedLayer)
|
||||
{
|
||||
var buttonName = resume ? "Yes Button" : "No Button";
|
||||
var buttonText = resume ? "Resume" : "OK";
|
||||
testRunner.WaitForName(buttonName, 90, predicate: (w) => w.Children.FirstOrDefault().Text == buttonText);
|
||||
Assert.AreEqual(expectedLayer,
|
||||
printer.Connection.CurrentlyPrintingLayer,
|
||||
$"Expected the paused layer to be {expectedLayer} but was {printer.Connection.CurrentlyPrintingLayer}.");
|
||||
|
||||
testRunner.ClickByName(buttonName);
|
||||
testRunner.WaitFor(() => !testRunner.NameExists(buttonName), 2);
|
||||
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
public static void NavigateToFolder(this AutomationRunner testRunner, string libraryRowItemName)
|
||||
{
|
||||
testRunner.EnsureContentMenuOpen();
|
||||
|
|
@ -594,8 +612,8 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
testRunner.ClickByName("SetupPrinter");
|
||||
|
||||
// Configure ABS as selected material
|
||||
//testRunner.ClickByName("Material DropDown List");
|
||||
//testRunner.ClickByName("ABS Menu");
|
||||
// testRunner.ClickByName("Material DropDown List");
|
||||
// testRunner.ClickByName("ABS Menu");
|
||||
|
||||
// Currently material selection is not required, simply act of clicking 'Select' clears setup required
|
||||
testRunner.ClickByName("Already Loaded Button");
|
||||
|
|
@ -659,7 +677,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
testRunner.WaitForWidgetDisappear("Automation Dialog TextEdit", 5);
|
||||
}
|
||||
|
||||
public static void AddItemToBedplate(this AutomationRunner testRunner, string containerName = "Calibration Parts Row Item Collection", string partName = "Row Item Calibration - Box.stl")
|
||||
public static AutomationRunner AddItemToBedplate(this AutomationRunner testRunner, string containerName = "Calibration Parts Row Item Collection", string partName = "Row Item Calibration - Box.stl")
|
||||
{
|
||||
if (!testRunner.NameExists(partName, 1) && !string.IsNullOrEmpty(containerName))
|
||||
{
|
||||
|
|
@ -671,6 +689,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
{
|
||||
testRunner.ClickByName(partName);
|
||||
}
|
||||
|
||||
testRunner.ClickByName("Print Library Overflow Menu");
|
||||
|
||||
var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget;
|
||||
|
|
@ -686,6 +705,8 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
{
|
||||
testRunner.WaitFor(() => scene.Children.LastOrDefault() as InsertionGroupObject3D != null, 10);
|
||||
}
|
||||
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
public static void SaveBedplateToFolder(this AutomationRunner testRunner, string newFileName, string folderName)
|
||||
|
|
@ -706,17 +727,19 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
testRunner.Delay(2);
|
||||
}
|
||||
|
||||
public static void WaitForPrintFinished(this AutomationRunner testRunner, PrinterConfig printer, int maxSeconds = 500)
|
||||
public static AutomationRunner WaitForPrintFinished(this AutomationRunner testRunner, PrinterConfig printer, int maxSeconds = 500)
|
||||
{
|
||||
testRunner.WaitFor(() => printer.Connection.CommunicationState == CommunicationStates.FinishedPrint, maxSeconds);
|
||||
// click the ok button on the print complete dialog
|
||||
testRunner.ClickByName("Ok Button");
|
||||
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a reference to the first and only active printer. Throws if called when multiple active printers exists
|
||||
/// </summary>
|
||||
/// <param name="testRunner"></param>
|
||||
/// <param name="testRunner">The AutomationRunner in use</param>
|
||||
/// <returns>The first active printer</returns>
|
||||
public static PrinterConfig FirstPrinter(this AutomationRunner testRunner)
|
||||
{
|
||||
|
|
@ -753,8 +776,8 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
string defaultTestImages = null)
|
||||
{
|
||||
// Walk back a step in the stack and output the callers name
|
||||
//StackTrace st = new StackTrace(false);
|
||||
//Debug.WriteLine("\r\n ***** Running automation test: {0} {1} ", st.GetFrames().Skip(1).First().GetMethod().Name, DateTime.Now);
|
||||
// StackTrace st = new StackTrace(false);
|
||||
// Debug.WriteLine("\r\n ***** Running automation test: {0} {1} ", st.GetFrames().Skip(1).First().GetMethod().Name, DateTime.Now);
|
||||
|
||||
if (staticDataPathOverride == null)
|
||||
{
|
||||
|
|
@ -771,7 +794,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
Environment.CurrentDirectory = TestContext.CurrentContext.ResolveProjectPath(5, "MatterControl", "bin", outputDirectory);
|
||||
|
||||
// Override the default SystemWindow type without config.json
|
||||
//AggContext.Config.ProviderTypes.SystemWindowProvider = "MatterHackers.Agg.UI.OpenGLWinformsWindowProvider, agg_platform_win32";
|
||||
// AggContext.Config.ProviderTypes.SystemWindowProvider = "MatterHackers.Agg.UI.OpenGLWinformsWindowProvider, agg_platform_win32";
|
||||
AggContext.Config.ProviderTypes.SystemWindowProvider = "MatterHackers.MatterControl.WinformsSingleWindowProvider, MatterControl.Winforms";
|
||||
|
||||
#if !__ANDROID__
|
||||
|
|
@ -792,7 +815,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
}
|
||||
|
||||
UserSettings.Instance.set(UserSettingsKey.ThumbnailRenderingMode, "orthographic");
|
||||
//GL.HardwareAvailable = false;
|
||||
// GL.HardwareAvailable = false;
|
||||
|
||||
var config = TestAutomationConfig.Load();
|
||||
if (config.UseAutomationDialogs)
|
||||
|
|
@ -891,12 +914,13 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
Environment.CurrentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
}
|
||||
|
||||
public static void StartSlicing(this AutomationRunner testRunner)
|
||||
public static AutomationRunner StartSlicing(this AutomationRunner testRunner)
|
||||
{
|
||||
testRunner.ClickByName("Generate Gcode Button");
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
public static void OpenPrintPopupMenu(this AutomationRunner testRunner)
|
||||
public static AutomationRunner OpenPrintPopupMenu(this AutomationRunner testRunner)
|
||||
{
|
||||
var printerConnection = ApplicationController.Instance.DragDropData.View3DWidget.Printer.Connection;
|
||||
|
||||
|
|
@ -912,13 +936,16 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
|
||||
// Wait for child control
|
||||
testRunner.WaitForName("Start Print Button");
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open the Print popup menu and click the Start Print button
|
||||
/// </summary>
|
||||
/// <param name="testRunner"></param>
|
||||
public static void StartPrint(this AutomationRunner testRunner, string pauseAtLayers = null)
|
||||
/// <param name="testRunner">The AutomationRunner we are using.</param>
|
||||
/// <param name="pauseAtLayers">The string to write into the pause field in the print menu.</param>
|
||||
/// <returns></returns>
|
||||
public static AutomationRunner StartPrint(this AutomationRunner testRunner, string pauseAtLayers = null)
|
||||
{
|
||||
// Open popup
|
||||
testRunner.OpenPrintPopupMenu();
|
||||
|
|
@ -932,6 +959,20 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
}
|
||||
|
||||
testRunner.ClickByName("Start Print Button");
|
||||
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
public static AutomationRunner WaitForPause(this AutomationRunner testRunner, PrinterConfig printer, int expectedLayer)
|
||||
{
|
||||
testRunner.WaitForName("Yes Button", 15, predicate: (w) => w.Children.FirstOrDefault().Text == "Resume");
|
||||
// validate the current layer
|
||||
if (expectedLayer != printer.Connection.CurrentlyPrintingLayer)
|
||||
{
|
||||
throw new Exception($"Expected the paused layer to be {expectedLayer} but was {printer.Connection.CurrentlyPrintingLayer}.");
|
||||
}
|
||||
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
public static void OpenPrintPopupAdvanced(this AutomationRunner testRunner)
|
||||
|
|
@ -960,7 +1001,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
/// <summary>
|
||||
/// Switch to the primary SliceSettings tab
|
||||
/// </summary>
|
||||
/// <param name="testRunner"></param>
|
||||
/// <param name="testRunner">The AutomationRunner in use</param>
|
||||
public static void SwitchToSliceSettings(this AutomationRunner testRunner)
|
||||
{
|
||||
EnsurePrinterSidebarOpen(testRunner);
|
||||
|
|
@ -970,19 +1011,19 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
testRunner.ClickByName("Slice Settings Tab");
|
||||
}
|
||||
|
||||
public static void Complete9StepLeveling(this AutomationRunner testRunner, int numUpClicks = 1)
|
||||
public static AutomationRunner WaitForPageAndAdvance(this AutomationRunner testRunner, string headerText)
|
||||
{
|
||||
void waitForPageAndAdvance(string headerText)
|
||||
{
|
||||
testRunner.WaitForPage(headerText);
|
||||
testRunner.ClickByName("Next Button");
|
||||
}
|
||||
testRunner.WaitForPage(headerText)
|
||||
.ClickByName("Next Button");
|
||||
|
||||
testRunner.Delay();
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
waitForPageAndAdvance("Print Leveling Overview");
|
||||
|
||||
waitForPageAndAdvance("Heating the printer");
|
||||
public static AutomationRunner Complete9StepLeveling(this AutomationRunner testRunner, int numUpClicks = 1)
|
||||
{
|
||||
testRunner.Delay()
|
||||
.WaitForPageAndAdvance("Print Leveling Overview")
|
||||
.WaitForPageAndAdvance("Heating the printer");
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
|
|
@ -995,19 +1036,17 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
testRunner.ClickByName("Move Z positive");
|
||||
}
|
||||
|
||||
testRunner.WaitForPage($"Step {section} of 9");
|
||||
testRunner.ClickByName("Next Button");
|
||||
|
||||
testRunner.WaitForPage($"Step {section + 1} of 9");
|
||||
testRunner.ClickByName("Next Button");
|
||||
|
||||
testRunner.WaitForPage($"Step {section + 2} of 9");
|
||||
testRunner.ClickByName("Next Button");
|
||||
testRunner.WaitForPage($"Step {section} of 9")
|
||||
.ClickByName("Next Button")
|
||||
.WaitForPage($"Step {section + 1} of 9")
|
||||
.ClickByName("Next Button")
|
||||
.WaitForPage($"Step {section + 2} of 9")
|
||||
.ClickByName("Next Button");
|
||||
}
|
||||
|
||||
testRunner.ClickByName("Done Button");
|
||||
testRunner.ClickByName("Done Button")
|
||||
.Delay();
|
||||
|
||||
testRunner.Delay();
|
||||
if (testRunner.NameExists("Already Loaded Button", 0.2))
|
||||
{
|
||||
testRunner.ClickByName("Already Loaded Button");
|
||||
|
|
@ -1015,12 +1054,14 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
|
||||
// Close the staged wizard window
|
||||
testRunner.ClickByName("Cancel Wizard Button");
|
||||
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Switch to printer settings
|
||||
/// </summary>
|
||||
/// <param name="testRunner"></param>
|
||||
/// <param name="testRunner">The AutomationRunner in use</param>
|
||||
public static void SwitchToPrinterSettings(this AutomationRunner testRunner)
|
||||
{
|
||||
EnsurePrinterSidebarOpen(testRunner);
|
||||
|
|
@ -1030,6 +1071,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
testRunner.ClickByName("Printer Overflow Menu");
|
||||
testRunner.ClickByName("Configure Printer Menu Item");
|
||||
}
|
||||
|
||||
testRunner.ClickByName("Printer Tab");
|
||||
}
|
||||
|
||||
|
|
@ -1085,7 +1127,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
/// <summary>
|
||||
/// Switch to Printer -> Controls
|
||||
/// </summary>
|
||||
/// <param name="testRunner"></param>
|
||||
/// <param name="testRunner">The AutomationRunner in use</param>
|
||||
public static void SwitchToControlsTab(this AutomationRunner testRunner)
|
||||
{
|
||||
// Change to Printer Controls
|
||||
|
|
@ -1103,7 +1145,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
/// <summary>
|
||||
/// Switch to Printer -> Terminal
|
||||
/// </summary>
|
||||
/// <param name="testRunner"></param>
|
||||
/// <param name="testRunner">The AutomationRunner in use</param>
|
||||
public static void SwitchToTerminalTab(this AutomationRunner testRunner)
|
||||
{
|
||||
// Change to Printer Controls
|
||||
|
|
@ -1121,7 +1163,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
/// <summary>
|
||||
/// Switch to Printer -> GCode Tab - NOTE: as a short term hack this helper as adds content to the bed and slices to ensure GCode view options appear as expected
|
||||
/// </summary>
|
||||
/// <param name="testRunner"></param>
|
||||
/// <param name="testRunner">The AutomationRunner in use</param>
|
||||
public static void SwitchToGCodeTab(this AutomationRunner testRunner)
|
||||
{
|
||||
testRunner.ClickByName("Layers3D Button");
|
||||
|
|
@ -1145,7 +1187,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
/// <summary>
|
||||
/// Adds the given asset names to the local library and validates the result
|
||||
/// </summary>
|
||||
/// <param name="testRunner"></param>
|
||||
/// <param name="testRunner">The AutomationRunner in use</param>
|
||||
/// <param name="assetNames">The test assets to add to the library</param>
|
||||
public static void AddTestAssetsToLibrary(this AutomationRunner testRunner, IEnumerable<string> assetNames, string targetLibrary = "Local Library Row Item Collection")
|
||||
{
|
||||
|
|
@ -1183,7 +1225,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
/// <summary>
|
||||
/// Control clicks each specified item
|
||||
/// </summary>
|
||||
/// <param name="testRunner"></param>
|
||||
/// <param name="testRunner">The AutomationRunner in use</param>
|
||||
/// <param name="widgetNames">The widgets to click</param>
|
||||
public static void SelectListItems(this AutomationRunner testRunner, params string[] widgetNames)
|
||||
{
|
||||
|
|
@ -1193,6 +1235,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
{
|
||||
testRunner.ClickByName(widgetName);
|
||||
}
|
||||
|
||||
Keyboard.SetKeyDownState(Keys.ControlKey, down: false);
|
||||
}
|
||||
}
|
||||
|
|
@ -1210,7 +1253,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
|
||||
public class TestAutomationConfig
|
||||
{
|
||||
private static readonly string configPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "MHTest.config");
|
||||
private static readonly string ConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "MHTest.config");
|
||||
|
||||
/// <summary>
|
||||
/// The ClientToken used by tests to emulate an external client
|
||||
|
|
@ -1246,14 +1289,14 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
{
|
||||
TestAutomationConfig config = null;
|
||||
|
||||
if (!File.Exists(configPath))
|
||||
if (!File.Exists(ConfigPath))
|
||||
{
|
||||
config = new TestAutomationConfig();
|
||||
config.Save();
|
||||
}
|
||||
else
|
||||
{
|
||||
config = JsonConvert.DeserializeObject<TestAutomationConfig>(File.ReadAllText(configPath));
|
||||
config = JsonConvert.DeserializeObject<TestAutomationConfig>(File.ReadAllText(ConfigPath));
|
||||
}
|
||||
|
||||
return config;
|
||||
|
|
@ -1264,7 +1307,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
File.WriteAllText(configPath, JsonConvert.SerializeObject(this, Formatting.Indented));
|
||||
File.WriteAllText(ConfigPath, JsonConvert.SerializeObject(this, Formatting.Indented));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue