diff --git a/.gitignore b/.gitignore index f4531ab50..6e12d892c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,8 @@ # mstest test results TestResults -Tests/temp +Tests/temp/ +Tests/TestData/ExportedGcode/ StaticData/Translations/L10N/ @@ -120,3 +121,4 @@ MatterControl.userprefs # JetBrains Rider user configuration directory /.idea/ +/MainOutputDirectory.cs diff --git a/App.config b/App.config deleted file mode 100644 index 12ace6c0f..000000000 --- a/App.config +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/Community.CsharpSqlite/app.config b/Community.CsharpSqlite/app.config deleted file mode 100644 index 57f307ff6..000000000 --- a/Community.CsharpSqlite/app.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/Launcher/Launcher.csproj b/Launcher/Launcher.csproj index d9884aa52..f427c4485 100644 --- a/Launcher/Launcher.csproj +++ b/Launcher/Launcher.csproj @@ -1,54 +1,15 @@ - - + + net6.0 Release - AnyCPU - 8.0.50727 - 2.0 Exe - {3DF4CB3D-9A03-4256-9A81-70523AAD828B} - bin\Release\ - Properties MatterHackers.MatterControl.Launcher - Launcher - - - - - 2.0 - v4.8 - - - - True - full - False - bin\Debug\ - DEBUG;TRACE - prompt - 4 + false True - AnyCPU - true - - - pdbonly - True - TRACE - prompt - 4 - True - AnyCPU - false - + + all + - - - - - - - \ No newline at end of file diff --git a/Launcher/Properties/launchSettings.json b/Launcher/Properties/launchSettings.json new file mode 100644 index 000000000..cf9a6528e --- /dev/null +++ b/Launcher/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "Launcher": { + "commandName": "Project", + "commandLineArgs": "C:\\Windows\\notepad.exe 1000" + } + } +} \ No newline at end of file diff --git a/Launcher/app.config b/Launcher/app.config deleted file mode 100644 index c0c3aed4e..000000000 --- a/Launcher/app.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/MainInstanceService.cs b/MainInstanceService.cs new file mode 100644 index 000000000..04a89da78 --- /dev/null +++ b/MainInstanceService.cs @@ -0,0 +1,279 @@ +// For communication with the main instance. Use ServiceWire or just pipes. +#define USE_SERVICEWIRE + +using MatterHackers.MatterControl; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Threading; +using System.Security.AccessControl; +using System.Security.Principal; + +#if USE_SERVICEWIRE +using ServiceWire; +#else +using System.IO.Pipes; +using System.Xml.Serialization; +#endif + +namespace MatterHackers.MatterControl +{ + public interface IMainService + { + void ShellOpenFile(string[] files); + } + + [Serializable] + public class LocalService : IMainService + { + private const string ServicePipeName = "MatterControlMainInstance"; + +#if USE_SERVICEWIRE + private const string MainInstanceMutexName = "MatterControlMainInstanceMutex"; +#pragma warning disable IDE0052 // Remove unread private members + // Don't let the GC clean this up. + private static Mutex MainInstanceMutex = null; +#pragma warning restore IDE0052 // Remove unread private members +#else + static string readPipeMessage(PipeStream pipe) + { + MemoryStream ms = new MemoryStream(); + using var cancellation = new CancellationTokenSource(); + byte[] buffer = new byte[1024]; + do + { + var task = pipe.ReadAsync(buffer, 0, buffer.Length, cancellation.Token); + cancellation.CancelAfter(1000); + task.Wait(); + ms.Write(buffer, 0, task.Result); + if (task.Result <= 0) + break; + } while (!pipe.IsMessageComplete); + + return Encoding.Unicode.GetString(ms.ToArray()); + } +#endif + + private static readonly object locker = new(); + + public static bool TryStartServer() + { +#if USE_SERVICEWIRE + // ServiceWire will allow lots of pipes to exist under the same name, so a mutex is needed. + // Locking isn't needed. Windows should clean up when the main instance closes. + Mutex mutex = new(false, MainInstanceMutexName, out bool createdNew); + try + { + if (createdNew) + { + try + { + var host = new ServiceWire.NamedPipes.NpHost(ServicePipeName, new ServiceWireLogger()); + host.AddService(new LocalService()); + host.Open(); + + // Keep the mutex alive. + MainInstanceMutex = mutex; + mutex = null; + + return true; + } + catch (Exception) + { + } + } + } + finally + { + // Not the main instance. Release the handle. + mutex?.Dispose(); + } + + return false; +#else + NamedPipeServerStream pipeServer = null; + try + { + pipeServer = new NamedPipeServerStream(ServicePipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.CurrentUserOnly); + } + catch (IOException) + { + return false; + } + + new Task(() => + { + try + { + var localService = new LocalService(); + + for (; ; ) + { + pipeServer.WaitForConnection(); + + try + { + string str = readPipeMessage(pipeServer); + + var serializer = new XmlSerializer(typeof(InstancePipeMessage)); + var message = (InstancePipeMessage)serializer.Deserialize(new StringReader(str)); + localService.ShellOpenFile(message.Paths); + + using var cancellation = new CancellationTokenSource(); + var task = pipeServer.WriteAsync(Encoding.Unicode.GetBytes("ok"), cancellation.Token).AsTask(); + cancellation.CancelAfter(1000); + task.Wait(); + } + catch (Exception) + { + } + + // NamedPipeServerStream can only handle one client ever. Need a new server pipe. ServiceWire does the same thing. + // So here, there is a time where there is no server pipe. Another instance could become the main instance. + // NamedPipeClientStream.Connect should retry the connection. + pipeServer.Dispose(); + pipeServer = new NamedPipeServerStream(ServicePipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.CurrentUserOnly); + } + } + catch (Exception ex) // TimeoutException or IOException + { + //System.Windows.Forms.MessageBox.Show(ex.ToString()); + System.Diagnostics.Trace.WriteLine("Main instance pipe server died: " + ex.ToString()); + } + + pipeServer.Dispose(); + pipeServer = null; + }).Start(); + + return true; +#endif + } + + public static bool TrySendToServer(string[] shellFiles) + { +#if USE_SERVICEWIRE + try + { + using (var client = new ServiceWire.NamedPipes.NpClient(new ServiceWire.NamedPipes.NpEndPoint(ServicePipeName))) + { + if (client.IsConnected) + { + // notify the running instance of the event + client.Proxy.ShellOpenFile(shellFiles); + + System.Threading.Thread.Sleep(1000); + + // Finally, close the process spawned by Explorer.exe + return true; + } + } + } + catch (Exception) + { + } +#else + try + { + using var pipeClient = new NamedPipeClientStream(".", ServicePipeName, PipeDirection.InOut, PipeOptions.CurrentUserOnly); + pipeClient.Connect(1000); + pipeClient.ReadMode = PipeTransmissionMode.Message; + + StringBuilder sb = new(); + using (var writer = new StringWriter(sb)) + new XmlSerializer(typeof(InstancePipeMessage)).Serialize(writer, new InstancePipeMessage { Paths = shellFiles.ToArray() }); + + using var cancellation = new CancellationTokenSource(); + var task = pipeClient.WriteAsync(Encoding.Unicode.GetBytes(sb.ToString()), cancellation.Token).AsTask(); + cancellation.CancelAfter(1000); + task.Wait(); + if (task.IsCompletedSuccessfully && readPipeMessage(pipeClient).Trim() == "ok") + return true; + } + catch (Exception ex) // TimeoutException or IOException + { + //System.Windows.Forms.MessageBox.Show(ex.ToString()); + System.Diagnostics.Trace.WriteLine("Instance pipe client died: " + ex.ToString()); + } +#endif + + return false; + } + + public void ShellOpenFile(string[] files) + { + // If at least one argument is an acceptable shell file extension + var itemsToAdd = files.Where(f => File.Exists(f) + && ApplicationController.ShellFileExtensions.Contains(Path.GetExtension(f).ToLower())); + + if (itemsToAdd.Any()) + { + lock (locker) + { + // Add each file + foreach (string file in itemsToAdd) + { + ApplicationController.Instance.ShellOpenFile(file); + } + } + } + } + + + +#if USE_SERVICEWIRE + private class ServiceWireLogger : ServiceWire.ILog + { + static private void Log(ServiceWire.LogLevel level, string formattedMessage, params object[] args) + { + // Handled as in https://github.com/tylerjensen/ServiceWire/blob/master/src/ServiceWire/Logger.cs + + if (null == formattedMessage) + return; + + if (level <= LogLevel.Warn) + { + string msg = (null != args && args.Length > 0) + ? string.Format(formattedMessage, args) + : formattedMessage; + + System.Diagnostics.Trace.WriteLine(msg); + } + } + + void ILog.Debug(string formattedMessage, params object[] args) + { + Log(LogLevel.Debug, formattedMessage, args); + } + + void ILog.Error(string formattedMessage, params object[] args) + { + Log(LogLevel.Error, formattedMessage, args); + } + + void ILog.Fatal(string formattedMessage, params object[] args) + { + Log(LogLevel.Fatal, formattedMessage, args); + } + + void ILog.Info(string formattedMessage, params object[] args) + { + Log(LogLevel.Info, formattedMessage, args); + } + + void ILog.Warn(string formattedMessage, params object[] args) + { + Log(LogLevel.Warn, formattedMessage, args); + } + } +#else + [Serializable] + public struct InstancePipeMessage + { + public string[] Paths; + } +#endif + } +} diff --git a/MatterControl.Common/MatterControl.Common.csproj b/MatterControl.Common/MatterControl.Common.csproj index 1e8458629..1dd56b219 100644 --- a/MatterControl.Common/MatterControl.Common.csproj +++ b/MatterControl.Common/MatterControl.Common.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + net6.0 MatterHackers Inc. true 2.20.12 diff --git a/MatterControl.MeshOperations/MatterControl.MeshOperations.csproj b/MatterControl.MeshOperations/MatterControl.MeshOperations.csproj index 2a52fe411..e8f1f40ef 100644 --- a/MatterControl.MeshOperations/MatterControl.MeshOperations.csproj +++ b/MatterControl.MeshOperations/MatterControl.MeshOperations.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + net6.0 MatterHackers Inc. true 2.20.12 diff --git a/MatterControl.OpenGL/MatterControl.OpenGL.csproj b/MatterControl.OpenGL/MatterControl.OpenGL.csproj index 950501308..ab675da1a 100644 --- a/MatterControl.OpenGL/MatterControl.OpenGL.csproj +++ b/MatterControl.OpenGL/MatterControl.OpenGL.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + net6.0 MatterHackers Inc. true 2.20.12 diff --git a/MatterControl.Printing/MatterControl.Printing.csproj b/MatterControl.Printing/MatterControl.Printing.csproj index f76342677..9fb4cc09a 100644 --- a/MatterControl.Printing/MatterControl.Printing.csproj +++ b/MatterControl.Printing/MatterControl.Printing.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + net6.0 MatterHackers Inc. true 2.20.12 @@ -13,6 +13,7 @@ + diff --git a/MatterControl.SLA/MatterControl.SLA.csproj b/MatterControl.SLA/MatterControl.SLA.csproj index e3955a7d3..74eaf264e 100644 --- a/MatterControl.SLA/MatterControl.SLA.csproj +++ b/MatterControl.SLA/MatterControl.SLA.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + net6.0 MatterHackers Inc. true 2.20.12 diff --git a/MatterControl.Winforms/MatterControl.Winforms.csproj b/MatterControl.Winforms/MatterControl.Winforms.csproj index a484a9f43..5826623fd 100644 --- a/MatterControl.Winforms/MatterControl.Winforms.csproj +++ b/MatterControl.Winforms/MatterControl.Winforms.csproj @@ -1,109 +1,35 @@ - - - + - Debug - AnyCPU - {D6DC2669-7B1F-40FE-89BF-45D4C94473E3} + net6.0-windows Library - Properties - MatterControl.Winforms - MatterControl.Winforms - v4.8 - 512 - true - + false + true + true + $(SolutionDir)bin - true - full - false - ..\bin\Debug\ TRACE;DEBUG;USE_OPENGL;IS_WINDOWS;IS_WINDOWS_FORMS - prompt - 4 - AnyCPU - pdbonly - true - ..\bin\Release\ TRACE;USE_OPENGL;IS_WINDOWS;IS_WINDOWS_FORMS - prompt - 4 - AnyCPU - - - - - - - - - - + + + + + + + + + + - - - - Form - - - InspectForm.cs - - - - + + + + all + - - - {f1653f20-d47d-4f29-8c55-3c835542af5f} - Community.CsharpSqlite - - - {2af30557-fc50-4de3-ad1c-7eb57131a9c5} - MatterControl.Common - - - {D557B079-612F-467F-AE0D-3F77BCD627F7} - MatterControlLib - - - {657dbc6d-c3ea-4398-a3fa-ddb73c14f71b} - Agg - - - {94838988-523c-4b11-ad82-8b9b76f23a31} - DataConverters2D - - - {04667764-dc7b-4b95-aef6-b4e6c87a54e9} - DataConverters3D - - - {74f6bb6c-9d02-4512-a59a-21940e35c532} - Gui - - - {CD8A3D1A-24D5-4184-8CF3-7B2AD5CD7A71} - PlatformWin32 - - - {545b6912-77ff-4b34-ba76-6c3d6a32be6a} - RenderOpenGl - - - {d3e41b4e-bfbb-44ca-94c8-95c00f754fdd} - VectorMath - - - - - InspectForm.cs - - - \ No newline at end of file diff --git a/MatterControl.Winforms/Properties/AssemblyInfo.cs b/MatterControl.Winforms/Properties/AssemblyInfo.cs index 1035c00bb..e4310dbee 100644 --- a/MatterControl.Winforms/Properties/AssemblyInfo.cs +++ b/MatterControl.Winforms/Properties/AssemblyInfo.cs @@ -34,3 +34,6 @@ using System.Runtime.InteropServices; // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] + +// https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1416 +[assembly: System.Runtime.Versioning.SupportedOSPlatform("windows7.0")] \ No newline at end of file diff --git a/MatterControl.Winforms/WindowsPlatformsFeatures.cs b/MatterControl.Winforms/WindowsPlatformsFeatures.cs index 8bd82a084..50b515b3c 100644 --- a/MatterControl.Winforms/WindowsPlatformsFeatures.cs +++ b/MatterControl.Winforms/WindowsPlatformsFeatures.cs @@ -31,6 +31,7 @@ using System; using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.Loader; using MatterHackers.Agg; using MatterHackers.Agg.Image; using MatterHackers.Agg.Platform; @@ -207,7 +208,9 @@ namespace MatterHackers.MatterControl { try { - PluginFinder.LoadTypesFromAssembly(Assembly.LoadFile(file)); + // Be sure not to load a DLL more than once! + // https://github.com/dotnet/runtime/issues/39783 + PluginFinder.LoadTypesFromAssembly(AssemblyLoadContext.Default.LoadFromAssemblyPath(file)); } catch (Exception ex) { diff --git a/MatterControl.csproj b/MatterControl.csproj index 14760918c..87ab59970 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -1,151 +1,145 @@ - - - - - Debug - AnyCPU - {B2B001EE-A142-4E20-ACF8-AE4A9CB984F8} - WinExe - MatterControl - MatterControl - v4.8 - win - 512 - - true - PackageReference - true - - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - - - - application.ico - - - - - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - - - {f1653f20-d47d-4f29-8c55-3c835542af5f} - Community.CsharpSqlite - - - {97d5ade3-c1b4-4b46-8a3e-718a4f7f079f} - MatterControl.Printing - - - {e2b1af22-4143-4b33-9781-fc5527e959f6} - MatterControl.SLA - - - {D6DC2669-7B1F-40FE-89BF-45D4C94473E3} - MatterControl.Winforms - - - {93bebfdf-b81a-4344-ab82-0dbf58b234cd} - MatterControlLib - - - {990a9ad3-b6a4-407b-9dfc-9c722af7c9b9} - InfInstaller - - - {657dbc6d-c3ea-4398-a3fa-ddb73c14f71b} - Agg - - - {4da97548-2588-4ac3-a21d-ba4fee6fe5e4} - GlfwProvider - - - {74F6BB6C-9D02-4512-A59A-21940E35C532} - Gui - - - {d3e41b4e-bfbb-44ca-94c8-95c00f754fdd} - VectorMath - - - {b0aed568-8796-42b9-baa9-ebc796134e78} - MatterSlice - - - {50505F12-985B-4C5F-8DAB-D5BEA734CD51} - MatterControl.Common - - - - - PreserveNewest - - - - - - - - - - - - - 27.2.1 - - - 5.2.9 - - - 5.13.0 - - - 1.0.2-beta1 - - - + + + net6.0-windows + WinExe + false + + + + + + application.ico + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + + + + + + + + 27.2.1 + + + + + + + 1.0.2-beta1 + + + + all + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + <_Parameter1>$(OutputPath) + <_Parameter2>$(SolutionDir) + + + + + + + \ No newline at end of file diff --git a/MatterControl.sln b/MatterControl.sln index f36386b4d..5a215e2d4 100644 --- a/MatterControl.sln +++ b/MatterControl.sln @@ -34,27 +34,27 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "clipper_library", "Submodul EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarchingSquares", "Submodules\agg-sharp\MarchingSquares\MarchingSquares.csproj", "{DF6845CD-64C6-4263-8357-DA8066855739}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Launcher", "Launcher\Launcher.csproj", "{3DF4CB3D-9A03-4256-9A81-70523AAD828B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Launcher", "Launcher\Launcher.csproj", "{3DF4CB3D-9A03-4256-9A81-70523AAD828B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "agg-sharp", "agg-sharp", "{2AB9B589-5C98-4C05-BBEA-F97DAE168EAB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfInstaller", "PrinterDriverInstaller\InfInstaller.csproj", "{990A9AD3-B6A4-407B-9DFC-9C722AF7C9B9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InfInstaller", "PrinterDriverInstaller\InfInstaller.csproj", "{990A9AD3-B6A4-407B-9DFC-9C722AF7C9B9}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{FBE6DF29-85A9-4A8B-B739-35BE4CA0A9B7}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataConverters3D", "Submodules\agg-sharp\DataConverters3D\DataConverters3D.csproj", "{04667764-DC7B-4B95-AEF6-B4E6C87A54E9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatterControl.Tests", "Tests\MatterControl.Tests\MatterControl.Tests.csproj", "{E1455E5C-127C-4282-8CC5-452C300E91D0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatterControl.Tests", "Tests\MatterControl.Tests\MatterControl.Tests.csproj", "{E1455E5C-127C-4282-8CC5-452C300E91D0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Agg.Tests", "Submodules\agg-sharp\Tests\Agg.Tests\Agg.Tests.csproj", "{195CBE56-E654-437B-AB05-3BE1B9452497}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Agg.Tests", "Submodules\agg-sharp\Tests\Agg.Tests\Agg.Tests.csproj", "{195CBE56-E654-437B-AB05-3BE1B9452497}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatterSlice.Tests", "Submodules\MatterSlice\Tests\MatterSlice.Tests\MatterSlice.Tests.csproj", "{8CD15B23-D30F-470E-99BA-9276FB7CABD4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatterSlice.Tests", "Submodules\MatterSlice\Tests\MatterSlice.Tests\MatterSlice.Tests.csproj", "{8CD15B23-D30F-470E-99BA-9276FB7CABD4}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GuiAutomation", "Submodules\agg-sharp\GuiAutomation\GuiAutomation.csproj", "{E9102310-0029-4D8F-B1E9-88FBA6147D45}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataConverters2D", "Submodules\agg-sharp\DataConverters2D\DataConverters2D.csproj", "{94838988-523C-4B11-AD82-8B9B76F23A31}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatterControl.AutomationTests", "Tests\MatterControl.AutomationTests\MatterControl.AutomationTests.csproj", "{418E7058-92EE-4329-86BA-AC26B65AFB25}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatterControl.AutomationTests", "Tests\MatterControl.AutomationTests\MatterControl.AutomationTests.csproj", "{418E7058-92EE-4329-86BA-AC26B65AFB25}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{FED00F38-E911-45E1-A788-26980E84C3D6}" EndProject @@ -72,15 +72,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatterControl.OpenGL", "Mat EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatterControl.Printing", "MatterControl.Printing\MatterControl.Printing.csproj", "{97D5ADE3-C1B4-4B46-8A3E-718A4F7F079F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatterControl.Winforms", "MatterControl.Winforms\MatterControl.Winforms.csproj", "{D6DC2669-7B1F-40FE-89BF-45D4C94473E3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatterControl.Winforms", "MatterControl.Winforms\MatterControl.Winforms.csproj", "{D6DC2669-7B1F-40FE-89BF-45D4C94473E3}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatterSliceLib", "Submodules\MatterSlice\MatterSliceLib\MatterSliceLib.csproj", "{7F077116-2923-4A77-87CC-EC3BE7EB8BC3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatterSlice", "Submodules\MatterSlice\MatterSlice.csproj", "{B0AED568-8796-42B9-BAA9-EBC796134E78}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatterSlice", "Submodules\MatterSlice\MatterSlice.csproj", "{B0AED568-8796-42B9-BAA9-EBC796134E78}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatterControlLib", "MatterControlLib\MatterControlLib.csproj", "{93BEBFDF-B81A-4344-AB82-0DBF58B234CD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatterControl", "MatterControl.csproj", "{B2B001EE-A142-4E20-ACF8-AE4A9CB984F8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatterControl", "MatterControl.csproj", "{B2B001EE-A142-4E20-ACF8-AE4A9CB984F8}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatterControl.Common", "MatterControl.Common\MatterControl.Common.csproj", "{50505F12-985B-4C5F-8DAB-D5BEA734CD51}" EndProject @@ -104,6 +104,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatterControl.SLA", "Matter EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "geometry3Sharp", "Submodules\agg-sharp\geometry3Sharp\geometry3Sharp.csproj", "{3A25C796-F676-4422-8F30-01D4FDB240F1}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestInvoker", "Submodules\agg-sharp\Tests\TestInvoker\TestInvoker.csproj", "{A1F2F1DA-2B86-461E-9602-EAB2BD899A8F}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution Submodules\agg-sharp\Typography\Typography.OpenFont\Typography.OpenFont.projitems*{235a071b-8d06-40ae-a5c5-b1ce59715ee9}*SharedItemsImports = 13 @@ -113,339 +115,177 @@ Global EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU - Debug|Mixed Platforms = Debug|Mixed Platforms Release|Any CPU = Release|Any CPU - Release|Mixed Platforms = Release|Mixed Platforms EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {AE37DE1F-22F7-49EE-8732-FC6BC8DC58D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AE37DE1F-22F7-49EE-8732-FC6BC8DC58D9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AE37DE1F-22F7-49EE-8732-FC6BC8DC58D9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {AE37DE1F-22F7-49EE-8732-FC6BC8DC58D9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {AE37DE1F-22F7-49EE-8732-FC6BC8DC58D9}.Release|Any CPU.ActiveCfg = Release|Any CPU {AE37DE1F-22F7-49EE-8732-FC6BC8DC58D9}.Release|Any CPU.Build.0 = Release|Any CPU - {AE37DE1F-22F7-49EE-8732-FC6BC8DC58D9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {AE37DE1F-22F7-49EE-8732-FC6BC8DC58D9}.Release|Mixed Platforms.Build.0 = Release|Any CPU {670BDDFF-927B-425D-9DD1-22ACB14356EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {670BDDFF-927B-425D-9DD1-22ACB14356EB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {670BDDFF-927B-425D-9DD1-22ACB14356EB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {670BDDFF-927B-425D-9DD1-22ACB14356EB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {670BDDFF-927B-425D-9DD1-22ACB14356EB}.Release|Any CPU.ActiveCfg = Release|Any CPU {670BDDFF-927B-425D-9DD1-22ACB14356EB}.Release|Any CPU.Build.0 = Release|Any CPU - {670BDDFF-927B-425D-9DD1-22ACB14356EB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {670BDDFF-927B-425D-9DD1-22ACB14356EB}.Release|Mixed Platforms.Build.0 = Release|Any CPU {D3E41B4E-BFBB-44CA-94C8-95C00F754FDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D3E41B4E-BFBB-44CA-94C8-95C00F754FDD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D3E41B4E-BFBB-44CA-94C8-95C00F754FDD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {D3E41B4E-BFBB-44CA-94C8-95C00F754FDD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {D3E41B4E-BFBB-44CA-94C8-95C00F754FDD}.Release|Any CPU.ActiveCfg = Release|Any CPU {D3E41B4E-BFBB-44CA-94C8-95C00F754FDD}.Release|Any CPU.Build.0 = Release|Any CPU - {D3E41B4E-BFBB-44CA-94C8-95C00F754FDD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {D3E41B4E-BFBB-44CA-94C8-95C00F754FDD}.Release|Mixed Platforms.Build.0 = Release|Any CPU {545B6912-77FF-4B34-BA76-6C3D6A32BE6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {545B6912-77FF-4B34-BA76-6C3D6A32BE6A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {545B6912-77FF-4B34-BA76-6C3D6A32BE6A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {545B6912-77FF-4B34-BA76-6C3D6A32BE6A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {545B6912-77FF-4B34-BA76-6C3D6A32BE6A}.Release|Any CPU.ActiveCfg = Release|Any CPU {545B6912-77FF-4B34-BA76-6C3D6A32BE6A}.Release|Any CPU.Build.0 = Release|Any CPU - {545B6912-77FF-4B34-BA76-6C3D6A32BE6A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {545B6912-77FF-4B34-BA76-6C3D6A32BE6A}.Release|Mixed Platforms.Build.0 = Release|Any CPU {74F6BB6C-9D02-4512-A59A-21940E35C532}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {74F6BB6C-9D02-4512-A59A-21940E35C532}.Debug|Any CPU.Build.0 = Debug|Any CPU - {74F6BB6C-9D02-4512-A59A-21940E35C532}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {74F6BB6C-9D02-4512-A59A-21940E35C532}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {74F6BB6C-9D02-4512-A59A-21940E35C532}.Release|Any CPU.ActiveCfg = Release|Any CPU {74F6BB6C-9D02-4512-A59A-21940E35C532}.Release|Any CPU.Build.0 = Release|Any CPU - {74F6BB6C-9D02-4512-A59A-21940E35C532}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {74F6BB6C-9D02-4512-A59A-21940E35C532}.Release|Mixed Platforms.Build.0 = Release|Any CPU {7E61A5BD-E78F-4B80-88C9-3821B4FA062E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7E61A5BD-E78F-4B80-88C9-3821B4FA062E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7E61A5BD-E78F-4B80-88C9-3821B4FA062E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {7E61A5BD-E78F-4B80-88C9-3821B4FA062E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {7E61A5BD-E78F-4B80-88C9-3821B4FA062E}.Release|Any CPU.ActiveCfg = Release|Any CPU {7E61A5BD-E78F-4B80-88C9-3821B4FA062E}.Release|Any CPU.Build.0 = Release|Any CPU - {7E61A5BD-E78F-4B80-88C9-3821B4FA062E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {7E61A5BD-E78F-4B80-88C9-3821B4FA062E}.Release|Mixed Platforms.Build.0 = Release|Any CPU {86F6AAF2-9B50-40B8-A427-1897D76471C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {86F6AAF2-9B50-40B8-A427-1897D76471C5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {86F6AAF2-9B50-40B8-A427-1897D76471C5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {86F6AAF2-9B50-40B8-A427-1897D76471C5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {86F6AAF2-9B50-40B8-A427-1897D76471C5}.Release|Any CPU.ActiveCfg = Release|Any CPU {86F6AAF2-9B50-40B8-A427-1897D76471C5}.Release|Any CPU.Build.0 = Release|Any CPU - {86F6AAF2-9B50-40B8-A427-1897D76471C5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {86F6AAF2-9B50-40B8-A427-1897D76471C5}.Release|Mixed Platforms.Build.0 = Release|Any CPU {657DBC6D-C3EA-4398-A3FA-DDB73C14F71B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {657DBC6D-C3EA-4398-A3FA-DDB73C14F71B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {657DBC6D-C3EA-4398-A3FA-DDB73C14F71B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {657DBC6D-C3EA-4398-A3FA-DDB73C14F71B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {657DBC6D-C3EA-4398-A3FA-DDB73C14F71B}.Release|Any CPU.ActiveCfg = Release|Any CPU {657DBC6D-C3EA-4398-A3FA-DDB73C14F71B}.Release|Any CPU.Build.0 = Release|Any CPU - {657DBC6D-C3EA-4398-A3FA-DDB73C14F71B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {657DBC6D-C3EA-4398-A3FA-DDB73C14F71B}.Release|Mixed Platforms.Build.0 = Release|Any CPU {F1653F20-D47D-4F29-8C55-3C835542AF5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F1653F20-D47D-4F29-8C55-3C835542AF5F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F1653F20-D47D-4F29-8C55-3C835542AF5F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {F1653F20-D47D-4F29-8C55-3C835542AF5F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {F1653F20-D47D-4F29-8C55-3C835542AF5F}.Release|Any CPU.ActiveCfg = Release|Any CPU {F1653F20-D47D-4F29-8C55-3C835542AF5F}.Release|Any CPU.Build.0 = Release|Any CPU - {F1653F20-D47D-4F29-8C55-3C835542AF5F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {F1653F20-D47D-4F29-8C55-3C835542AF5F}.Release|Mixed Platforms.Build.0 = Release|Any CPU {CA96058C-1A37-465D-A357-D6D695B13D25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CA96058C-1A37-465D-A357-D6D695B13D25}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CA96058C-1A37-465D-A357-D6D695B13D25}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {CA96058C-1A37-465D-A357-D6D695B13D25}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {CA96058C-1A37-465D-A357-D6D695B13D25}.Release|Any CPU.ActiveCfg = Release|Any CPU {CA96058C-1A37-465D-A357-D6D695B13D25}.Release|Any CPU.Build.0 = Release|Any CPU - {CA96058C-1A37-465D-A357-D6D695B13D25}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {CA96058C-1A37-465D-A357-D6D695B13D25}.Release|Mixed Platforms.Build.0 = Release|Any CPU {036BCCBA-52D8-457C-84AE-8821F209FE4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {036BCCBA-52D8-457C-84AE-8821F209FE4A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {036BCCBA-52D8-457C-84AE-8821F209FE4A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {036BCCBA-52D8-457C-84AE-8821F209FE4A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {036BCCBA-52D8-457C-84AE-8821F209FE4A}.Release|Any CPU.ActiveCfg = Release|Any CPU {036BCCBA-52D8-457C-84AE-8821F209FE4A}.Release|Any CPU.Build.0 = Release|Any CPU - {036BCCBA-52D8-457C-84AE-8821F209FE4A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {036BCCBA-52D8-457C-84AE-8821F209FE4A}.Release|Mixed Platforms.Build.0 = Release|Any CPU {9B062971-A88E-4A3D-B3C9-12B78D15FA66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9B062971-A88E-4A3D-B3C9-12B78D15FA66}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9B062971-A88E-4A3D-B3C9-12B78D15FA66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {9B062971-A88E-4A3D-B3C9-12B78D15FA66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {9B062971-A88E-4A3D-B3C9-12B78D15FA66}.Release|Any CPU.ActiveCfg = Release|Any CPU {9B062971-A88E-4A3D-B3C9-12B78D15FA66}.Release|Any CPU.Build.0 = Release|Any CPU - {9B062971-A88E-4A3D-B3C9-12B78D15FA66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {9B062971-A88E-4A3D-B3C9-12B78D15FA66}.Release|Mixed Platforms.Build.0 = Release|Any CPU {DF6845CD-64C6-4263-8357-DA8066855739}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DF6845CD-64C6-4263-8357-DA8066855739}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DF6845CD-64C6-4263-8357-DA8066855739}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {DF6845CD-64C6-4263-8357-DA8066855739}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {DF6845CD-64C6-4263-8357-DA8066855739}.Release|Any CPU.ActiveCfg = Release|Any CPU {DF6845CD-64C6-4263-8357-DA8066855739}.Release|Any CPU.Build.0 = Release|Any CPU - {DF6845CD-64C6-4263-8357-DA8066855739}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {DF6845CD-64C6-4263-8357-DA8066855739}.Release|Mixed Platforms.Build.0 = Release|Any CPU {3DF4CB3D-9A03-4256-9A81-70523AAD828B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3DF4CB3D-9A03-4256-9A81-70523AAD828B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3DF4CB3D-9A03-4256-9A81-70523AAD828B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {3DF4CB3D-9A03-4256-9A81-70523AAD828B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {3DF4CB3D-9A03-4256-9A81-70523AAD828B}.Release|Any CPU.ActiveCfg = Release|Any CPU {3DF4CB3D-9A03-4256-9A81-70523AAD828B}.Release|Any CPU.Build.0 = Release|Any CPU - {3DF4CB3D-9A03-4256-9A81-70523AAD828B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {3DF4CB3D-9A03-4256-9A81-70523AAD828B}.Release|Mixed Platforms.Build.0 = Release|Any CPU {990A9AD3-B6A4-407B-9DFC-9C722AF7C9B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {990A9AD3-B6A4-407B-9DFC-9C722AF7C9B9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {990A9AD3-B6A4-407B-9DFC-9C722AF7C9B9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {990A9AD3-B6A4-407B-9DFC-9C722AF7C9B9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {990A9AD3-B6A4-407B-9DFC-9C722AF7C9B9}.Release|Any CPU.ActiveCfg = Release|Any CPU {990A9AD3-B6A4-407B-9DFC-9C722AF7C9B9}.Release|Any CPU.Build.0 = Release|Any CPU - {990A9AD3-B6A4-407B-9DFC-9C722AF7C9B9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {990A9AD3-B6A4-407B-9DFC-9C722AF7C9B9}.Release|Mixed Platforms.Build.0 = Release|Any CPU {04667764-DC7B-4B95-AEF6-B4E6C87A54E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {04667764-DC7B-4B95-AEF6-B4E6C87A54E9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {04667764-DC7B-4B95-AEF6-B4E6C87A54E9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {04667764-DC7B-4B95-AEF6-B4E6C87A54E9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {04667764-DC7B-4B95-AEF6-B4E6C87A54E9}.Release|Any CPU.ActiveCfg = Release|Any CPU {04667764-DC7B-4B95-AEF6-B4E6C87A54E9}.Release|Any CPU.Build.0 = Release|Any CPU - {04667764-DC7B-4B95-AEF6-B4E6C87A54E9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {04667764-DC7B-4B95-AEF6-B4E6C87A54E9}.Release|Mixed Platforms.Build.0 = Release|Any CPU {E1455E5C-127C-4282-8CC5-452C300E91D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E1455E5C-127C-4282-8CC5-452C300E91D0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E1455E5C-127C-4282-8CC5-452C300E91D0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {E1455E5C-127C-4282-8CC5-452C300E91D0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {E1455E5C-127C-4282-8CC5-452C300E91D0}.Release|Any CPU.ActiveCfg = Release|Any CPU {E1455E5C-127C-4282-8CC5-452C300E91D0}.Release|Any CPU.Build.0 = Release|Any CPU - {E1455E5C-127C-4282-8CC5-452C300E91D0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {E1455E5C-127C-4282-8CC5-452C300E91D0}.Release|Mixed Platforms.Build.0 = Release|Any CPU {195CBE56-E654-437B-AB05-3BE1B9452497}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {195CBE56-E654-437B-AB05-3BE1B9452497}.Debug|Any CPU.Build.0 = Debug|Any CPU - {195CBE56-E654-437B-AB05-3BE1B9452497}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {195CBE56-E654-437B-AB05-3BE1B9452497}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {195CBE56-E654-437B-AB05-3BE1B9452497}.Release|Any CPU.ActiveCfg = Release|Any CPU {195CBE56-E654-437B-AB05-3BE1B9452497}.Release|Any CPU.Build.0 = Release|Any CPU - {195CBE56-E654-437B-AB05-3BE1B9452497}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {195CBE56-E654-437B-AB05-3BE1B9452497}.Release|Mixed Platforms.Build.0 = Release|Any CPU {8CD15B23-D30F-470E-99BA-9276FB7CABD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8CD15B23-D30F-470E-99BA-9276FB7CABD4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8CD15B23-D30F-470E-99BA-9276FB7CABD4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {8CD15B23-D30F-470E-99BA-9276FB7CABD4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {8CD15B23-D30F-470E-99BA-9276FB7CABD4}.Release|Any CPU.ActiveCfg = Release|Any CPU {8CD15B23-D30F-470E-99BA-9276FB7CABD4}.Release|Any CPU.Build.0 = Release|Any CPU - {8CD15B23-D30F-470E-99BA-9276FB7CABD4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {8CD15B23-D30F-470E-99BA-9276FB7CABD4}.Release|Mixed Platforms.Build.0 = Release|Any CPU {E9102310-0029-4D8F-B1E9-88FBA6147D45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E9102310-0029-4D8F-B1E9-88FBA6147D45}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E9102310-0029-4D8F-B1E9-88FBA6147D45}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {E9102310-0029-4D8F-B1E9-88FBA6147D45}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {E9102310-0029-4D8F-B1E9-88FBA6147D45}.Release|Any CPU.ActiveCfg = Release|Any CPU {E9102310-0029-4D8F-B1E9-88FBA6147D45}.Release|Any CPU.Build.0 = Release|Any CPU - {E9102310-0029-4D8F-B1E9-88FBA6147D45}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {E9102310-0029-4D8F-B1E9-88FBA6147D45}.Release|Mixed Platforms.Build.0 = Release|Any CPU {94838988-523C-4B11-AD82-8B9B76F23A31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {94838988-523C-4B11-AD82-8B9B76F23A31}.Debug|Any CPU.Build.0 = Debug|Any CPU - {94838988-523C-4B11-AD82-8B9B76F23A31}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {94838988-523C-4B11-AD82-8B9B76F23A31}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {94838988-523C-4B11-AD82-8B9B76F23A31}.Release|Any CPU.ActiveCfg = Release|Any CPU {94838988-523C-4B11-AD82-8B9B76F23A31}.Release|Any CPU.Build.0 = Release|Any CPU - {94838988-523C-4B11-AD82-8B9B76F23A31}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {94838988-523C-4B11-AD82-8B9B76F23A31}.Release|Mixed Platforms.Build.0 = Release|Any CPU {418E7058-92EE-4329-86BA-AC26B65AFB25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {418E7058-92EE-4329-86BA-AC26B65AFB25}.Debug|Any CPU.Build.0 = Debug|Any CPU - {418E7058-92EE-4329-86BA-AC26B65AFB25}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {418E7058-92EE-4329-86BA-AC26B65AFB25}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {418E7058-92EE-4329-86BA-AC26B65AFB25}.Release|Any CPU.ActiveCfg = Release|Any CPU {418E7058-92EE-4329-86BA-AC26B65AFB25}.Release|Any CPU.Build.0 = Release|Any CPU - {418E7058-92EE-4329-86BA-AC26B65AFB25}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {418E7058-92EE-4329-86BA-AC26B65AFB25}.Release|Mixed Platforms.Build.0 = Release|Any CPU {8CB3464F-6130-4EDB-8DC6-CCD2697FAFBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8CB3464F-6130-4EDB-8DC6-CCD2697FAFBB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8CB3464F-6130-4EDB-8DC6-CCD2697FAFBB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {8CB3464F-6130-4EDB-8DC6-CCD2697FAFBB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {8CB3464F-6130-4EDB-8DC6-CCD2697FAFBB}.Release|Any CPU.ActiveCfg = Release|Any CPU {8CB3464F-6130-4EDB-8DC6-CCD2697FAFBB}.Release|Any CPU.Build.0 = Release|Any CPU - {8CB3464F-6130-4EDB-8DC6-CCD2697FAFBB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {8CB3464F-6130-4EDB-8DC6-CCD2697FAFBB}.Release|Mixed Platforms.Build.0 = Release|Any CPU {23EC3364-7C93-4169-9AB2-7181C66004C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {23EC3364-7C93-4169-9AB2-7181C66004C0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {23EC3364-7C93-4169-9AB2-7181C66004C0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {23EC3364-7C93-4169-9AB2-7181C66004C0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {23EC3364-7C93-4169-9AB2-7181C66004C0}.Release|Any CPU.ActiveCfg = Release|Any CPU {23EC3364-7C93-4169-9AB2-7181C66004C0}.Release|Any CPU.Build.0 = Release|Any CPU - {23EC3364-7C93-4169-9AB2-7181C66004C0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {23EC3364-7C93-4169-9AB2-7181C66004C0}.Release|Mixed Platforms.Build.0 = Release|Any CPU {2C564BE1-352D-4DDB-8226-F0981F983C60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2C564BE1-352D-4DDB-8226-F0981F983C60}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2C564BE1-352D-4DDB-8226-F0981F983C60}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {2C564BE1-352D-4DDB-8226-F0981F983C60}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {2C564BE1-352D-4DDB-8226-F0981F983C60}.Release|Any CPU.ActiveCfg = Release|Any CPU {2C564BE1-352D-4DDB-8226-F0981F983C60}.Release|Any CPU.Build.0 = Release|Any CPU - {2C564BE1-352D-4DDB-8226-F0981F983C60}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {2C564BE1-352D-4DDB-8226-F0981F983C60}.Release|Mixed Platforms.Build.0 = Release|Any CPU {1A901129-C885-425F-8D4B-86698F98A2B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1A901129-C885-425F-8D4B-86698F98A2B4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1A901129-C885-425F-8D4B-86698F98A2B4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {1A901129-C885-425F-8D4B-86698F98A2B4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {1A901129-C885-425F-8D4B-86698F98A2B4}.Release|Any CPU.ActiveCfg = Release|Any CPU {1A901129-C885-425F-8D4B-86698F98A2B4}.Release|Any CPU.Build.0 = Release|Any CPU - {1A901129-C885-425F-8D4B-86698F98A2B4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {1A901129-C885-425F-8D4B-86698F98A2B4}.Release|Mixed Platforms.Build.0 = Release|Any CPU {CBDEEC31-D688-417B-9BF2-F0DB2E4FB268}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CBDEEC31-D688-417B-9BF2-F0DB2E4FB268}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CBDEEC31-D688-417B-9BF2-F0DB2E4FB268}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {CBDEEC31-D688-417B-9BF2-F0DB2E4FB268}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {CBDEEC31-D688-417B-9BF2-F0DB2E4FB268}.Release|Any CPU.ActiveCfg = Release|Any CPU {CBDEEC31-D688-417B-9BF2-F0DB2E4FB268}.Release|Any CPU.Build.0 = Release|Any CPU - {CBDEEC31-D688-417B-9BF2-F0DB2E4FB268}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {CBDEEC31-D688-417B-9BF2-F0DB2E4FB268}.Release|Mixed Platforms.Build.0 = Release|Any CPU {97D5ADE3-C1B4-4B46-8A3E-718A4F7F079F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {97D5ADE3-C1B4-4B46-8A3E-718A4F7F079F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {97D5ADE3-C1B4-4B46-8A3E-718A4F7F079F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {97D5ADE3-C1B4-4B46-8A3E-718A4F7F079F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {97D5ADE3-C1B4-4B46-8A3E-718A4F7F079F}.Release|Any CPU.ActiveCfg = Release|Any CPU {97D5ADE3-C1B4-4B46-8A3E-718A4F7F079F}.Release|Any CPU.Build.0 = Release|Any CPU - {97D5ADE3-C1B4-4B46-8A3E-718A4F7F079F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {97D5ADE3-C1B4-4B46-8A3E-718A4F7F079F}.Release|Mixed Platforms.Build.0 = Release|Any CPU {D6DC2669-7B1F-40FE-89BF-45D4C94473E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D6DC2669-7B1F-40FE-89BF-45D4C94473E3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D6DC2669-7B1F-40FE-89BF-45D4C94473E3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {D6DC2669-7B1F-40FE-89BF-45D4C94473E3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {D6DC2669-7B1F-40FE-89BF-45D4C94473E3}.Release|Any CPU.ActiveCfg = Release|Any CPU {D6DC2669-7B1F-40FE-89BF-45D4C94473E3}.Release|Any CPU.Build.0 = Release|Any CPU - {D6DC2669-7B1F-40FE-89BF-45D4C94473E3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {D6DC2669-7B1F-40FE-89BF-45D4C94473E3}.Release|Mixed Platforms.Build.0 = Release|Any CPU {7F077116-2923-4A77-87CC-EC3BE7EB8BC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7F077116-2923-4A77-87CC-EC3BE7EB8BC3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7F077116-2923-4A77-87CC-EC3BE7EB8BC3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {7F077116-2923-4A77-87CC-EC3BE7EB8BC3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {7F077116-2923-4A77-87CC-EC3BE7EB8BC3}.Release|Any CPU.ActiveCfg = Release|Any CPU {7F077116-2923-4A77-87CC-EC3BE7EB8BC3}.Release|Any CPU.Build.0 = Release|Any CPU - {7F077116-2923-4A77-87CC-EC3BE7EB8BC3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {7F077116-2923-4A77-87CC-EC3BE7EB8BC3}.Release|Mixed Platforms.Build.0 = Release|Any CPU {B0AED568-8796-42B9-BAA9-EBC796134E78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B0AED568-8796-42B9-BAA9-EBC796134E78}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B0AED568-8796-42B9-BAA9-EBC796134E78}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {B0AED568-8796-42B9-BAA9-EBC796134E78}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {B0AED568-8796-42B9-BAA9-EBC796134E78}.Release|Any CPU.ActiveCfg = Release|Any CPU {B0AED568-8796-42B9-BAA9-EBC796134E78}.Release|Any CPU.Build.0 = Release|Any CPU - {B0AED568-8796-42B9-BAA9-EBC796134E78}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {B0AED568-8796-42B9-BAA9-EBC796134E78}.Release|Mixed Platforms.Build.0 = Release|Any CPU {93BEBFDF-B81A-4344-AB82-0DBF58B234CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {93BEBFDF-B81A-4344-AB82-0DBF58B234CD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {93BEBFDF-B81A-4344-AB82-0DBF58B234CD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {93BEBFDF-B81A-4344-AB82-0DBF58B234CD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {93BEBFDF-B81A-4344-AB82-0DBF58B234CD}.Release|Any CPU.ActiveCfg = Release|Any CPU {93BEBFDF-B81A-4344-AB82-0DBF58B234CD}.Release|Any CPU.Build.0 = Release|Any CPU - {93BEBFDF-B81A-4344-AB82-0DBF58B234CD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {93BEBFDF-B81A-4344-AB82-0DBF58B234CD}.Release|Mixed Platforms.Build.0 = Release|Any CPU {B2B001EE-A142-4E20-ACF8-AE4A9CB984F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B2B001EE-A142-4E20-ACF8-AE4A9CB984F8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B2B001EE-A142-4E20-ACF8-AE4A9CB984F8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {B2B001EE-A142-4E20-ACF8-AE4A9CB984F8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {B2B001EE-A142-4E20-ACF8-AE4A9CB984F8}.Release|Any CPU.ActiveCfg = Release|Any CPU {B2B001EE-A142-4E20-ACF8-AE4A9CB984F8}.Release|Any CPU.Build.0 = Release|Any CPU - {B2B001EE-A142-4E20-ACF8-AE4A9CB984F8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {B2B001EE-A142-4E20-ACF8-AE4A9CB984F8}.Release|Mixed Platforms.Build.0 = Release|Any CPU {50505F12-985B-4C5F-8DAB-D5BEA734CD51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {50505F12-985B-4C5F-8DAB-D5BEA734CD51}.Debug|Any CPU.Build.0 = Debug|Any CPU - {50505F12-985B-4C5F-8DAB-D5BEA734CD51}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {50505F12-985B-4C5F-8DAB-D5BEA734CD51}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {50505F12-985B-4C5F-8DAB-D5BEA734CD51}.Release|Any CPU.ActiveCfg = Release|Any CPU {50505F12-985B-4C5F-8DAB-D5BEA734CD51}.Release|Any CPU.Build.0 = Release|Any CPU - {50505F12-985B-4C5F-8DAB-D5BEA734CD51}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {50505F12-985B-4C5F-8DAB-D5BEA734CD51}.Release|Mixed Platforms.Build.0 = Release|Any CPU {312CE0DD-0F8F-4366-96A4-44D0AAEF60AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {312CE0DD-0F8F-4366-96A4-44D0AAEF60AA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {312CE0DD-0F8F-4366-96A4-44D0AAEF60AA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {312CE0DD-0F8F-4366-96A4-44D0AAEF60AA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {312CE0DD-0F8F-4366-96A4-44D0AAEF60AA}.Release|Any CPU.ActiveCfg = Release|Any CPU {312CE0DD-0F8F-4366-96A4-44D0AAEF60AA}.Release|Any CPU.Build.0 = Release|Any CPU - {312CE0DD-0F8F-4366-96A4-44D0AAEF60AA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {312CE0DD-0F8F-4366-96A4-44D0AAEF60AA}.Release|Mixed Platforms.Build.0 = Release|Any CPU {8A33EE41-BEFA-499F-9184-1B8D0C8A4600}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8A33EE41-BEFA-499F-9184-1B8D0C8A4600}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8A33EE41-BEFA-499F-9184-1B8D0C8A4600}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {8A33EE41-BEFA-499F-9184-1B8D0C8A4600}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {8A33EE41-BEFA-499F-9184-1B8D0C8A4600}.Release|Any CPU.ActiveCfg = Release|Any CPU {8A33EE41-BEFA-499F-9184-1B8D0C8A4600}.Release|Any CPU.Build.0 = Release|Any CPU - {8A33EE41-BEFA-499F-9184-1B8D0C8A4600}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {8A33EE41-BEFA-499F-9184-1B8D0C8A4600}.Release|Mixed Platforms.Build.0 = Release|Any CPU {B112455B-E42E-4718-821F-862884B9C07C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B112455B-E42E-4718-821F-862884B9C07C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B112455B-E42E-4718-821F-862884B9C07C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {B112455B-E42E-4718-821F-862884B9C07C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {B112455B-E42E-4718-821F-862884B9C07C}.Release|Any CPU.ActiveCfg = Release|Any CPU {B112455B-E42E-4718-821F-862884B9C07C}.Release|Any CPU.Build.0 = Release|Any CPU - {B112455B-E42E-4718-821F-862884B9C07C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {B112455B-E42E-4718-821F-862884B9C07C}.Release|Mixed Platforms.Build.0 = Release|Any CPU {5AC2F31C-BD33-4BD1-8A90-D6A23941A74F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5AC2F31C-BD33-4BD1-8A90-D6A23941A74F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5AC2F31C-BD33-4BD1-8A90-D6A23941A74F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {5AC2F31C-BD33-4BD1-8A90-D6A23941A74F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {5AC2F31C-BD33-4BD1-8A90-D6A23941A74F}.Release|Any CPU.ActiveCfg = Release|Any CPU {5AC2F31C-BD33-4BD1-8A90-D6A23941A74F}.Release|Any CPU.Build.0 = Release|Any CPU - {5AC2F31C-BD33-4BD1-8A90-D6A23941A74F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {5AC2F31C-BD33-4BD1-8A90-D6A23941A74F}.Release|Mixed Platforms.Build.0 = Release|Any CPU {7ECC040E-19FC-4E10-B314-412CF7AB2170}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7ECC040E-19FC-4E10-B314-412CF7AB2170}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7ECC040E-19FC-4E10-B314-412CF7AB2170}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {7ECC040E-19FC-4E10-B314-412CF7AB2170}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {7ECC040E-19FC-4E10-B314-412CF7AB2170}.Release|Any CPU.ActiveCfg = Release|Any CPU {7ECC040E-19FC-4E10-B314-412CF7AB2170}.Release|Any CPU.Build.0 = Release|Any CPU - {7ECC040E-19FC-4E10-B314-412CF7AB2170}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {7ECC040E-19FC-4E10-B314-412CF7AB2170}.Release|Mixed Platforms.Build.0 = Release|Any CPU {34383A75-1831-4816-A38A-AB06B969D7C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {34383A75-1831-4816-A38A-AB06B969D7C7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {34383A75-1831-4816-A38A-AB06B969D7C7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {34383A75-1831-4816-A38A-AB06B969D7C7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {34383A75-1831-4816-A38A-AB06B969D7C7}.Release|Any CPU.ActiveCfg = Release|Any CPU {34383A75-1831-4816-A38A-AB06B969D7C7}.Release|Any CPU.Build.0 = Release|Any CPU - {34383A75-1831-4816-A38A-AB06B969D7C7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {34383A75-1831-4816-A38A-AB06B969D7C7}.Release|Mixed Platforms.Build.0 = Release|Any CPU {3A25C796-F676-4422-8F30-01D4FDB240F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3A25C796-F676-4422-8F30-01D4FDB240F1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3A25C796-F676-4422-8F30-01D4FDB240F1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {3A25C796-F676-4422-8F30-01D4FDB240F1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {3A25C796-F676-4422-8F30-01D4FDB240F1}.Release|Any CPU.ActiveCfg = Release|Any CPU {3A25C796-F676-4422-8F30-01D4FDB240F1}.Release|Any CPU.Build.0 = Release|Any CPU - {3A25C796-F676-4422-8F30-01D4FDB240F1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {3A25C796-F676-4422-8F30-01D4FDB240F1}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {A1F2F1DA-2B86-461E-9602-EAB2BD899A8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1F2F1DA-2B86-461E-9602-EAB2BD899A8F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1F2F1DA-2B86-461E-9602-EAB2BD899A8F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1F2F1DA-2B86-461E-9602-EAB2BD899A8F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -493,6 +333,7 @@ Global {7ECC040E-19FC-4E10-B314-412CF7AB2170} = {2AB9B589-5C98-4C05-BBEA-F97DAE168EAB} {34383A75-1831-4816-A38A-AB06B969D7C7} = {FED00F38-E911-45E1-A788-26980E84C3D6} {3A25C796-F676-4422-8F30-01D4FDB240F1} = {2AB9B589-5C98-4C05-BBEA-F97DAE168EAB} + {A1F2F1DA-2B86-461E-9602-EAB2BD899A8F} = {FBE6DF29-85A9-4A8B-B739-35BE4CA0A9B7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {42D74E06-00EA-43D2-A05B-9BEAD4A2C8A0} diff --git a/MatterControlLib/ActionBar/TemperatureWidgetExtruder.cs b/MatterControlLib/ActionBar/TemperatureWidgetExtruder.cs index b490976a9..e109885e3 100644 --- a/MatterControlLib/ActionBar/TemperatureWidgetExtruder.cs +++ b/MatterControlLib/ActionBar/TemperatureWidgetExtruder.cs @@ -307,7 +307,7 @@ namespace MatterHackers.MatterControl.ActionBar graph.AddData(this.ActualTemperature); }, 1); - var valueField = temperatureRow.Descendants().FirstOrDefault(); + var valueField = temperatureRow.Descendants().FirstOrDefault(); valueField.Name = "Temperature Input"; valueField.ActuallNumberEdit.EditComplete += (s, e) => diff --git a/MatterControlLib/ApplicationView/AppContext.cs b/MatterControlLib/ApplicationView/AppContext.cs index 5bfa21579..8bf0c134d 100644 --- a/MatterControlLib/ApplicationView/AppContext.cs +++ b/MatterControlLib/ApplicationView/AppContext.cs @@ -107,9 +107,10 @@ namespace MatterHackers.MatterControl { _themeset = JsonConvert.DeserializeObject(File.ReadAllText(ProfileManager.Instance.ProfileThemeSetPath)); ThemeSet.Theme.EnsureDefaults(); + MatterHackersThemeConfigExtensions.RebuildTheme(ThemeSet.Theme); - // If the serialized format is older than the current format, null and fall back to latest default below - if (ThemeSet.SchemeVersion != ThemeSet.LatestSchemeVersion) + // If the serialized format is older than the current format, null and fall back to latest default below + if (ThemeSet.SchemeVersion != ThemeSet.LatestSchemeVersion) { _themeset = null; } @@ -163,6 +164,7 @@ namespace MatterHackers.MatterControl var themeConfig = JsonConvert.DeserializeObject(json); themeConfig.EnsureDefaults(); + MatterHackersThemeConfigExtensions.RebuildTheme(ThemeSet.Theme); return themeConfig; } diff --git a/MatterControlLib/ApplicationView/Application.cs b/MatterControlLib/ApplicationView/Application.cs index 212ea34fa..912378e6f 100644 --- a/MatterControlLib/ApplicationView/Application.cs +++ b/MatterControlLib/ApplicationView/Application.cs @@ -788,7 +788,7 @@ namespace MatterHackers.MatterControl await applicationController.Tasks.Execute(task.Title, null, task.Action); } - + // If we have not cancled the show welcome message and there is a window open if (UserSettings.Instance.get(UserSettingsKey.ShownWelcomeMessage) != "false" && ApplicationController.Instance.Workspaces.Count > 0) @@ -802,7 +802,7 @@ namespace MatterHackers.MatterControl else { - } + } } catch { diff --git a/MatterControlLib/ApplicationView/ApplicationController.cs b/MatterControlLib/ApplicationView/ApplicationController.cs index 4ec51783a..19088f5e5 100644 --- a/MatterControlLib/ApplicationView/ApplicationController.cs +++ b/MatterControlLib/ApplicationView/ApplicationController.cs @@ -39,6 +39,7 @@ using System.Net; using System.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using System.Threading; @@ -566,10 +567,39 @@ namespace MatterHackers.MatterControl targetUri += internalLink; } - Process.Start(targetUri); + ProcessStart(targetUri); }); } + public static void ProcessStart(string input) + { + try + { + Process.Start(input); + } + catch + { + // hack because of this: https://github.com/dotnet/corefx/issues/10361 + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + input = input.Replace("&", "^&"); + Process.Start(new ProcessStartInfo("cmd", $"/c start {input}") { CreateNoWindow = true }); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Process.Start("xdg-open", input); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + Process.Start("open", input); + } + else + { + throw; + } + } + } + internal void MakeGrayscale(ImageBuffer sourceImage) { var buffer = sourceImage.GetBuffer(); diff --git a/MatterControlLib/ApplicationView/Config/RunningTasksConfig.cs b/MatterControlLib/ApplicationView/Config/RunningTasksConfig.cs index 519ef7471..fe20129c3 100644 --- a/MatterControlLib/ApplicationView/Config/RunningTasksConfig.cs +++ b/MatterControlLib/ApplicationView/Config/RunningTasksConfig.cs @@ -27,56 +27,15 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +using MatterHackers.Agg; +using MatterHackers.Agg.UI; using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Diagnostics; -using System.IO; -using System.IO.Compression; using System.Linq; -using System.Net; -using System.Net.Http; -using System.Reflection; using System.Runtime.CompilerServices; -using System.Text; -using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; -using global::MatterControl.Printing; -using Markdig.Agg; -using Markdig.Renderers.Agg; -using MatterHackers.Agg; -using MatterHackers.Agg.Font; -using MatterHackers.Agg.Image; -using MatterHackers.Agg.Platform; -using MatterHackers.Agg.UI; -using MatterHackers.Agg.VertexSource; -using MatterHackers.DataConverters3D; -using MatterHackers.DataConverters3D.UndoCommands; -using MatterHackers.Localizations; -using MatterHackers.MatterControl.CustomWidgets; -using MatterHackers.MatterControl.DataStorage; -using MatterHackers.MatterControl.DesignTools; -using MatterHackers.MatterControl.DesignTools.Operations; -using MatterHackers.MatterControl.Extensibility; -using MatterHackers.MatterControl.Library; -using MatterHackers.MatterControl.PartPreviewWindow; -using MatterHackers.MatterControl.PartPreviewWindow.View3D; -using MatterHackers.MatterControl.Plugins; -using MatterHackers.MatterControl.PrinterCommunication; -using MatterHackers.MatterControl.PrinterControls.PrinterConnections; -using MatterHackers.MatterControl.PrintQueue; -using MatterHackers.MatterControl.SettingsManagement; -using MatterHackers.MatterControl.SlicerConfiguration; -using MatterHackers.MatterControl.Tour; -using MatterHackers.PolygonMesh; -using MatterHackers.PolygonMesh.Processors; -using MatterHackers.VectorMath; -using MatterHackers.VectorMath.TrackBall; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using Newtonsoft.Json.Linq; [assembly: InternalsVisibleTo("MatterControl.Tests")] [assembly: InternalsVisibleTo("MatterControl.AutomationTests")] @@ -84,7 +43,7 @@ using Newtonsoft.Json.Linq; namespace MatterHackers.MatterControl { - public class RunningTasksConfig + public class RunningTasksConfig { public event EventHandler TasksChanged; diff --git a/MatterControlLib/ApplicationView/Config/ThumbnailsConfig.cs b/MatterControlLib/ApplicationView/Config/ThumbnailsConfig.cs index 1af1e1e7b..4369ad0ec 100644 --- a/MatterControlLib/ApplicationView/Config/ThumbnailsConfig.cs +++ b/MatterControlLib/ApplicationView/Config/ThumbnailsConfig.cs @@ -33,9 +33,9 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MatterHackers.Agg; using MatterHackers.Agg.Image; using MatterHackers.Agg.Platform; +using MatterHackers.Agg.UI; using MatterHackers.ImageProcessing; using MatterHackers.MatterControl.Library; diff --git a/MatterControlLib/ApplicationView/Themes/ThemeConfig.cs b/MatterControlLib/ApplicationView/Themes/ThemeConfig.cs index 6ba63cdd5..44b97e759 100644 --- a/MatterControlLib/ApplicationView/Themes/ThemeConfig.cs +++ b/MatterControlLib/ApplicationView/Themes/ThemeConfig.cs @@ -42,11 +42,8 @@ using MatterHackers.VectorMath; namespace MatterHackers.MatterControl { - public class ThemeConfig + public class ThemeConfig3 { - private ImageBuffer restoreNormal; - private ImageBuffer restoreHover; - public int FontSize7 { get; } = 7; public int FontSize8 { get; } = 8; @@ -73,10 +70,6 @@ namespace MatterHackers.MatterControl public double MenuGutterWidth => 35 * GuiWidget.DeviceScale; - public double MicroButtonHeight => 20 * GuiWidget.DeviceScale; - - private double MicroButtonWidth => 30 * GuiWidget.DeviceScale; - private readonly int defaultScrollBarWidth = 120; public void MakeRoundedButton(GuiWidget button, Color? boarderColor = null) @@ -100,44 +93,6 @@ namespace MatterHackers.MatterControl } } - public void ApplyPrimaryActionStyle(GuiWidget guiWidget) - { - guiWidget.BackgroundColor = new Color(this.AccentMimimalOverlay, 50); - - Color hoverColor = this.AccentMimimalOverlay; - - switch (guiWidget) - { - case PopupMenuButton menuButton: - menuButton.HoverColor = hoverColor; - break; - case SimpleFlowButton flowButton: - flowButton.HoverColor = hoverColor; - break; - case SimpleButton button: - button.HoverColor = hoverColor; - break; - } - } - - internal void RemovePrimaryActionStyle(GuiWidget guiWidget) - { - guiWidget.BackgroundColor = Color.Transparent; - - // Buttons in toolbars should revert to ToolbarButtonHover when reset - bool parentIsToolbar = guiWidget.Parent?.Parent is Toolbar; - - switch (guiWidget) - { - case SimpleFlowButton flowButton: - flowButton.HoverColor = parentIsToolbar ? this.ToolbarButtonHover : Color.Transparent; - break; - case SimpleButton button: - button.HoverColor = parentIsToolbar ? this.ToolbarButtonHover : Color.Transparent; - break; - } - } - public BorderDouble TextButtonPadding { get; } = new BorderDouble(14, 0); public BorderDouble ButtonSpacing { get; } = new BorderDouble(right: 3); @@ -210,8 +165,6 @@ namespace MatterHackers.MatterControl public BorderDouble SeparatorMargin { get; } - public ImageBuffer GeneratingThumbnailIcon { get; private set; } - public class StateColor { public Color BackgroundColor { get; set; } @@ -249,12 +202,6 @@ namespace MatterHackers.MatterControl public Color BorderColor20 { get; set; } - internal void EnsureDefaults() - { - // EnsureDefaults is called after deserialization and at a point when state should be fully loaded. Invoking RebuildTheme here ensures icons shaded correctly - this.RebuildTheme(); - } - public Color RowBorder { get; set; } public DropListStyle DropList { get; set; } = new DropListStyle(); @@ -280,128 +227,12 @@ namespace MatterHackers.MatterControl public GridColors BedGridColors { get; set; } = new GridColors(); public double ButtonRadius { get; set; } = 3; - public GuiWidget CreateSearchButton() - { - return new IconButton(StaticData.Instance.LoadIcon("icon_search_24x24.png", 16, 16).SetToColor(TextColor), this) - { - ToolTipText = "Search".Localize(), - }; - } - - public ThemeConfig() - { - this.SeparatorMargin = (this.ButtonSpacing * 2).Clone(left: this.ButtonSpacing.Right); - this.RebuildTheme(); - } - public void SetDefaults() { this.DisabledColor = new Color(this.LightTextColor, 50); this.SplashAccentColor = new Color(this.PrimaryAccentColor, 185).OverlayOn(Color.White).ToColor(); } - public void RebuildTheme() - { - int size = (int)(16 * GuiWidget.DeviceScale); - - // On Android, use red icon as no hover events, otherwise transparent and red on hover - restoreNormal = ColorCircle(size, (AggContext.OperatingSystem == OSType.Android) ? new Color(200, 0, 0) : Color.Transparent); - restoreHover = ColorCircle(size, new Color("#DB4437")); - - this.GeneratingThumbnailIcon = StaticData.Instance.LoadIcon("building_thumbnail_40x40.png", 40, 40).SetToColor(TextColor); - - ScrollBar.DefaultBackgroundColor = this.TextColor.WithAlpha(30); - ScrollBar.DefaultThumbColor = this.TextColor.WithAlpha(130); - ScrollBar.DefaultThumbHoverColor = this.PrimaryAccentColor.WithAlpha(130); - } - - public JogControls.MoveButton CreateMoveButton(PrinterConfig printer, string label, PrinterConnection.Axis axis, double movementFeedRate, bool levelingButtons = false) - { - return new JogControls.MoveButton(label, printer, axis, movementFeedRate, this) - { - BackgroundColor = this.MinimalShade, - BorderColor = this.BorderColor40, - BackgroundOutlineWidth = 1, - VAnchor = VAnchor.Absolute, - HAnchor = HAnchor.Absolute, - Margin = 0, - Padding = 0, - Height = (levelingButtons ? 45 : 40) * GuiWidget.DeviceScale, - Width = (levelingButtons ? 90 : 40) * GuiWidget.DeviceScale, - }; - } - - public JogControls.ExtrudeButton CreateExtrudeButton(PrinterConfig printer, string label, double movementFeedRate, int extruderNumber, bool levelingButtons = false) - { - return new JogControls.ExtrudeButton(printer, label, movementFeedRate, extruderNumber, this) - { - BackgroundColor = this.MinimalShade, - BorderColor = this.BorderColor40, - BackgroundOutlineWidth = 1, - VAnchor = VAnchor.Absolute, - HAnchor = HAnchor.Absolute, - Margin = 0, - Padding = 0, - Height = (levelingButtons ? 45 : 40) * GuiWidget.DeviceScale, - Width = (levelingButtons ? 90 : 40) * GuiWidget.DeviceScale, - }; - } - - public RadioTextButton CreateMicroRadioButton(string text, IList siblingRadioButtonList = null) - { - var radioButton = new RadioTextButton(text, this, this.FontSize8) - { - SiblingRadioButtonList = siblingRadioButtonList, - Padding = new BorderDouble(5, 0), - SelectedBackgroundColor = this.SlightShade, - UnselectedBackgroundColor = this.SlightShade, - HoverColor = this.AccentMimimalOverlay, - Margin = new BorderDouble(right: 1), - HAnchor = HAnchor.Absolute, - Height = this.MicroButtonHeight, - Width = this.MicroButtonWidth - }; - - // Add to sibling list if supplied - siblingRadioButtonList?.Add(radioButton); - - return radioButton; - } - - public TextButton CreateLightDialogButton(string text) - { - return CreateDialogButton(text, new Color(Color.White, 15), new Color(Color.White, 25)); - } - - public TextButton CreateDialogButton(string text) - { - return CreateDialogButton(text, this.SlightShade, this.SlightShade.WithAlpha(75)); - } - - public TextButton CreateDialogButton(string text, Color backgroundColor, Color hoverColor) - { -#if !__ANDROID__ - return new TextButton(text, this) - { - BackgroundColor = backgroundColor, - HoverColor = hoverColor, - MinimumSize = new Vector2(75, 0), - Margin = this.ButtonSpacing - }; -#else - var button = new TextButton(text, this, this.FontSize14) - { - BackgroundColor = backgroundColor, - HoverColor = hoverColor, - // Enlarge button height and margin on Android - Height = 34 * GuiWidget.DeviceScale, - }; - button.Padding = button.Padding * 1.2; - - return button; -#endif - } - public Color GetBorderColor(int alpha) { return new Color(this.BorderColor, alpha); @@ -419,215 +250,6 @@ namespace MatterHackers.MatterControl return new BlenderBGRA().Blend(background, overlay); } - public FlowLayoutWidget CreateMenuItems(PopupMenu popupMenu, IEnumerable menuActions) - { - // Create menu items in the DropList for each element in this.menuActions - foreach (var menuAction in menuActions) - { - if (menuAction is ActionSeparator) - { - popupMenu.CreateSeparator(); - } - else - { - if (menuAction is NamedActionGroup namedActionButtons) - { - var content = new FlowLayoutWidget() - { - HAnchor = HAnchor.Fit | HAnchor.Stretch - }; - - var textWidget = new TextWidget(menuAction.Title, pointSize: this.DefaultFontSize, textColor: this.TextColor) - { - // Padding = MenuPadding, - VAnchor = VAnchor.Center - }; - content.AddChild(textWidget); - - content.AddChild(new HorizontalSpacer()); - - foreach (var actionButton in namedActionButtons.Group) - { - var button = new TextButton(actionButton.Title, this) - { - Border = new BorderDouble(1, 0, 0, 0), - BorderColor = this.MinimalShade, - HoverColor = this.AccentMimimalOverlay, - Enabled = actionButton.IsEnabled() - }; - - content.AddChild(button); - - if (actionButton.IsEnabled()) - { - button.Click += (s, e) => - { - actionButton.Action(); - popupMenu.Unfocus(); - }; - } - } - - var menuItem = new PopupMenu.MenuItem(content, this) - { - HAnchor = HAnchor.Fit | HAnchor.Stretch, - VAnchor = VAnchor.Fit, - HoverColor = Color.Transparent, - }; - popupMenu.AddChild(menuItem); - menuItem.Padding = new BorderDouble(menuItem.Padding.Left, - menuItem.Padding.Bottom, - 0, - menuItem.Padding.Top); - } - else - { - PopupMenu.MenuItem menuItem; - - if (menuAction is NamedBoolAction boolAction) - { - menuItem = popupMenu.CreateBoolMenuItem(menuAction.Title, boolAction.GetIsActive, boolAction.SetIsActive); - } - else - { - menuItem = popupMenu.CreateMenuItem(menuAction.Title, menuAction.Icon, menuAction.Shortcut); - } - - menuItem.Name = $"{menuAction.Title} Menu Item"; - - menuItem.Enabled = menuAction is NamedActionGroup - || (menuAction.Action != null && menuAction.IsEnabled?.Invoke() != false); - - menuItem.ClearRemovedFlag(); - - if (menuItem.Enabled) - { - menuItem.Click += (s, e) => - { - menuAction.Action(); - }; - } - } - } - } - - return popupMenu; - } - - public PopupMenuButton CreateSplitButton(SplitButtonParams buttonParams, OperationGroup operationGroup = null) - { - PopupMenuButton menuButton = null; - - GuiWidget innerButton; - if (buttonParams.ButtonText == null) - { - innerButton = new IconButton(buttonParams.Icon, this) - { - Name = buttonParams.ButtonName + " Inner SplitButton", - Enabled = buttonParams.ButtonEnabled, - ToolTipText = buttonParams.ButtonTooltip, - }; - - // Remove right Padding for drop style - innerButton.Padding = innerButton.Padding.Clone(right: 0); - } - else - { - if (buttonParams.Icon == null) - { - innerButton = new TextButton(buttonParams.ButtonText, this) - { - Name = buttonParams.ButtonName, - Enabled = buttonParams.ButtonEnabled, - ToolTipText = buttonParams.ButtonTooltip, - }; - } - else - { - innerButton = new TextIconButton(buttonParams.ButtonText, buttonParams.Icon, this) - { - Name = buttonParams.ButtonName, - Enabled = buttonParams.ButtonEnabled, - ToolTipText = buttonParams.ButtonTooltip, - Padding = new BorderDouble(5, 0, 5, 0) - }; - } - } - - innerButton.Click += (s, e) => - { - buttonParams.ButtonAction.Invoke(menuButton); - }; - - - if (operationGroup == null) - { - menuButton = new PopupMenuButton(innerButton, this); - } - else - { - menuButton = new OperationGroupButton(operationGroup, innerButton, this); - } - - var theme = ApplicationController.Instance.MenuTheme; - menuButton.DynamicPopupContent = () => - { - var popupMenu = new PopupMenu(theme); - buttonParams.ExtendPopupMenu?.Invoke(popupMenu); - - return popupMenu; - }; - - menuButton.Name = buttonParams.ButtonName + " Menu SplitButton"; - menuButton.BackgroundColor = buttonParams.BackgroundColor; - if (menuButton.BackgroundColor == Color.Transparent) - { - menuButton.BackgroundColor = this.ToolbarButtonBackground; - } - - menuButton.HoverColor = this.ToolbarButtonHover; - menuButton.MouseDownColor = this.ToolbarButtonDown; - menuButton.DrawArrow = true; - menuButton.Margin = this.ButtonSpacing; - menuButton.DistinctPopupButton = true; - menuButton.BackgroundRadius = new RadiusCorners(theme.ButtonRadius * GuiWidget.DeviceScale, theme.ButtonRadius * GuiWidget.DeviceScale, 0, 0); - - innerButton.Selectable = true; - return menuButton; - } - - private static ImageBuffer ColorCircle(int size, Color color) - { - var imageBuffer = new ImageBuffer(size, size); - Graphics2D normalGraphics = imageBuffer.NewGraphics2D(); - var center = new Vector2(size / 2.0, size / 2.0); - - Color barColor; - if (color != Color.Transparent) - { - normalGraphics.Circle(center, size / 2.0, color); - barColor = Color.White; - } - else - { - barColor = new Color("#999"); - } - - normalGraphics.Line(center + new Vector2(-size / 4.0, -size / 4.0), center + new Vector2(size / 4.0, size / 4.0), barColor, 2 * GuiWidget.DeviceScale); - normalGraphics.Line(center + new Vector2(-size / 4.0, size / 4.0), center + new Vector2(size / 4.0, -size / 4.0), barColor, 2 * GuiWidget.DeviceScale); - - return imageBuffer; - } - - public GuiWidget CreateSmallResetButton() - { - return new HoverImageWidget(restoreNormal, restoreHover) - { - VAnchor = VAnchor.Center, - Margin = new BorderDouble(0, 0, 5, 0) - }; - } - public SolidSlider CreateSolidSlider(GuiWidget wordOptionContainer, string header, ThemeConfig theme, double min = 0, double max = .5) { double scrollBarWidth = 10; @@ -678,55 +300,6 @@ namespace MatterHackers.MatterControl widget.BorderColor = shadedBorder ? this.MinimalShade : this.BorderColor20; widget.Border = border; } - - public SectionWidget ApplyBoxStyle(SectionWidget sectionWidget) - { - return ApplyBoxStyle( - sectionWidget, - this.SectionBackgroundColor, - margin: new BorderDouble(this.DefaultContainerPadding, 0, this.DefaultContainerPadding, this.DefaultContainerPadding)); - } - - public SolidSlider ApplySliderStyle(SolidSlider solidSlider) - { - solidSlider.View.TrackColor = this.SlightShade; - solidSlider.View.TrackRadius = 4; - - return solidSlider; - } - - public DoubleSolidSlider ApplySliderStyle(DoubleSolidSlider solidSlider) - { - solidSlider.View.TrackColor = this.SlightShade; - solidSlider.View.TrackRadius = 4; - - return solidSlider; - } - - // ApplySquareBoxStyle - public SectionWidget ApplyBoxStyle(SectionWidget sectionWidget, BorderDouble margin) - { - sectionWidget.BackgroundColor = this.SectionBackgroundColor; - sectionWidget.Margin = 0; - sectionWidget.Border = new BorderDouble(bottom: 1); - sectionWidget.BorderColor = this.RowBorder; - - return sectionWidget; - } - - public SectionWidget ApplyBoxStyle(SectionWidget sectionWidget, Color backgroundColor, BorderDouble margin) - { - // Enforce panel padding - // sectionWidget.ContentPanel.Padding = new BorderDouble(10, 0, 10, 2); - // sectionWidget.ContentPanel.Padding = 0; - - sectionWidget.BorderColor = Color.Transparent; - sectionWidget.BorderRadius = 5; - sectionWidget.Margin = margin; - sectionWidget.BackgroundColor = backgroundColor; - - return sectionWidget; - } } public class PresetColors @@ -771,4 +344,349 @@ namespace MatterHackers.MatterControl public Color BackgroundColor { get; set; } } + + public static class MatterHackersThemeConfigExtensions + { + public static JogControls.MoveButton CreateMoveButton(this ThemeConfig config, PrinterConfig printer, string label, PrinterConnection.Axis axis, double movementFeedRate, bool levelingButtons = false) + { + return new JogControls.MoveButton(label, printer, axis, movementFeedRate, config) + { + BackgroundColor = config.MinimalShade, + BorderColor = config.BorderColor40, + BackgroundOutlineWidth = 1, + VAnchor = VAnchor.Absolute, + HAnchor = HAnchor.Absolute, + Margin = 0, + Padding = 0, + Height = (levelingButtons ? 45 : 40) * GuiWidget.DeviceScale, + Width = (levelingButtons ? 90 : 40) * GuiWidget.DeviceScale, + }; + } + + public static JogControls.ExtrudeButton CreateExtrudeButton(this ThemeConfig config, PrinterConfig printer, string label, double movementFeedRate, int extruderNumber, bool levelingButtons = false) + { + return new JogControls.ExtrudeButton(printer, label, movementFeedRate, extruderNumber, config) + { + BackgroundColor = config.MinimalShade, + BorderColor = config.BorderColor40, + BackgroundOutlineWidth = 1, + VAnchor = VAnchor.Absolute, + HAnchor = HAnchor.Absolute, + Margin = 0, + Padding = 0, + Height = (levelingButtons ? 45 : 40) * GuiWidget.DeviceScale, + Width = (levelingButtons ? 90 : 40) * GuiWidget.DeviceScale, + }; + } + + public static PopupMenuButton CreateSplitButton(this ThemeConfig config, SplitButtonParams buttonParams, OperationGroup operationGroup = null) + { + PopupMenuButton menuButton = null; + + GuiWidget innerButton; + if (buttonParams.ButtonText == null) + { + innerButton = new IconButton(buttonParams.Icon, config) + { + Name = buttonParams.ButtonName + " Inner SplitButton", + Enabled = buttonParams.ButtonEnabled, + ToolTipText = buttonParams.ButtonTooltip, + }; + + // Remove right Padding for drop style + innerButton.Padding = innerButton.Padding.Clone(right: 0); + } + else + { + if (buttonParams.Icon == null) + { + innerButton = new TextButton(buttonParams.ButtonText, config) + { + Name = buttonParams.ButtonName, + Enabled = buttonParams.ButtonEnabled, + ToolTipText = buttonParams.ButtonTooltip, + }; + } + else + { + innerButton = new TextIconButton(buttonParams.ButtonText, buttonParams.Icon, config) + { + Name = buttonParams.ButtonName, + Enabled = buttonParams.ButtonEnabled, + ToolTipText = buttonParams.ButtonTooltip, + Padding = new BorderDouble(5, 0, 5, 0) + }; + } + } + + innerButton.Click += (s, e) => + { + buttonParams.ButtonAction.Invoke(menuButton); + }; + + + if (operationGroup == null) + { + menuButton = new PopupMenuButton(innerButton, config); + } + else + { + menuButton = new OperationGroupButton(operationGroup, innerButton, config); + } + + var theme = ApplicationController.Instance.MenuTheme; + menuButton.DynamicPopupContent = () => + { + var popupMenu = new PopupMenu(theme); + buttonParams.ExtendPopupMenu?.Invoke(popupMenu); + + return popupMenu; + }; + + menuButton.Name = buttonParams.ButtonName + " Menu SplitButton"; + menuButton.BackgroundColor = buttonParams.BackgroundColor; + if (menuButton.BackgroundColor == Color.Transparent) + { + menuButton.BackgroundColor = config.ToolbarButtonBackground; + } + + menuButton.HoverColor = config.ToolbarButtonHover; + menuButton.MouseDownColor = config.ToolbarButtonDown; + menuButton.DrawArrow = true; + menuButton.Margin = config.ButtonSpacing; + menuButton.DistinctPopupButton = true; + menuButton.BackgroundRadius = new RadiusCorners(theme.ButtonRadius * GuiWidget.DeviceScale, theme.ButtonRadius * GuiWidget.DeviceScale, 0, 0); + + innerButton.Selectable = true; + return menuButton; + } + + public static GuiWidget CreateSearchButton(this ThemeConfig config) + { + return new IconButton(StaticData.Instance.LoadIcon("icon_search_24x24.png", 16, 16).SetToColor(config.TextColor), config) + { + ToolTipText = "Search".Localize(), + }; + } + + public static double MicroButtonHeight => 20 * GuiWidget.DeviceScale; + private static double MicroButtonWidth => 30 * GuiWidget.DeviceScale; + + public static RadioTextButton CreateMicroRadioButton(this ThemeConfig config, string text, IList siblingRadioButtonList = null) + { + var radioButton = new RadioTextButton(text, config, config.FontSize8) + { + SiblingRadioButtonList = siblingRadioButtonList, + Padding = new BorderDouble(5, 0), + SelectedBackgroundColor = config.SlightShade, + UnselectedBackgroundColor = config.SlightShade, + HoverColor = config.AccentMimimalOverlay, + Margin = new BorderDouble(right: 1), + HAnchor = HAnchor.Absolute, + Height = config.MicroButtonHeight, + Width = MicroButtonWidth + }; + + // Add to sibling list if supplied + siblingRadioButtonList?.Add(radioButton); + + return radioButton; + } + + public static FlowLayoutWidget CreateMenuItems(this ThemeConfig config, PopupMenu popupMenu, IEnumerable menuActions) + { + // Create menu items in the DropList for each element in this.menuActions + foreach (var menuAction in menuActions) + { + if (menuAction is ActionSeparator) + { + popupMenu.CreateSeparator(); + } + else + { + if (menuAction is NamedActionGroup namedActionButtons) + { + var content = new FlowLayoutWidget() + { + HAnchor = HAnchor.Fit | HAnchor.Stretch + }; + + var textWidget = new TextWidget(menuAction.Title, pointSize: config.DefaultFontSize, textColor: config.TextColor) + { + // Padding = MenuPadding, + VAnchor = VAnchor.Center + }; + content.AddChild(textWidget); + + content.AddChild(new HorizontalSpacer()); + + foreach (var actionButton in namedActionButtons.Group) + { + var button = new TextButton(actionButton.Title, config) + { + Border = new BorderDouble(1, 0, 0, 0), + BorderColor = config.MinimalShade, + HoverColor = config.AccentMimimalOverlay, + Enabled = actionButton.IsEnabled() + }; + + content.AddChild(button); + + if (actionButton.IsEnabled()) + { + button.Click += (s, e) => + { + actionButton.Action(); + popupMenu.Unfocus(); + }; + } + } + + var menuItem = new PopupMenu.MenuItem(content, config) + { + HAnchor = HAnchor.Fit | HAnchor.Stretch, + VAnchor = VAnchor.Fit, + HoverColor = Color.Transparent, + }; + popupMenu.AddChild(menuItem); + menuItem.Padding = new BorderDouble(menuItem.Padding.Left, + menuItem.Padding.Bottom, + 0, + menuItem.Padding.Top); + } + else + { + PopupMenu.MenuItem menuItem; + + if (menuAction is NamedBoolAction boolAction) + { + menuItem = popupMenu.CreateBoolMenuItem(menuAction.Title, boolAction.GetIsActive, boolAction.SetIsActive); + } + else + { + menuItem = popupMenu.CreateMenuItem(menuAction.Title, menuAction.Icon, menuAction.Shortcut); + } + + menuItem.Name = $"{menuAction.Title} Menu Item"; + + menuItem.Enabled = menuAction is NamedActionGroup + || (menuAction.Action != null && menuAction.IsEnabled?.Invoke() != false); + + menuItem.ClearRemovedFlag(); + + if (menuItem.Enabled) + { + menuItem.Click += (s, e) => + { + menuAction.Action(); + }; + } + } + } + } + + return popupMenu; + } + + public static void ApplyPrimaryActionStyle(this ThemeConfig config, GuiWidget guiWidget) + { + guiWidget.BackgroundColor = new Color(config.AccentMimimalOverlay, 50); + + Color hoverColor = config.AccentMimimalOverlay; + + switch (guiWidget) + { + case PopupMenuButton menuButton: + menuButton.HoverColor = hoverColor; + break; + case SimpleFlowButton flowButton: + flowButton.HoverColor = hoverColor; + break; + case SimpleButton button: + button.HoverColor = hoverColor; + break; + } + } + + public static void RemovePrimaryActionStyle(this ThemeConfig config, GuiWidget guiWidget) + { + guiWidget.BackgroundColor = Color.Transparent; + + // Buttons in toolbars should revert to ToolbarButtonHover when reset + bool parentIsToolbar = guiWidget.Parent?.Parent is Toolbar; + + switch (guiWidget) + { + case SimpleFlowButton flowButton: + flowButton.HoverColor = parentIsToolbar ? config.ToolbarButtonHover : Color.Transparent; + break; + case SimpleButton button: + button.HoverColor = parentIsToolbar ? config.ToolbarButtonHover : Color.Transparent; + break; + } + } + + public static SolidSlider ApplySliderStyle(this ThemeConfig config, SolidSlider solidSlider) + { + solidSlider.View.TrackColor = config.SlightShade; + solidSlider.View.TrackRadius = 4; + + return solidSlider; + } + + public static DoubleSolidSlider ApplySliderStyle(this ThemeConfig config, DoubleSolidSlider solidSlider) + { + solidSlider.View.TrackColor = config.SlightShade; + solidSlider.View.TrackRadius = 4; + + return solidSlider; + } + + public static SectionWidget ApplyBoxStyle(this ThemeConfig config, SectionWidget sectionWidget) + { + return config.ApplyBoxStyle( + sectionWidget, + config.SectionBackgroundColor, + margin: new BorderDouble(config.DefaultContainerPadding, 0, config.DefaultContainerPadding, config.DefaultContainerPadding)); + } + + // ApplySquareBoxStyle + public static SectionWidget ApplyBoxStyle(this ThemeConfig config, SectionWidget sectionWidget, BorderDouble margin) + { + sectionWidget.BackgroundColor = config.SectionBackgroundColor; + sectionWidget.Margin = 0; + sectionWidget.Border = new BorderDouble(bottom: 1); + sectionWidget.BorderColor = config.RowBorder; + + return sectionWidget; + } + + public static SectionWidget ApplyBoxStyle(this ThemeConfig config, SectionWidget sectionWidget, Color backgroundColor, BorderDouble margin) + { + // Enforce panel padding + // sectionWidget.ContentPanel.Padding = new BorderDouble(10, 0, 10, 2); + // sectionWidget.ContentPanel.Padding = 0; + + sectionWidget.BorderColor = Color.Transparent; + sectionWidget.BorderRadius = 5; + sectionWidget.Margin = margin; + sectionWidget.BackgroundColor = backgroundColor; + + return sectionWidget; + } + + public static GuiWidget CreateSmallResetButton(this ThemeConfig config) + { + return new HoverImageWidget(config.RestoreNormal, config.RestoreHover) + { + VAnchor = VAnchor.Center, + Margin = new BorderDouble(0, 0, 5, 0) + }; + } + + public static void RebuildTheme(this ThemeConfig config) + { + config.GeneratingThumbnailIcon = StaticData.Instance.LoadIcon("building_thumbnail_40x40.png", 40, 40).SetToColor(config.TextColor); + } + } } \ No newline at end of file diff --git a/MatterControlLib/ApplicationView/Themes/ThemeSet.cs b/MatterControlLib/ApplicationView/Themes/ThemeSet.cs index 359ef68e1..bf22486c2 100644 --- a/MatterControlLib/ApplicationView/Themes/ThemeSet.cs +++ b/MatterControlLib/ApplicationView/Themes/ThemeSet.cs @@ -29,6 +29,7 @@ either expressed or implied, of the FreeBSD Project. using System.Collections.Generic; using MatterHackers.Agg; +using MatterHackers.Agg.UI; namespace MatterHackers.MatterControl { diff --git a/MatterControlLib/ConfigurationPage/PrintLeveling/WizardPages/WizardPage.cs b/MatterControlLib/ConfigurationPage/PrintLeveling/WizardPages/WizardPage.cs index db15411b5..54250ff63 100644 --- a/MatterControlLib/ConfigurationPage/PrintLeveling/WizardPages/WizardPage.cs +++ b/MatterControlLib/ConfigurationPage/PrintLeveling/WizardPages/WizardPage.cs @@ -39,7 +39,7 @@ namespace MatterHackers.MatterControl { public class WizardPage : DialogPage { - public TextButton NextButton { get; } + public ThemedTextButton NextButton { get; } protected PrinterConfig printer; public Action PageLoad { get; set; } diff --git a/MatterControlLib/ControlElements/MHNumberEdit.cs b/MatterControlLib/ControlElements/MHNumberEdit.cs deleted file mode 100644 index 75ba8da5a..000000000 --- a/MatterControlLib/ControlElements/MHNumberEdit.cs +++ /dev/null @@ -1,184 +0,0 @@ -/* -Copyright (c) 2018, Lars Brubaker, John Lewin -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the FreeBSD Project. -*/ - -using MatterHackers.Agg; -using MatterHackers.Agg.UI; - -namespace MatterHackers.MatterControl -{ - public class MHNumberEdit : GuiWidget - { - private ThemeConfig theme; - - public NumberEdit ActuallNumberEdit { get; } - - public MHNumberEdit(double startingValue, ThemeConfig theme, char singleCharLabel = char.MaxValue, string unitsLabel = "", double pixelWidth = 0, double pixelHeight = 0, bool allowNegatives = false, bool allowDecimals = false, double minValue = int.MinValue, double maxValue = int.MaxValue, double increment = 1, int tabIndex = 0) - { - using (this.LayoutLock()) - { - this.Padding = 3; - this.HAnchor = HAnchor.Fit; - this.VAnchor = VAnchor.Fit; - this.Border = 1; - this.theme = theme; - - this.ActuallNumberEdit = new NumberEdit(startingValue, 0, 0, theme.DefaultFontSize, pixelWidth, pixelHeight, allowNegatives, allowDecimals, minValue, maxValue, increment, tabIndex) - { - VAnchor = VAnchor.Bottom, - }; - - TextWidget labelWidget = null; - if (singleCharLabel != char.MaxValue) - { - labelWidget = new TextWidget(singleCharLabel.ToString(), pointSize: theme.DefaultFontSize - 2, textColor: theme.PrimaryAccentColor) - { - Margin = new BorderDouble(left: 2), - HAnchor = HAnchor.Left, - VAnchor = VAnchor.Center, - Selectable = false - }; - - this.AddChild(labelWidget); - - var labelWidth = labelWidget.Width + labelWidget.Margin.Left; - ActuallNumberEdit.Margin = ActuallNumberEdit.Margin.Clone(left: labelWidth + 2); - } - - var internalWidget = this.ActuallNumberEdit.InternalTextEditWidget; - internalWidget.TextColor = theme.EditFieldColors.Inactive.TextColor; - internalWidget.FocusChanged += (s, e) => - { - internalWidget.TextColor = (internalWidget.Focused) ? theme.EditFieldColors.Focused.TextColor : theme.EditFieldColors.Inactive.TextColor; - - if (labelWidget != null) - { - var labelDetailsColor = theme.PrimaryAccentColor.WithContrast(theme.EditFieldColors.Focused.BackgroundColor, 3).ToColor(); - labelWidget.TextColor = (internalWidget.Focused) ? labelDetailsColor : theme.PrimaryAccentColor; - } - }; - - this.ActuallNumberEdit.InternalNumberEdit.MaxDecimalsPlaces = 5; - this.AddChild(this.ActuallNumberEdit); - } - - this.PerformLayout(); - } - - public override Color BackgroundColor - { - get - { - if (base.BackgroundColor != Color.Transparent) - { - return base.BackgroundColor; - } - else if (this.ContainsFocus) - { - return theme.EditFieldColors.Focused.BackgroundColor; - } - else if (this.mouseInBounds) - { - return theme.EditFieldColors.Hovered.BackgroundColor; - } - else - { - return theme.EditFieldColors.Inactive.BackgroundColor; - } - } - set => base.BackgroundColor = value; - } - - public override Color BorderColor - { - get - { - if (base.BorderColor != Color.Transparent) - { - return base.BorderColor; - } - else if (this.ContainsFocus) - { - return theme.EditFieldColors.Focused.BorderColor; - } - else if (this.mouseInBounds && this.ContainsFirstUnderMouseRecursive()) - { - return theme.EditFieldColors.Hovered.BorderColor; - } - else - { - return theme.EditFieldColors.Inactive.BorderColor; - } - } - set => base.BorderColor = value; - } - - private bool mouseInBounds = false; - - public override void OnMouseEnterBounds(MouseEventArgs mouseEvent) - { - mouseInBounds = true; - base.OnMouseEnterBounds(mouseEvent); - - this.Invalidate(); - } - - public override void OnMouseLeaveBounds(MouseEventArgs mouseEvent) - { - mouseInBounds = false; - base.OnMouseLeaveBounds(mouseEvent); - - this.Invalidate(); - } - - public override int TabIndex - { - // TODO: This looks invalid - setter and getter should use same context - get => base.TabIndex; - set => this.ActuallNumberEdit.TabIndex = value; - } - - public double Value - { - get => this.ActuallNumberEdit.Value; - set => this.ActuallNumberEdit.Value = value; - } - - public override string Text - { - get => this.ActuallNumberEdit.Text; - set => this.ActuallNumberEdit.Text = value; - } - - public bool SelectAllOnFocus - { - get => this.ActuallNumberEdit.InternalNumberEdit.SelectAllOnFocus; - set => this.ActuallNumberEdit.InternalNumberEdit.SelectAllOnFocus = value; - } - } -} \ No newline at end of file diff --git a/MatterControlLib/ControlElements/MHPasswordTextEditWidget.cs b/MatterControlLib/ControlElements/MHPasswordTextEditWidget.cs deleted file mode 100644 index 0e9cb7580..000000000 --- a/MatterControlLib/ControlElements/MHPasswordTextEditWidget.cs +++ /dev/null @@ -1,100 +0,0 @@ -/* -Copyright (c) 2017, Lars Brubaker, John Lewin -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the FreeBSD Project. -*/ - -using System; -using MatterHackers.Agg; -using MatterHackers.Agg.UI; -using MatterHackers.VectorMath; - -namespace MatterHackers.MatterControl -{ - public class MHPasswordTextEditWidget : MHTextEditWidget - { - private TextEditWidget passwordCoverText; - - private class TextEditOverlay : TextEditWidget - { - public TextEditOverlay(string text, int pointSize, double pixelWidth, double pixelHeight, bool multiLine) - : base(text, 0, 0, pointSize, pixelWidth, pixelHeight, multiLine) - { - } - - public override Color BackgroundColor - { - get => this.Parent.BackgroundColor; - set - { - if (this.Parent != null) - { - this.Parent.BackgroundColor = value; - } - } - } - } - - public MHPasswordTextEditWidget(string text, ThemeConfig theme, double pixelWidth = 0, double pixelHeight = 0, bool multiLine = false, int tabIndex = 0, string messageWhenEmptyAndNotSelected = "") - : base(text, theme, pixelWidth, pixelHeight, multiLine, tabIndex, messageWhenEmptyAndNotSelected) - { - // remove this so that we can have other content first (the hidden letters) - this.RemoveChild(noContentFieldDescription); - - passwordCoverText = new TextEditOverlay(text, theme.DefaultFontSize, pixelWidth, pixelHeight, multiLine) - { - Selectable = false, - HAnchor = HAnchor.Stretch, - VAnchor = VAnchor.Bottom, - TextColor = theme.EditFieldColors.Inactive.TextColor - }; - passwordCoverText.MinimumSize = new Vector2(Math.Max(passwordCoverText.MinimumSize.X, pixelWidth), Math.Max(passwordCoverText.MinimumSize.Y, pixelHeight)); - - var internalWidget = this.ActualTextEditWidget.InternalTextEditWidget; - internalWidget.FocusChanged += (s, e) => - { - passwordCoverText.TextColor = (internalWidget.Focused) ? theme.EditFieldColors.Focused.TextColor : theme.EditFieldColors.Inactive.TextColor; - }; - - this.AddChild(passwordCoverText); - - this.ActualTextEditWidget.TextChanged += (sender, e) => - { - passwordCoverText.Text = new string('●', this.ActualTextEditWidget.Text.Length); - }; - - // put in back in after the hidden text - noContentFieldDescription.ClearRemovedFlag(); - this.AddChild(noContentFieldDescription); - } - - public bool Hidden - { - get => !passwordCoverText.Visible; - set => passwordCoverText.Visible = !value; - } - } -} \ No newline at end of file diff --git a/MatterControlLib/ControlElements/MHTextEditWidget.cs b/MatterControlLib/ControlElements/MHTextEditWidget.cs deleted file mode 100644 index 5f72795ec..000000000 --- a/MatterControlLib/ControlElements/MHTextEditWidget.cs +++ /dev/null @@ -1,210 +0,0 @@ -/* -Copyright (c) 2018, Lars Brubaker, John Lewin -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the FreeBSD Project. -*/ - -using System; -using MatterHackers.Agg; -using MatterHackers.Agg.Font; -using MatterHackers.Agg.UI; -using MatterHackers.VectorMath; - -namespace MatterHackers.MatterControl -{ - public class MHTextEditWidget : GuiWidget - { - protected TextWidget noContentFieldDescription = null; - private readonly ThemeConfig theme; - private bool mouseInBounds = false; - - public MHTextEditWidget(string text, ThemeConfig theme, double pixelWidth = 0, double pixelHeight = 0, bool multiLine = false, int tabIndex = 0, string messageWhenEmptyAndNotSelected = "", TypeFace typeFace = null) - { - this.Padding = new BorderDouble(3); - this.HAnchor = HAnchor.Fit; - this.VAnchor = VAnchor.Fit; - this.Border = 1; - this.theme = theme; - - this.ActualTextEditWidget = new TextEditWidget(text, 0, 0, theme.DefaultFontSize, pixelWidth, pixelHeight, multiLine, tabIndex: tabIndex, typeFace: typeFace) - { - VAnchor = VAnchor.Bottom, - BackgroundColor = Color.Transparent - }; - - TextWidget labelWidget = null; - - var internalWidget = this.ActualTextEditWidget.InternalTextEditWidget; - internalWidget.TextColor = theme.EditFieldColors.Inactive.TextColor; - internalWidget.FocusChanged += (s, e) => - { - internalWidget.TextColor = internalWidget.Focused ? theme.EditFieldColors.Focused.TextColor : theme.EditFieldColors.Inactive.TextColor; - noContentFieldDescription.TextColor = internalWidget.Focused ? theme.EditFieldColors.Focused.LightTextColor : theme.EditFieldColors.Inactive.LightTextColor; - - if (labelWidget != null) - { - var labelDetailsColor = theme.PrimaryAccentColor.WithContrast(theme.EditFieldColors.Focused.BackgroundColor, 3).ToColor(); - labelWidget.TextColor = (internalWidget.Focused) ? labelDetailsColor : theme.PrimaryAccentColor; - } - }; - - this.ActualTextEditWidget.InternalTextEditWidget.BackgroundColor = Color.Transparent; - - this.ActualTextEditWidget.MinimumSize = new Vector2(Math.Max(ActualTextEditWidget.MinimumSize.X, pixelWidth), Math.Max(ActualTextEditWidget.MinimumSize.Y, pixelHeight)); - this.AddChild(this.ActualTextEditWidget); - - this.AddChild(noContentFieldDescription = new TextWidget(messageWhenEmptyAndNotSelected, pointSize: theme.DefaultFontSize, textColor: theme.EditFieldColors.Focused.LightTextColor) - { - VAnchor = VAnchor.Top, - AutoExpandBoundsToText = true - }); - - SetNoContentFieldDescriptionVisibility(); - } - - public TextEditWidget ActualTextEditWidget { get; } - - public override Color BackgroundColor - { - get - { - if (base.BackgroundColor != Color.Transparent) - { - return base.BackgroundColor; - } - else if (this.ContainsFocus) - { - return theme.EditFieldColors.Focused.BackgroundColor; - } - else if (this.mouseInBounds) - { - return theme.EditFieldColors.Hovered.BackgroundColor; - } - else - { - return theme.EditFieldColors.Inactive.BackgroundColor; - } - } - set => base.BackgroundColor = value; - } - - public override Color BorderColor - { - get - { - if (base.BorderColor != Color.Transparent) - { - return base.BackgroundColor; - } - else if (this.ContainsFocus) - { - return theme.EditFieldColors.Focused.BorderColor; - } - else if (this.mouseInBounds && this.ContainsFirstUnderMouseRecursive()) - { - return theme.EditFieldColors.Hovered.BorderColor; - } - else - { - return theme.EditFieldColors.Inactive.BorderColor; - } - } - set => base.BorderColor = value; - } - - public override void OnMouseEnterBounds(MouseEventArgs mouseEvent) - { - mouseInBounds = true; - base.OnMouseEnterBounds(mouseEvent); - - this.Invalidate(); - } - - public override void OnMouseLeaveBounds(MouseEventArgs mouseEvent) - { - mouseInBounds = false; - base.OnMouseLeaveBounds(mouseEvent); - - this.Invalidate(); - } - - public override HAnchor HAnchor - { - get => base.HAnchor; - set - { - base.HAnchor = value; - if (ActualTextEditWidget != null) - { - ActualTextEditWidget.HAnchor = value; - } - } - } - - private void SetNoContentFieldDescriptionVisibility() - { - if (noContentFieldDescription != null) - { - noContentFieldDescription.Visible = string.IsNullOrEmpty(Text); - } - } - - public override void OnDraw(Graphics2D graphics2D) - { - SetNoContentFieldDescriptionVisibility(); - base.OnDraw(graphics2D); - } - - public override string Text - { - get => ActualTextEditWidget.Text; - set => ActualTextEditWidget.Text = value; - } - - public bool SelectAllOnFocus - { - get => ActualTextEditWidget.InternalTextEditWidget.SelectAllOnFocus; - set => ActualTextEditWidget.InternalTextEditWidget.SelectAllOnFocus = value; - } - - public bool ReadOnly - { - get => ActualTextEditWidget.ReadOnly; - set => ActualTextEditWidget.ReadOnly = value; - } - - public void DrawFromHintedCache() - { - ActualTextEditWidget.Printer.DrawFromHintedCache = true; - ActualTextEditWidget.DoubleBuffer = false; - } - - public override void Focus() - { - ActualTextEditWidget.Focus(); - } - } -} \ No newline at end of file diff --git a/MatterControlLib/CustomWidgets/CalibrationTabWidget.cs b/MatterControlLib/CustomWidgets/CalibrationTabWidget.cs index 383c5bc31..087ce7e40 100644 --- a/MatterControlLib/CustomWidgets/CalibrationTabWidget.cs +++ b/MatterControlLib/CustomWidgets/CalibrationTabWidget.cs @@ -52,7 +52,7 @@ namespace MatterHackers.MatterControl private XyCalibrationWizard calibrationWizard; private ThemeConfig theme; - public TextButton NextButton { get; } + public ThemedTextButton NextButton { get; } private Color tabBaseColor; private TextWidget xLabel; @@ -60,7 +60,7 @@ namespace MatterHackers.MatterControl private PrinterConnection.Axis _collectionMode = PrinterConnection.Axis.X; - public CalibrationTabWidget(XyCalibrationWizard calibrationWizard, TextButton nextButton, ThemeConfig theme) + public CalibrationTabWidget(XyCalibrationWizard calibrationWizard, ThemedTextButton nextButton, ThemeConfig theme) { this.calibrationWizard = calibrationWizard; this.theme = theme; diff --git a/MatterControlLib/CustomWidgets/InlineEditControl.cs b/MatterControlLib/CustomWidgets/InlineEditControl.cs index d7497ff40..c6ec49bb2 100644 --- a/MatterControlLib/CustomWidgets/InlineEditControl.cs +++ b/MatterControlLib/CustomWidgets/InlineEditControl.cs @@ -38,7 +38,7 @@ namespace MatterHackers.MatterControl.CustomWidgets public class InlineEditControl : GuiWidget { private TextWidget numberDisplay; - private MHNumberEdit numberEdit; + private ThemedNumberEdit numberEdit; private Func _getDisplayString = (value) => "{0:0.0}".FormatWith(value); private RunningInterval runningInterval; private ThemeConfig theme; @@ -78,7 +78,7 @@ namespace MatterHackers.MatterControl.CustomWidgets AddChild(numberDisplay); - numberEdit = new MHNumberEdit(0, theme, pixelWidth: numberDisplay.Width, allowNegatives: true, allowDecimals: true) + numberEdit = new ThemedNumberEdit(0, theme, pixelWidth: numberDisplay.Width, allowNegatives: true, allowDecimals: true) { Visible = false, VAnchor = VAnchor.Bottom, diff --git a/MatterControlLib/CustomWidgets/InlineListItemEdit.cs b/MatterControlLib/CustomWidgets/InlineListItemEdit.cs index 398979d99..bb6881670 100644 --- a/MatterControlLib/CustomWidgets/InlineListItemEdit.cs +++ b/MatterControlLib/CustomWidgets/InlineListItemEdit.cs @@ -30,6 +30,7 @@ either expressed or implied, of the FreeBSD Project. using System; using MatterHackers.Agg; using MatterHackers.Agg.Platform; +using MatterHackers.Agg.UI; using MatterHackers.ImageProcessing; using MatterHackers.Localizations; diff --git a/MatterControlLib/CustomWidgets/PrintingWindow/BedStatusWidget.cs b/MatterControlLib/CustomWidgets/PrintingWindow/BedStatusWidget.cs index 80dbb0abb..906a39d02 100644 --- a/MatterControlLib/CustomWidgets/PrintingWindow/BedStatusWidget.cs +++ b/MatterControlLib/CustomWidgets/PrintingWindow/BedStatusWidget.cs @@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project. */ using System; +using MatterHackers.Agg.UI; using MatterHackers.Localizations; namespace MatterHackers.MatterControl.CustomWidgets diff --git a/MatterControlLib/CustomWidgets/PrintingWindow/ExtruderStatusWidget.cs b/MatterControlLib/CustomWidgets/PrintingWindow/ExtruderStatusWidget.cs index 45f006942..376c5c61b 100644 --- a/MatterControlLib/CustomWidgets/PrintingWindow/ExtruderStatusWidget.cs +++ b/MatterControlLib/CustomWidgets/PrintingWindow/ExtruderStatusWidget.cs @@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project. */ using System; +using MatterHackers.Agg.UI; using MatterHackers.Localizations; namespace MatterHackers.MatterControl.CustomWidgets diff --git a/MatterControlLib/DesignTools/OpenSCAD/OpenSCADBuilder.cs b/MatterControlLib/DesignTools/OpenSCAD/OpenSCADBuilder.cs index 9b74aec6e..9d45a8b4b 100644 --- a/MatterControlLib/DesignTools/OpenSCAD/OpenSCADBuilder.cs +++ b/MatterControlLib/DesignTools/OpenSCAD/OpenSCADBuilder.cs @@ -203,7 +203,7 @@ namespace MatterHackers.MatterControl.Library double val; double.TryParse(latest, out val); - var editor = new MHNumberEdit(val, theme, pixelWidth: 50 * GuiWidget.DeviceScale, allowDecimals: true, increment: .05) + var editor = new ThemedNumberEdit(val, theme, pixelWidth: 50 * GuiWidget.DeviceScale, allowDecimals: true, increment: .05) { SelectAllOnFocus = true, VAnchor = VAnchor.Center diff --git a/MatterControlLib/DesignTools/Operations/ScaleObject3D.cs b/MatterControlLib/DesignTools/Operations/ScaleObject3D.cs index f5fe73341..70a37b8a0 100644 --- a/MatterControlLib/DesignTools/Operations/ScaleObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/ScaleObject3D.cs @@ -43,7 +43,6 @@ using MatterHackers.Localizations; using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.RenderOpenGl; using MatterHackers.VectorMath; -using MatterHackers.RenderOpenGl; using Newtonsoft.Json; namespace MatterHackers.MatterControl.DesignTools.Operations diff --git a/MatterControlLib/DesignTools/Primitives/CubeObject3D.cs b/MatterControlLib/DesignTools/Primitives/CubeObject3D.cs index 7770dfb59..97f03c54b 100644 --- a/MatterControlLib/DesignTools/Primitives/CubeObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/CubeObject3D.cs @@ -34,7 +34,7 @@ using MatterHackers.Localizations; using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.PolygonMesh; using MatterHackers.VectorMath; -using PolygonMesh.Solids; +using MatterHackers.PolygonMesh.Solids; namespace MatterHackers.MatterControl.DesignTools { diff --git a/MatterControlLib/DesignTools/PublicPropertyEditor.cs b/MatterControlLib/DesignTools/PublicPropertyEditor.cs index 5c4fd3e84..b469331cf 100644 --- a/MatterControlLib/DesignTools/PublicPropertyEditor.cs +++ b/MatterControlLib/DesignTools/PublicPropertyEditor.cs @@ -1248,7 +1248,7 @@ namespace MatterHackers.MatterControl.DesignTools Margin = new BorderDouble(5, 0) }; - var searchField = new MHTextEditWidget("", theme, messageWhenEmptyAndNotSelected: "Search Google for images") + var searchField = new ThemedTextEditWidget("", theme, messageWhenEmptyAndNotSelected: "Search Google for images") { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Center diff --git a/MatterControlLib/DesignTools/Sheets/SheetObject3D.cs b/MatterControlLib/DesignTools/Sheets/SheetObject3D.cs index d121ce648..716bc6b3e 100644 --- a/MatterControlLib/DesignTools/Sheets/SheetObject3D.cs +++ b/MatterControlLib/DesignTools/Sheets/SheetObject3D.cs @@ -29,11 +29,14 @@ either expressed or implied, of the FreeBSD Project. using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; +using System.Reflection; using System.Text.RegularExpressions; using System.Threading.Tasks; +using MatterHackers.Agg; using MatterHackers.Agg.Platform; using MatterHackers.Agg.UI; using MatterHackers.DataConverters3D; @@ -375,6 +378,59 @@ namespace MatterHackers.MatterControl.DesignTools return stringWithConstants; } + private static string GetDisplayName(PropertyInfo prop) + { + var nameAttribute = prop.GetCustomAttributes(true).OfType().FirstOrDefault(); + return nameAttribute?.DisplayName ?? prop.Name.SplitCamelCase(); + } + + private static string SearchSiblingProperties(IObject3D owner, string inExpression) + { + var parent = owner.Parent; + if (parent != null) + { + var matches = ConstantFinder.Matches(inExpression); + + for (int i = 0; i < matches.Count; i++) + { + var constant = matches[i].Value; + // split inExpression on . + var splitExpression = constant.Split('.'); + if (splitExpression.Length == 2) + { + foreach (var child in parent.Children) + { + // skip if owner + if (child != owner) + { + var itemName = splitExpression[0]; + var propertyName = splitExpression[1]; + // if child has the same name as itemName + if (child.Name == itemName) + { + // enumerate public properties on child + foreach (var property in child.GetType().GetProperties()) + { + var displayName = GetDisplayName(property); + // if property name matches propertyName + if (displayName == propertyName) + { + // return the value + var expression = child.GetType().GetProperty(property.Name).GetValue(child, null).ToString(); + var value = SheetObject3D.EvaluateExpression(child, expression).ToString(); + inExpression = inExpression.Replace("[" + constant + "]", value); + } + } + } + } + } + } + } + } + + return inExpression; + } + public static T EvaluateExpression(IObject3D owner, string inExpression) { var inputExpression = inExpression; @@ -384,6 +440,8 @@ namespace MatterHackers.MatterControl.DesignTools inputExpression = printer.Settings.ReplaceSettingsNamesWithValues(inputExpression, false); } + inputExpression = SearchSiblingProperties(owner, inputExpression); + inputExpression = ReplaceConstantsWithValues(owner, inputExpression); // check if the expression is not an equation (does not start with "=") diff --git a/MatterControlLib/EeProm/EePromMarlinWindow.cs b/MatterControlLib/EeProm/EePromMarlinWindow.cs index dc1af6992..ab0448781 100644 --- a/MatterControlLib/EeProm/EePromMarlinWindow.cs +++ b/MatterControlLib/EeProm/EePromMarlinWindow.cs @@ -41,45 +41,45 @@ namespace MatterHackers.MatterControl.EeProm { private EePromMarlinSettings currentEePromSettings; - private MHNumberEdit stepsPerMmX; - private MHNumberEdit stepsPerMmY; - private MHNumberEdit stepsPerMmZ; - private MHNumberEdit stepsPerMmE; + private ThemedNumberEdit stepsPerMmX; + private ThemedNumberEdit stepsPerMmY; + private ThemedNumberEdit stepsPerMmZ; + private ThemedNumberEdit stepsPerMmE; - private MHNumberEdit maxFeedrateMmPerSX; - private MHNumberEdit maxFeedrateMmPerSY; - private MHNumberEdit maxFeedrateMmPerSZ; - private MHNumberEdit maxFeedrateMmPerSE; + private ThemedNumberEdit maxFeedrateMmPerSX; + private ThemedNumberEdit maxFeedrateMmPerSY; + private ThemedNumberEdit maxFeedrateMmPerSZ; + private ThemedNumberEdit maxFeedrateMmPerSE; - private MHNumberEdit maxAccelerationMmPerSSqrdX; - private MHNumberEdit maxAccelerationMmPerSSqrdY; - private MHNumberEdit maxAccelerationMmPerSSqrdZ; - private MHNumberEdit maxAccelerationMmPerSSqrdE; + private ThemedNumberEdit maxAccelerationMmPerSSqrdX; + private ThemedNumberEdit maxAccelerationMmPerSSqrdY; + private ThemedNumberEdit maxAccelerationMmPerSSqrdZ; + private ThemedNumberEdit maxAccelerationMmPerSSqrdE; - private MHNumberEdit accelerationPrintingMoves; - private MHNumberEdit accelerationRetraction; - private MHNumberEdit accelerationTravelMoves; + private ThemedNumberEdit accelerationPrintingMoves; + private ThemedNumberEdit accelerationRetraction; + private ThemedNumberEdit accelerationTravelMoves; - private MHNumberEdit pidP; - private MHNumberEdit pidI; - private MHNumberEdit pidD; + private ThemedNumberEdit pidP; + private ThemedNumberEdit pidI; + private ThemedNumberEdit pidD; - private MHNumberEdit bedPidP; - private MHNumberEdit bedPidI; - private MHNumberEdit bedPidD; + private ThemedNumberEdit bedPidP; + private ThemedNumberEdit bedPidI; + private ThemedNumberEdit bedPidD; - private MHNumberEdit homingOffsetX; - private MHNumberEdit homingOffsetY; - private MHNumberEdit homingOffsetZ; + private ThemedNumberEdit homingOffsetX; + private ThemedNumberEdit homingOffsetY; + private ThemedNumberEdit homingOffsetZ; - private MHNumberEdit minFeedrate; - private MHNumberEdit minTravelFeedrate; - private MHNumberEdit minSegmentTime; + private ThemedNumberEdit minFeedrate; + private ThemedNumberEdit minTravelFeedrate; + private ThemedNumberEdit minSegmentTime; - private MHNumberEdit maxXYJerk; - private MHNumberEdit maxZJerk; - private MHNumberEdit maxEJerk; - private MHNumberEdit maxDeviation; + private ThemedNumberEdit maxXYJerk; + private ThemedNumberEdit maxZJerk; + private ThemedNumberEdit maxEJerk; + private ThemedNumberEdit maxDeviation; private EventHandler unregisterEvents; @@ -254,9 +254,9 @@ namespace MatterHackers.MatterControl.EeProm }); } - private GuiWidget CreateMHNumEdit(ref MHNumberEdit numberEditToCreate) + private GuiWidget CreateMHNumEdit(ref ThemedNumberEdit numberEditToCreate) { - numberEditToCreate = new MHNumberEdit(0, theme, pixelWidth: 80 * GuiWidget.DeviceScale, allowNegatives: true, allowDecimals: true) + numberEditToCreate = new ThemedNumberEdit(0, theme, pixelWidth: 80 * GuiWidget.DeviceScale, allowNegatives: true, allowDecimals: true) { SelectAllOnFocus = true, VAnchor = VAnchor.Center, @@ -267,9 +267,9 @@ namespace MatterHackers.MatterControl.EeProm return numberEditToCreate; } - private GuiWidget CreateField(string label, ref MHNumberEdit field1) + private GuiWidget CreateField(string label, ref ThemedNumberEdit field1) { - MHNumberEdit none = null; + ThemedNumberEdit none = null; return Create4FieldSet(label, "", ref field1, @@ -279,11 +279,11 @@ namespace MatterHackers.MatterControl.EeProm } private GuiWidget Create3FieldSet(string label, - string field1Label, ref MHNumberEdit field1, - string field2Label, ref MHNumberEdit field2, - string field3Label, ref MHNumberEdit field3) + string field1Label, ref ThemedNumberEdit field1, + string field2Label, ref ThemedNumberEdit field2, + string field3Label, ref ThemedNumberEdit field3) { - MHNumberEdit none = null; + ThemedNumberEdit none = null; return Create4FieldSet(label, field1Label, ref field1, @@ -307,10 +307,10 @@ namespace MatterHackers.MatterControl.EeProm } private GuiWidget Create4FieldSet(string label, - string field1Label, ref MHNumberEdit field1, - string field2Label, ref MHNumberEdit field2, - string field3Label, ref MHNumberEdit field3, - string field4Label, ref MHNumberEdit field4) + string field1Label, ref ThemedNumberEdit field1, + string field2Label, ref ThemedNumberEdit field2, + string field3Label, ref ThemedNumberEdit field3, + string field4Label, ref ThemedNumberEdit field4) { var row = new FlowLayoutWidget { diff --git a/MatterControlLib/EeProm/EePromRepetierWindow.cs b/MatterControlLib/EeProm/EePromRepetierWindow.cs index c45a09044..0ad9fd597 100644 --- a/MatterControlLib/EeProm/EePromRepetierWindow.cs +++ b/MatterControlLib/EeProm/EePromRepetierWindow.cs @@ -301,7 +301,7 @@ namespace MatterHackers.MatterControl.EeProm CreateSpacer(row); double.TryParse(newSetting.Value, out double currentValue); - var valueEdit = new MHNumberEdit(currentValue, theme, pixelWidth: 80 * GuiWidget.DeviceScale, allowNegatives: true, allowDecimals: true) + var valueEdit = new ThemedNumberEdit(currentValue, theme, pixelWidth: 80 * GuiWidget.DeviceScale, allowNegatives: true, allowDecimals: true) { SelectAllOnFocus = true, TabIndex = currentTabIndex++, diff --git a/MatterControlLib/Graphics2DOverrides.cs b/MatterControlLib/Graphics2DOverrides.cs index cbbd87af5..a418739b0 100644 --- a/MatterControlLib/Graphics2DOverrides.cs +++ b/MatterControlLib/Graphics2DOverrides.cs @@ -30,6 +30,7 @@ either expressed or implied, of the FreeBSD Project. using System; using MatterHackers.Agg; using MatterHackers.Agg.Transform; +using MatterHackers.Agg.UI; using MatterHackers.Agg.VertexSource; using MatterHackers.VectorMath; diff --git a/MatterControlLib/History/PrintHistoryEditor.cs b/MatterControlLib/History/PrintHistoryEditor.cs index 2036e5ccb..ab8bafcce 100644 --- a/MatterControlLib/History/PrintHistoryEditor.cs +++ b/MatterControlLib/History/PrintHistoryEditor.cs @@ -444,7 +444,7 @@ Support and tutorials:" + articles; public class CollectPrintDetailsPage : DialogPage { - private readonly MHTextEditWidget textEditWidget; + private readonly ThemedTextEditWidget textEditWidget; public override string Text { get => textEditWidget.Text; set => textEditWidget.Text = value; } @@ -507,7 +507,7 @@ Support and tutorials:" + articles; // Adds text box and check box to the above container var emptyText = "What went wrong?".Localize(); var initialValue = printTask.Note ?? ""; - textEditWidget = new MHTextEditWidget(initialValue, theme, pixelWidth: 300, messageWhenEmptyAndNotSelected: emptyText) + textEditWidget = new ThemedTextEditWidget(initialValue, theme, pixelWidth: 300, messageWhenEmptyAndNotSelected: emptyText) { Name = "InputBoxPage TextEditWidget", HAnchor = HAnchor.Stretch, diff --git a/MatterControlLib/Library/ContentProviders/MeshContentProvider.cs b/MatterControlLib/Library/ContentProviders/MeshContentProvider.cs index e45545a23..03aca8c98 100644 --- a/MatterControlLib/Library/ContentProviders/MeshContentProvider.cs +++ b/MatterControlLib/Library/ContentProviders/MeshContentProvider.cs @@ -38,7 +38,8 @@ namespace MatterHackers.MatterControl using System.Threading; using MatterHackers.Agg.Image; using MatterHackers.Agg.Platform; - using MatterHackers.DataConverters3D; + using MatterHackers.Agg.UI; + using MatterHackers.DataConverters3D; using MatterHackers.ImageProcessing; using MatterHackers.MatterControl.DataStorage; using MatterHackers.MatterControl.DesignTools.Operations; diff --git a/MatterControlLib/Library/Widgets/AddMaterialDialog.cs b/MatterControlLib/Library/Widgets/AddMaterialDialog.cs index 92230ccab..6f2aef4d5 100644 --- a/MatterControlLib/Library/Widgets/AddMaterialDialog.cs +++ b/MatterControlLib/Library/Widgets/AddMaterialDialog.cs @@ -40,7 +40,7 @@ namespace MatterHackers.MatterControl.Library.Widgets { private readonly RadioButton createPrinterRadioButton = null; private readonly AddMaterialWidget materialPanel; - private readonly TextButton nextButton; + private readonly ThemedTextButton nextButton; public AddMaterialDialog(Action addedMaterial, Action defineNewClicked) { diff --git a/MatterControlLib/Library/Widgets/AddPrinterWidget.cs b/MatterControlLib/Library/Widgets/AddPrinterWidget.cs index 898a7d495..d8e6d8294 100644 --- a/MatterControlLib/Library/Widgets/AddPrinterWidget.cs +++ b/MatterControlLib/Library/Widgets/AddPrinterWidget.cs @@ -45,7 +45,7 @@ namespace MatterHackers.MatterControl.Library.Widgets public class AddPrinterWidget : SearchableTreePanel { private SectionWidget nameSection; - private MHTextEditWidget printerNameInput; + private ThemedTextEditWidget printerNameInput; private bool usingDefaultName = true; private Action nextButtonEnabled; private FlowLayoutWidget printerInfo; @@ -154,7 +154,7 @@ namespace MatterHackers.MatterControl.Library.Widgets horizontalSplitter.Panel2.AddChild(panel2Column); - printerNameInput = new MHTextEditWidget("", theme) + printerNameInput = new ThemedTextEditWidget("", theme) { HAnchor = HAnchor.Stretch, }; diff --git a/MatterControlLib/Library/Widgets/CloneSettingsPage.cs b/MatterControlLib/Library/Widgets/CloneSettingsPage.cs index 9a5020d44..5749b6cf6 100644 --- a/MatterControlLib/Library/Widgets/CloneSettingsPage.cs +++ b/MatterControlLib/Library/Widgets/CloneSettingsPage.cs @@ -58,9 +58,9 @@ namespace MatterHackers.MatterControl.Library.Widgets }; contentRow.AddChild(pathRow); - TextButton importButton = null; + ThemedTextButton importButton = null; - var textEditWidget = new MHTextEditWidget("", theme) + var textEditWidget = new ThemedTextEditWidget("", theme) { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Center, diff --git a/MatterControlLib/Library/Widgets/ContainerTreeNode.cs b/MatterControlLib/Library/Widgets/ContainerTreeNode.cs index 7c31e3038..c69feacc1 100644 --- a/MatterControlLib/Library/Widgets/ContainerTreeNode.cs +++ b/MatterControlLib/Library/Widgets/ContainerTreeNode.cs @@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project. */ +using MatterHackers.Agg.UI; using MatterHackers.MatterControl.CustomWidgets; namespace MatterHackers.MatterControl.Library.Widgets diff --git a/MatterControlLib/Library/Widgets/PrintLibraryWidget.cs b/MatterControlLib/Library/Widgets/PrintLibraryWidget.cs index 0cda5329b..8b1d7e6f8 100644 --- a/MatterControlLib/Library/Widgets/PrintLibraryWidget.cs +++ b/MatterControlLib/Library/Widgets/PrintLibraryWidget.cs @@ -419,7 +419,7 @@ namespace MatterHackers.MatterControl.Library.Widgets public class TextEditWithInlineCancel : GuiWidget { - public MHTextEditWidget TextEditWidget { get; } + public ThemedTextEditWidget TextEditWidget { get; } public GuiWidget ResetButton { get; } @@ -433,7 +433,7 @@ namespace MatterHackers.MatterControl.Library.Widgets this.VAnchor = VAnchor.Center | VAnchor.Fit; this.HAnchor = HAnchor.Stretch; - TextEditWidget = new MHTextEditWidget("", theme, messageWhenEmptyAndNotSelected: emptyText) + TextEditWidget = new ThemedTextEditWidget("", theme, messageWhenEmptyAndNotSelected: emptyText) { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Center diff --git a/MatterControlLib/MatterControlLib.csproj b/MatterControlLib/MatterControlLib.csproj index ad004c2b0..70ab59732 100644 --- a/MatterControlLib/MatterControlLib.csproj +++ b/MatterControlLib/MatterControlLib.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + net6.0-windows MatterHackers Inc. 2.20.12 @@ -84,6 +84,7 @@ + diff --git a/MatterControlLib/PartPreviewWindow/HelpSearchResultRow.cs b/MatterControlLib/PartPreviewWindow/HelpSearchResultRow.cs index 05cb79dd9..6a0cc347e 100644 --- a/MatterControlLib/PartPreviewWindow/HelpSearchResultRow.cs +++ b/MatterControlLib/PartPreviewWindow/HelpSearchResultRow.cs @@ -29,6 +29,7 @@ either expressed or implied, of the FreeBSD Project. using MatterHackers.Agg; using MatterHackers.Agg.Platform; +using MatterHackers.Agg.UI; using MatterHackers.MatterControl.CustomWidgets; namespace MatterHackers.MatterControl.PartPreviewWindow diff --git a/MatterControlLib/PartPreviewWindow/LibraryBrowserPage.cs b/MatterControlLib/PartPreviewWindow/LibraryBrowserPage.cs index ef68cc854..8d6a84d9e 100644 --- a/MatterControlLib/PartPreviewWindow/LibraryBrowserPage.cs +++ b/MatterControlLib/PartPreviewWindow/LibraryBrowserPage.cs @@ -41,7 +41,7 @@ namespace MatterHackers.MatterControl public class LibraryBrowserPage : DialogPage { protected GuiWidget acceptButton = null; - protected MHTextEditWidget itemNameWidget; + protected ThemedTextEditWidget itemNameWidget; protected ILibraryContext libraryNavContext; protected LibraryListView librarySelectorWidget; private FolderBreadCrumbWidget breadCrumbWidget = null; diff --git a/MatterControlLib/PartPreviewWindow/MarkdownEditPage.cs b/MatterControlLib/PartPreviewWindow/MarkdownEditPage.cs index 71e7ddadf..672dccc98 100644 --- a/MatterControlLib/PartPreviewWindow/MarkdownEditPage.cs +++ b/MatterControlLib/PartPreviewWindow/MarkdownEditPage.cs @@ -39,7 +39,7 @@ namespace MatterHackers.MatterControl { public class MarkdownEditPage : DialogPage { - private MHTextEditWidget editWidget; + private ThemedTextEditWidget editWidget; private MarkdownWidget markdownWidget; public MarkdownEditPage(UIField uiField) @@ -66,7 +66,7 @@ namespace MatterHackers.MatterControl BackgroundColor = theme.BackgroundColor }; - editWidget = new MHTextEditWidget("", theme, multiLine: true, typeFace: ApplicationController.GetTypeFace(NamedTypeFace.Liberation_Mono)) + editWidget = new ThemedTextEditWidget("", theme, multiLine: true, typeFace: ApplicationController.GetTypeFace(NamedTypeFace.Liberation_Mono)) { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Stretch, diff --git a/MatterControlLib/PartPreviewWindow/RunningTaskRow.cs b/MatterControlLib/PartPreviewWindow/RunningTaskRow.cs index 2143ece10..96beff314 100644 --- a/MatterControlLib/PartPreviewWindow/RunningTaskRow.cs +++ b/MatterControlLib/PartPreviewWindow/RunningTaskRow.cs @@ -108,7 +108,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow taskDetails.Options?.PauseText, taskDetails.Options?.PauseAction, taskDetails.Options?.PauseToolTip ?? "Pause".Localize(), - "", + "Pause Task Button", theme, 0); diff --git a/MatterControlLib/PartPreviewWindow/SaveAsPage.cs b/MatterControlLib/PartPreviewWindow/SaveAsPage.cs index ac496080e..541db9f7a 100644 --- a/MatterControlLib/PartPreviewWindow/SaveAsPage.cs +++ b/MatterControlLib/PartPreviewWindow/SaveAsPage.cs @@ -60,7 +60,7 @@ namespace MatterHackers.MatterControl contentRow.AddChild(fileNameHeader); // Adds text box and check box to the above container - itemNameWidget = new MHTextEditWidget("", theme, pixelWidth: 300, messageWhenEmptyAndNotSelected: "Enter a Design Name Here".Localize()) + itemNameWidget = new ThemedTextEditWidget("", theme, pixelWidth: 300, messageWhenEmptyAndNotSelected: "Enter a Design Name Here".Localize()) { HAnchor = HAnchor.Stretch, Margin = new BorderDouble(5), diff --git a/MatterControlLib/PartPreviewWindow/View3D/Actions/SheetEditor.cs b/MatterControlLib/PartPreviewWindow/View3D/Actions/SheetEditor.cs index 5fd679e5d..d01b45db5 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/Actions/SheetEditor.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/Actions/SheetEditor.cs @@ -47,8 +47,8 @@ namespace MatterHackers.MatterControl.DesignTools public UndoBuffer UndoBuffer { get; } private ThemeConfig theme; - private MHTextEditWidget editSelectedName; - public MHTextEditWidget EditSelectedExpression { get; private set; } + private ThemedTextEditWidget editSelectedName; + public ThemedTextEditWidget EditSelectedExpression { get; private set; } private GridWidget gridWidget; public SheetEditorWidget(SheetData sheetData, SheetObject3D sheetObject, UndoBuffer undoBuffer, ThemeConfig theme) @@ -68,13 +68,13 @@ namespace MatterHackers.MatterControl.DesignTools VAnchor = VAnchor.Fit, }); - editSelectedName = new MHTextEditWidget("", theme, cellEditNameWidth, messageWhenEmptyAndNotSelected: "Name".Localize()) + editSelectedName = new ThemedTextEditWidget("", theme, cellEditNameWidth, messageWhenEmptyAndNotSelected: "Name".Localize()) { HAnchor = HAnchor.Absolute, }; editSelectedName.ActualTextEditWidget.EditComplete += SelectedName_EditComplete; editSelectionGroup.AddChild(editSelectedName); - EditSelectedExpression = new MHTextEditWidget("", theme, messageWhenEmptyAndNotSelected: "Select cell to edit".Localize()) + EditSelectedExpression = new ThemedTextEditWidget("", theme, messageWhenEmptyAndNotSelected: "Select cell to edit".Localize()) { HAnchor = HAnchor.Stretch, }; diff --git a/MatterControlLib/PartPreviewWindow/View3D/Gui3D/SelectionShadow.cs b/MatterControlLib/PartPreviewWindow/View3D/Gui3D/SelectionShadow.cs index e4ab1571c..9691f5685 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/Gui3D/SelectionShadow.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/Gui3D/SelectionShadow.cs @@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project. */ using MatterHackers.Agg; +using MatterHackers.Agg.UI; using MatterHackers.DataConverters3D; using MatterHackers.MeshVisualizer; using MatterHackers.PolygonMesh; diff --git a/MatterControlLib/PartPreviewWindow/View3D/Object3DControlsLayer.cs b/MatterControlLib/PartPreviewWindow/View3D/Object3DControlsLayer.cs index 318c65fc7..94b41ddfe 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/Object3DControlsLayer.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/Object3DControlsLayer.cs @@ -402,6 +402,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { mouseDownObject3DControl.OnMouseDown(new Mouse3DEventArgs(mouseEvent, ray, info)); SelectedObject3DControl = mouseDownObject3DControl; + + // Needed for testing DimensionsWorkWhenNoSheet to work (more) reliably. Otherwise, OnMouseMove's defered update might not pick up the hover in time. + HoveredObject3DControl = mouseDownObject3DControl; } else { diff --git a/MatterControlLib/PrinterCommunication/Drivers/Emulator/Emulator.cs b/MatterControlLib/PrinterCommunication/Drivers/Emulator/Emulator.cs index 028b9062e..42113267a 100644 --- a/MatterControlLib/PrinterCommunication/Drivers/Emulator/Emulator.cs +++ b/MatterControlLib/PrinterCommunication/Drivers/Emulator/Emulator.cs @@ -21,6 +21,9 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Semaphore implementation might stop the rare chance of a super slow print occuring in the ReSliceHasCorrectEPositions test. +#define USE_SEMAPHORE_FOR_RECEIVE_QUEUE + using System; using System.Collections.Generic; using System.Globalization; @@ -410,8 +413,11 @@ ok if (!shuttingDown) { shuttingDown = true; +#if USE_SEMAPHORE_FOR_RECEIVE_QUEUE + receiveResetEvent.Release(); +#endif - HeatedBed.Stop(); + HeatedBed.Stop(); foreach (var extruder in Extruders) { extruder.Stop(); @@ -739,7 +745,12 @@ ok private readonly object receiveLock = new object(); private readonly Queue receiveQueue = new Queue(); + +#if !USE_SEMAPHORE_FOR_RECEIVE_QUEUE private AutoResetEvent receiveResetEvent = new AutoResetEvent(false); +#else + private SemaphoreSlim receiveResetEvent = new(0); +#endif private readonly object sendLock = new object(); private readonly Queue sendQueue = new Queue(new string[] { "Emulator v0.1\n" }); @@ -788,7 +799,11 @@ ok { this.IsOpen = true; +#if !USE_SEMAPHORE_FOR_RECEIVE_QUEUE receiveResetEvent = new AutoResetEvent(false); +#else + receiveResetEvent = new(0); +#endif this.ReadTimeout = 500; this.WriteTimeout = 500; @@ -814,6 +829,7 @@ ok { Thread.CurrentThread.Name = "EmulatorPipeline"; +#if !USE_SEMAPHORE_FOR_RECEIVE_QUEUE while (!shuttingDown || receiveQueue.Count > 0) { if (receiveQueue.Count == 0) @@ -856,10 +872,38 @@ ok } } } +#else + for (; ;) + { + receiveResetEvent.Wait(); - this.IsOpen = false; + string receivedLine; + + lock (receiveLock) + { + if (receiveQueue.Count <= 0) + { + // End of queue. The only other thing the semaphore is signalled for is shutdown. + System.Diagnostics.Debug.Assert(shuttingDown); + break; + } + + receivedLine = receiveQueue.Dequeue(); + } + + if (receivedLine?.Length > 0) + { + // Thread.Sleep(250); + string emulatedResponse = GetCorrectResponse(receivedLine); + + lock (sendLock) + { + sendQueue.Enqueue(emulatedResponse); + } + } + } +#endif - this.Dispose(); }); } @@ -886,7 +930,11 @@ ok } // Release the main loop to process the received command +#if !USE_SEMAPHORE_FOR_RECEIVE_QUEUE receiveResetEvent.Set(); +#else + receiveResetEvent.Release(); +#endif } public void Write(byte[] buffer, int offset, int count) => throw new NotImplementedException(); diff --git a/MatterControlLib/PrinterControls/ControlWidgets/AdjustmentControls.cs b/MatterControlLib/PrinterControls/ControlWidgets/AdjustmentControls.cs index cf2125314..20f54b4d9 100644 --- a/MatterControlLib/PrinterControls/ControlWidgets/AdjustmentControls.cs +++ b/MatterControlLib/PrinterControls/ControlWidgets/AdjustmentControls.cs @@ -41,8 +41,8 @@ namespace MatterHackers.MatterControl.PrinterControls { public class AdjustmentControls : FlowLayoutWidget { - private MHNumberEdit feedRateValue; - private MHNumberEdit extrusionValue; + private ThemedNumberEdit feedRateValue; + private ThemedNumberEdit extrusionValue; private SolidSlider feedRateRatioSlider; private SolidSlider extrusionRatioSlider; @@ -55,7 +55,7 @@ namespace MatterHackers.MatterControl.PrinterControls private PrinterConfig printer; private AdjustmentControls(PrinterConfig printer, ThemeConfig theme) - : base (FlowDirection.TopToBottom) + : base(FlowDirection.TopToBottom) { double sliderWidth = 300 * GuiWidget.DeviceScale; double sliderThumbWidth = 10 * GuiWidget.DeviceScale; @@ -99,7 +99,7 @@ namespace MatterHackers.MatterControl.PrinterControls }; settingsRow.AddChild(feedRateRatioSlider); - feedRateValue = new MHNumberEdit(Math.Round(printer.Settings.GetValue(SettingsKey.feedrate_ratio), 2), theme, allowDecimals: true, minValue: minFeedRateRatio, maxValue: maxFeedRateRatio, pixelWidth: 40 * GuiWidget.DeviceScale) + feedRateValue = new ThemedNumberEdit(Math.Round(printer.Settings.GetValue(SettingsKey.feedrate_ratio), 2), theme, allowDecimals: true, minValue: minFeedRateRatio, maxValue: maxFeedRateRatio, pixelWidth: 40 * GuiWidget.DeviceScale) { Name = "Feed Rate NumberEdit", SelectAllOnFocus = true, @@ -157,7 +157,7 @@ namespace MatterHackers.MatterControl.PrinterControls }; settingsRow.AddChild(extrusionRatioSlider); - extrusionValue = new MHNumberEdit(Math.Round(printer.Settings.GetValue(SettingsKey.extrusion_ratio), 2), theme, allowDecimals: true, minValue: minExtrutionRatio, maxValue: maxExtrusionRatio, pixelWidth: 40 * GuiWidget.DeviceScale) + extrusionValue = new ThemedNumberEdit(Math.Round(printer.Settings.GetValue(SettingsKey.extrusion_ratio), 2), theme, allowDecimals: true, minValue: minExtrutionRatio, maxValue: maxExtrusionRatio, pixelWidth: 40 * GuiWidget.DeviceScale) { Name = "Extrusion Multiplier NumberEdit", SelectAllOnFocus = true, diff --git a/MatterControlLib/PrinterControls/ControlWidgets/FanControlsRow.cs b/MatterControlLib/PrinterControls/ControlWidgets/FanControlsRow.cs index 6381ad02b..5adb9544a 100644 --- a/MatterControlLib/PrinterControls/ControlWidgets/FanControlsRow.cs +++ b/MatterControlLib/PrinterControls/ControlWidgets/FanControlsRow.cs @@ -38,7 +38,7 @@ namespace MatterHackers.MatterControl.PrinterControls { public class FanControlsRow : SettingsRow { - private MHNumberEdit fanSpeedDisplay; + private ThemedNumberEdit fanSpeedDisplay; private RoundedToggleSwitch toggleSwitch; private PrinterConfig printer; @@ -57,7 +57,7 @@ namespace MatterHackers.MatterControl.PrinterControls this.AddChild(container); this.BorderColor = Color.Transparent; - fanSpeedDisplay = new MHNumberEdit(0, theme, minValue: 0, maxValue: 100, pixelWidth: 30 * GuiWidget.DeviceScale) + fanSpeedDisplay = new ThemedNumberEdit(0, theme, minValue: 0, maxValue: 100, pixelWidth: 30 * GuiWidget.DeviceScale) { Value = printer.Connection.GetFanSpeed0To255(fanIndex) * 100 / 255, VAnchor = VAnchor.Center | VAnchor.Fit, diff --git a/MatterControlLib/PrinterControls/EditLevelingSettingsPage.cs b/MatterControlLib/PrinterControls/EditLevelingSettingsPage.cs index b1e0e2493..eb1075985 100644 --- a/MatterControlLib/PrinterControls/EditLevelingSettingsPage.cs +++ b/MatterControlLib/PrinterControls/EditLevelingSettingsPage.cs @@ -117,7 +117,7 @@ namespace MatterHackers.MatterControl int linkCompatibleRow = row; int linkCompatibleAxis = axis; - var valueEdit = new MHNumberEdit(positions[linkCompatibleRow][linkCompatibleAxis], theme, allowNegatives: true, allowDecimals: true, pixelWidth: 60 * GuiWidget.DeviceScale, tabIndex: tab_index++) + var valueEdit = new ThemedNumberEdit(positions[linkCompatibleRow][linkCompatibleAxis], theme, allowNegatives: true, allowDecimals: true, pixelWidth: 60 * GuiWidget.DeviceScale, tabIndex: tab_index++) { Name = $"{axisName} Position {row}" }; diff --git a/MatterControlLib/PrinterControls/JogControls.cs b/MatterControlLib/PrinterControls/JogControls.cs index 5626f09e5..98213c64c 100644 --- a/MatterControlLib/PrinterControls/JogControls.cs +++ b/MatterControlLib/PrinterControls/JogControls.cs @@ -62,10 +62,10 @@ namespace MatterHackers.MatterControl private List eMinusButtons = new List(); private List ePlusButtons = new List(); - private RadioTextButton movePointZeroTwoMmButton; - private RadioTextButton moveOneMmButton; - private RadioTextButton oneHundredButton; - private RadioTextButton tenButton; + private ThemedRadioTextButton movePointZeroTwoMmButton; + private ThemedRadioTextButton moveOneMmButton; + private ThemedRadioTextButton oneHundredButton; + private ThemedRadioTextButton tenButton; private GuiWidget disableableEButtons; private GuiWidget keyboardFocusBorder; private GuiWidget keyboardImage; diff --git a/MatterControlLib/PrinterControls/MacroDetailPage.cs b/MatterControlLib/PrinterControls/MacroDetailPage.cs index ff610b909..c4b395e81 100644 --- a/MatterControlLib/PrinterControls/MacroDetailPage.cs +++ b/MatterControlLib/PrinterControls/MacroDetailPage.cs @@ -45,8 +45,8 @@ namespace MatterHackers.MatterControl public MacroDetailPage(GCodeMacro gcodeMacro, PrinterSettings printerSettings) { // Form validation fields - MHTextEditWidget macroNameInput; - MHTextEditWidget macroCommandInput; + ThemedTextEditWidget macroNameInput; + ThemedTextEditWidget macroCommandInput; WrappedTextWidget macroCommandError; WrappedTextWidget macroNameError; @@ -64,7 +64,7 @@ namespace MatterHackers.MatterControl Margin = new BorderDouble(0, 0, 0, 1) }); - contentRow.AddChild(macroNameInput = new MHTextEditWidget(GCodeMacro.FixMacroName(gcodeMacro.Name), theme) + contentRow.AddChild(macroNameInput = new ThemedTextEditWidget(GCodeMacro.FixMacroName(gcodeMacro.Name), theme) { HAnchor = HAnchor.Stretch }); @@ -82,7 +82,7 @@ namespace MatterHackers.MatterControl Margin = new BorderDouble(0, 0, 0, 1) }); - macroCommandInput = new MHTextEditWidget(gcodeMacro.GCode, theme, pixelHeight: 120, multiLine: true, typeFace: ApplicationController.GetTypeFace(NamedTypeFace.Liberation_Mono)) + macroCommandInput = new ThemedTextEditWidget(gcodeMacro.GCode, theme, pixelHeight: 120, multiLine: true, typeFace: ApplicationController.GetTypeFace(NamedTypeFace.Liberation_Mono)) { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Stretch diff --git a/MatterControlLib/PrinterControls/MovementSpeedsPage.cs b/MatterControlLib/PrinterControls/MovementSpeedsPage.cs index d512d3de4..eaa5266e8 100644 --- a/MatterControlLib/PrinterControls/MovementSpeedsPage.cs +++ b/MatterControlLib/PrinterControls/MovementSpeedsPage.cs @@ -105,7 +105,7 @@ namespace MatterHackers.MatterControl movementSpeed = movementSpeed / 60.0; // Convert from mm/min to mm/s } - var valueEdit = new MHNumberEdit(movementSpeed, theme, minValue: 0, pixelWidth: 60 * GuiWidget.DeviceScale, tabIndex: tab_index++, allowDecimals: true) + var valueEdit = new ThemedNumberEdit(movementSpeed, theme, minValue: 0, pixelWidth: 60 * GuiWidget.DeviceScale, tabIndex: tab_index++, allowDecimals: true) { Margin = 3 }; diff --git a/MatterControlLib/PrinterControls/PrinterConnections/SetupStepBaudRate.cs b/MatterControlLib/PrinterControls/PrinterConnections/SetupStepBaudRate.cs index e8b08b207..baf0eebe7 100644 --- a/MatterControlLib/PrinterControls/PrinterConnections/SetupStepBaudRate.cs +++ b/MatterControlLib/PrinterControls/PrinterConnections/SetupStepBaudRate.cs @@ -44,7 +44,7 @@ namespace MatterHackers.MatterControl.PrinterControls.PrinterConnections private TextWidget printerBaudRateError; private GuiWidget baudRateWidget; private RadioButton otherBaudRateRadioButton; - private MHTextEditWidget otherBaudRateInput; + private ThemedTextEditWidget otherBaudRateInput; private GuiWidget nextButton; private GuiWidget printerBaudRateHelpLink; private TextWidget printerBaudRateHelpMessage; @@ -159,7 +159,7 @@ namespace MatterHackers.MatterControl.PrinterControls.PrinterConnections //See if the baud rate of the current print is in the list of displayed rates, //flag the 'other' option if it is not and prefill the rate. - otherBaudRateInput = new MHTextEditWidget("", theme); + otherBaudRateInput = new ThemedTextEditWidget("", theme); otherBaudRateInput.Visible = false; otherBaudRateInput.HAnchor = HAnchor.Stretch; diff --git a/MatterControlLib/PrinterControls/PrinterConnections/SetupStepMakeModelName.cs b/MatterControlLib/PrinterControls/PrinterConnections/SetupStepMakeModelName.cs index 919ad280f..eb60ec21a 100644 --- a/MatterControlLib/PrinterControls/PrinterConnections/SetupStepMakeModelName.cs +++ b/MatterControlLib/PrinterControls/PrinterConnections/SetupStepMakeModelName.cs @@ -39,7 +39,7 @@ namespace MatterHackers.MatterControl.PrinterControls.PrinterConnections // Normally step one of the setup process public class SetupStepMakeModelName : DialogPage { - private readonly TextButton nextButton; + private readonly ThemedTextButton nextButton; private readonly AddPrinterWidget printerPanel; private readonly RadioButton createPrinterRadioButton = null; diff --git a/MatterControlLib/PrinterControls/TerminalWindow/TerminalWidget.cs b/MatterControlLib/PrinterControls/TerminalWindow/TerminalWidget.cs index 78e6238ac..90a981ebc 100644 --- a/MatterControlLib/PrinterControls/TerminalWindow/TerminalWidget.cs +++ b/MatterControlLib/PrinterControls/TerminalWindow/TerminalWidget.cs @@ -44,7 +44,7 @@ namespace MatterHackers.MatterControl public class TerminalWidget : FlowLayoutWidget, ICloseableTab { private CheckBox autoUppercase; - private MHTextEditWidget manualCommandTextEdit; + private ThemedTextEditWidget manualCommandTextEdit; private TextScrollWidget textScrollWidget; private PrinterConfig printer; @@ -181,7 +181,7 @@ namespace MatterHackers.MatterControl }; this.AddChild(inputRow); - manualCommandTextEdit = new MHTextEditWidget("", theme, typeFace: ApplicationController.GetTypeFace(NamedTypeFace.Liberation_Mono)) + manualCommandTextEdit = new ThemedTextEditWidget("", theme, typeFace: ApplicationController.GetTypeFace(NamedTypeFace.Liberation_Mono)) { Margin = new BorderDouble(right: 3), HAnchor = HAnchor.Stretch, diff --git a/MatterControlLib/SettingsManagement/ApplicationSettingsPage.cs b/MatterControlLib/SettingsManagement/ApplicationSettingsPage.cs index 55c815e40..ee76ef2a5 100644 --- a/MatterControlLib/SettingsManagement/ApplicationSettingsPage.cs +++ b/MatterControlLib/SettingsManagement/ApplicationSettingsPage.cs @@ -412,7 +412,7 @@ namespace MatterHackers.MatterControl { gitHubPat = ""; } - var accessToken = new MHTextEditWidget(gitHubPat, theme, pixelWidth: 350, messageWhenEmptyAndNotSelected: "Enter Person Access Token".Localize()) + var accessToken = new ThemedTextEditWidget(gitHubPat, theme, pixelWidth: 350, messageWhenEmptyAndNotSelected: "Enter Person Access Token".Localize()) { HAnchor = HAnchor.Absolute, Margin = new BorderDouble(5), diff --git a/MatterControlLib/SetupWizard/DialogWindow.cs b/MatterControlLib/SetupWizard/DialogWindow.cs index 5aca696a5..b98541900 100644 --- a/MatterControlLib/SetupWizard/DialogWindow.cs +++ b/MatterControlLib/SetupWizard/DialogWindow.cs @@ -71,7 +71,7 @@ namespace MatterHackers.MatterControl DialogWindow wizardWindow = GetWindow(typeof(PanelType)); var newPanel = wizardWindow.ChangeToPage(); wizardWindow.Title = newPanel.WindowTitle; - + SetSizeAndShow(wizardWindow, newPanel); } diff --git a/MatterControlLib/SetupWizard/HelpArticleTreeNode.cs b/MatterControlLib/SetupWizard/HelpArticleTreeNode.cs index fe19e9293..447b0fa48 100644 --- a/MatterControlLib/SetupWizard/HelpArticleTreeNode.cs +++ b/MatterControlLib/SetupWizard/HelpArticleTreeNode.cs @@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project. */ using MatterHackers.Agg.Platform; +using MatterHackers.Agg.UI; using MatterHackers.MatterControl.CustomWidgets; namespace MatterHackers.MatterControl diff --git a/MatterControlLib/SetupWizard/InputBoxPage.cs b/MatterControlLib/SetupWizard/InputBoxPage.cs index d7784957d..d7dc2033b 100644 --- a/MatterControlLib/SetupWizard/InputBoxPage.cs +++ b/MatterControlLib/SetupWizard/InputBoxPage.cs @@ -36,7 +36,7 @@ namespace MatterHackers.MatterControl { public class InputBoxPage : DialogPage { - public MHTextEditWidget TextEditWidget { get; private set; } + public ThemedTextEditWidget TextEditWidget { get; private set; } public override string Text { get => TextEditWidget.Text; set => TextEditWidget.Text = value; } @@ -56,7 +56,7 @@ namespace MatterHackers.MatterControl }); // Adds text box and check box to the above container - TextEditWidget = new MHTextEditWidget(initialValue, theme, pixelWidth: 300, messageWhenEmptyAndNotSelected: emptyText); + TextEditWidget = new ThemedTextEditWidget(initialValue, theme, pixelWidth: 300, messageWhenEmptyAndNotSelected: emptyText); TextEditWidget.Name = "InputBoxPage TextEditWidget"; TextEditWidget.HAnchor = HAnchor.Stretch; TextEditWidget.Margin = new BorderDouble(5); diff --git a/MatterControlLib/SlicerConfiguration/UIFields/BoundDoubleField.cs b/MatterControlLib/SlicerConfiguration/UIFields/BoundDoubleField.cs index 038db6404..5d670db88 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/BoundDoubleField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/BoundDoubleField.cs @@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project. */ using MatterHackers.Agg; +using MatterHackers.Agg.UI; namespace MatterHackers.MatterControl.SlicerConfiguration { diff --git a/MatterControlLib/SlicerConfiguration/UIFields/BoundsField.cs b/MatterControlLib/SlicerConfiguration/UIFields/BoundsField.cs index cc15d6b27..e2694e895 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/BoundsField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/BoundsField.cs @@ -27,6 +27,8 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +using MatterHackers.Agg.UI; + namespace MatterHackers.MatterControl.SlicerConfiguration { public class BoundsField : Vector4Field diff --git a/MatterControlLib/SlicerConfiguration/UIFields/CharField.cs b/MatterControlLib/SlicerConfiguration/UIFields/CharField.cs index bab545fe9..4728baa2a 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/CharField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/CharField.cs @@ -34,7 +34,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { public class CharField : UIField { - protected MHTextEditWidget textEditWidget; + protected ThemedTextEditWidget textEditWidget; private ThemeConfig theme; public CharField(ThemeConfig theme) @@ -44,7 +44,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public override void Initialize(int tabIndex) { - textEditWidget = new MHTextEditWidget("", theme, pixelWidth: ControlWidth, tabIndex: tabIndex) + textEditWidget = new ThemedTextEditWidget("", theme, pixelWidth: ControlWidth, tabIndex: tabIndex) { ToolTipText = this.HelpText, SelectAllOnFocus = true, diff --git a/MatterControlLib/SlicerConfiguration/UIFields/DoubleOrIncompatible.cs b/MatterControlLib/SlicerConfiguration/UIFields/DoubleOrIncompatible.cs index 99287926c..cabaaf013 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/DoubleOrIncompatible.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/DoubleOrIncompatible.cs @@ -27,6 +27,7 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +using MatterHackers.Agg.UI; using System; namespace MatterHackers.MatterControl.SlicerConfiguration diff --git a/MatterControlLib/SlicerConfiguration/UIFields/ExpressionField.cs b/MatterControlLib/SlicerConfiguration/UIFields/ExpressionField.cs index ddaad7d95..4080b329a 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/ExpressionField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/ExpressionField.cs @@ -33,7 +33,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { public class ExpressionField : UIField { - protected MHTextEditWidget textEditWidget; + protected ThemedTextEditWidget textEditWidget; private ThemeConfig theme; public ExpressionField(ThemeConfig theme) @@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration VAnchor = VAnchor.Fit }; - aligner.AddChild(textEditWidget = new MHTextEditWidget("", theme, pixelWidth: ControlWidth, tabIndex: tabIndex) + aligner.AddChild(textEditWidget = new ThemedTextEditWidget("", theme, pixelWidth: ControlWidth, tabIndex: tabIndex) { ToolTipText = this.HelpText, SelectAllOnFocus = true, diff --git a/MatterControlLib/SlicerConfiguration/UIFields/ExtruderOffsetField.cs b/MatterControlLib/SlicerConfiguration/UIFields/ExtruderOffsetField.cs index fd9d0d49a..d463b4608 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/ExtruderOffsetField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/ExtruderOffsetField.cs @@ -110,6 +110,11 @@ namespace MatterHackers.MatterControl.SlicerConfiguration base.Initialize(tabIndex); } + private static double StripZeroSign(double x) + { + return x == 0 ? 0 : x; + } + protected override string ConvertValue(string newValue) { var offsets = newValue?.Split(','); @@ -126,7 +131,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { // Import deprecated z_offset data if missing var zOffset = printer.Settings.GetValue(SettingsKey.z_offset); - corrected += xyz[0] + "x" + xyz[1] + "x" + (-zOffset).ToString(); + corrected += xyz[0] + "x" + xyz[1] + "x" + StripZeroSign(-zOffset).ToString(); } else { diff --git a/MatterControlLib/SlicerConfiguration/UIFields/IntField.cs b/MatterControlLib/SlicerConfiguration/UIFields/IntField.cs index 2e3ca5069..69de52623 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/IntField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/IntField.cs @@ -27,6 +27,7 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +using MatterHackers.Agg.UI; using System; namespace MatterHackers.MatterControl.SlicerConfiguration diff --git a/MatterControlLib/SlicerConfiguration/UIFields/MultilineStringField.cs b/MatterControlLib/SlicerConfiguration/UIFields/MultilineStringField.cs index ba41930d0..a904e7cb5 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/MultilineStringField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/MultilineStringField.cs @@ -34,7 +34,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { public class MultilineStringField : UIField { - private MHTextEditWidget editWidget; + private ThemedTextEditWidget editWidget; private ThemeConfig theme; public MultilineStringField(ThemeConfig theme) @@ -44,7 +44,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public override void Initialize(int tabIndex) { - editWidget = new MHTextEditWidget("", theme, pixelWidth: 320, multiLine: true, tabIndex: tabIndex, typeFace: ApplicationController.GetTypeFace(NamedTypeFace.Liberation_Mono)) + editWidget = new ThemedTextEditWidget("", theme, pixelWidth: 320, multiLine: true, tabIndex: tabIndex, typeFace: ApplicationController.GetTypeFace(NamedTypeFace.Liberation_Mono)) { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, diff --git a/MatterControlLib/SlicerConfiguration/UIFields/NumberField.cs b/MatterControlLib/SlicerConfiguration/UIFields/NumberField.cs index a592e2640..58edc1e57 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/NumberField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/NumberField.cs @@ -33,7 +33,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { public abstract class NumberField : UIField { - protected MHNumberEdit numberEdit; + protected ThemedNumberEdit numberEdit; private readonly ThemeConfig theme; protected bool AllowNegatives { get; set; } = true; @@ -47,7 +47,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public override void Initialize(int tabIndex) { - numberEdit = new MHNumberEdit(0, theme, pixelWidth: ControlWidth, allowDecimals: this.AllowDecimals, allowNegatives: this.AllowNegatives, tabIndex: tabIndex) + numberEdit = new ThemedNumberEdit(0, theme, pixelWidth: ControlWidth, allowDecimals: this.AllowDecimals, allowNegatives: this.AllowNegatives, tabIndex: tabIndex) { ToolTipText = this.HelpText, SelectAllOnFocus = true, diff --git a/MatterControlLib/SlicerConfiguration/UIFields/PositiveDoubleField.cs b/MatterControlLib/SlicerConfiguration/UIFields/PositiveDoubleField.cs index 5856a46ed..b1e284343 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/PositiveDoubleField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/PositiveDoubleField.cs @@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project. */ +using MatterHackers.Agg.UI; using System; namespace MatterHackers.MatterControl.SlicerConfiguration diff --git a/MatterControlLib/SlicerConfiguration/UIFields/SurfacedEditorPage.cs b/MatterControlLib/SlicerConfiguration/UIFields/SurfacedEditorPage.cs index 6565f54cd..41f1480e2 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/SurfacedEditorPage.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/SurfacedEditorPage.cs @@ -44,7 +44,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { public event EventHandler ValueChanged; - private MHTextEditWidget editWidget; + private ThemedTextEditWidget editWidget; public SurfacedEditorPage(IObject3D selectedItem) { @@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration BackgroundColor = theme.BackgroundColor }; - editWidget = new MHTextEditWidget("", theme) + editWidget = new ThemedTextEditWidget("", theme) { HAnchor = HAnchor.Stretch, Name = this.Name, diff --git a/MatterControlLib/SlicerConfiguration/UIFields/TextField.cs b/MatterControlLib/SlicerConfiguration/UIFields/TextField.cs index 09be78c81..89ae50b29 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/TextField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/TextField.cs @@ -33,7 +33,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { public class TextField : UIField { - protected MHTextEditWidget textEditWidget; + protected ThemedTextEditWidget textEditWidget; private ThemeConfig theme; public TextField(ThemeConfig theme) @@ -55,7 +55,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public override void Initialize(int tabIndex) { - textEditWidget = new MHTextEditWidget("", theme, pixelWidth: ControlWidth, tabIndex: tabIndex) + textEditWidget = new ThemedTextEditWidget("", theme, pixelWidth: ControlWidth, tabIndex: tabIndex) { ToolTipText = this.HelpText, SelectAllOnFocus = true, diff --git a/MatterControlLib/SlicerConfiguration/UIFields/UIField.cs b/MatterControlLib/SlicerConfiguration/UIFields/UIField.cs index 647161e63..292caa0d6 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/UIField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/UIField.cs @@ -82,12 +82,12 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public void ClearUndoHistory() { - foreach (var widget in this.Content.DescendantsAndSelf()) + foreach (var widget in this.Content.DescendantsAndSelf()) { widget.ActualTextEditWidget.InternalTextEditWidget.ClearUndoHistory(); } - foreach (var widget in this.Content.DescendantsAndSelf()) + foreach (var widget in this.Content.DescendantsAndSelf()) { widget.ActuallNumberEdit.InternalTextEditWidget.ClearUndoHistory(); } diff --git a/MatterControlLib/SlicerConfiguration/UIFields/ValueOrUnitsField.cs b/MatterControlLib/SlicerConfiguration/UIFields/ValueOrUnitsField.cs index c399157cb..2cfe57ac2 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/ValueOrUnitsField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/ValueOrUnitsField.cs @@ -28,6 +28,8 @@ either expressed or implied, of the FreeBSD Project. */ +using MatterHackers.Agg.UI; + namespace MatterHackers.MatterControl.SlicerConfiguration { public abstract class ValueOrUnitsField : TextField diff --git a/MatterControlLib/SlicerConfiguration/UIFields/Vector2Field.cs b/MatterControlLib/SlicerConfiguration/UIFields/Vector2Field.cs index 658cc15da..9854e8b21 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/Vector2Field.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/Vector2Field.cs @@ -38,9 +38,9 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { public static readonly int VectorXYEditWidth = (int)(60 * GuiWidget.DeviceScale + .5); - private MHNumberEdit yEditWidget; + private ThemedNumberEdit yEditWidget; - private MHNumberEdit xEditWidget; + private ThemedNumberEdit xEditWidget; private ThemeConfig theme; public Vector2Field(ThemeConfig theme) @@ -71,7 +71,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration double.TryParse(xyValueStrings[0], out double currentXValue); - xEditWidget = new MHNumberEdit(currentXValue, theme, singleCharLabel: 'X', allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYEditWidth, tabIndex: tabIndex) + xEditWidget = new ThemedNumberEdit(currentXValue, theme, singleCharLabel: 'X', allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYEditWidth, tabIndex: tabIndex) { ToolTipText = this.HelpText, TabIndex = tabIndex, @@ -89,7 +89,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration double.TryParse(xyValueStrings[1], out double currentYValue); - yEditWidget = new MHNumberEdit(currentYValue, theme, 'Y', allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYEditWidth, tabIndex: tabIndex) + yEditWidget = new ThemedNumberEdit(currentYValue, theme, 'Y', allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYEditWidth, tabIndex: tabIndex) { ToolTipText = this.HelpText, TabIndex = tabIndex + 1, diff --git a/MatterControlLib/SlicerConfiguration/UIFields/Vector3Field.cs b/MatterControlLib/SlicerConfiguration/UIFields/Vector3Field.cs index 0697093ed..78ed3f0fe 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/Vector3Field.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/Vector3Field.cs @@ -37,9 +37,9 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { public static readonly int VectorXYZEditWidth = (int)(60 * GuiWidget.DeviceScale + .5); - private MHNumberEdit xEditWidget; - private MHNumberEdit yEditWidget; - private MHNumberEdit zEditWidget; + private ThemedNumberEdit xEditWidget; + private ThemedNumberEdit yEditWidget; + private ThemedNumberEdit zEditWidget; private ThemeConfig theme; public Vector3Field(ThemeConfig theme) @@ -71,7 +71,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration double.TryParse(xyzStrings[0], out double currentXValue); - xEditWidget = new MHNumberEdit(currentXValue, theme, 'X', allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZEditWidth, tabIndex: tabIndex++) + xEditWidget = new ThemedNumberEdit(currentXValue, theme, 'X', allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZEditWidth, tabIndex: tabIndex++) { ToolTipText = this.HelpText, TabIndex = tabIndex, @@ -93,7 +93,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration double.TryParse(xyzStrings[1], out double currentYValue); - yEditWidget = new MHNumberEdit(currentYValue, theme, 'Y', allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZEditWidth, tabIndex: tabIndex++) + yEditWidget = new ThemedNumberEdit(currentYValue, theme, 'Y', allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZEditWidth, tabIndex: tabIndex++) { ToolTipText = this.HelpText, TabIndex = tabIndex + 1, @@ -115,7 +115,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration double.TryParse(xyzStrings[2], out double currentZValue); - zEditWidget = new MHNumberEdit(currentZValue, theme, 'Z', allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZEditWidth, tabIndex: tabIndex++) + zEditWidget = new ThemedNumberEdit(currentZValue, theme, 'Z', allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZEditWidth, tabIndex: tabIndex++) { ToolTipText = this.HelpText, TabIndex = tabIndex + 1, diff --git a/MatterControlLib/SlicerConfiguration/UIFields/Vector4Field.cs b/MatterControlLib/SlicerConfiguration/UIFields/Vector4Field.cs index 46367a39a..8e144d5d9 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/Vector4Field.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/Vector4Field.cs @@ -37,10 +37,10 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { public static int VectorXYZWEditWidth = (int)(45 * GuiWidget.DeviceScale + .5); - private MHNumberEdit xEditWidget; - private MHNumberEdit yEditWidget; - private MHNumberEdit zEditWidget; - private MHNumberEdit wEditWidget; + private ThemedNumberEdit xEditWidget; + private ThemedNumberEdit yEditWidget; + private ThemedNumberEdit zEditWidget; + private ThemedNumberEdit wEditWidget; private ThemeConfig theme; @@ -76,7 +76,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration double.TryParse(xyzValueStrings[0], out double currentXValue); - xEditWidget = new MHNumberEdit(currentXValue, theme, Labels[0] /* X */, allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZWEditWidth, tabIndex: tabIndex) + xEditWidget = new ThemedNumberEdit(currentXValue, theme, Labels[0] /* X */, allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZWEditWidth, tabIndex: tabIndex) { ToolTipText = this.HelpText, TabIndex = tabIndex, @@ -98,7 +98,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration double.TryParse(xyzValueStrings[1], out double currentYValue); - yEditWidget = new MHNumberEdit(currentYValue, theme, Labels[1] /* Y */, allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZWEditWidth, tabIndex: tabIndex) + yEditWidget = new ThemedNumberEdit(currentYValue, theme, Labels[1] /* Y */, allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZWEditWidth, tabIndex: tabIndex) { ToolTipText = this.HelpText, TabIndex = tabIndex + 1, @@ -120,7 +120,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration double.TryParse(xyzValueStrings[2], out double currentZValue); - zEditWidget = new MHNumberEdit(currentZValue, theme, Labels[2] /* Z */, allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZWEditWidth, tabIndex: tabIndex) + zEditWidget = new ThemedNumberEdit(currentZValue, theme, Labels[2] /* Z */, allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZWEditWidth, tabIndex: tabIndex) { ToolTipText = this.HelpText, TabIndex = tabIndex + 1, @@ -142,7 +142,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration double.TryParse(xyzValueStrings[3], out double currentWValue); - wEditWidget = new MHNumberEdit(currentZValue, theme, Labels[3] /* W */, allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZWEditWidth, tabIndex: tabIndex) + wEditWidget = new ThemedNumberEdit(currentZValue, theme, Labels[3] /* W */, allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYZWEditWidth, tabIndex: tabIndex) { ToolTipText = this.HelpText, TabIndex = tabIndex + 1, diff --git a/MatterControlLib/Utilities/FieldValidation.cs b/MatterControlLib/Utilities/FieldValidation.cs index 84a7d105b..0a8df97ed 100644 --- a/MatterControlLib/Utilities/FieldValidation.cs +++ b/MatterControlLib/Utilities/FieldValidation.cs @@ -122,13 +122,13 @@ namespace MatterHackers.MatterControl.FieldValidation { public delegate ValidationStatus ValidationHandler(string valueToValidate); - public MHTextEditWidget FieldEditWidget { get; set; } + public ThemedTextEditWidget FieldEditWidget { get; set; } public WrappedTextWidget FieldErrorMessageWidget { get; set; } private ValidationHandler[] FieldValidationHandlers { get; set; } - public FormField(MHTextEditWidget textEditWidget, WrappedTextWidget errorMessageWidget, ValidationHandler[] validationHandlers) + public FormField(ThemedTextEditWidget textEditWidget, WrappedTextWidget errorMessageWidget, ValidationHandler[] validationHandlers) { this.FieldEditWidget = textEditWidget; this.FieldErrorMessageWidget = errorMessageWidget; diff --git a/MatterControlLib/Utilities/ManifestFileHandler.cs b/MatterControlLib/Utilities/ManifestFileHandler.cs index b91f62479..6c5406c84 100644 --- a/MatterControlLib/Utilities/ManifestFileHandler.cs +++ b/MatterControlLib/Utilities/ManifestFileHandler.cs @@ -57,7 +57,14 @@ namespace MatterHackers.MatterControl get { var queueDirectory = LegacyQueueFiles.QueueDirectory; - return Directory.EnumerateFiles(queueDirectory).Count(); + try + { + return Directory.EnumerateFiles(queueDirectory).Count(); + } + catch (DirectoryNotFoundException) + { + return 0; + } } } diff --git a/MatterControlLib/Utilities/MarkdigAgg/AggMatchingTextRenderer.cs b/MatterControlLib/Utilities/MarkdigAgg/AggMatchingTextRenderer.cs index 1615c443f..50bfb9671 100644 --- a/MatterControlLib/Utilities/MarkdigAgg/AggMatchingTextRenderer.cs +++ b/MatterControlLib/Utilities/MarkdigAgg/AggMatchingTextRenderer.cs @@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project. */ using Markdig.Renderers.Agg.Inlines; +using MatterHackers.Agg.UI; using MatterHackers.MatterControl; namespace Markdig.Renderers.Agg diff --git a/Plugins/MatterControl.PartSheet/MatterControl.PartSheet.csproj b/Plugins/MatterControl.PartSheet/MatterControl.PartSheet.csproj index 9309b7713..67a4575c3 100644 --- a/Plugins/MatterControl.PartSheet/MatterControl.PartSheet.csproj +++ b/Plugins/MatterControl.PartSheet/MatterControl.PartSheet.csproj @@ -1,35 +1,28 @@  - - netstandard2.0 - MatterHackers Inc. - true - false - + + net6.0-windows + MatterHackers Inc. + true + $(SolutionDir)bin + - - ..\..\bin\Debug\ - + + + + - - ..\..\bin\Release\ - - - - - - - - - {2af30557-fc50-4de3-ad1c-7eb57131a9c5} - MatterControl.Common - - - - - - - - + + + {2af30557-fc50-4de3-ad1c-7eb57131a9c5} + MatterControl.Common + + + + + + + + diff --git a/Plugins/MatterControl.PartSheet/PartSheetPlugin.cs b/Plugins/MatterControl.PartSheet/PartSheetPlugin.cs index 7f8eff83d..9ce6a4491 100644 --- a/Plugins/MatterControl.PartSheet/PartSheetPlugin.cs +++ b/Plugins/MatterControl.PartSheet/PartSheetPlugin.cs @@ -23,6 +23,10 @@ namespace MatterHackers.MatterControl.Plugins return; } + // Needed for PDFSharp on .NET core. + // https://stackoverflow.com/questions/50858209/system-notsupportedexception-no-data-is-available-for-encoding-1252 + System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); + ApplicationController.Instance.Library.MenuExtensions.Add( new LibraryAction(ActionScope.ListItem) { diff --git a/Plugins/MatterControl.PartSheet/PartsSheetCreator.cs b/Plugins/MatterControl.PartSheet/PartsSheetCreator.cs index a61995915..669ca1151 100644 --- a/Plugins/MatterControl.PartSheet/PartsSheetCreator.cs +++ b/Plugins/MatterControl.PartSheet/PartsSheetCreator.cs @@ -213,7 +213,7 @@ namespace MatterHackers.MatterControl.Plugins // Now try and open the document. This will launch whatever PDF viewer is on the system and ask it // to show the file (at least on Windows). - Process.Start(pathAndFileToSaveTo); + ApplicationController.ProcessStart(pathAndFileToSaveTo); } catch (Exception) { diff --git a/PrinterDriverInstaller/InfInstaller.csproj b/PrinterDriverInstaller/InfInstaller.csproj index c2b5b281e..ea786e9f7 100644 --- a/PrinterDriverInstaller/InfInstaller.csproj +++ b/PrinterDriverInstaller/InfInstaller.csproj @@ -1,58 +1,15 @@ - - + - Debug - AnyCPU - 8.0.30703 - 2.0 - {990A9AD3-B6A4-407B-9DFC-9C722AF7C9B9} + net6.0 Exe - bin\Release\ - Properties MatterHackers.InfInstaller - InfInstaller - - - - - 2.0 - v4.8 - - - - True - full - False - bin\Debug\ - DEBUG;TRACE - prompt - 4 + false True - x86 - true - - - pdbonly - True - TRACE - prompt - 4 - True - x86 - false - - - - - + + + all + - - - - - - - \ No newline at end of file diff --git a/PrinterDriverInstaller/app.config b/PrinterDriverInstaller/app.config deleted file mode 100644 index c0c3aed4e..000000000 --- a/PrinterDriverInstaller/app.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/Program.cs b/Program.cs index 79f7ae881..2993eac33 100644 --- a/Program.cs +++ b/Program.cs @@ -31,9 +31,8 @@ using System; using System.Globalization; using System.IO; using System.Linq; +using System.Reflection; using System.Runtime.InteropServices; -using System.ServiceModel; -using System.ServiceModel.Description; using System.Threading; using MatterHackers.Agg; using MatterHackers.Agg.Platform; @@ -64,17 +63,13 @@ namespace MatterHackers.MatterControl [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); - private static EventWaitHandle waitHandle; - private const int RaygunMaxNotifications = 15; private static int raygunNotificationCount = 0; private static RaygunClient _raygunClient; - private static string mainServiceName = "shell"; - - private const string ServiceBaseUri = "net.pipe://localhost/mattercontrol"; + [DllImport("Shcore.dll")] static extern int SetProcessDpiAwareness(int PROCESS_DPI_AWARENESS); @@ -141,6 +136,24 @@ namespace MatterHackers.MatterControl } #endif + // If StaticData is missing, use the StaticData at the relative project root if it exists. + if (!StaticData.Instance.DirectoryExists(".")) + { + var mainOutputDirectoryAttribute = MainOutputDirectoryAttribute.GetFromProgramAssembly(); + var executableDirectory = AppDomain.CurrentDomain.BaseDirectory; + var buildOutputDirectory = Path.Combine(mainOutputDirectoryAttribute.ProjectRoot, mainOutputDirectoryAttribute.MainOutputDirectory); + + // In case the whole project moved, determine the relative path. + var buildAbsStaticDataPath = Path.Combine(mainOutputDirectoryAttribute.ProjectRoot, "StaticData"); + var relStaticDataPath = Path.GetRelativePath(buildOutputDirectory, buildAbsStaticDataPath); + var workingAbsStaticDataPath = Path.GetFullPath(Path.Combine(executableDirectory, relStaticDataPath)); + + if (Directory.Exists(workingAbsStaticDataPath)) + { + StaticData.OverrideRootPath(workingAbsStaticDataPath); + } + } + // Set the global culture for the app, current thread and all new threads CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture; @@ -167,42 +180,22 @@ namespace MatterHackers.MatterControl ApplicationVersion = VersionInfo.Instance.ReleaseVersion }; + // If MatterControl isn't running and valid files were shelled, schedule a StartupAction to open the files after load + var shellFiles = args.Where(f => File.Exists(f) && ApplicationController.ShellFileExtensions.Contains(Path.GetExtension(f).ToLower())).ToArray(); + + // Single instance handling. #if !DEBUG - if (AggContext.OperatingSystem == OSType.Windows) + if (!LocalService.TryStartServer()) { - waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset, "MatterControl#Startup", out bool created); - - if (!created) + if (shellFiles.Any()) { - // If an instance is already running, create a service proxy and execute ShellOpenFile - var proxy = new ServiceProxy(); - - // and at least one argument is an acceptable shell file extension - var itemsToAdd = args.Where(f => File.Exists(f) && ApplicationController.ShellFileExtensions.Contains(Path.GetExtension(f).ToLower())); - if (itemsToAdd.Any()) - { - // notify the running instance of the event - proxy.ShellOpenFile(itemsToAdd.ToArray()); - } - - System.Threading.Thread.Sleep(1000); - - // Finally, close the process spawned by Explorer.exe - return; + LocalService.TrySendToServer(shellFiles); } - var serviceHost = new ServiceHost(typeof(LocalService), new[] { new Uri(ServiceBaseUri) }); - serviceHost.AddServiceEndpoint(typeof(IMainService), new NetNamedPipeBinding(), mainServiceName); - serviceHost.Open(); - - Console.Write( - "Service started: {0};", - string.Join(", ", serviceHost.Description.Endpoints.Select(s => s.ListenUri.AbsoluteUri).ToArray())); + return; } #endif - // If MatterControl isn't running and valid files were shelled, schedule a StartupAction to open the files after load - var shellFiles = args.Where(f => File.Exists(f) && ApplicationController.ShellFileExtensions.Contains(Path.GetExtension(f).ToLower())); if (shellFiles.Any()) { ApplicationController.StartupActions.Add(new ApplicationController.StartupAction() @@ -318,8 +311,6 @@ namespace MatterHackers.MatterControl rootSystemWindow.ShowAsSystemWindow(); } - private static readonly object locker = new object(); - static void KeepAwake(bool keepAwake) { if (keepAwake) @@ -332,51 +323,24 @@ namespace MatterHackers.MatterControl SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS); } } - - public class LocalService : IMainService - { - public void ShellOpenFile(string[] files) - { - // If at least one argument is an acceptable shell file extension - var itemsToAdd = files.Where(f => File.Exists(f) - && ApplicationController.ShellFileExtensions.Contains(Path.GetExtension(f).ToLower())); - - if (itemsToAdd.Any()) - { - lock (locker) - { - // Add each file - foreach (string file in itemsToAdd) - { - ApplicationController.Instance.ShellOpenFile(file); - } - } - } - } - } - - public class ServiceProxy : ClientBase - { - public ServiceProxy() - : base( - new ServiceEndpoint( - ContractDescription.GetContract(typeof(IMainService)), - new NetNamedPipeBinding(), - new EndpointAddress($"{ServiceBaseUri}/{mainServiceName}"))) - { - } - - public void ShellOpenFile(string[] files) - { - Channel.ShellOpenFile(files); - } - } } - [ServiceContract] - public interface IMainService + + [AttributeUsage(AttributeTargets.Assembly)] + public class MainOutputDirectoryAttribute : Attribute { - [OperationContract] - void ShellOpenFile(string[] files); + public readonly string MainOutputDirectory; // Relative to ProjectRoot. + public readonly string ProjectRoot; // Absolute + + public MainOutputDirectoryAttribute(string path, string projectRoot) + { + MainOutputDirectory = path; + ProjectRoot = projectRoot; + } + + public static MainOutputDirectoryAttribute GetFromProgramAssembly() + { + return typeof(MatterControl.Program).Assembly.GetCustomAttribute(); + } } } diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 782dc17ba..6c739dac4 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -34,3 +34,6 @@ using System.Runtime.InteropServices; // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] + +// https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1416 +[assembly: System.Runtime.Versioning.SupportedOSPlatform("windows7.0")] \ No newline at end of file diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json new file mode 100644 index 000000000..43782c141 --- /dev/null +++ b/Properties/launchSettings.json @@ -0,0 +1,9 @@ +{ + "profiles": { + "MatterControl": { + "commandName": "Project", + "hotReloadEnabled": false, + "nativeDebugging": false + } + } +} \ No newline at end of file diff --git a/StaticData/Materials/3DXTech/CarbonX ABS+CF.material b/StaticData/Materials/3DXTech/CarbonX ABS+CF.material new file mode 100644 index 000000000..2947574fe --- /dev/null +++ b/StaticData/Materials/3DXTech/CarbonX ABS+CF.material @@ -0,0 +1,32 @@ +{ + "DocumentVersion": 201606171, + "ID": null, + "Macros": [], + "MaterialLayers": [ + { + "bed_temperature": "115", + "bed_temperature_blue_tape": "NC", + "bed_temperature_buildtak": "110", + "bed_temperature_garolite": "110", + "bed_temperature_glass": "110", + "bed_temperature_kapton": "110", + "bed_temperature_pei": "110", + "bed_temperature_pp": "NC", + "enable_fan": "0", + "filament_density": "1.08", + "infill_speed": "30", + "layer_id": "d9240109-d720-462a-9d72-4c4f53478710", + "layer_name": "3DXTech CarbonX ABS+CF", + "material_sku": "MP0ZXEV5", + "max_fan_speed": "0", + "min_fan_speed": "0", + "perimeter_speed": "26", + "temperature": "230", + "top_solid_infill_speed": "22" + } + ], + "OemLayer": null, + "QualityLayers": [], + "StagedUserSettings": {}, + "UserLayer": {} +} \ No newline at end of file diff --git a/StaticData/Translations/Master.txt b/StaticData/Translations/Master.txt index 0d8845bdd..91a2d91e2 100644 --- a/StaticData/Translations/Master.txt +++ b/StaticData/Translations/Master.txt @@ -1,39 +1,36 @@ English: Translated: -English: • Remove the paper -Translated: • Remove the paper - -English: is reporting a Hardware Error -Translated: is reporting a Hardware Error - -English:- none - -Translated:- none - - -English: Once it is finished homing we will heat the bed. -Translated: Once it is finished homing we will heat the bed. - English:\nBelow you can find a list of each setting that has changed. Translated:\nBelow you can find a list of each setting that has changed. English:\nUpdating a default setting will not change any override that you have applied. Translated:\nUpdating a default setting will not change any override that you have applied. +English: • Remove the paper +Translated: • Remove the paper + +English: is reporting a Hardware Error +Translated: is reporting a Hardware Error + +English: Once it is finished homing we will heat the bed. +Translated: Once it is finished homing we will heat the bed. + +English:- none - +Translated:- none - + +English:'Ok' Responses +Translated:'Ok' Responses + +English:'Wait' Responses +Translated:'Wait' Responses + English:"{0}" already exists.\nDo you want to replace it? Translated:"{0}" already exists.\nDo you want to replace it? -English:$/kg -Translated:$/kg - -English:% -Translated:% - English:(Press 'Skip' to setup connection later) Translated:(Press 'Skip' to setup connection later) -English:\"{0}\" already exists.\nDo you want to replace it? -Translated:\"{0}\" already exists.\nDo you want to replace it? - English:{0} (Update Available) Translated:{0} (Update Available) @@ -61,8 +58,11 @@ Translated:{0} should be greater than 2. English:{0} should be greater than or equal to 1/2 the {1}. Translated:{0} should be greater than or equal to 1/2 the {1}. -English:<< Back -Translated:<< Back +English:\"{0}\" already exists.\nDo you want to replace it? +Translated:\"{0}\" already exists.\nDo you want to replace it? + +English:% +Translated:% English:° Translated:° @@ -70,6 +70,12 @@ Translated:° English:°C Translated:°C +English:<< Back +Translated:<< Back + +English:$/kg +Translated:$/kg + English:1. Power on your 3D Printer. Translated:1. Power on your 3D Printer. @@ -592,6 +598,9 @@ Translated:Before Z-Calibration can begin you need to: English:Behavior Translated:Behavior +English:Below you can find a list of each setting that has changed. +Translated:Below you can find a list of each setting that has changed. + English:Bend Direction Translated:Bend Direction @@ -700,6 +709,15 @@ Translated:Calibration Print English:Calibration Tab Translated:Calibration Tab +English:Can't access +Translated:Can't access + +English:Can't log out while printing +Translated:Can't log out while printing + +English:Can't sign in while printing +Translated:Can't sign in while printing + English:Cancel Translated:Cancel @@ -718,15 +736,6 @@ Translated:Cancel Print? English:Cancel the current print? Translated:Cancel the current print? -English:Can't access -Translated:Can't access - -English:Can't log out while printing -Translated:Can't log out while printing - -English:Can't sign in while printing -Translated:Can't sign in while printing - English:Categories Translated:Categories @@ -1357,12 +1366,12 @@ Translated:Distance or Loops English:Documents Translated:Documents -English:Done -Translated:Done - English:Don't remind me again Translated:Don't remind me again +English:Done +Translated:Done + English:Down Arrow Translated:Down Arrow @@ -1975,15 +1984,6 @@ Translated:G Code To Send English:G Key Translated:G Key -English:g/cm³ -Translated:g/cm³ - -English:Garolite -Translated:Garolite - -English:Garolite Bed Temperature -Translated:Garolite Bed Temperature - English:G-Code Translated:G-Code @@ -2032,6 +2032,15 @@ Translated:G-Code to run when the printer is paused. English:G-Code used by Autopilot to clear the bed after a print completes. This is only useful on a printer designed to clear the bed. Translated:G-Code used by Autopilot to clear the bed after a print completes. This is only useful on a printer designed to clear the bed. +English:g/cm³ +Translated:g/cm³ + +English:Garolite +Translated:Garolite + +English:Garolite Bed Temperature +Translated:Garolite Bed Temperature + English:Gear Translated:Gear @@ -2650,12 +2659,12 @@ Translated:Loading English:Loading Filament Translated:Loading Filament -English:Loading GCode -Translated:Loading GCode - English:Loading G-Code Translated:Loading G-Code +English:Loading GCode +Translated:Loading GCode + English:Loading Help Translated:Loading Help @@ -3136,12 +3145,12 @@ Translated:No results found English:No setting currently need to be updated. Translated:No setting currently need to be updated. -English:None -Translated:None - English:Non-Manifold Translated:Non-Manifold +English:None +Translated:None + English:Normal Translated:Normal @@ -3238,9 +3247,6 @@ Translated:Ok English:OK Translated:OK -English:'Ok' Responses -Translated:'Ok' Responses - English:On Connect G-Code Translated:On Connect G-Code @@ -3928,6 +3934,12 @@ Translated:Ratio English:Ratio or % Translated:Ratio or % +English:Re-enter New Password +Translated:Re-enter New Password + +English:Re-enter Password +Translated:Re-enter Password + English:Read Filter Translated:Read Filter @@ -3979,12 +3991,6 @@ Translated:Reduce English:Reduced Width Translated:Reduced Width -English:Re-enter New Password -Translated:Re-enter New Password - -English:Re-enter Password -Translated:Re-enter Password - English:Refresh Translated:Refresh @@ -4927,6 +4933,12 @@ Translated:Subtract English:Subtract & Replace Translated:Subtract & Replace +English:Success!\n\nYour filament should now be loaded +Translated:Success!\n\nYour filament should now be loaded + +English:Success!\n\nYour filament should now be unloaded +Translated:Success!\n\nYour filament should now be unloaded + English:Success! Please check your email for the reset code. Translated:Success! Please check your email for the reset code. @@ -4936,12 +4948,6 @@ Translated:Success! Your account has been created. English:Success! Your password has been updated. Translated:Success! Your password has been updated. -English:Success!\n\nYour filament should now be loaded -Translated:Success!\n\nYour filament should now be loaded - -English:Success!\n\nYour filament should now be unloaded -Translated:Success!\n\nYour filament should now be unloaded - English:Support Translated:Support @@ -5032,6 +5038,12 @@ Translated:Text Size English:Text2 Translated:Text2 +English:The 'Material' you have selected is incompatible with the 'Bed Surface' you have selected. You may get poor bed adhesion or printing results. Changing the 'Bed Surface' is recommended. You can change it in the 'Bed Temperature' menu on the top right of your screen. +Translated:The 'Material' you have selected is incompatible with the 'Bed Surface' you have selected. You may get poor bed adhesion or printing results. Changing the 'Bed Surface' is recommended. You can change it in the 'Bed Temperature' menu on the top right of your screen. + +English:The 'Serial Port' section lists all available serial\nports on your device. Changing which USB port the printer\nis connected to may change the associated serial port.\n\nTip: If you are uncertain, unplug/plug in your printer\nand hit refresh. The new port that appears should be\nyour printer. +Translated:The 'Serial Port' section lists all available serial\nports on your device. Changing which USB port the printer\nis connected to may change the associated serial port.\n\nTip: If you are uncertain, unplug/plug in your printer\nand hit refresh. The new port that appears should be\nyour printer. + English:The {0} can only go as high as 100%. Translated:The {0} can only go as high as 100%. @@ -5248,9 +5260,6 @@ Translated:The Markdown that will be shown on the Trim Filament page. English:The Material you have selected is incompatible with the Bed Surface you have selected. You may get poor bed adhesion or printing results. Changing the bed is recommended. Translated:The Material you have selected is incompatible with the Bed Surface you have selected. You may get poor bed adhesion or printing results. Changing the bed is recommended. -English:The 'Material' you have selected is incompatible with the 'Bed Surface' you have selected. You may get poor bed adhesion or printing results. Changing the 'Bed Surface' is recommended. You can change it in the 'Bed Temperature' menu on the top right of your screen. -Translated:The 'Material' you have selected is incompatible with the 'Bed Surface' you have selected. You may get poor bed adhesion or printing results. Changing the 'Bed Surface' is recommended. You can change it in the 'Bed Temperature' menu on the top right of your screen. - English:The maximum amount that an avoid crossing travel can exceed the direct distance. If the avoid travel is too long, a direct move will be executed. Translated:The maximum amount that an avoid crossing travel can exceed the direct distance. If the avoid travel is too long, a direct move will be executed. @@ -5449,9 +5458,6 @@ Translated:The serial driver to use English:The serial port communication speed of the printers firmware. Translated:The serial port communication speed of the printers firmware. -English:The 'Serial Port' section lists all available serial\nports on your device. Changing which USB port the printer\nis connected to may change the associated serial port.\n\nTip: If you are uncertain, unplug/plug in your printer\nand hit refresh. The new port that appears should be\nyour printer. -Translated:The 'Serial Port' section lists all available serial\nports on your device. Changing which USB port the printer\nis connected to may change the associated serial port.\n\nTip: If you are uncertain, unplug/plug in your printer\nand hit refresh. The new port that appears should be\nyour printer. - English:The serial port to use while connecting to this printer. Translated:The serial port to use while connecting to this printer. @@ -6001,6 +6007,9 @@ Translated:Update Settings English:Update Settings... Translated:Update Settings... +English:Updating a default setting will not change any override that you have applied. +Translated:Updating a default setting will not change any override that you have applied. + English:Updating firmware... Translated:Updating firmware... @@ -6154,9 +6163,6 @@ Translated:Visit MatterHackers.com to Purchase English:Wait For Running Clean Translated:Wait For Running Clean -English:'Wait' Responses -Translated:'Wait' Responses - English:Waiting For Bed To Heat Translated:Waiting For Bed To Heat @@ -6205,9 +6211,6 @@ Translated:Warning - GCode file English:Warning - No EEProm Mapping Translated:Warning - No EEProm Mapping -English:Warning! The tip of the nozzle will be HOT! -Translated:Warning! The tip of the nozzle will be HOT! - English:Warning, very short print Translated:Warning, very short print @@ -6220,6 +6223,9 @@ Translated:WARNING: In order to perform print recovery, your printer must move d English:WARNING: Write Failed! Translated:WARNING: Write Failed! +English:Warning! The tip of the nozzle will be HOT! +Translated:Warning! The tip of the nozzle will be HOT! + English:Warping Translated:Warping @@ -6397,15 +6403,15 @@ Translated:You have successfully imported a new printer profile. You can find '{ English:You may need to wait a minute for your printer to finish initializing. Translated:You may need to wait a minute for your printer to finish initializing. -English:You need to select your printer's 'Bed Surface' under the bed setting menu on the top right of your screen -Translated:You need to select your printer's 'Bed Surface' under the bed setting menu on the top right of your screen - English:You need to select your printer's 'Bed Surface' under the 'Bed Temperature' menu on the top right of your screen Translated:You need to select your printer's 'Bed Surface' under the 'Bed Temperature' menu on the top right of your screen English:You need to select your printer's 'Bed Surface' under the 'Bed Temperature' menu on the top right of your screen. Translated:You need to select your printer's 'Bed Surface' under the 'Bed Temperature' menu on the top right of your screen. +English:You need to select your printer's 'Bed Surface' under the bed setting menu on the top right of your screen +Translated:You need to select your printer's 'Bed Surface' under the bed setting menu on the top right of your screen + English:You should have at least 3 top layers for this calibration to measure off of. Translated:You should have at least 3 top layers for this calibration to measure off of. diff --git a/Submodules/MatterSlice b/Submodules/MatterSlice index aed14d8ae..68c71c98b 160000 --- a/Submodules/MatterSlice +++ b/Submodules/MatterSlice @@ -1 +1 @@ -Subproject commit aed14d8ae6c0d2576271b4f48178686863ea19cc +Subproject commit 68c71c98b5f598f0f98f786cafbc06abb4e3915f diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 0454a13bb..36ed349d6 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 0454a13bb0f6761f582350157ac9fed7f2934861 +Subproject commit 36ed349d6c4e2cb317d85289c4f54120bb2c6590 diff --git a/Tests/MatterControl.AutomationTests/CameraFittingUtilTests.cs b/Tests/MatterControl.AutomationTests/CameraFittingUtilTests.cs index 5184358c0..afb80ebd0 100644 --- a/Tests/MatterControl.AutomationTests/CameraFittingUtilTests.cs +++ b/Tests/MatterControl.AutomationTests/CameraFittingUtilTests.cs @@ -7,10 +7,11 @@ using NUnit.Framework; using System; using System.Threading; using System.Threading.Tasks; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Category("MatterControl.UI.Automation"), Parallelizable(ParallelScope.Children)] public class CameraFittingUtilTests { private const string CoinName = "MatterControl - Coin.stl"; @@ -35,7 +36,9 @@ namespace MatterHackers.MatterControl.Tests.Automation Assert.IsTrue(!view3D.TrackballTumbleWidget.PerspectiveMode); } else + { Assert.IsTrue(view3D.TrackballTumbleWidget.PerspectiveMode); + } Vector3[] lookAtDirFwds = new Vector3[] { new Vector3(0, 0, -1), @@ -157,25 +160,25 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 60 * 3, overrideWidth: 1300, overrideHeight: 800); } - [Test] + [Test, ChildProcessTest] public Task OrthographicZoomToSelectionWide() { return DoZoomToSelectionTest(true, true); } - [Test] + [Test, ChildProcessTest] public Task OrthographicZoomToSelectionTall() { return DoZoomToSelectionTest(true, false); } - [Test] + [Test, ChildProcessTest] public Task PerspectiveZoomToSelectionWide() { return DoZoomToSelectionTest(false, true); } - [Test] + [Test, ChildProcessTest] public Task PerspectiveZoomToSelectionTall() { return DoZoomToSelectionTest(false, false); diff --git a/Tests/MatterControl.AutomationTests/CreateLibraryFolder.cs b/Tests/MatterControl.AutomationTests/CreateLibraryFolder.cs index 8cfc62375..07f52d800 100644 --- a/Tests/MatterControl.AutomationTests/CreateLibraryFolder.cs +++ b/Tests/MatterControl.AutomationTests/CreateLibraryFolder.cs @@ -34,13 +34,14 @@ using MatterHackers.Agg.UI; using MatterHackers.Agg.UI.Tests; using MatterHackers.GuiAutomation; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), Apartment(ApartmentState.STA), RunInApplicationDomain] + [TestFixture, Category("MatterControl.UI.Automation")] public class CreateLibraryFolder { - [Test, Apartment(ApartmentState.STA)] + [Test, ChildProcessTest] public async Task CreateFolderStartsWithTextFieldFocusedAndEditable() { await MatterControlUtilities.RunTest((testRunner) => @@ -54,7 +55,7 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.Type("Test Text"); testRunner.Delay(.5); - var textWidgetMH = testRunner.GetWidgetByName("InputBoxPage TextEditWidget", out _) as MHTextEditWidget; + var textWidgetMH = testRunner.GetWidgetByName("InputBoxPage TextEditWidget", out _) as ThemedTextEditWidget; Assert.IsTrue(textWidgetMH != null, "Found Text Widget"); Assert.IsTrue(textWidgetMH.Text == "Test Text", "Had the right text"); diff --git a/Tests/MatterControl.AutomationTests/DesignTools/SheetTests.cs b/Tests/MatterControl.AutomationTests/DesignTools/SheetTests.cs index 0831542ba..bddede25e 100644 --- a/Tests/MatterControl.AutomationTests/DesignTools/SheetTests.cs +++ b/Tests/MatterControl.AutomationTests/DesignTools/SheetTests.cs @@ -12,20 +12,21 @@ using MatterHackers.MatterControl.DesignTools.Operations; using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.VectorMath; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Category("MatterControl.UI.Automation"), Parallelizable(ParallelScope.Children)] public class PrimitiveAndSheetsTests { [SetUp] public void TestSetup() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); } - [Test] + [Test, ChildProcessTest] public void SheetEditorLayoutAndNavigation() { var systemWindow = new SystemWindow(800, 600) @@ -53,7 +54,7 @@ namespace MatterHackers.MatterControl.Tests.Automation 2000); } - [Test] + [Test, ChildProcessTest] public async Task DimensionsWorkWhenNoSheet() { await MatterControlUtilities.RunTest((testRunner) => @@ -65,7 +66,7 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.DoubleClickByName(primitiveName); // Get View3DWidget - View3DWidget view3D = testRunner.GetWidgetByName("View3DWidget", out _, 3) as View3DWidget; + View3DWidget view3D = testRunner.GetWidgetByName("View3DWidget", out var window, 3) as View3DWidget; var scene = view3D.Object3DControlLayer.Scene; testRunner.WaitForName(primitive); @@ -91,9 +92,24 @@ namespace MatterHackers.MatterControl.Tests.Automation // try scaling by text entry testRunner.ClickByName("ScaleWidthLeft") .ClickByName("XValueDisplay") + //.Assert(() => testRunner.GetWidgetByName("XValueDisplay", out var _).ContainsFocus, "Focus") // Sometimes, when the moves over to XValueDisplay, XValueDisplay just isn't there. .Type("35") + //.Assert(() => ((CustomWidgets.InlineEditControl)testRunner.GetWidgetByName("XValueDisplay", out var _)).Value == 35, "text") .Type("{Enter}"); + //.WaitFor(() => 35 == cube.Width.Value(cube)); + /*if (35 != cube.Width.Value(cube)) + { + System.Diagnostics.Debugger.Launch(); + System.Diagnostics.Debugger.Break(); + }*/ + + // NOTE: Happened once: Expected: 35, But was: 20.0d + // This can happen when running only this test, and alt-tabbing frequently. + // Failure again after platform focus fix. + // This can happen when running only this test, and not alt-tabbing frequently. + // Failure can happen in original .NET Framework MatterControl testing too. + // Possible cause is OnMouseMove(MatterHackers.Agg.UI.MouseEventArgs) (MatterHackers.MatterControl.PartPreviewWindow.Object3DControlsLayer) not updating the hover control in time. Assert.AreEqual(35, cube.Width.Value(cube)); testRunner.ClickByName("3D View Undo"); @@ -125,7 +141,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1300, maxTimeToRun: 60); } - [Test] + [Test, ChildProcessTest] public async Task ScaleObjectWorksWithAndWithoutSheet() { await MatterControlUtilities.RunTest((testRunner) => @@ -165,7 +181,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1300, maxTimeToRun: 60); } - [Test] + [Test, ChildProcessTest] public void SheetEditorNavigationTests() { var systemWindow = new SystemWindow(800, 600) diff --git a/Tests/MatterControl.AutomationTests/ExportItemWindowTests.cs b/Tests/MatterControl.AutomationTests/ExportItemWindowTests.cs index cda4f0128..ab7ebe419 100644 --- a/Tests/MatterControl.AutomationTests/ExportItemWindowTests.cs +++ b/Tests/MatterControl.AutomationTests/ExportItemWindowTests.cs @@ -3,13 +3,14 @@ using System.Threading; using System.Threading.Tasks; using NUnit.Framework; using System; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("Agg.UI.Automation"), Apartment(ApartmentState.STA), RunInApplicationDomain] + [TestFixture, Category("MatterControl.UI.Automation")] public class ExportGcodeFromExportWindow { - [Test] + [Test, ChildProcessTest] public async Task ExportAsGcode() { await MatterControlUtilities.RunTest(testRunner => @@ -56,7 +57,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task ExportDesignTabAsSTL() { await MatterControlUtilities.RunTest(testRunner => @@ -88,7 +89,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task ExportStreamG92HandlingTest() { await MatterControlUtilities.RunTest(testRunner => diff --git a/Tests/MatterControl.AutomationTests/HardwareLevelingUITests.cs b/Tests/MatterControl.AutomationTests/HardwareLevelingUITests.cs index ea1a1ca28..dad5c76f6 100644 --- a/Tests/MatterControl.AutomationTests/HardwareLevelingUITests.cs +++ b/Tests/MatterControl.AutomationTests/HardwareLevelingUITests.cs @@ -1,13 +1,14 @@ using System.Threading; using System.Threading.Tasks; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Category("MatterControl.UI.Automation"), Parallelizable(ParallelScope.Children)] public class HardwareLevelingUITests { - [Test] + [Test, ChildProcessTest] public async Task HasHardwareLevelingHidesLevelingSettings() { await MatterControlUtilities.RunTest((testRunner) => @@ -36,7 +37,8 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideHeight: 800); } - [Test, Category("Emulator")] + // NOTE: This test once failed, due to timing probably. + [Test, ChildProcessTest, Category("Emulator")] public async Task SoftwareLevelingTest() { await MatterControlUtilities.RunTest((testRunner) => @@ -82,7 +84,7 @@ namespace MatterHackers.MatterControl.Tests.Automation } return Task.CompletedTask; - }, maxTimeToRun: 90); + }, maxTimeToRun: 90); // NOTE: This test got stuck in ClickByName("Yes Button") -> WaitforDraw. It appears to be because WaitforDraw waited for a closed window to redraw itself. } } } diff --git a/Tests/MatterControl.AutomationTests/LibraryActionTests.cs b/Tests/MatterControl.AutomationTests/LibraryActionTests.cs index 29d7209fc..77794b0e2 100644 --- a/Tests/MatterControl.AutomationTests/LibraryActionTests.cs +++ b/Tests/MatterControl.AutomationTests/LibraryActionTests.cs @@ -35,7 +35,7 @@ using NUnit.Framework; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Ignore("Product code still needs to be implemented"), Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Ignore("Product code still needs to be implemented"), Category("MatterControl.UI.Automation")] public class LibraryActionTests { [Test] diff --git a/Tests/MatterControl.AutomationTests/LibraryContainerTests.cs b/Tests/MatterControl.AutomationTests/LibraryContainerTests.cs index cd5bbd8e7..1c79154c8 100644 --- a/Tests/MatterControl.AutomationTests/LibraryContainerTests.cs +++ b/Tests/MatterControl.AutomationTests/LibraryContainerTests.cs @@ -41,18 +41,23 @@ using MatterHackers.MatterControl.DataStorage; using MatterHackers.MatterControl.Library; using MatterHackers.MatterControl.Tests.Automation; using NUnit.Framework; +using TestInvoker; namespace MatterControl.Tests.MatterControl { - [TestFixture, Category("LibraryContainerTests"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Category("LibraryContainerTests")] public class LibraryContainerTests { + [SetUp] + public static void Setup() + { + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); + } + [Test] public Task TestExistsForEachContainerType() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); - // Find all test methods on this test class var thisClassMethods = this.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance); @@ -72,9 +77,6 @@ namespace MatterControl.Tests.MatterControl [Test] public async Task NoContentChangedOnLoad() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); - bool onIdlePumpActive = true; var uiPump = Task.Run(() => @@ -95,7 +97,7 @@ namespace MatterControl.Tests.MatterControl if (containerType == typeof(FileSystemContainer)) { - args.Add(TestContext.CurrentContext.ResolveProjectPath(4)); + args.Add(MatterControlUtilities.RootPath); } else if (containerType == typeof(RootLibraryContainer)) { @@ -107,7 +109,7 @@ namespace MatterControl.Tests.MatterControl { if (libraryContainer is ZipMemoryContainer zipContainer) { - zipContainer.Path = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "TestParts", "Batman.zip"); + zipContainer.Path = Path.Combine(MatterControlUtilities.RootPath, "Tests", "TestData", "TestParts", "Batman.zip"); zipContainer.RelativeDirectory = Path.GetDirectoryName(zipContainer.Path); } @@ -136,10 +138,7 @@ namespace MatterControl.Tests.MatterControl [Test] public async Task AddFiresContentChangedEvent() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); - - string filePath = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "TestParts", "Batman.stl"); + string filePath = Path.Combine(MatterControlUtilities.RootPath, "Tests", "TestData", "TestParts", "Batman.stl"); bool onIdlePumpActive = true; @@ -182,7 +181,7 @@ namespace MatterControl.Tests.MatterControl if (libraryContainer is ZipMemoryContainer zipContainer) { - zipContainer.Path = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "TestParts", "Batman.zip"); + zipContainer.Path = Path.Combine(MatterControlUtilities.RootPath, "Tests", "TestData", "TestParts", "Batman.zip"); zipContainer.RelativeDirectory = Path.GetDirectoryName(zipContainer.Path); } diff --git a/Tests/MatterControl.AutomationTests/LibraryDownloadsTest.cs b/Tests/MatterControl.AutomationTests/LibraryDownloadsTest.cs index 3a7795d38..dc063c1e9 100644 --- a/Tests/MatterControl.AutomationTests/LibraryDownloadsTest.cs +++ b/Tests/MatterControl.AutomationTests/LibraryDownloadsTest.cs @@ -4,10 +4,11 @@ using System.Threading.Tasks; using MatterHackers.Agg.UI.Tests; using MatterHackers.GuiAutomation; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), Apartment(ApartmentState.STA), RunInApplicationDomain] + [TestFixture, Category("MatterControl.UI.Automation")] public class LibraryDownloadsTests { [SetUp] @@ -22,7 +23,7 @@ namespace MatterHackers.MatterControl.Tests.Automation MatterControlUtilities.DeleteDownloadsSubFolder(); } - [Test] + [Test, ChildProcessTest] public async Task DownloadsAddButtonAddsMultipleFiles() { await MatterControlUtilities.RunTest(testRunner => @@ -37,7 +38,7 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.InvokeLibraryAddDialog(); testRunner.CompleteDialog( string.Format( - "\"{0}\" \"{1}\"", + "\"{0}\";\"{1}\"", MatterControlUtilities.GetTestItemPath("Fennec_Fox.stl"), MatterControlUtilities.GetTestItemPath("Batman.stl")), 5); @@ -49,7 +50,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task DownloadsAddButtonAddsAMFFiles() { await MatterControlUtilities.RunTest(testRunner => @@ -70,7 +71,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task DownloadsAddButtonAddsZipFiles() { await MatterControlUtilities.RunTest(testRunner => @@ -96,7 +97,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task RenameDownloadsPrintItem() { await MatterControlUtilities.RunTest(testRunner => @@ -126,7 +127,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task CreateFolder() { await MatterControlUtilities.RunTest(testRunner => diff --git a/Tests/MatterControl.AutomationTests/LocalLibraryTests.cs b/Tests/MatterControl.AutomationTests/LocalLibraryTests.cs index 544e769d0..a8f7c0db3 100644 --- a/Tests/MatterControl.AutomationTests/LocalLibraryTests.cs +++ b/Tests/MatterControl.AutomationTests/LocalLibraryTests.cs @@ -4,13 +4,15 @@ using System.Threading.Tasks; using MatterHackers.Agg.UI; using MatterHackers.MatterControl.PrintQueue; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + // Most of these tests are disabled. Local Library needs to be added by InitializeLibrary() (MatterHackers.MatterControl.ApplicationController). + [TestFixture, Category("MatterControl.UI.Automation"), Parallelizable(ParallelScope.Children)] public class LocalLibraryTests { - [Test] + [Test, ChildProcessTest] public async Task LocalLibraryAddButtonAddSingleItemToLibrary() { await MatterControlUtilities.RunTest((testRunner) => @@ -22,7 +24,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task LocalLibraryAddButtonAddsMultipleItemsToLibrary() { await MatterControlUtilities.RunTest((testRunner) => @@ -34,7 +36,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task LocalLibraryAddButtonAddAMFToLibrary() { await MatterControlUtilities.RunTest((testRunner) => @@ -46,7 +48,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1024, overrideHeight: 800); } - [Test] + [Test, ChildProcessTest] public async Task ParentFolderRefreshedOnPathPop() { // Expected: When descending into a child folder and moving items into the parent, popping the path to the parent should refresh and show the moved content @@ -94,7 +96,7 @@ namespace MatterHackers.MatterControl.Tests.Automation } - [Test] + [Test, ChildProcessTest] public async Task LocalLibraryAddButtonAddZipToLibrary() { await MatterControlUtilities.RunTest((testRunner) => @@ -126,7 +128,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task DoubleClickSwitchesToOpenTab() { await MatterControlUtilities.RunTest((testRunner) => @@ -180,7 +182,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task RenameButtonRenamesLocalLibraryFolder() { await MatterControlUtilities.RunTest((testRunner) => @@ -211,7 +213,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task RemoveButtonClickedRemovesSingleItem() { await MatterControlUtilities.RunTest((testRunner) => @@ -231,7 +233,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task RemoveButtonClickedRemovesMultipleItems() { await MatterControlUtilities.RunTest((testRunner) => diff --git a/Tests/MatterControl.AutomationTests/MatterControl.AutomationTests.csproj b/Tests/MatterControl.AutomationTests/MatterControl.AutomationTests.csproj index bdcc92c7d..7eebd7754 100644 --- a/Tests/MatterControl.AutomationTests/MatterControl.AutomationTests.csproj +++ b/Tests/MatterControl.AutomationTests/MatterControl.AutomationTests.csproj @@ -1,148 +1,55 @@ - - - + - Debug - AnyCPU - {418E7058-92EE-4329-86BA-AC26B65AFB25} + net6.0-windows Library - true - PackageReference true - - true - PackageReference - true - Properties - MatterControl.AutomationTests - MatterControl.AutomationTests - v4.8 win - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - AnyCPU - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - AnyCPU + false + $(MSBuildProjectName) + $(MSBuildProjectName.Replace(" ", "_")) + obj\ + $(AssemblyName) + $(VersionPrefix)$(OutputPath) + $(AssemblyName) + - - - 4.2.1 + + + all MatterControlUtilities.cs - - - - - - - - - - - - - - - - - - - - - - - {2af30557-fc50-4de3-ad1c-7eb57131a9c5} - MatterControl.Common - - - {3EC506A5-3C23-4663-A5F3-600119361A35} - MatterControl.MeshOperations - - - {97d5ade3-c1b4-4b46-8a3e-718a4f7f079f} - MatterControl.Printing - - - {d6dc2669-7b1f-40fe-89bf-45d4c94473e3} - MatterControl.Winforms - - - {D557B079-612F-467F-AE0D-3F77BCD627F7} - MatterControlLib - - - {657dbc6d-c3ea-4398-a3fa-ddb73c14f71b} - Agg - - - {04667764-dc7b-4b95-aef6-b4e6c87a54e9} - DataConverters3D - - - {807F5686-A3EC-4BCC-AA42-B75D79E0D855} - GuiAutomation - - - {74f6bb6c-9d02-4512-a59a-21940e35c532} - Gui - - - {CD8A3D1A-24D5-4184-8CF3-7B2AD5CD7A71} - PlatformWin32 - - - {86f6aaf2-9b50-40b8-a427-1897d76471c5} - PolygonMesh - - - {545b6912-77ff-4b34-ba76-6c3d6a32be6a} - RenderOpenGl - - - {195cbe56-e654-437b-ab05-3be1b9452497} - Agg.Tests - - - {d3e41b4e-bfbb-44ca-94c8-95c00f754fdd} - VectorMath - - - {D0B7E0DD-3517-4BFD-A934-95A568FEED1E} - MatterSliceLib - - - {8cd15b23-d30f-470e-99ba-9276fb7cabd4} - MatterSlice.Tests - + + + + + + + + + + + + + + + + + - + + + \ No newline at end of file diff --git a/Tests/MatterControl.AutomationTests/MatterControlTests.cs b/Tests/MatterControl.AutomationTests/MatterControlTests.cs index c898ca44b..435e642a9 100644 --- a/Tests/MatterControl.AutomationTests/MatterControlTests.cs +++ b/Tests/MatterControl.AutomationTests/MatterControlTests.cs @@ -36,13 +36,14 @@ using MatterHackers.MatterControl.Library; using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.MatterControl.SlicerConfiguration; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Category("MatterControl.UI.Automation"), Parallelizable(ParallelScope.Children)] public class MatterControlTests { - [Test] + [Test, ChildProcessTest] public async Task ThumbnailGenerationMode() { await MatterControlUtilities.RunTest(async (testRunner) => @@ -59,7 +60,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task ViewGenerateSupportMenu() { await MatterControlUtilities.RunTest(testRunner => @@ -74,7 +75,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task PrinterTabRemainsAfterReloadAll() { await MatterControlUtilities.RunTest((testRunner) => diff --git a/Tests/MatterControl.AutomationTests/OptionsTabTests.cs b/Tests/MatterControl.AutomationTests/OptionsTabTests.cs index 0cca78860..15ea419ee 100644 --- a/Tests/MatterControl.AutomationTests/OptionsTabTests.cs +++ b/Tests/MatterControl.AutomationTests/OptionsTabTests.cs @@ -2,13 +2,14 @@ using System.Threading.Tasks; using MatterHackers.Agg.UI; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("Agg.UI.Automation"), Apartment(ApartmentState.STA), RunInApplicationDomain] + [TestFixture, Category("MatterControl.UI.Automation")] public class ShowTerminalButtonClickedOpensTerminal { - [Test] + [Test, ChildProcessTest] public async Task ClickingShowTerminalButtonOpensTerminal() { await MatterControlUtilities.RunTest((testRunner) => diff --git a/Tests/MatterControl.AutomationTests/PartPreviewTests.cs b/Tests/MatterControl.AutomationTests/PartPreviewTests.cs index d356d36a3..31b8fc5dc 100644 --- a/Tests/MatterControl.AutomationTests/PartPreviewTests.cs +++ b/Tests/MatterControl.AutomationTests/PartPreviewTests.cs @@ -44,13 +44,14 @@ using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.MatterControl.PrintQueue; using MatterHackers.VectorMath; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Category("MatterControl.UI.Automation"), Parallelizable(ParallelScope.Children)] public class PartPreviewTests { - [Test] + [Test, ChildProcessTest] public async Task CopyButtonMakesCopyOfPart() { await MatterControlUtilities.RunTest((testRunner) => @@ -80,7 +81,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1300, maxTimeToRun: 60); } - [Test] + [Test, ChildProcessTest] public async Task AddMultiplePartsMultipleTimes() { await MatterControlUtilities.RunTest((testRunner) => @@ -110,7 +111,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1300, maxTimeToRun: 60); } - [Test] + [Test, ChildProcessTest] public async Task AddingImageConverterWorks() { await MatterControlUtilities.RunTest((testRunner) => @@ -129,7 +130,8 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1300, maxTimeToRun: 60); } - [Test] + // NOTE: On GLFW, this test appears to fail due to the (lack of) behavior in PressModifierKeys. + [Test, ChildProcessTest] public static async Task ControlClickInDesignTreeView() { await MatterControlUtilities.RunTest((testRunner) => @@ -419,7 +421,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1300, maxTimeToRun: 110); } - [Test] + [Test, ChildProcessTest] public async Task DesignTabFileOperations() { await MatterControlUtilities.RunTest((testRunner) => @@ -504,7 +506,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 60); } - [Test] + [Test, ChildProcessTest] public async Task GroupAndUngroup() { await MatterControlUtilities.RunTest((testRunner) => @@ -546,7 +548,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1300); } - [Test] + [Test, ChildProcessTest] public async Task RemoveButtonRemovesParts() { await MatterControlUtilities.RunTest((testRunner) => @@ -581,7 +583,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task SaveAsToQueue() { await MatterControlUtilities.RunTest((testRunner) => @@ -607,7 +609,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task SaveAsToLocalLibrary() { await MatterControlUtilities.RunTest((testRunner) => diff --git a/Tests/MatterControl.AutomationTests/PrintQueueTests.cs b/Tests/MatterControl.AutomationTests/PrintQueueTests.cs index 0c744ebe6..502dd8a13 100644 --- a/Tests/MatterControl.AutomationTests/PrintQueueTests.cs +++ b/Tests/MatterControl.AutomationTests/PrintQueueTests.cs @@ -34,13 +34,15 @@ using MatterHackers.GuiAutomation; using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.MatterControl.PrintQueue; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + // Most of these tests are disabled. Local Library and Queue needs to be added by InitializeLibrary() (MatterHackers.MatterControl.ApplicationController). + [TestFixture, Category("MatterControl.UI.Automation"), Parallelizable(ParallelScope.Children)] public class PrintQueueTests { - [Test] + [Test, ChildProcessTest] public async Task AddOneItemToQueue() { await MatterControlUtilities.RunTest((testRunner) => @@ -70,7 +72,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task AddTwoItemsToQueue() { await MatterControlUtilities.RunTest((testRunner) => @@ -88,7 +90,7 @@ namespace MatterHackers.MatterControl.Tests.Automation // Open Fennec_Fox, Batman files testRunner.CompleteDialog( string.Format( - "\"{0}\" \"{1}\"", + "\"{0}\";\"{1}\"", MatterControlUtilities.GetTestItemPath("Fennec_Fox.stl"), MatterControlUtilities.GetTestItemPath("Batman.stl")), secondsToWait: 2); @@ -105,7 +107,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task RemoveButtonRemovesSingleItem() { await MatterControlUtilities.RunTest((testRunner) => @@ -132,7 +134,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, queueItemFolderToAdd: QueueTemplate.Three_Queue_Items); } - [Test] + [Test, ChildProcessTest] public async Task RemoveButtonRemovesMultipleItems() { await MatterControlUtilities.RunTest((testRunner) => @@ -160,7 +162,8 @@ namespace MatterHackers.MatterControl.Tests.Automation }, queueItemFolderToAdd: QueueTemplate.Three_Queue_Items); } - [Test] + + [Test, ChildProcessTest] public async Task DragTo3DViewAddsItem() { await MatterControlUtilities.RunTest((testRunner) => @@ -186,7 +189,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, queueItemFolderToAdd: QueueTemplate.Three_Queue_Items); } - [Test] + [Test, ChildProcessTest] public async Task AddAmfFile() { await MatterControlUtilities.RunTest((testRunner) => @@ -216,7 +219,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task AddStlFile() { await MatterControlUtilities.RunTest((testRunner) => @@ -246,7 +249,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task AddGCodeFile() { await MatterControlUtilities.RunTest((testRunner) => diff --git a/Tests/MatterControl.AutomationTests/PrinterConnectionTests.cs b/Tests/MatterControl.AutomationTests/PrinterConnectionTests.cs index 1e66239e1..14f0816c8 100644 --- a/Tests/MatterControl.AutomationTests/PrinterConnectionTests.cs +++ b/Tests/MatterControl.AutomationTests/PrinterConnectionTests.cs @@ -11,13 +11,14 @@ using MatterHackers.PrinterEmulator; using MatterHackers.VectorMath; using NUnit.Framework; using static MatterHackers.MatterControl.PrinterCommunication.PrinterConnection; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Category("MatterControl.UI.Automation")] public class PrinterConnectionTests { - [Test] + [Test, ChildProcessTest] public async Task PrinterDisconnectedOnTabClose() { await MatterControlUtilities.RunTest((testRunner) => diff --git a/Tests/MatterControl.AutomationTests/PrinterDropDownTests.cs b/Tests/MatterControl.AutomationTests/PrinterDropDownTests.cs index 04a25ac94..e93f8a6c6 100644 --- a/Tests/MatterControl.AutomationTests/PrinterDropDownTests.cs +++ b/Tests/MatterControl.AutomationTests/PrinterDropDownTests.cs @@ -4,13 +4,14 @@ using System.Threading.Tasks; using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.MatterControl.SlicerConfiguration; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Category("MatterControl.UI.Automation"), Parallelizable(ParallelScope.Children)] public class PrinterNameChangeTests { - [Test] + [Test, ChildProcessTest] public async Task NameChangeOnlyEffectsOnePrinter() { await MatterControlUtilities.RunTest((testRunner) => @@ -51,7 +52,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 120); } - [Test] + [Test, ChildProcessTest] public async Task NameChangePersists() { // Ensures that printer model changes are applied correctly and observed by the view diff --git a/Tests/MatterControl.AutomationTests/PrintingTests.cs b/Tests/MatterControl.AutomationTests/PrintingTests.cs index aca1fe3c2..b2711d8f9 100644 --- a/Tests/MatterControl.AutomationTests/PrintingTests.cs +++ b/Tests/MatterControl.AutomationTests/PrintingTests.cs @@ -12,13 +12,14 @@ using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.PrinterEmulator; using MatterHackers.VectorMath; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Category("MatterControl.UI.Automation"), Parallelizable(ParallelScope.Children)] public class PrintingTests { - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task CompletingPrintTurnsoffHeat() { await MatterControlUtilities.RunTest((testRunner) => @@ -39,6 +40,10 @@ namespace MatterHackers.MatterControl.Tests.Automation var printer = testRunner.FirstPrinter(); + // TODO: Failure persisting GCode / MultilineTextField value + // Expected string length 3 but was 2.Strings differ at index 0. + // Shift-G is being swallowed by something. + // Validate GCode fields persist values Assert.AreEqual( "G28", @@ -82,7 +87,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 95); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task PulseLevelingTest() { // Validates the Pulse profile requires leveling and it works as expected @@ -135,6 +140,8 @@ namespace MatterHackers.MatterControl.Tests.Automation // assert the leveling is working Assert.AreEqual(12.25, emulator.Destination.Z); + // NOTE: System.Exception : WaitForWidgetEnabled Failed: Named GuiWidget not found [Print Progress Dial] + // Might be fixed in CancelPrint now. testRunner.CancelPrint(); // now modify the leveling data manually and assert that it is applied when printing @@ -170,7 +177,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 230); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public void ExpectedEmulatorResponses() { // TODO: Emulator behavior should emulate actual printer firmware and use configuration rather than M104/M109 sends to set extruder count @@ -281,7 +288,7 @@ namespace MatterHackers.MatterControl.Tests.Automation } } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task PrinterRequestsResumeWorkingAsExpected() { await MatterControlUtilities.RunTest((testRunner) => @@ -315,10 +322,10 @@ namespace MatterHackers.MatterControl.Tests.Automation } return Task.CompletedTask; - }, maxTimeToRun: 90); + }, maxTimeToRun: 90 * 2); // Once timed out at 90. } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task PrinterDeletedWhilePrinting() { await MatterControlUtilities.RunTest((testRunner) => @@ -345,7 +352,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 180); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task PrinterRecoveryTest() { await MatterControlUtilities.RunTest((testRunner) => @@ -384,7 +391,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 180); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task TemperatureTowerWorks() { await MatterControlUtilities.RunTest((testRunner) => @@ -422,16 +429,16 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 180); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task RecoveryT1NoProbe() { await ExtruderT1RecoveryTest("Airwolf 3D", "HD"); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task RecoveryT1WithProbe() { - await ExtruderT1RecoveryTest("Pulse", "S-500"); + await ExtruderT1RecoveryTest("FlashForge", "Creator Dual"); } public async Task ExtruderT1RecoveryTest(string make, string model) @@ -466,6 +473,7 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.ClickResumeButton(printer, false, 2) // close the pause dialog pop-up do not resume .ClickByName("Disconnect from printer button") + .ClickByName("Yes Button") // Are you sure? .ClickByName("Connect to printer button") // Reconnect .WaitFor(() => printer.Connection.CommunicationState == CommunicationStates.Connected); @@ -490,7 +498,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 180); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task TuningAdjustmentsDefaultToOneAndPersists() { double targetExtrusionRate = 1.5; @@ -521,6 +529,8 @@ namespace MatterHackers.MatterControl.Tests.Automation .ScrollIntoView("Extrusion Multiplier NumberEdit") .ScrollIntoView("Feed Rate NumberEdit"); + testRunner.PausePrint(); + // Tuning values should default to 1 when missing ConfirmExpectedSpeeds(testRunner, 1, 1, "Initial case"); @@ -540,6 +550,8 @@ namespace MatterHackers.MatterControl.Tests.Automation ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "While printing"); + testRunner.ResumePrint(); + // Wait up to 60 seconds for the print to finish printFinishedResetEvent.WaitOne(60 * 1000); @@ -564,7 +576,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideHeight: 900, maxTimeToRun: 120); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task TuningAdjustmentControlsBoundToStreamValues() { double targetExtrusionRate = 1.5; @@ -597,6 +609,8 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.StartPrint(printer); + testRunner.PausePrint(); + var container = testRunner.GetWidgetByName("ManualPrinterControls.ControlsContainer", out _, 5); // Scroll the widget into view @@ -633,6 +647,8 @@ namespace MatterHackers.MatterControl.Tests.Automation // Values should remain after print completes ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "While printing"); + testRunner.ResumePrint(); + // Wait for printing to complete printFinishedResetEvent.WaitOne(); @@ -656,7 +672,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideHeight: 900, maxTimeToRun: 120); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task CloseShouldNotStopSDPrint() { await MatterControlUtilities.RunTest((testRunner) => @@ -698,7 +714,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 90); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task CancelingPrintTurnsHeatAndFanOff() { await MatterControlUtilities.RunTest((testRunner) => diff --git a/Tests/MatterControl.AutomationTests/Properties/AssemblyInfo.cs b/Tests/MatterControl.AutomationTests/Properties/AssemblyInfo.cs index 5d9404736..59cd3f159 100644 --- a/Tests/MatterControl.AutomationTests/Properties/AssemblyInfo.cs +++ b/Tests/MatterControl.AutomationTests/Properties/AssemblyInfo.cs @@ -34,3 +34,6 @@ using System.Runtime.InteropServices; // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] + +// https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1416 +[assembly: System.Runtime.Versioning.SupportedOSPlatform("windows7.0")] \ No newline at end of file diff --git a/Tests/MatterControl.AutomationTests/Properties/launchSettings.json b/Tests/MatterControl.AutomationTests/Properties/launchSettings.json new file mode 100644 index 000000000..7fe2a0d92 --- /dev/null +++ b/Tests/MatterControl.AutomationTests/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "MatterControl.AutomationTests": { + "commandName": "Project", + "nativeDebugging": true + } + } +} \ No newline at end of file diff --git a/Tests/MatterControl.AutomationTests/ReSliceTests.cs b/Tests/MatterControl.AutomationTests/ReSliceTests.cs index 8e25765f2..35e2a9734 100644 --- a/Tests/MatterControl.AutomationTests/ReSliceTests.cs +++ b/Tests/MatterControl.AutomationTests/ReSliceTests.cs @@ -39,14 +39,15 @@ using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.MatterControl.VersionManagement; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Category("MatterControl.UI.Automation")] public class ReSliceTests { // [Test, Category("Emulator"), Ignore("WIP")] - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task ReSliceHasCorrectEPositions() { await MatterControlUtilities.RunTest((testRunner) => @@ -99,6 +100,9 @@ namespace MatterHackers.MatterControl.Tests.Automation .StartPrint(printer, pauseAtLayers: "50;60") // Wait for pause // the yes button is 'Resume' + // NOTE: ClickByName Failed: Named GuiWidget not found [No Button] + // It appears that printing can just take too long. + // This might be fixed by using a semaphore in MatterHackers.PrinterEmulator.Emulator. .ClickByName("No Button", secondsToWait: 80) // Delete the cube .ClickByName("Bed Options Menu") diff --git a/Tests/MatterControl.AutomationTests/SceneUndoRedoCopyTests.cs b/Tests/MatterControl.AutomationTests/SceneUndoRedoCopyTests.cs index f137e5937..1c21afc37 100644 --- a/Tests/MatterControl.AutomationTests/SceneUndoRedoCopyTests.cs +++ b/Tests/MatterControl.AutomationTests/SceneUndoRedoCopyTests.cs @@ -41,10 +41,11 @@ using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.VectorMath; using Newtonsoft.Json; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Category("MatterControl.UI.Automation"), Parallelizable(ParallelScope.Children)] public class SceneUndoRedoCopyTests { private const string CoinName = "MatterControl - Coin.stl"; @@ -52,11 +53,11 @@ namespace MatterHackers.MatterControl.Tests.Automation [SetUp] public void TestSetup() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); } - [Test] + [Test, ChildProcessTest] public async Task CopyRemoveUndoRedo() { await MatterControlUtilities.RunTest(testRunner => @@ -96,7 +97,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1300); } - [Test] + [Test, ChildProcessTest] public async Task UndoRedoCopy() { await MatterControlUtilities.RunTest(testRunner => @@ -146,7 +147,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1300); } - [Test] + [Test, ChildProcessTest] public async Task ValidateDoUndoOnUnGroupSingleMesh() { await MatterControlUtilities.RunTest(testRunner => @@ -185,7 +186,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1300); } - [Test] + [Test, ChildProcessTest] public async Task ValidateDoUndoOnGroup2Items() { await MatterControlUtilities.RunTest(testRunner => @@ -221,7 +222,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1300); } - [Test] + [Test, ChildProcessTest] public async Task ValidateDoUndoUnGroup2Items() { await MatterControlUtilities.RunTest(testRunner => @@ -270,7 +271,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1300); } - [Test] + [Test, ChildProcessTest] public async Task ValidateDoUndoMirror() { await MatterControlUtilities.RunTest(testRunner => @@ -300,7 +301,8 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1300); } - [Test] + // NOTE: This test once failed on GLFW. Could be timing or accidental input. + [Test, ChildProcessTest] public async Task ValidateDoUndoTranslateXY() { await MatterControlUtilities.RunTest(testRunner => @@ -313,6 +315,15 @@ namespace MatterHackers.MatterControl.Tests.Automation // Initialize AddCoinToBed(testRunner, scene); + // NOTE: Test failed with this once: + // Should be same (6): ' "Matrix": "[1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,-10.000661239027977,-19.05065578967333,-5.421010862427522E-17,1.0]", + // ' ' "Matrix": "[1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,2.999338760972023,-24.00067986547947,-5.421010862427522E-17,1.0]", + // Expected: True + // But was: False + // UndoTestExtensionMethods.SceneFilesAreSame(String fileName1, String fileName2, Boolean expectedResult) line 474 + // UndoTestExtensionMethods.AssertUndoRedo(AutomationRunner testRunner, InteractiveScene scene, String scenePath, String preOperationPath, String postOperationPath, Int32 preOperationDescendantCount, Int32 postOperationDescendantCount) line 541 + // UndoTestExtensionMethods.RunDoUndoTest(AutomationRunner testRunner, InteractiveScene scene, Action performOperation) line 453 + // test drag x y translation testRunner.RunDoUndoTest( scene, @@ -324,6 +335,9 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.DragDropByName(CoinName, CoinName, offsetDrag: new Point2D(-4, 0), offsetDrop: new Point2D(40, 0)); var end = part.GetAxisAlignedBoundingBox(Matrix4X4.Identity).Center; + // NOTE: Test failed with this once: Expected: greater than 15.399987526237965d, But was: 15.399987526237965d + // ClickWidget now waits for 2 redraws in case there is more deferred processing. + // Assert Assert.Greater(end.X, start.X); Assert.Less(end.Y, start.Y); @@ -333,8 +347,21 @@ namespace MatterHackers.MatterControl.Tests.Automation return Task.CompletedTask; }, overrideWidth: 1300); } + // Parallel testing of this single test. + //[Test, ChildProcessTest] public async Task ValidateDoUndoTranslateXY1() => await ValidateDoUndoTranslateXY(); + //[Test, ChildProcessTest] public async Task ValidateDoUndoTranslateXY2() => await ValidateDoUndoTranslateXY(); + //[Test, ChildProcessTest] public async Task ValidateDoUndoTranslateXY3() => await ValidateDoUndoTranslateXY(); + //[Test, ChildProcessTest] public async Task ValidateDoUndoTranslateXY4() => await ValidateDoUndoTranslateXY(); + //[Test, ChildProcessTest] public async Task ValidateDoUndoTranslateXY5() => await ValidateDoUndoTranslateXY(); + //[Test, ChildProcessTest] public async Task ValidateDoUndoTranslateXY6() => await ValidateDoUndoTranslateXY(); + //[Test, ChildProcessTest] public async Task ValidateDoUndoTranslateXY7() => await ValidateDoUndoTranslateXY(); + //[Test, ChildProcessTest] public async Task ValidateDoUndoTranslateXY8() => await ValidateDoUndoTranslateXY(); + //[Test, ChildProcessTest] public async Task ValidateDoUndoTranslateXY9() => await ValidateDoUndoTranslateXY(); + //[Test, ChildProcessTest] public async Task ValidateDoUndoTranslateXYa() => await ValidateDoUndoTranslateXY(); + //[Test, ChildProcessTest] public async Task ValidateDoUndoTranslateXYb() => await ValidateDoUndoTranslateXY(); - [Test] + + [Test, ChildProcessTest] public async Task ValidateDoUndoTranslateZ() { await MatterControlUtilities.RunTest(testRunner => @@ -370,6 +397,7 @@ namespace MatterHackers.MatterControl.Tests.Automation private static void AddBoxABoxBToBed(AutomationRunner testRunner, InteractiveScene scene) { var item = "Calibration - Box.stl"; + // NOTE: Test once failed here. Probably due to timing. testRunner.AddItemToBed() .Delay(.1) // move the first one over @@ -398,7 +426,8 @@ namespace MatterHackers.MatterControl.Tests.Automation { public static void RunDoUndoTest(this AutomationRunner testRunner, InteractiveScene scene, Action performOperation) { - string scenePath = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "temp", "undo_test_scene"); + string scenePath = Path.Combine(MatterControlUtilities.RootPath, "Tests", "temp", "undo_test_scene_" + Path.GetRandomFileName()); + Directory.CreateDirectory(scenePath); Object3D.AssetsPath = Path.Combine(scenePath, "Assets"); diff --git a/Tests/MatterControl.AutomationTests/SliceSettingsTests.cs b/Tests/MatterControl.AutomationTests/SliceSettingsTests.cs index 6e8bdc416..637b83018 100644 --- a/Tests/MatterControl.AutomationTests/SliceSettingsTests.cs +++ b/Tests/MatterControl.AutomationTests/SliceSettingsTests.cs @@ -9,13 +9,14 @@ using MatterHackers.GuiAutomation; using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.MatterControl.SlicerConfiguration; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Category("MatterControl.UI.Automation"), Parallelizable(ParallelScope.Children)] public class SliceSetingsTests { - [Test] + [Test, ChildProcessTest] public async Task RaftEnabledPassedToSliceEngine() { await MatterControlUtilities.RunTest((testRunner) => @@ -36,9 +37,10 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1224, overrideHeight: 800); } - [Test] + [Test, ChildProcessTest] public async Task RelativeRetractionExecutesCorrectly() { + // NOTE: This test once timed out at 120, but took 38.4s when run on its own. await MatterControlUtilities.RunTest((testRunner) => { testRunner.WaitForName("Cancel Wizard Button"); @@ -65,7 +67,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 120); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task PauseOnLayerTest() { await MatterControlUtilities.RunTest((testRunner) => @@ -88,7 +90,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 120); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task OemSettingsChangeOfferedToUserTest() { await MatterControlUtilities.RunTest(async (testRunner) => @@ -146,7 +148,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 120); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task MenuStaysOpenOnRebuildSettings() { await MatterControlUtilities.RunTest((testRunner) => @@ -174,7 +176,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 120); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task SettingsStayOpenOnRebuildSettings() { await MatterControlUtilities.RunTest((testRunner) => @@ -201,7 +203,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 120); } - [Test, Category("Emulator")] + [Test, ChildProcessTest, Category("Emulator")] public async Task CancelWorksAsExpected() { await MatterControlUtilities.RunTest((testRunner) => @@ -234,7 +236,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 120); } - [Test /* Test will fail if screen size is and "HeatBeforeHoming" falls below the fold */] + [Test /* Test will fail if screen size is and "HeatBeforeHoming" falls below the fold */, ChildProcessTest] public async Task ClearingCheckBoxClearsUserOverride() { await MatterControlUtilities.RunTest((testRunner) => @@ -255,7 +257,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, overrideWidth: 1224, overrideHeight: 900, maxTimeToRun: 600); } - [Test] + [Test, ChildProcessTest] public async Task DualExtrusionShowsCorrectHotendData() { await MatterControlUtilities.RunTest((testRunner) => @@ -272,7 +274,7 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.ClickByName("Hotend 0"); // assert the temp is set when we first open (it comes from the material) - MHNumberEdit tempWidget = testRunner.GetWidgetByName("Temperature Input", out _) as MHNumberEdit; + ThemedNumberEdit tempWidget = testRunner.GetWidgetByName("Temperature Input", out _) as ThemedNumberEdit; Assert.AreEqual(240, (int)tempWidget.Value); // change material @@ -350,9 +352,14 @@ namespace MatterHackers.MatterControl.Tests.Automation Assert.AreEqual(60, (int)emulator.CurrentExtruder.TargetTemperature); // click the remove override and have it change to default temp + // NOTE: Got test failure twice: The printer should report the expected goal temp + // Expected: 220 + // But was: 60 + // Even though WaitFor was used. Maybe the emulator is just delayed sometimes. + // Adding Math.Round anyway. And more waiting. testRunner.ClickByName("Restore temperature") - .WaitFor(() => hipsGoalTemp == emulator.CurrentExtruder.TargetTemperature); - Assert.AreEqual(hipsGoalTemp, (int)emulator.CurrentExtruder.TargetTemperature, "The printer should report the expected goal temp"); + .WaitFor(() => hipsGoalTemp == (int)Math.Round(emulator.CurrentExtruder.TargetTemperature), maxSeconds: 10); + Assert.AreEqual(hipsGoalTemp, (int)Math.Round(emulator.CurrentExtruder.TargetTemperature), "The printer should report the expected goal temp"); // type in 60 and have the heater turn on testRunner.ClickByName("Temperature Input") @@ -426,10 +433,10 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 120); } - [Test] + [Test, ChildProcessTest] public void SliceSettingsOrganizerSupportsKeyLookup() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(5, "MatterControl", "StaticData"); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; var organizer = PrinterSettings.Layout; @@ -446,7 +453,7 @@ namespace MatterHackers.MatterControl.Tests.Automation Assert.IsFalse(organizer.AllSliceSettings.ContainsKey("non_existing_setting")); } - [Test /* Test will fail if screen size is and "HeatBeforeHoming" falls below the fold */] + [Test, ChildProcessTest] public async Task SwitchingMaterialsCausesSettingsChangedEvents() { await MatterControlUtilities.RunTest((testRunner) => @@ -513,7 +520,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 1000); } - [Test] + [Test, ChildProcessTest] public async Task DeleteProfileWorksForGuest() { await MatterControlUtilities.RunTest((testRunner) => @@ -575,7 +582,7 @@ namespace MatterHackers.MatterControl.Tests.Automation Assert.IsFalse(printer.Settings.UserLayer.ContainsKey(settingToChange)); } - [Test] + [Test, ChildProcessTest] public async Task HasHeatedBedCheckedHidesBedTemperatureOptions() { await MatterControlUtilities.RunTest((testRunner) => @@ -591,8 +598,9 @@ namespace MatterHackers.MatterControl.Tests.Automation .SelectSliceSettingsField(SettingsKey.temperature) // Uncheck Has Heated Bed checkbox and make sure Bed Temp Textbox is not visible .SwitchToPrinterSettings() - .SelectSliceSettingsField(SettingsKey.has_heated_bed) - .Delay(.5) + //.SelectSliceSettingsField(SettingsKey.has_heated_bed) // NOTE: Happened once: System.Exception : ClickByName Failed: Named GuiWidget not found [Hardware SliceSettingsTab] + //.Delay(1.0) // Wait for reload reliably: + .WaitForReloadAll(() => testRunner.SelectSliceSettingsField(SettingsKey.has_heated_bed)) .SwitchToSliceSettings() .NavigateToSliceSettingsField(SettingsKey.temperature); @@ -607,7 +615,7 @@ namespace MatterHackers.MatterControl.Tests.Automation }); } - [Test] + [Test, ChildProcessTest] public async Task QualitySettingsStayAsOverrides() { await MatterControlUtilities.RunTest((testRunner) => @@ -671,11 +679,11 @@ namespace MatterHackers.MatterControl.Tests.Automation }, maxTimeToRun: 120); } - [Test] + [Test, ChildProcessTest] public void CopyFromTest() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); var settings = new PrinterSettings(); settings.ID = "12345-print"; diff --git a/Tests/MatterControl.AutomationTests/SqLiteLibraryProvider.cs b/Tests/MatterControl.AutomationTests/SqLiteLibraryProvider.cs index 4150fd5bf..407f6fb71 100644 --- a/Tests/MatterControl.AutomationTests/SqLiteLibraryProvider.cs +++ b/Tests/MatterControl.AutomationTests/SqLiteLibraryProvider.cs @@ -2,13 +2,14 @@ using System.Threading.Tasks; using MatterHackers.MatterControl.PartPreviewWindow; using NUnit.Framework; +using TestInvoker; namespace MatterHackers.MatterControl.Tests.Automation { - [TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Category("MatterControl.UI.Automation")] public class SqLiteLibraryProviderTests { - [Test] + [Test, ChildProcessTest] public async Task LibraryQueueViewRefreshesOnAddItem() { await MatterControlUtilities.RunTest((testRunner) => diff --git a/Tests/MatterControl.Tests/MatterControl.Tests.csproj b/Tests/MatterControl.Tests/MatterControl.Tests.csproj index 3af225a86..4011d3964 100644 --- a/Tests/MatterControl.Tests/MatterControl.Tests.csproj +++ b/Tests/MatterControl.Tests/MatterControl.Tests.csproj @@ -1,170 +1,55 @@ - - - + - Debug - AnyCPU - {E1455E5C-127C-4282-8CC5-452C300E91D0} + net6.0-windows Library - true - PackageReference true - true - PackageReference true - Properties - MatterControl.Tests - MatterControl.Tests - v4.8 win - 512 ..\..\ - - - + false + + + false + false - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - AnyCPU - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - AnyCPU - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {f1653f20-d47d-4f29-8c55-3c835542af5f} - Community.CsharpSqlite - - - {2af30557-fc50-4de3-ad1c-7eb57131a9c5} - MatterControl.Common - - - {b2b001ee-a142-4e20-acf8-ae4a9cb984f8} - MatterControl - - - {3ec506a5-3c23-4663-a5f3-600119361a35} - MatterControl.MeshOperations - - - {97d5ade3-c1b4-4b46-8a3e-718a4f7f079f} - MatterControl.Printing - - - {d6dc2669-7b1f-40fe-89bf-45d4c94473e3} - MatterControl.Winforms - - - {D557B079-612F-467F-AE0D-3F77BCD627F7} - MatterControlLib - - - {657dbc6d-c3ea-4398-a3fa-ddb73c14f71b} - Agg - - - {04667764-dc7b-4b95-aef6-b4e6c87a54e9} - DataConverters3D - - - {807F5686-A3EC-4BCC-AA42-B75D79E0D855} - GuiAutomation - - - {74f6bb6c-9d02-4512-a59a-21940e35c532} - Gui - - - {ca96058c-1a37-465d-a357-d6d695b13d25} - Localizations - - - {CD8A3D1A-24D5-4184-8CF3-7B2AD5CD7A71} - PlatformWin32 - - - {86f6aaf2-9b50-40b8-a427-1897d76471c5} - PolygonMesh - - - {545b6912-77ff-4b34-ba76-6c3d6a32be6a} - RenderOpenGl - - - {195cbe56-e654-437b-ab05-3be1b9452497} - Agg.Tests - - - {d3e41b4e-bfbb-44ca-94c8-95c00f754fdd} - VectorMath - - - {b0aed568-8796-42b9-baa9-ebc796134e78} - MatterSlice - - - {D0B7E0DD-3517-4BFD-A934-95A568FEED1E} - MatterSliceLib - + + + + + + + + + + + + + + + + + + + - + - + + all + - - + + + - \ No newline at end of file diff --git a/Tests/MatterControl.Tests/MatterControl/ApplicationControllerTests.cs b/Tests/MatterControl.Tests/MatterControl/ApplicationControllerTests.cs index 5a43b3235..92ace875a 100644 --- a/Tests/MatterControl.Tests/MatterControl/ApplicationControllerTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/ApplicationControllerTests.cs @@ -44,8 +44,8 @@ namespace MatterControl.Tests.MatterControl [Test] public async Task LoadCachableShouldFallbackToStaticData() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(5, "MatterControl", "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(5)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); string cacheScope = Path.Combine("Some", "Specific", "Scope"); @@ -69,8 +69,8 @@ namespace MatterControl.Tests.MatterControl [Test] public async Task LoadCachableShouldStoreCollectedResults() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(5, "MatterControl", "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(5)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); string cacheScope = Path.Combine("Some", "Specific", "Scope"); diff --git a/Tests/MatterControl.Tests/MatterControl/AssetManagerTests.cs b/Tests/MatterControl.Tests/MatterControl/AssetManagerTests.cs index a036b4c33..78637aab8 100644 --- a/Tests/MatterControl.Tests/MatterControl/AssetManagerTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/AssetManagerTests.cs @@ -19,8 +19,8 @@ namespace MatterControl.Tests.MatterControl [Test] public async Task StoreAssetFile() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); // Create sample asset file string tempFile = ApplicationDataStorage.Instance.GetNewLibraryFilePath(".txt"); @@ -58,8 +58,8 @@ namespace MatterControl.Tests.MatterControl [Test] public async Task StoreAsset() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); // Create sample asset file string tempFile = ApplicationDataStorage.Instance.GetNewLibraryFilePath(".txt"); @@ -98,8 +98,8 @@ namespace MatterControl.Tests.MatterControl [Test] public async Task StoreMesh() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); // Create sample asset file string tempFile = ApplicationDataStorage.Instance.GetNewLibraryFilePath(".txt"); diff --git a/Tests/MatterControl.Tests/MatterControl/BoundDropListTests.cs b/Tests/MatterControl.Tests/MatterControl/BoundDropListTests.cs index e5d4a5acd..12cacc32a 100644 --- a/Tests/MatterControl.Tests/MatterControl/BoundDropListTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/BoundDropListTests.cs @@ -15,10 +15,14 @@ namespace MatterControl.Tests.MatterControl [Test] public void BoundDropListHonorsWhitelist() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); - var manufacturers = new string[] { "3D Factory", "3D Stuffmaker", "Airwolf 3D", "BCN3D", "BeeVeryCreative", "Blue Eagle Labs", "Deezmaker", "FlashForge", "gCreate", "IRA3D", "JumpStart", "Leapfrog", "Lulzbot", "MAKEiT", "Maker's Tool Works", "MakerBot", "MakerGear", "Me3D", "OpenBeam", "Organic Thinking System", "Other", "Portabee", "Printrbot", "PrintSpace", "Revolution 3D Printers", "ROBO 3D", "SeeMeCNC", "Solidoodle", "Tosingraf", "Type A Machines", "Ultimaker", "Velleman", "Wanhao" }; + var manufacturers = new string[] { "3D Factory", "3D Stuffmaker", "Airwolf 3D", "BCN3D", "BeeVeryCreative", "Blue Eagle Labs", + "Deezmaker", "FlashForge", "gCreate", "IRA3D", "JumpStart", "Leapfrog", "Lulzbot", "MAKEiT", "Maker's Tool Works", + "MakerBot", "MakerGear", "Me3D", "OpenBeam", "Organic Thinking System", "Other", "Portabee", "Printrbot", "PrintSpace", + "Revolution 3D Printers", "ROBO 3D", "SeeMeCNC", "Solidoodle", "Tosingraf", "Type A Machines", "Ultimaker", "Velleman", + "Wanhao" }; var allManufacturers = manufacturers.Select(m => new KeyValuePair(m, m)).ToList(); diff --git a/Tests/MatterControl.Tests/MatterControl/GCodeProcessingTests.cs b/Tests/MatterControl.Tests/MatterControl/GCodeProcessingTests.cs index c7bdf1b8f..cf029a6cd 100644 --- a/Tests/MatterControl.Tests/MatterControl/GCodeProcessingTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/GCodeProcessingTests.cs @@ -78,8 +78,8 @@ namespace MatterControl.Tests.MatterControl [Test, Category("GCodeProcessing")] public void ReplaceMacroValuesWorking() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); var settings = new PrinterSettings(); settings.Slicer = new EngineMappingsMatterSlice(); diff --git a/Tests/MatterControl.Tests/MatterControl/GCodeStreamTests.cs b/Tests/MatterControl.Tests/MatterControl/GCodeStreamTests.cs index 6f85323eb..35bf79139 100644 --- a/Tests/MatterControl.Tests/MatterControl/GCodeStreamTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/GCodeStreamTests.cs @@ -40,20 +40,21 @@ using MatterHackers.MatterControl.Tests.Automation; using MatterHackers.VectorMath; using Newtonsoft.Json; using NUnit.Framework; +using TestInvoker; namespace MatterControl.Tests.MatterControl { - [TestFixture, RunInApplicationDomain, Category("GCodeStream")] + [TestFixture, Category("GCodeStream"), Parallelizable(ParallelScope.Children)] public class GCodeStreamTests { [SetUp] public void TestSetup() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); } - [Test] + [Test, ChildProcessTest] public void MaxLengthStreamTests() { string[] lines = new string[] @@ -84,7 +85,7 @@ namespace MatterControl.Tests.MatterControl ValidateStreamResponse(expected, maxLengthStream); } - [Test] + [Test, ChildProcessTest] public void ExportStreamG30Tests() { string[] inputLines = new string[] @@ -129,7 +130,7 @@ namespace MatterControl.Tests.MatterControl ValidateStreamResponse(expected, testStream); } - [Test] + [Test, ChildProcessTest] public void SmoothieRewriteTest() { string[] inputLines = new string[] @@ -162,7 +163,7 @@ namespace MatterControl.Tests.MatterControl ValidateStreamResponse(expected, testStream); } - [Test] + [Test, ChildProcessTest] public void LineCuttingOffWhenNoLevelingTest() { string[] inputLines = new string[] @@ -186,7 +187,7 @@ namespace MatterControl.Tests.MatterControl ValidateStreamResponse(expected, testStream); } - [Test] + [Test, ChildProcessTest] public void LineCuttingOnWhenLevelingOnWithProbeTest() { string[] inputLines = new string[] @@ -235,7 +236,7 @@ namespace MatterControl.Tests.MatterControl ValidateStreamResponse(expected, testStream); } - [Test] + [Test, ChildProcessTest] public void LineCuttingOnWhenLevelingOnNoProbeTest() { string[] inputLines = new string[] @@ -299,7 +300,7 @@ namespace MatterControl.Tests.MatterControl return totalGCodeStream; } - [Test] + [Test, ChildProcessTest] public void RegexReplacementStreamIsLast() { var printer = new PrinterConfig(new PrinterSettings()); @@ -316,7 +317,7 @@ namespace MatterControl.Tests.MatterControl Assert.IsTrue(streamProcessors.First() is ProcessWriteRegexStream, "ProcessWriteRegexStream should be the last stream in the stack"); } - [Test] + [Test, ChildProcessTest] public void CorrectEOutputPositionsG91() { string[] inputLines = new string[] @@ -377,7 +378,7 @@ namespace MatterControl.Tests.MatterControl ValidateStreamResponse(expected, testStream); } - [Test] + [Test, ChildProcessTest] public void CorrectEOutputPositionsM83() { string[] inputLines = new string[] @@ -441,7 +442,7 @@ namespace MatterControl.Tests.MatterControl ValidateStreamResponse(expected, testStream); } - [Test] + [Test, ChildProcessTest] public void CorrectEOutputForMiniStartupWithM83() { string[] inputLines = new string[] @@ -534,7 +535,7 @@ namespace MatterControl.Tests.MatterControl ValidateStreamResponse(expected, testStream); } - [Test] + [Test, ChildProcessTest] public void CorrectZOutputPositions() { string[] inputLines = new string[] @@ -564,7 +565,7 @@ namespace MatterControl.Tests.MatterControl ValidateStreamResponse(expected, testStream); } - [Test] + [Test, ChildProcessTest] public void PauseHandlingStreamTests() { int readX = 50; @@ -627,7 +628,7 @@ namespace MatterControl.Tests.MatterControl ValidateStreamResponse(expected, pauseHandlingStream); } - [Test, Ignore("WIP")] + [Test, ChildProcessTest, Ignore("WIP")] public void SoftwareEndstopstreamTests() { string[] inputLines = new string[] @@ -675,7 +676,7 @@ namespace MatterControl.Tests.MatterControl ValidateStreamResponse(expected, pauseHandlingStream); } - [Test] + [Test, ChildProcessTest] public void MorePauseHandlingStreamTests() { string[] inputLines = new string[] @@ -790,7 +791,7 @@ namespace MatterControl.Tests.MatterControl } } - [Test] + [Test, ChildProcessTest] public void KnownLayerLinesTest() { Assert.AreEqual(8, GCodeFile.GetLayerNumber("; layer 8, Z = 0.800"), "Simplify3D ~ 2019"); @@ -798,7 +799,7 @@ namespace MatterControl.Tests.MatterControl Assert.AreEqual(7, GCodeFile.GetLayerNumber(";LAYER:7"), "Slic3r Prusa Edition 1.38.7-prusa3d on 2018-04-25"); } - [Test] + [Test, ChildProcessTest] public void WriteReplaceStreamTests() { string[] inputLines = new string[] @@ -837,7 +838,7 @@ namespace MatterControl.Tests.MatterControl ValidateStreamResponse(expected, writeStream); } - [Test] + [Test, ChildProcessTest] public void FeedRateRatioChangesFeedRate() { string line; @@ -857,7 +858,7 @@ namespace MatterControl.Tests.MatterControl Assert.AreEqual("G1 Y5 F2000", line, "FeedRate should scale from F1000 to F2000 when FeedRateRatio is 2x"); } - [Test] + [Test, ChildProcessTest] public void ExtrusionRatioChangesExtrusionAmount() { string line; diff --git a/Tests/MatterControl.Tests/MatterControl/ImportSettingsTests.cs b/Tests/MatterControl.Tests/MatterControl/ImportSettingsTests.cs index f795c6741..ce078050b 100644 --- a/Tests/MatterControl.Tests/MatterControl/ImportSettingsTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/ImportSettingsTests.cs @@ -13,8 +13,8 @@ namespace MatterControl.Tests.MatterControl [Test] public void CheckImportPrinterSettingsToPrinter() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); var printerSettings = new PrinterSettings(); printerSettings.SetValue(SettingsKey.cancel_gcode, "cancel gcode"); @@ -44,8 +44,8 @@ namespace MatterControl.Tests.MatterControl { // Validates that field are dropped during import if they are already set in a base layer // - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); var printerSettings = new PrinterSettings(); printerSettings.SetValue(SettingsKey.cancel_gcode, "cancel gcode"); diff --git a/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs b/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs index f240fda4c..fbb5ce7ff 100644 --- a/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs @@ -51,8 +51,8 @@ namespace MatterControl.Tests.MatterControl { public static void StartupMC() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); // Automation runner must do as much as program.cs to spin up platform string platformFeaturesProvider = "MatterHackers.MatterControl.WindowsPlatformsFeatures, MatterControl.Winforms"; diff --git a/Tests/MatterControl.Tests/MatterControl/LevelingTests.cs b/Tests/MatterControl.Tests/MatterControl/LevelingTests.cs index df335e8f7..10bd502f7 100644 --- a/Tests/MatterControl.Tests/MatterControl/LevelingTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/LevelingTests.cs @@ -46,8 +46,8 @@ namespace MatterControl.Tests.MatterControl [Test, Category("Leveling")] public void LevelingMesh3x3CorectInterpolation() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); var printerSettings = new PrinterSettings(); printerSettings.SetValue(SettingsKey.probe_offset, "0,0,0"); diff --git a/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs b/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs index 1f34380b5..bbe723395 100644 --- a/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs +++ b/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs @@ -66,14 +66,25 @@ namespace MatterHackers.MatterControl.Tests.Automation private static event EventHandler UnregisterEvents; - private static int testID = 0; - private static string runName = DateTime.Now.ToString("yyyy-MM-ddTHH-mm-ss"); public static string PathToDownloadsSubFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads", "-Temporary"); + public static readonly string RootPath = ResolveProjectPath(new string[] { "..", "..", ".." }); + public static readonly string StaticDataPath = Path.Combine(RootPath, "StaticData"); + public static readonly string TestsPath = Path.Combine(RootPath, "Tests"); + public static readonly string MainBinOutputPath = Path.Combine(RootPath, + // This attribute is generated by an MSBuild task. + MainOutputDirectoryAttribute.GetFromProgramAssembly().MainOutputDirectory + ); + private static SystemWindow rootSystemWindow; + private static string GetPathToRootRelative(params string[] relPathPieces) + { + return Path.Combine(RootPath, Path.Combine(relPathPieces)); + } + public static void RemoveAllFromQueue(this AutomationRunner testRunner) { testRunner.ClickByName("Queue... Menu") @@ -260,12 +271,12 @@ namespace MatterHackers.MatterControl.Tests.Automation public static string PathToExportGcodeFolder { - get => TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "ExportedGcode", runName); + get => GetPathToRootRelative("Tests", "TestData", "ExportedGcode", runName); } public static string GetTestItemPath(string queueItemToLoad) { - return TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "QueueItems", queueItemToLoad); + return GetPathToRootRelative("Tests", "TestData", "QueueItems", queueItemToLoad); } public static void CloseMatterControl(this AutomationRunner testRunner) @@ -325,6 +336,11 @@ namespace MatterHackers.MatterControl.Tests.Automation // and close the product tour offer .ClickByName("Cancel Wizard Button"); + //testRunner.Delay(1); + // If testing is to be reliable, that dialog really shouldn't be showing now. + // NOTE: This may fail rarely still. Happened once with OrthographicZoomToSelectionWide. + Assert.IsFalse(testRunner.NamedWidgetExists("Cancel Wizard Button")); + if (removeDefaultPhil) { testRunner.VerifyAndRemovePhil(); @@ -394,6 +410,24 @@ namespace MatterHackers.MatterControl.Tests.Automation return Emulator.Instance; } + public static AutomationRunner PausePrint(this AutomationRunner testRunner) + { + testRunner.WaitForWidgetEnabled("Print Progress Dial", 15) + .WaitForWidgetEnabled("Pause Task Button") + .ClickByName("Pause Task Button"); + + return testRunner; + } + + public static AutomationRunner ResumePrint(this AutomationRunner testRunner) + { + testRunner.WaitForWidgetEnabled("Print Progress Dial", 15) + .WaitForWidgetEnabled("Resume Task Button") + .ClickByName("Resume Task Button"); + + return testRunner; + } + public static AutomationRunner CancelPrint(this AutomationRunner testRunner) { // If the pause/resume dialog is open, dismiss it before canceling the print @@ -402,12 +436,28 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.ClickByName("Yes Button"); } - 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 + // Delay to test with an already completed print in PulseLevelingTest. + //testRunner.Delay(5); - testRunner.ClickByName("Cancel Wizard Button"); + // Race condition: Print may complete by itself at any time. + for (; ; ) + { + if (testRunner.NamedWidgetExists("Print Progress Dial") + && testRunner.GetWidgetsByName("Stop Task Button", secondsToWait: 0).FirstOrDefault()?.Widget is GuiWidget widgetStopTask) + { + System.Console.WriteLine("CancelPrint finishing by stopping task."); + testRunner.ClickWidget(widgetStopTask); + } + + if (testRunner.GetWidgetsByName("Cancel Wizard Button", secondsToWait: 0).FirstOrDefault()?.Widget is GuiWidget widgetClose) + { + System.Console.WriteLine("CancelPrint confirming completed print."); + testRunner.ClickWidget(widgetClose); + break; + } + + testRunner.Delay(); + } return testRunner; } @@ -549,7 +599,7 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.ClickByName("Hardware Tab") .ClickByName("Import Printer Button"); - string profilePath = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "TestProfiles", profileName + ".printer"); + string profilePath = GetPathToRootRelative("Tests", "TestData", "TestProfiles", profileName + ".printer"); // Apply filter testRunner.ClickByName("Profile Path Widget") // Continue to next page @@ -621,7 +671,7 @@ namespace MatterHackers.MatterControl.Tests.Automation /// public static void OverrideAppDataLocation(string matterControlDirectory) { - string tempFolderPath = Path.Combine(matterControlDirectory, "Tests", "temp", runName, $"Test{testID++}"); + string tempFolderPath = Path.Combine(matterControlDirectory, "Tests", "temp", runName, Path.GetRandomFileName()); ApplicationDataStorage.Instance.OverrideAppDataLocation(tempFolderPath, () => DesktopSqlite.CreateInstance()); } @@ -647,7 +697,7 @@ namespace MatterHackers.MatterControl.Tests.Automation // Create empty TestParts folder Directory.CreateDirectory(queueData); - string queueItemsDirectory = TestContext.CurrentContext.ResolveProjectPath(5, "MatterControl", "Tests", "TestData", "QueueItems", queueItemFolderToLoad); + string queueItemsDirectory = GetPathToRootRelative("..", "MatterControl", "Tests", "TestData", "QueueItems", queueItemFolderToLoad); foreach (string file in Directory.GetFiles(queueItemsDirectory)) { @@ -915,7 +965,7 @@ namespace MatterHackers.MatterControl.Tests.Automation public static async Task RunTest( AutomationTest testMethod, string staticDataPathOverride = null, - double maxTimeToRun = 60, + double maxTimeToRun = 120, QueueTemplate queueItemFolderToAdd = QueueTemplate.None, int overrideWidth = -1, int overrideHeight = -1, @@ -928,19 +978,15 @@ namespace MatterHackers.MatterControl.Tests.Automation if (staticDataPathOverride == null) { // Popping one directory above MatterControl, then back down into MatterControl ensures this works in MCCentral as well and MatterControl - staticDataPathOverride = TestContext.CurrentContext.ResolveProjectPath(5, "MatterControl", "StaticData"); + staticDataPathOverride = StaticDataPath; + Assert.True(Directory.Exists(staticDataPathOverride)); } -#if DEBUG - string outputDirectory = "Debug"; -#else - string outputDirectory = "Release"; -#endif - - Environment.CurrentDirectory = TestContext.CurrentContext.ResolveProjectPath(5, "MatterControl", "bin", outputDirectory); + Environment.CurrentDirectory = MainBinOutputPath; + Assert.True(Directory.Exists(Environment.CurrentDirectory)); // 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__ @@ -948,7 +994,7 @@ namespace MatterHackers.MatterControl.Tests.Automation StaticData.RootPath = staticDataPathOverride; #endif // Popping one directory above MatterControl, then back down into MatterControl ensures this works in MCCentral as well and MatterControl - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(5, "MatterControl")); + MatterControlUtilities.OverrideAppDataLocation(RootPath); if (queueItemFolderToAdd != QueueTemplate.None) { @@ -957,7 +1003,7 @@ namespace MatterHackers.MatterControl.Tests.Automation if (defaultTestImages == null) { - defaultTestImages = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "TestImages"); + defaultTestImages = GetPathToRootRelative("Tests", "TestData", "TestImages"); } UserSettings.Instance.set(UserSettingsKey.ThumbnailRenderingMode, "orthographic"); @@ -987,6 +1033,11 @@ namespace MatterHackers.MatterControl.Tests.Automation overrideWidth == -1 ? width : overrideWidth, overrideHeight == -1 ? height : overrideHeight); + // Stop parallel UI tests fighting over platform UI focus. + IPlatformWindow.EnablePlatformWindowInput = false; + + rootSystemWindow.Title += " - " + testMethod.GetMethodInfo().Name; + OemSettings.Instance.ShowShopButton = false; if (!config.UseAutomationMouse) @@ -1044,19 +1095,9 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.ClickByName("Move Menu Item"); } - public static string ResolveProjectPath(this TestContext context, int stepsToProjectRoot, params string[] relativePathSteps) + private static string ResolveProjectPath(string[] relativePathPieces, [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = null) { - string assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - - var allPathSteps = new List { assemblyPath }; - allPathSteps.AddRange(Enumerable.Repeat("..", stepsToProjectRoot)); - - if (relativePathSteps.Any()) - { - allPathSteps.AddRange(relativePathSteps); - } - - return Path.GetFullPath(Path.Combine(allPathSteps.ToArray())); + return Path.GetFullPath(Path.Combine(Path.GetDirectoryName(sourceFilePath), Path.Combine(relativePathPieces))); } /// @@ -1324,10 +1365,24 @@ namespace MatterHackers.MatterControl.Tests.Automation var category = group.Category; // Click tab - testRunner.ClickByName(category.Name + " SliceSettingsTab"); + var foundWidget = testRunner.GetWidgetByName(category.Name + " SliceSettingsTab", out _, 1.0); + if (foundWidget == null) + { + // turn on advanced mode and try to get it again + testRunner.ClickByName("Slice Settings Overflow Menu") + .ClickByName("Advanced Menu Item"); + foundWidget = testRunner.GetWidgetByName(category.Name + " SliceSettingsTab", out _, 1.0); + //if (foundWidget == null) + //{ + // System.Diagnostics.Debugger.Launch(); + // System.Diagnostics.Debugger.Break(); + //} + } + + testRunner.ClickWidget(foundWidget); // Open the subGroup if required - var foundWidget = testRunner.GetWidgetByName(group.Name + " Panel", out _, .1); + foundWidget = testRunner.GetWidgetByName(group.Name + " Panel", out _, .1); if (foundWidget == null) { // turn on advanced mode and try to get it again @@ -1467,7 +1522,7 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.InvokeLibraryAddDialog(); // Generate the full, quoted paths for the requested assets - string fullQuotedAssetPaths = string.Join(" ", assetNames.Select(name => $"\"{MatterControlUtilities.GetTestItemPath(name)}\"")); + string fullQuotedAssetPaths = string.Join(";", assetNames.Select(name => $"\"{MatterControlUtilities.GetTestItemPath(name)}\"")); testRunner.CompleteDialog(fullQuotedAssetPaths); // Assert that the added items *are* in the list diff --git a/Tests/MatterControl.Tests/MatterControl/MeshRebuildTests.cs b/Tests/MatterControl.Tests/MatterControl/MeshRebuildTests.cs index b978c43bf..85b94c1ec 100644 --- a/Tests/MatterControl.Tests/MatterControl/MeshRebuildTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/MeshRebuildTests.cs @@ -45,8 +45,8 @@ namespace MatterHackers.PolygonMesh.UnitTests { public void SetupEvnironment() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); // Automation runner must do as much as program.cs to spin up platform string platformFeaturesProvider = "MatterHackers.MatterControl.WindowsPlatformsFeatures, MatterControl.Winforms"; @@ -76,8 +76,8 @@ namespace MatterHackers.PolygonMesh.UnitTests { public void SetupEvnironment() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); // Automation runner must do as much as program.cs to spin up platform string platformFeaturesProvider = "MatterHackers.MatterControl.WindowsPlatformsFeatures, MatterControl.Winforms"; diff --git a/Tests/MatterControl.Tests/MatterControl/OemProfileTests.cs b/Tests/MatterControl.Tests/MatterControl/OemProfileTests.cs index c15ed6838..fc3d57c6c 100644 --- a/Tests/MatterControl.Tests/MatterControl/OemProfileTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/OemProfileTests.cs @@ -9,6 +9,7 @@ using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.MatterControl.Tests.Automation; using Newtonsoft.Json; using NUnit.Framework; +using TestInvoker; namespace MatterControl.Tests.MatterControl { @@ -16,7 +17,7 @@ namespace MatterControl.Tests.MatterControl public class OemProfileTests { private static List allPrinters; - private static string printerSettingsDirectory = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData", "Profiles"); + private static string printerSettingsDirectory = Path.Combine(MatterControlUtilities.StaticDataPath, "Profiles"); private string pauseGCode = @"M76 ; pause print timer G91 @@ -63,8 +64,8 @@ M300 S3000 P30 ; Resume Tone"; static OemProfileTests() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); allPrinters = (from printerFile in new DirectoryInfo(printerSettingsDirectory).GetFiles("*.printer", SearchOption.AllDirectories) select new PrinterTestDetails @@ -77,14 +78,14 @@ M300 S3000 P30 ; Resume Tone"; }).ToList(); } - [Test, RunInApplicationDomain] + [Test, ChildProcessTest] public void ModifyPulsePrinterProfilesSettings() { // This is not really a test. It updaets our profiles with new settings. return; - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); string profilePath = @"C:\\Users\\LarsBrubaker\\Downloads\\Pulse E Profiles"; allPrinters = (from printerFile in new DirectoryInfo(profilePath).GetFiles("*.printer", SearchOption.TopDirectoryOnly) @@ -188,10 +189,10 @@ M300 S3000 P30 ; Resume Tone"; int a = 0; } - [Test, RunInApplicationDomain] + [Test, ChildProcessTest] public void AllMaterialsLibraryHasGoodProfiles() { - var materialSettingsDirectory = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData", "Materials"); + var materialSettingsDirectory = Path.Combine(MatterControlUtilities.StaticDataPath, "Materials"); var directoryInfo = new DirectoryInfo(materialSettingsDirectory); var files = directoryInfo.GetFiles("*.material", SearchOption.AllDirectories); var profiles = files.Select(f => PrinterSettings.LoadFile(f.FullName)).ToList(); @@ -265,7 +266,7 @@ M300 S3000 P30 ; Resume Tone"; } - [Test, RunInApplicationDomain] + [Test, ChildProcessTest] public void LayerGCodeHasExpectedValue() { // Verifies "layer_gcode" is expected value: "; LAYER:[layer_num]" diff --git a/Tests/MatterControl.Tests/MatterControl/PathTests.cs b/Tests/MatterControl.Tests/MatterControl/PathTests.cs index 83b57b1ae..7eaf80300 100644 --- a/Tests/MatterControl.Tests/MatterControl/PathTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/PathTests.cs @@ -36,16 +36,17 @@ using MatterHackers.MatterControl; using MatterHackers.MatterControl.DataStorage; using MatterHackers.MatterControl.Tests.Automation; using NUnit.Framework; +using TestInvoker; namespace MatterControl.Tests.MatterControl { - [TestFixture, RunInApplicationDomain, Apartment(ApartmentState.STA)] + [TestFixture, Parallelizable(ParallelScope.Children)] public class PathTests { - [Test] + [Test, ChildProcessTest] public Task CacheablePathTest() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); + StaticData.RootPath = StaticData.RootPath = MatterControlUtilities.StaticDataPath; string path = ApplicationController.CacheablePath("scope", "key.file"); @@ -57,10 +58,10 @@ namespace MatterControl.Tests.MatterControl return Task.CompletedTask; } - [Test] + [Test, ChildProcessTest] public Task CacheDirectoryTest() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; string path = ApplicationDataStorage.Instance.CacheDirectory; @@ -72,10 +73,10 @@ namespace MatterControl.Tests.MatterControl return Task.CompletedTask; } - [Test] + [Test, ChildProcessTest] public Task TempPathTest() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; string path = ApplicationDataStorage.Instance.ApplicationTempDataPath; diff --git a/Tests/MatterControl.Tests/MatterControl/PopupAnchorTests.cs b/Tests/MatterControl.Tests/MatterControl/PopupAnchorTests.cs index 87660b2a4..60bea8b0d 100644 --- a/Tests/MatterControl.Tests/MatterControl/PopupAnchorTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/PopupAnchorTests.cs @@ -12,20 +12,22 @@ using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.MatterControl.Tests.Automation; using MatterHackers.VectorMath; using NUnit.Framework; +using TestInvoker; namespace MatterControl.Tests.MatterControl { - [TestFixture, Category("PopupAnchorTests"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + // NOTE: These tests hang on GLFW currently as the window isn't closed properly. + [TestFixture, Category("PopupAnchorTests"), Parallelizable(ParallelScope.Children)] public class PopupAnchorTests { [SetUp] public void TestSetup() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); } - [Test] + [Test, ChildProcessTest] public async Task WindowTest() { var systemWindow = new PopupsTestWindow(700, 300) @@ -77,7 +79,7 @@ namespace MatterControl.Tests.MatterControl }, 30); } - [Test] + [Test, ChildProcessTest] public async Task TopBottomPopupTest() { var systemWindow = new PopupsTestWindow(800, 600) @@ -113,7 +115,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public async Task TopTopPopupTest() { var systemWindow = new PopupsTestWindow(800, 600) @@ -149,7 +151,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public async Task BottomTopPopupTest() { var systemWindow = new PopupsTestWindow(800, 600) @@ -185,7 +187,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public async Task BottomBottomPopupTest() { var systemWindow = new PopupsTestWindow(800, 600) @@ -222,7 +224,7 @@ namespace MatterControl.Tests.MatterControl } // Redirect down to up - [Test] + [Test, ChildProcessTest] public async Task BottomTopUpRedirectTest() { var systemWindow = new PopupsTestWindow(800, 600) @@ -264,7 +266,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public async Task TopTopUpRedirectTest() { var systemWindow = new PopupsTestWindow(800, 600) @@ -308,7 +310,7 @@ namespace MatterControl.Tests.MatterControl // Redirect up to down - [Test] + [Test, ChildProcessTest] public async Task BottomTopDownRedirectTest() { var systemWindow = new PopupsTestWindow(800, 600) @@ -350,7 +352,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public async Task TopTopDownRedirectTest() { var systemWindow = new PopupsTestWindow(800, 600) @@ -393,7 +395,7 @@ namespace MatterControl.Tests.MatterControl } // Redirect left to right - [Test] + [Test, ChildProcessTest] public async Task LeftRightRedirectTest() { var systemWindow = new PopupsTestWindow(800, 600) @@ -447,7 +449,7 @@ namespace MatterControl.Tests.MatterControl } // Redirect right to left - [Test] + [Test, ChildProcessTest] public async Task RightLeftRedirectTest() { var systemWindow = new PopupsTestWindow(800, 600) diff --git a/Tests/MatterControl.Tests/MatterControl/PrinterConfigurationTests.cs b/Tests/MatterControl.Tests/MatterControl/PrinterConfigurationTests.cs index 249b00f50..82d4491da 100644 --- a/Tests/MatterControl.Tests/MatterControl/PrinterConfigurationTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/PrinterConfigurationTests.cs @@ -17,7 +17,7 @@ namespace MatterControl.Tests.MatterControl [Test, Category("PrinterConfigurationFiles"), Ignore("Not Finished/previously ignored")] public void PrinterConfigTests() { - string staticDataPath = TestContext.CurrentContext.ResolveProjectPath(5, "MatterControl", "StaticData"); + string staticDataPath = MatterControlUtilities.StaticDataPath; StaticData.RootPath = staticDataPath; diff --git a/Tests/MatterControl.Tests/MatterControl/PrinterSettingsTests.cs b/Tests/MatterControl.Tests/MatterControl/PrinterSettingsTests.cs index 5c88091c2..120644293 100644 --- a/Tests/MatterControl.Tests/MatterControl/PrinterSettingsTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/PrinterSettingsTests.cs @@ -17,8 +17,8 @@ namespace MatterControl.Tests.MatterControl [Test] public void StartGCodeHasHeating() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); var printer = new PrinterConfig(new PrinterSettings()); printer.Settings.Slicer = new EngineMappingsMatterSlice(); @@ -70,8 +70,8 @@ namespace MatterControl.Tests.MatterControl [Test] public void ExpectedPropertiesOnlyTest() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); var expectedProperties = new HashSet( new[] diff --git a/Tests/MatterControl.Tests/MatterControl/PrinterWhiteListTests.cs b/Tests/MatterControl.Tests/MatterControl/PrinterWhiteListTests.cs index 386b50efb..faae6fa06 100644 --- a/Tests/MatterControl.Tests/MatterControl/PrinterWhiteListTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/PrinterWhiteListTests.cs @@ -11,7 +11,7 @@ namespace MatterControl.Tests.MatterControl [Test, Category("PrinterWhiteListTests")] public void DesktopCalibrationPartsInSettings() { - string settingsJsonPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData", "OEMSettings", "Settings.json"); + string settingsJsonPath = Path.Combine(MatterControlUtilities.StaticDataPath, "OEMSettings", "Settings.json"); if (File.Exists(settingsJsonPath)) { @@ -27,7 +27,7 @@ namespace MatterControl.Tests.MatterControl [Test, Category("SamplePartsTests")] public void DesktopCalibrationPartsExist() { - string samplePartsPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData", "OEMSettings", "SampleParts"); + string samplePartsPath = Path.Combine(MatterControlUtilities.StaticDataPath, "OEMSettings", "SampleParts"); string[] files = Directory.GetFiles(samplePartsPath); bool hasPhil = files.Where(l => l.Contains("Phil A Ment.stl")).Any(); Assert.IsTrue(hasPhil, "Expected Phil file not found"); diff --git a/Tests/MatterControl.Tests/MatterControl/ReleaseBuildTests.cs b/Tests/MatterControl.Tests/MatterControl/ReleaseBuildTests.cs index 5ea8030b5..4f8f1ce6e 100644 --- a/Tests/MatterControl.Tests/MatterControl/ReleaseBuildTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/ReleaseBuildTests.cs @@ -12,15 +12,16 @@ using System.Xml.Linq; using System.Threading.Tasks; using System.Threading; using MatterHackers.MatterControl; +using TestInvoker; namespace MatterControl.Tests { - [TestFixture, Apartment(ApartmentState.STA), RunInApplicationDomain] + [TestFixture, Parallelizable(ParallelScope.Children)] public class ReleaseBuildTests { private static Type debuggableAttribute = typeof(DebuggableAttribute); - [Test, Category("ReleaseQuality")] + [Test, ChildProcessTest, Category("ReleaseQuality")] public void MatterControlAssemblyIsOptimized() { #if (!DEBUG) @@ -28,15 +29,9 @@ namespace MatterControl.Tests #endif } - [Test, Category("ReleaseQuality")] + [Test, ChildProcessTest, Category("ReleaseQuality")] public void MatterControlKnownAssembliesAreOptimized() { -#if DEBUG - string configuration = "Debug"; -#else - string configuration = "Release"; -#endif - //MatterHackers.RenderOpenGl.dll // This list can be refreshed via the rebuildDependencies() helper function below @@ -56,7 +51,9 @@ namespace MatterControl.Tests foreach (string assemblyName in knownAssemblies.Split('\n').Select(s => s.Trim())) { - var assemblyPath = TestContext.CurrentContext.ResolveProjectPath(4, "bin", configuration, assemblyName); + var assemblyPath = Path.Combine(MatterControlUtilities.MainBinOutputPath, assemblyName); + + // Missing/renamed assemblies should fail the test and force a correction Assert.IsTrue(File.Exists(assemblyPath), "Assembly missing: " + assemblyPath); @@ -90,7 +87,7 @@ namespace MatterControl.Tests } #if !__ANDROID__ - [Test] + [Test, ChildProcessTest] public async Task MatterControlRuns() { await MatterControlUtilities.RunTest((testRunner) => @@ -104,7 +101,7 @@ namespace MatterControl.Tests } #endif - [Test, Category("ReleaseQuality")] + [Test, ChildProcessTest, Category("ReleaseQuality")] public void MatterControlDependenciesAreOptimized() { #if (!DEBUG) @@ -125,7 +122,7 @@ namespace MatterControl.Tests #endif } - [Test, Category("ReleaseQuality")] + [Test, ChildProcessTest, Category("ReleaseQuality")] public void ClassicDebugComplicationFlagTests() { #if (!DEBUG) diff --git a/Tests/MatterControl.Tests/MatterControl/SettingsParseTests.cs b/Tests/MatterControl.Tests/MatterControl/SettingsParseTests.cs index e33f5835f..07468fce5 100644 --- a/Tests/MatterControl.Tests/MatterControl/SettingsParseTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/SettingsParseTests.cs @@ -20,8 +20,8 @@ namespace MatterControl.Tests.MatterControl [Test] public void Check3PointLevelingPositions() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); var printer = new PrinterConfig(new PrinterSettings()); var levelingSolution = new LevelWizard3Point(printer); @@ -41,7 +41,8 @@ namespace MatterControl.Tests.MatterControl [Test] public void SupportInterfaceMaterialAssignedToExtruderOne() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); // first_layer_extrusion_width { @@ -90,8 +91,8 @@ namespace MatterControl.Tests.MatterControl // Validates that all SetSettingsOnChange linked fields exist and have their required TargetSetting and Value definitions public void LinkedSettingsExist() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); var settingsByName = PrinterSettings.SettingsData; var allSettings = settingsByName.Values; @@ -112,8 +113,8 @@ namespace MatterControl.Tests.MatterControl [Test] public void PresentationNamesLackColon() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); var allSettings = PrinterSettings.SettingsData.Values; diff --git a/Tests/MatterControl.Tests/MatterControl/SliceSettingsFieldTests.cs b/Tests/MatterControl.Tests/MatterControl/SliceSettingsFieldTests.cs index 1298bcbfb..cde545f0e 100644 --- a/Tests/MatterControl.Tests/MatterControl/SliceSettingsFieldTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/SliceSettingsFieldTests.cs @@ -45,6 +45,7 @@ using MatterHackers.MatterControl.Tests.Automation; using MatterHackers.SerialPortCommunication.FrostedSerial; using NUnit.Framework; using static MatterControl.Tests.MatterControl.SliceSettingsFieldTests; +using TestInvoker; namespace MatterControl.Tests.MatterControl { @@ -62,17 +63,18 @@ namespace MatterControl.Tests.MatterControl } } - [TestFixture, Category("SliceSettingsTests"), RunInApplicationDomain, Apartment(ApartmentState.STA)] + // NOTE: These tests hang on GLFW currently as the window isn't closed properly. + [TestFixture, Category("SliceSettingsTests"), Parallelizable(ParallelScope.Children)] public class SliceSettingsFieldTests { [SetUp] public void TestSetup() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); } - [Test] + [Test, ChildProcessTest] public Task TestExistsForEachUIFieldType() { var testClass = this.GetType(); @@ -96,7 +98,7 @@ namespace MatterControl.Tests.MatterControl return Task.CompletedTask; } - [Test] + [Test, ChildProcessTest] public async Task DoubleFieldTest() { var theme = MatterHackers.MatterControl.AppContext.Theme; @@ -105,7 +107,7 @@ namespace MatterControl.Tests.MatterControl await ValidateAgainstValueMap( testField, theme, - (field) => (field.Content as MHNumberEdit).ActuallNumberEdit.Text, + (field) => (field.Content as ThemedNumberEdit).ActuallNumberEdit.Text, new List() { { "0.12345", "0.12345" }, @@ -127,7 +129,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public async Task PositiveDoubleFieldTest() { var theme = MatterHackers.MatterControl.AppContext.Theme; @@ -136,7 +138,7 @@ namespace MatterControl.Tests.MatterControl await ValidateAgainstValueMap( testField, theme, - (field) => (field.Content as MHNumberEdit).ActuallNumberEdit.Text, + (field) => (field.Content as ThemedNumberEdit).ActuallNumberEdit.Text, new List() { { "0.12345", "0.12345" }, @@ -158,7 +160,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public async Task IntFieldTest() { var theme = MatterHackers.MatterControl.AppContext.Theme; @@ -167,7 +169,7 @@ namespace MatterControl.Tests.MatterControl await ValidateAgainstValueMap( testField, theme, - (field) => (field.Content as MHNumberEdit).ActuallNumberEdit.Text, + (field) => (field.Content as ThemedNumberEdit).ActuallNumberEdit.Text, new List() { { "0.12345", "0" }, @@ -189,7 +191,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public async Task DoubleOrPercentFieldTest() { var theme = MatterHackers.MatterControl.AppContext.Theme; @@ -198,7 +200,7 @@ namespace MatterControl.Tests.MatterControl await ValidateAgainstValueMap( testField, theme, - (field) => (field.Content as MHTextEditWidget).ActualTextEditWidget.Text, + (field) => (field.Content as ThemedTextEditWidget).ActualTextEditWidget.Text, new List() { { "0.12345", "0.12345" }, @@ -235,7 +237,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public async Task IntOrMmFieldTest() { var theme = MatterHackers.MatterControl.AppContext.Theme; @@ -244,7 +246,7 @@ namespace MatterControl.Tests.MatterControl await ValidateAgainstValueMap( testField, theme, - (field) => (field.Content as MHTextEditWidget).ActualTextEditWidget.Text, + (field) => (field.Content as ThemedTextEditWidget).ActualTextEditWidget.Text, new List() { { "0.12345", "0" }, @@ -281,7 +283,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public void CorrectStyleForSettingsRow() { var settings = new PrinterSettings(); @@ -345,7 +347,7 @@ namespace MatterControl.Tests.MatterControl settings.MaterialLayer.Remove(key); } - [Test] + [Test, ChildProcessTest] public void RightClickMenuWorksOnSliceSettings() { PrinterSettings.SliceEngines["MatterSlice"] = new EngineMappingsMatterSlice(); @@ -411,50 +413,51 @@ namespace MatterControl.Tests.MatterControl testRunner.RightClickByName(GetSliceSettingsField(setting)); if (selectsOnFocus) { - testRunner.Delay(); // wait a moment for the selection - Assert.IsTrue(!string.IsNullOrEmpty(textWidget.Selection), "Should have selection"); + testRunner.Assert(() => !string.IsNullOrEmpty(textWidget.Selection), "Should have selection"); } else { - Assert.IsTrue(string.IsNullOrEmpty(textWidget.Selection), "Should not have selection"); + testRunner.Assert(() => string.IsNullOrEmpty(textWidget.Selection), "Should not have selection"); } - testRunner.ClickByName("Select All Menu Item") - .Delay(); - Assert.IsTrue(textWidget.Selection == textWidget.Text, "Everything is selected"); + testRunner + .ClickByName("Select All Menu Item") + .Assert(() => textWidget.Selection == textWidget.Text, "Everything is selected"); // make sure there is no text in the copy buffer Clipboard.Instance.SetText(""); // copy text out and make sure we get it - testRunner.RightClickByName(GetSliceSettingsField(setting)); - Assert.IsTrue(textWidget.Selection == textWidget.Text, "Selection remains after right click"); - testRunner.ClickByName("Copy Menu Item"); - Assert.AreEqual(Clipboard.Instance.GetText(), textWidget.Text, "Copied everything"); + testRunner + .RightClickByName(GetSliceSettingsField(setting)) + .Assert(() => textWidget.Selection == textWidget.Text, "Selection remains after right click") + .ClickByName("Copy Menu Item") + .Assert(() => Clipboard.Instance.GetText() == textWidget.Text, "Copied everything"); // past in text and make sure it changed Clipboard.Instance.SetText(pastText); - testRunner.RightClickByName(GetSliceSettingsField(setting)) - .ClickByName("Paste Menu Item"); - Assert.AreEqual(pastText, textWidget.Text, "Pasted everything"); + testRunner + .RightClickByName(GetSliceSettingsField(setting)) + .ClickByName("Paste Menu Item") + .Assert(() => pastText == textWidget.Text, "Pasted everything"); // make sure we lose selection if we click off the menu // cut works - testRunner.RightClickByName(GetSliceSettingsField(setting)) + testRunner + .RightClickByName(GetSliceSettingsField(setting)) .ClickByName("Select All Menu Item") - .Delay(); - Assert.IsTrue(textWidget.Selection == textWidget.Text, "Everything is selected"); + .Assert(() => textWidget.Selection == textWidget.Text, "Everything is selected"); - testRunner.RightClickByName(GetSliceSettingsField(setting)); - Assert.IsTrue(textWidget.Selection == textWidget.Text, "Selection remains after right click"); + testRunner + .RightClickByName(GetSliceSettingsField(setting)) + .Assert(() => textWidget.Selection == textWidget.Text, "Selection remains after right click"); var preCutText = textWidget.Text; - testRunner.ClickByName("Cut Menu Item"); - // loose the selection - testRunner.ClickByName("Main Window") - .Delay(); - Assert.AreEqual(postCutAll, textWidget.Text, "Cut everything"); - Assert.AreEqual(preCutText, Clipboard.Instance.GetText(), "Cut everything"); + testRunner + .ClickByName("Cut Menu Item") + .ClickByName("Main Window") // loose the selection + .Assert(() => postCutAll == textWidget.Text, "Cut everything") + .Assert(() => preCutText == Clipboard.Instance.GetText(), "Cut everything"); } // testRunner.Delay(2000); @@ -476,7 +479,7 @@ namespace MatterControl.Tests.MatterControl return $"{settingData.PresentationName} Field"; } - [Test] + [Test, ChildProcessTest] public async Task ComPortFieldTest() { FrostedSerialPort.MockPortsForTest = true; @@ -535,7 +538,7 @@ namespace MatterControl.Tests.MatterControl Assert.Fail(); } - [Test] + [Test, ChildProcessTest] public async Task MultilineStringFieldTest() { var theme = MatterHackers.MatterControl.AppContext.Theme; @@ -545,7 +548,7 @@ namespace MatterControl.Tests.MatterControl await ValidateAgainstValueMap( testField, theme, - (field) => (field.Content as MHTextEditWidget).ActualTextEditWidget.Text, + (field) => (field.Content as ThemedTextEditWidget).ActualTextEditWidget.Text, new List() { { "0.12345", "0.12345" }, @@ -567,7 +570,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public async Task Vector2FieldTest() { var theme = MatterHackers.MatterControl.AppContext.Theme; @@ -579,7 +582,7 @@ namespace MatterControl.Tests.MatterControl theme, (field) => { - return string.Join(",", field.Content.Children.OfType().Select(w => w.ActuallNumberEdit.Text).ToArray()); + return string.Join(",", field.Content.Children.OfType().Select(w => w.ActuallNumberEdit.Text).ToArray()); }, new List() { @@ -591,7 +594,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public async Task Vector3FieldTest() { var theme = MatterHackers.MatterControl.AppContext.Theme; @@ -603,7 +606,7 @@ namespace MatterControl.Tests.MatterControl theme, (field) => { - return string.Join(",", field.Content.Children.OfType().Select(w => w.ActuallNumberEdit.Text).ToArray()); + return string.Join(",", field.Content.Children.OfType().Select(w => w.ActuallNumberEdit.Text).ToArray()); }, new List() { @@ -615,7 +618,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public async Task Vector4FieldTest() { var theme = MatterHackers.MatterControl.AppContext.Theme; @@ -629,7 +632,7 @@ namespace MatterControl.Tests.MatterControl theme, (field) => { - return string.Join(",", field.Content.Children.OfType().Select(w => w.ActuallNumberEdit.Text).ToArray()); + return string.Join(",", field.Content.Children.OfType().Select(w => w.ActuallNumberEdit.Text).ToArray()); }, new List() { @@ -641,7 +644,7 @@ namespace MatterControl.Tests.MatterControl }); } - [Test] + [Test, ChildProcessTest] public async Task BoundsFieldTest() { var theme = MatterHackers.MatterControl.AppContext.Theme; @@ -653,7 +656,7 @@ namespace MatterControl.Tests.MatterControl theme, (field) => { - return string.Join(",", field.Content.Children.OfType().Select(w => w.ActuallNumberEdit.Text).ToArray()); + return string.Join(",", field.Content.Children.OfType().Select(w => w.ActuallNumberEdit.Text).ToArray()); }, new List() { @@ -671,7 +674,7 @@ namespace MatterControl.Tests.MatterControl Assert.Fail(); } - [Test] + [Test, ChildProcessTest] public async Task ExtruderOffsetFieldTest() { var theme = MatterHackers.MatterControl.AppContext.Theme; @@ -686,7 +689,7 @@ namespace MatterControl.Tests.MatterControl theme, (field) => { - return string.Join("x", field.Content.Descendants().Select(w => w.ActuallNumberEdit.Text).ToArray()); + return string.Join("x", field.Content.Descendants().Select(w => w.ActuallNumberEdit.Text).ToArray()); }, new List() { diff --git a/Tests/MatterControl.Tests/MatterControl/Slicing/SliceLayersTests.cs b/Tests/MatterControl.Tests/MatterControl/Slicing/SliceLayersTests.cs index c19283d38..71314cc28 100644 --- a/Tests/MatterControl.Tests/MatterControl/Slicing/SliceLayersTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/Slicing/SliceLayersTests.cs @@ -27,6 +27,7 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +using System.IO; using System.Threading; using MatterHackers.Agg.Platform; using MatterHackers.MatterControl.Tests.Automation; @@ -49,7 +50,8 @@ namespace MatterHackers.MatterControl.Slicing.Tests return; } - string meshFileName = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "TestMeshes", "SliceLayers", "Box20x20x10.stl"); + string meshFileName = Path.Combine(MatterControlUtilities.RootPath, "Tests", "TestData", "TestMeshes", "SliceLayers", "Box20x20x10.stl"); + Mesh cubeMesh = StlProcessing.Load(meshFileName, CancellationToken.None); AxisAlignedBoundingBox bounds = cubeMesh.GetAxisAlignedBoundingBox(); diff --git a/Tests/MatterControl.Tests/MatterControl/SupportGeneratorTests.cs b/Tests/MatterControl.Tests/MatterControl/SupportGeneratorTests.cs index bcd610d36..6b9438d73 100644 --- a/Tests/MatterControl.Tests/MatterControl/SupportGeneratorTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/SupportGeneratorTests.cs @@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project. */ using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -52,8 +53,8 @@ namespace MatterControl.Tests.MatterControl var minimumSupportHeight = .05; // Set the static data to point to the directory of MatterControl - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); // make a single cube in the air and ensure that support is generated // _________ @@ -311,8 +312,8 @@ namespace MatterControl.Tests.MatterControl var minimumSupportHeight = .05; // Set the static data to point to the directory of MatterControl - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); // make a single cube in the air and ensure that support is generated // _________ @@ -500,14 +501,14 @@ namespace MatterControl.Tests.MatterControl public async Task ComplexPartNoSupport() { // Set the static data to point to the directory of MatterControl - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); // load a complex part that should have no support required var minimumSupportHeight = .05; var scene = new InteractiveScene(); - var meshPath = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "TestParts", "NoSupportNeeded.stl"); + var meshPath = Path.Combine(MatterControlUtilities.RootPath, "Tests", "TestData", "TestParts", "NoSupportNeeded.stl"); var supportObject = new Object3D() { diff --git a/Tests/MatterControl.Tests/MatterControl/ToolChangeTests.cs b/Tests/MatterControl.Tests/MatterControl/ToolChangeTests.cs index 829151501..907706e1e 100644 --- a/Tests/MatterControl.Tests/MatterControl/ToolChangeTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/ToolChangeTests.cs @@ -46,20 +46,21 @@ using MatterHackers.PrinterEmulator; using MatterHackers.SerialPortCommunication.FrostedSerial; using MatterHackers.VectorMath; using NUnit.Framework; +using TestInvoker; namespace MatterControl.Tests.MatterControl.ToolChanges { - [TestFixture, Category("GCodeStream")] + [TestFixture, Category("GCodeStream"), Parallelizable(ParallelScope.Children)] public class ToolChangeTests { [SetUp] public void TestSetup() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); } - [Test] + [Test, ChildProcessTest] public async Task ToolChangeNoHeat() { var printer = ToolChangeTests.CreatePrinter(); @@ -117,7 +118,7 @@ namespace MatterControl.Tests.MatterControl.ToolChanges } // A test that proves that: T0, no move, T1, T0, move does not send switch extruder gcode - [Test] + [Test, ChildProcessTest] public async Task NoToolChangeIfNoMove() { var printer = ToolChangeTests.CreatePrinter(); @@ -141,12 +142,16 @@ namespace MatterControl.Tests.MatterControl.ToolChanges "G1 X10 Y10 Z10 F2500", // go to the position requested "G1 X11 Y11 Z11", // go to the position requested }; - Assert.AreEqual(expectedLines, sentLines); + Console.WriteLine("==="); + Console.WriteLine(String.Join("\n", sentLines)); + Console.WriteLine("==="); + Console.WriteLine(String.Join("\n", expectedLines)); + Assert.That(sentLines, Is.EqualTo(expectedLines).NoClip); } // A test that proves that: T0, no move, T1, temp set, T0, move does not send switch extruder gcode // but there is the correct extruder set, T1, then temp, than T0 - [Test] + [Test, ChildProcessTest] public async Task ToolChangeTempSetWithNoMove() { var printer = ToolChangeTests.CreatePrinter(); @@ -177,7 +182,7 @@ namespace MatterControl.Tests.MatterControl.ToolChanges Assert.AreEqual(expectedLines, sentLines); } - [Test] + [Test, ChildProcessTest] public async Task SetTempDirectSmoothie() { var printer = ToolChangeTests.CreatePrinter(); @@ -206,7 +211,7 @@ namespace MatterControl.Tests.MatterControl.ToolChanges Assert.AreEqual(expectedLines, sentLines); } - [Test] + [Test, ChildProcessTest] public async Task SetTempDirectMarlin() { var printer = ToolChangeTests.CreatePrinter(); @@ -237,7 +242,7 @@ namespace MatterControl.Tests.MatterControl.ToolChanges // A test that proves that: T0, no move, T1, extrude, T0, move does not send switch extruder gcode // but does switch to and back for extrude - [Test] + [Test, ChildProcessTest] public async Task NoMoveOnToolChangeButWithExtrude() { var printer = ToolChangeTests.CreatePrinter(); @@ -280,7 +285,7 @@ namespace MatterControl.Tests.MatterControl.ToolChanges Assert.AreEqual(expectedLines, sentLines); } - [Test] + [Test, ChildProcessTest] public async Task MarlinPrintingToolChanges() { var printer = ToolChangeTests.CreatePrinter(); @@ -329,7 +334,7 @@ namespace MatterControl.Tests.MatterControl.ToolChanges Assert.AreEqual(expectedLines, sentLines); } - [Test] + [Test, ChildProcessTest] public async Task ToolChangeTempAndSwitch() { var printer = ToolChangeTests.CreatePrinter(); @@ -385,7 +390,7 @@ namespace MatterControl.Tests.MatterControl.ToolChanges Assert.AreEqual(expectedLines, sentLines); } - [Test] + [Test, ChildProcessTest] public async Task ToolChangeWithCoolDown() { var printer = ToolChangeTests.CreatePrinter(); @@ -470,7 +475,7 @@ namespace MatterControl.Tests.MatterControl.ToolChanges Assert.AreEqual(expectedLines, sentLines); } - [Test] + [Test, ChildProcessTest] public async Task ToolChangeHeatOnlyT0() { var printer = ToolChangeTests.CreatePrinter(); @@ -496,7 +501,7 @@ namespace MatterControl.Tests.MatterControl.ToolChanges // cooling and heating } - [Test] + [Test, ChildProcessTest] public async Task ToolChangeHeatOnlyT1() { var printer = ToolChangeTests.CreatePrinter(); @@ -595,6 +600,11 @@ namespace MatterControl.Tests.MatterControl.ToolChanges // start a print printer.Connection.CommunicationState = CommunicationStates.PreparingToPrint; + + // NOTE: Test can sometimes fail due to resends if this happens too quickly, it seems. + // Extra commands were sent by: WriteRaw(allCheckSumLinesSent[currentLineIndexToSend++] + "\n", "resend"); + Thread.Sleep(1000); + await printer.Connection.StartPrint(inputStream, null, null, PrinterConnection.PrintingModes.Normal); // wait up to 40 seconds for the print to finish diff --git a/Tests/MatterControl.Tests/MatterControl/TranslationsTests.cs b/Tests/MatterControl.Tests/MatterControl/TranslationsTests.cs index a50f64a43..28d3d174a 100644 --- a/Tests/MatterControl.Tests/MatterControl/TranslationsTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/TranslationsTests.cs @@ -44,7 +44,8 @@ namespace MatterControl.Tests.MatterControl [TestFixture] public class TranslationsTests { - [Test, Category("Translations")] + // Culture-sensitive DateTime strings here. + [Test, Category("Translations"), SetCulture("")] public void RelativeFriendlyDatesTest() { { @@ -52,33 +53,33 @@ namespace MatterControl.Tests.MatterControl DateTime nowTime = new DateTime(2016, 05, 28, 15, 13, 37); DateTime testTime = nowTime.AddMinutes(-63); - Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.Today); - Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "2:10 PM"); + Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.Today); + Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "2:10 PM"); - testTime = nowTime.AddHours(-25); - Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.Yesterday); - Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "2:13 PM"); + testTime = nowTime.AddHours(-25); + Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.Yesterday); + Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "2:13 PM"); - testTime = nowTime.AddDays(-4); - Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.SameWeek); - Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "Tuesday 3:13 PM"); + testTime = nowTime.AddDays(-4); + Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.SameWeek); + Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "Tuesday 3:13 PM"); - testTime = nowTime.AddDays(-6); - Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.SameWeek); - Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "Sunday 3:13 PM"); + testTime = nowTime.AddDays(-6); + Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.SameWeek); + Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "Sunday 3:13 PM"); - testTime = nowTime.AddDays(-7); - Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.SameMonth); - Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "May 21, 3:13 PM"); + testTime = nowTime.AddDays(-7); + Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.SameMonth); + Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "May 21, 3:13 PM"); - testTime = nowTime.AddDays(-37); - Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.SameYear); - Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "April 21, 3:13 PM"); + testTime = nowTime.AddDays(-37); + Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.SameYear); + Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "April 21, 3:13 PM"); - testTime = nowTime.AddDays(-364); - Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.PastYear); - Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "2015 May 30, 3:13 PM"); - } + testTime = nowTime.AddDays(-364); + Assert.IsTrue(RelativeTime.GetTimeBlock(nowTime, testTime) == TimeBlock.PastYear); + Assert.IsTrue(RelativeTime.GetDetail(nowTime, testTime) == "2015 May 30, 3:13 PM"); + } // make a grouped list { @@ -112,7 +113,7 @@ namespace MatterControl.Tests.MatterControl [Test, Category("Translations")] public void EnglishLinesOnlyContainEnglishCharachters() { - string fullPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData", "Translations"); + string fullPath = Path.Combine(MatterControlUtilities.StaticDataPath, "Translations"); foreach (string directory in Directory.GetDirectories(fullPath)) { diff --git a/Tests/MatterControl.Tests/MatterControl/UIFieldTestWindow.cs b/Tests/MatterControl.Tests/MatterControl/UIFieldTestWindow.cs index 231d81e5f..b5abfe5d5 100644 --- a/Tests/MatterControl.Tests/MatterControl/UIFieldTestWindow.cs +++ b/Tests/MatterControl.Tests/MatterControl/UIFieldTestWindow.cs @@ -30,7 +30,6 @@ either expressed or implied, of the FreeBSD Project. using System; using MatterHackers.Agg; using MatterHackers.Agg.UI; -using MatterHackers.MatterControl; using MatterHackers.MatterControl.SlicerConfiguration; using NUnit.Framework; @@ -38,8 +37,8 @@ namespace MatterControl.Tests.MatterControl { public class UIFieldTestWindow : SystemWindow { - public MHTextEditWidget ExpectedText { get; } - public MHTextEditWidget InputText { get; } + public ThemedTextEditWidget ExpectedText { get; } + public ThemedTextEditWidget InputText { get; } private UIField field; @@ -77,7 +76,7 @@ namespace MatterControl.Tests.MatterControl Margin = new BorderDouble(right: 10, bottom: 2), }); - this.InputText = new MHTextEditWidget("", theme, pixelWidth: pixelWidth) + this.InputText = new ThemedTextEditWidget("", theme, pixelWidth: pixelWidth) { Margin = new BorderDouble(right: 8) }; @@ -94,7 +93,7 @@ namespace MatterControl.Tests.MatterControl Margin = new BorderDouble(right: 10, bottom: 2) }); - this.ExpectedText = new MHTextEditWidget("", theme, pixelWidth: pixelWidth) + this.ExpectedText = new ThemedTextEditWidget("", theme, pixelWidth: pixelWidth) { Margin = new BorderDouble(right: 8) }; diff --git a/Tests/MatterControl.Tests/Properties/AssemblyInfo.cs b/Tests/MatterControl.Tests/Properties/AssemblyInfo.cs index 2fb1e6a59..bbc2870b5 100644 --- a/Tests/MatterControl.Tests/Properties/AssemblyInfo.cs +++ b/Tests/MatterControl.Tests/Properties/AssemblyInfo.cs @@ -34,3 +34,6 @@ using System.Runtime.InteropServices; // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] + +// https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1416 +[assembly: System.Runtime.Versioning.SupportedOSPlatform("windows7.0")] \ No newline at end of file diff --git a/Tests/MatterControl.Tests/Properties/launchSettings.json b/Tests/MatterControl.Tests/Properties/launchSettings.json new file mode 100644 index 000000000..34d789256 --- /dev/null +++ b/Tests/MatterControl.Tests/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "MatterControl.Tests": { + "commandName": "Project", + "nativeDebugging": true + } + } +} \ No newline at end of file diff --git a/Tests/MatterControl.Tests/SceneTests.cs b/Tests/MatterControl.Tests/SceneTests.cs index c8045378e..3c6bfd06b 100644 --- a/Tests/MatterControl.Tests/SceneTests.cs +++ b/Tests/MatterControl.Tests/SceneTests.cs @@ -39,10 +39,11 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using TestInvoker; namespace MatterHackers.PolygonMesh.UnitTests { - [TestFixture, Category("Agg.PolygonMesh"), RunInApplicationDomain] + [TestFixture, Category("Agg.PolygonMesh"), Parallelizable(ParallelScope.Children)] public class SceneTests { private readonly int BlueMaterialIndex = 6; @@ -83,13 +84,13 @@ namespace MatterHackers.PolygonMesh.UnitTests public static string GetSceneTempPath(string folder) { - string tempPath = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "temp", folder); + string tempPath = Path.Combine(MatterControlUtilities.RootPath, "Tests", "temp", folder); Directory.CreateDirectory(tempPath); return tempPath; } - [Test] + [Test, ChildProcessTest] public void AmfFilesSaveObjectProperties() { AssetObject3D.AssetManager = new AssetManager(); @@ -141,7 +142,7 @@ namespace MatterHackers.PolygonMesh.UnitTests Assert.True(new AxisAlignedBoundingBox(20, -10, -10, 40, 10, 10).Equals(aabb2, .001)); } - [Test] + [Test, ChildProcessTest] public async Task AutoArrangeChildrenTests() { // arrange a single item around the origin @@ -228,7 +229,7 @@ namespace MatterHackers.PolygonMesh.UnitTests } } - [Test] + [Test, ChildProcessTest] public void CreatesAndLinksAmfsForUnsavedMeshes() { AssetObject3D.AssetManager = new AssetManager(); @@ -260,7 +261,7 @@ namespace MatterHackers.PolygonMesh.UnitTests Assert.IsTrue(meshItem.Mesh.Faces.Count > 0); } - [Test] + [Test, ChildProcessTest] public async Task ResavedSceneRemainsConsistent() { AssetObject3D.AssetManager = new AssetManager(); @@ -403,7 +404,7 @@ namespace MatterHackers.PolygonMesh.UnitTests return scene; } - [Test] + [Test, ChildProcessTest] public void SaveSimpleScene() { var scene = new InteractiveScene(); @@ -426,13 +427,13 @@ namespace MatterHackers.PolygonMesh.UnitTests [SetUp] public void SetupUserSettings() { - StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "MatterControl", "StaticData"); - MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4)); + StaticData.RootPath = MatterControlUtilities.StaticDataPath; + MatterControlUtilities.OverrideAppDataLocation(MatterControlUtilities.RootPath); UserSettings.Instance.set(UserSettingsKey.PublicProfilesSha, "0"); //Clears DB so we will download the latest list } - [Test] + [Test, ChildProcessTest] public void WorldColorBasicTest() { var scene = SampleScene(); @@ -465,7 +466,7 @@ namespace MatterHackers.PolygonMesh.UnitTests Assert.AreEqual(Color.Black, redItem.WorldColor(null), "WorldColor on Red with null param should be root color (Black)"); } - [Test] + [Test, ChildProcessTest] public void WorldFunctionNonExistingAncestorOverride() { var scene = SampleScene(); @@ -517,7 +518,7 @@ namespace MatterHackers.PolygonMesh.UnitTests Assert.AreEqual(this.RootOutputType, redItem.WorldOutputType(nonAncestor), "WorldOutputType on Red with non-ancestor should be RootOutputType"); } - [Test] + [Test, ChildProcessTest] public void WorldMaterialIndexBasicTest() { var scene = SampleScene(); @@ -550,7 +551,7 @@ namespace MatterHackers.PolygonMesh.UnitTests Assert.AreEqual(this.RootMaterialIndex, redItem.WorldMaterialIndex(null), "WorldMaterialIndex on Red with null param should be root color (RootMaterialIndex)"); } - [Test] + [Test, ChildProcessTest] public void WorldMatrixBasicTest() { var scene = SampleScene(); @@ -583,7 +584,7 @@ namespace MatterHackers.PolygonMesh.UnitTests Assert.AreEqual(this.RedMatrix * this.GroupMatrix * this.SuperGroupMatrix, redItem.WorldMatrix(null), "WorldMatrix on Red with null param should be root color (RootMatrix)"); } - [Test] + [Test, ChildProcessTest] public void WorldOutputTypeBasicTest() { var scene = SampleScene();