diff options
author | Tiago Conceição <Tiago_caza@hotmail.com> | 2022-05-21 02:59:28 +0300 |
---|---|---|
committer | Tiago Conceição <Tiago_caza@hotmail.com> | 2022-05-21 02:59:28 +0300 |
commit | 13ff766d05780ca195f7d373a4f6a583e7ac2f2d (patch) | |
tree | ba1886826f73d3f892c3365e2ac95e2717da8669 | |
parent | c800f887d2d50f9f34500c323f5cc8c750ef258b (diff) |
v3.4.3v3.4.3
- (Add) Information about the loaded file when copying from the about box
- (Improvement) Tools are now disabled on the menu if not supported by the file format once each file load (#476)
- (Fix) Tool - Edit tool parameters: Overlap label on "per layer override" mode (#478)
- (Fix) Corruption of `GZip` and `Deflate` layer compression methods
-rw-r--r-- | CHANGELOG.md | 9 | ||||
-rw-r--r-- | RELEASE_NOTES.md | 35 | ||||
-rw-r--r-- | UVtools.Core/Extensions/CompressionExtensions.cs | 132 | ||||
-rw-r--r-- | UVtools.Core/Extensions/EmguExtensions.cs | 35 | ||||
-rw-r--r-- | UVtools.Core/Layers/Layer.cs | 34 | ||||
-rw-r--r-- | UVtools.Core/Operations/OperationPattern.cs | 1 | ||||
-rw-r--r-- | UVtools.Core/UVtools.Core.csproj | 3 | ||||
-rw-r--r-- | UVtools.InstallerMM/UVtools.InstallerMM.wxs | 5 | ||||
-rw-r--r-- | UVtools.WPF/App.axaml.cs | 2 | ||||
-rw-r--r-- | UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs | 11 | ||||
-rw-r--r-- | UVtools.WPF/Controls/WindowEx.cs | 16 | ||||
-rw-r--r-- | UVtools.WPF/MainWindow.axaml.cs | 11 | ||||
-rw-r--r-- | UVtools.WPF/UVtools.WPF.csproj | 2 | ||||
-rw-r--r-- | UVtools.WPF/Windows/AboutWindow.axaml.cs | 10 | ||||
-rw-r--r-- | UVtools.WPF/Windows/MessageWindow.axaml.cs | 6 |
15 files changed, 235 insertions, 77 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 06bbe51..6397818 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,16 @@ # Changelog +## 21/05/2022 - v3.4.3 + +- (Add) Information about the loaded file when copying from the about box +- (Improvement) Tools are now disabled on the menu if not supported by the file format once each file load (#476) +- (Fix) Tool - Edit tool parameters: Overlap label on "per layer override" mode (#478) +- (Fix) Corruption of `GZip` and `Deflate` layer compression methods + ## 16/05/2022 - v3.4.2 - **Core:** - - (Add) Getter `FileFormat.DisplayPixelCount` Gets the display total number of pixels (ResolutionX * ResolutionY) + - (Add) Getter `FileFormat.DisplayPixelCount` Gets the display total number of pixels (`ResolutionX` * `ResolutionY`) - (Add) Getter `Layer.NonZeroPixelRatio` Gets the ratio between non zero pixels and display number of pixels - (Add) Getter `Layer.NonZeroPixelPercentage` Gets the percentage of non zero pixels relative to the display number of pixels - (Add) Getter `Layer.PreviousHeightLayer()` Gets the previous layer with a different height from the current, returns null if no previous layer diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index d889774..0e44f02 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,32 +1,5 @@ -- **Core:** - - (Add) Getter `FileFormat.DisplayPixelCount` Gets the display total number of pixels (ResolutionX * ResolutionY) - - (Add) Getter `Layer.NonZeroPixelRatio` Gets the ratio between non zero pixels and display number of pixels - - (Add) Getter `Layer.NonZeroPixelPercentage` Gets the percentage of non zero pixels relative to the display number of pixels - - (Add) Getter `Layer.PreviousHeightLayer()` Gets the previous layer with a different height from the current, returns null if no previous layer - - (Add) Getter `Layer.NextHeightLayer()` Gets the next layer with a different height from the current, returns null if no next layer - - (Add) Method `Layer.GetPreviousLayerWithAtLeastPixelCountOf()` Gets the previous layer matching at least a number of pixels, returns null if no previous layer - - (Add) Method `Layer.GetNextLayerWithAtLeastPixelCountOf()` Gets the next layer matching at least a number of pixels, returns null if no next layer - - (Add) Method `Operation.GetRoiOrVolumeBounds()` returns the selected ROI rectangle or model volume bounds rectangle - - (Add) Documentation around `Operation` methods - - (Fix) Open files in partial mode when the resolution is not defined would cause a `NullPointerException` (#474) -- **Suggestion: Wait time before cure** - - (Add) Proportional maximum time change: Sets the maximum allowed time difference relative to the previous layer (#471) - - (Add) Proportional mass get modes: Previous, Average and Maximum relative to a defined height (#471) - - (Change) Proportional set type sets fallback time to the first layer - - (Fix) Proportional set type was taking current layer mass instead of looking to the previous cured layer (#471) -- **Tools:** - - **Edit print parameters:** - - (Change) Incorporate the unit label into the numeric input box - - (Change) Allow TSMC speeds to be 0 as minimum value (#472) - - (Fix) PCB Exposure: The thumbnail has random noise around the image -- **Settings:** - - (Add) Tools: "Always prompt for confirmation before execute the operation" - - (Fix) Changing layer compression method when no file is loaded would cause a error -- **UI:** - - (Add) Holding Shift key while drag and drop a .uvtop file will try to execute the operation without showing the window or prompt - - (Add) Drag and drop a .cs or .csx file into UVtools will load and show the scripting dialog with the file selected -- (Add) Errors that crash application will now show an report window with the crash information and able to fast report them -- (Upgrade) AvaloniaUI from 0.10.13 to 0.10.14 -- (Upgrade) .NET from 6.0.4 to 6.0.5 -- +- (Add) Information about the loaded file when copying from the about box +- (Improvement) Tools are now disabled on the menu if not supported by the file format once each file load (#476) +- (Fix) Tool - Edit tool parameters: Overlap label on "per layer override" mode (#478) +- (Fix) Corruption of `GZip` and `Deflate` layer compression methods diff --git a/UVtools.Core/Extensions/CompressionExtensions.cs b/UVtools.Core/Extensions/CompressionExtensions.cs new file mode 100644 index 0000000..210c0e2 --- /dev/null +++ b/UVtools.Core/Extensions/CompressionExtensions.cs @@ -0,0 +1,132 @@ +/* + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ + +using System; +using System.IO; +using System.IO.Compression; +using System.Runtime.CompilerServices; +using Microsoft.Toolkit.HighPerformance; + +namespace UVtools.Core.Extensions +{ + public static class CompressionExtensions + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetGzipUncompressedLength(ReadOnlyMemory<byte> compressedData) + { + return BitConverter.ToInt32(compressedData.Slice(compressedData.Length - 4, 4).Span); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetGzipUncompressedLength(Stream stream) + { + Span<byte> uncompressedLength = stackalloc byte[4]; + stream.Position = stream.Length - 4; + stream.Read(uncompressedLength); + stream.Seek(0, SeekOrigin.Begin); + return BitConverter.ToInt32(uncompressedLength); + } + + public static MemoryStream GZipCompress(Stream inputStream, CompressionLevel compressionLevel, bool leaveStreamOpen = false) + { + if (inputStream.Position == inputStream.Length) { inputStream.Seek(0, SeekOrigin.Begin); } + + var compressedStream = new MemoryStream(); + using (var gzipStream = new GZipStream(compressedStream, compressionLevel, true)) + { + inputStream.CopyTo(gzipStream); + } + if (!leaveStreamOpen) { inputStream.Close(); } + + compressedStream.Seek(0, SeekOrigin.Begin); + return compressedStream; + } + + public static MemoryStream GZipCompress(byte[] inputStream, CompressionLevel compressionLevel) => + GZipCompress(new ReadOnlyMemory<byte>(inputStream).AsStream(), compressionLevel); + + public static byte[] GZipCompressToBytes(byte[] inputStream, CompressionLevel compressionLevel) + { + using var ms = GZipCompress(new ReadOnlyMemory<byte>(inputStream).AsStream(), compressionLevel); + return ms.ToArray(); + } + + + public static MemoryStream GZipDecompress(Stream compressedStream, bool leaveStreamOpen = false) + { + if (compressedStream.Position == compressedStream.Length) { compressedStream.Seek(0, SeekOrigin.Begin); } + + var uncompressedStream = new MemoryStream(GetGzipUncompressedLength(compressedStream)); + using var gzipStream = new GZipStream(compressedStream, CompressionMode.Decompress, leaveStreamOpen); + gzipStream.CopyTo(uncompressedStream); + + return uncompressedStream; + } + + public static ArraySegment<byte> GZipDecompress(ReadOnlyMemory<byte> compressedData) + { + using var uncompressedStream = new MemoryStream(GetGzipUncompressedLength(compressedData)); + using (var gzipStream = new GZipStream(compressedData.AsStream(), CompressionMode.Decompress, false)) + { + gzipStream.CopyTo(uncompressedStream); + } + + return uncompressedStream.TryGetBuffer(out var buffer) + ? buffer + : uncompressedStream.ToArray(); + } + + public static MemoryStream DeflateCompress(Stream inputStream, CompressionLevel compressionLevel, bool leaveStreamOpen = false) + { + if (inputStream.Position == inputStream.Length) { inputStream.Seek(0, SeekOrigin.Begin); } + + var compressedStream = new MemoryStream(); + using (var gzipStream = new DeflateStream(compressedStream, compressionLevel, true)) + { + inputStream.CopyTo(gzipStream); + } + if (!leaveStreamOpen) { inputStream.Close(); } + + compressedStream.Seek(0, SeekOrigin.Begin); + return compressedStream; + } + + public static MemoryStream DeflateCompress(byte[] inputStream, CompressionLevel compressionLevel) => + DeflateCompress(new ReadOnlyMemory<byte>(inputStream).AsStream(), compressionLevel); + + public static byte[] DeflateCompressToBytes(byte[] inputStream, CompressionLevel compressionLevel) + { + using var ms = DeflateCompress(new ReadOnlyMemory<byte>(inputStream).AsStream(), compressionLevel); + return ms.ToArray(); + } + + public static MemoryStream DeflateDecompress(Stream compressedStream, bool leaveStreamOpen = false) + { + if (compressedStream.Position == compressedStream.Length) { compressedStream.Seek(0, SeekOrigin.Begin); } + + var uncompressedStream = new MemoryStream(); + using var gzipStream = new DeflateStream(compressedStream, CompressionMode.Decompress, leaveStreamOpen); + gzipStream.CopyTo(uncompressedStream); + + return uncompressedStream; + } + + public static ArraySegment<byte> DeflateDecompress(ReadOnlyMemory<byte> compressedData) + { + using var uncompressedStream = new MemoryStream(); + using (var gzipStream = new DeflateStream(compressedData.AsStream(), CompressionMode.Decompress, false)) + { + gzipStream.CopyTo(uncompressedStream); + } + + return uncompressedStream.TryGetBuffer(out var buffer) + ? buffer + : uncompressedStream.ToArray(); + } + } +} diff --git a/UVtools.Core/Extensions/EmguExtensions.cs b/UVtools.Core/Extensions/EmguExtensions.cs index 833fd8d..4b75aea 100644 --- a/UVtools.Core/Extensions/EmguExtensions.cs +++ b/UVtools.Core/Extensions/EmguExtensions.cs @@ -13,7 +13,9 @@ using Emgu.CV.Structure; using Emgu.CV.Util; using System; using System.Drawing; +using System.IO; using System.Runtime.InteropServices; +using Microsoft.Toolkit.HighPerformance; using UVtools.Core.EmguCV; using UVtools.Core.Objects; @@ -169,6 +171,18 @@ public static class EmguExtensions #region Memory accessors /// <summary> + /// Gets the mat bytes as <see cref="UnmanagedMemoryStream"/> + /// </summary> + /// <param name="mat"></param> + /// <param name="accessMode"></param> + /// <returns></returns> + public static unsafe UnmanagedMemoryStream GetUnmanagedMemoryStream(this Mat mat, FileAccess accessMode) + { + var length = mat.GetLength(); + return new UnmanagedMemoryStream(mat.GetBytePointer(), length, length, accessMode); + } + + /// <summary> /// Gets the byte pointer of this <see cref="Mat"/> /// </summary> /// <param name="mat"></param> @@ -184,8 +198,24 @@ public static class EmguExtensions public static unsafe Span<byte> GetDataByteSpan(this Mat mat) => new(mat.DataPointer.ToPointer(), mat.GetLength()); - public static unsafe Span<byte> GetDataByteSpan(this Mat mat, int length, int offset = 0) - => new(IntPtr.Add(mat.DataPointer, offset).ToPointer(), length <= 0 ? mat.GetLength() : length); + /// <summary> + /// Gets the whole data span to manipulate or read pixels + /// </summary> + /// <returns></returns> + public static Span<byte> GetDataByteSpan(this Mat mat, int length, int offset = 0) + => GetDataSpan<byte>(mat, length, offset); + + /// <summary> + /// Gets the whole data span to manipulate or read pixels, use this when possibly using ROI + /// </summary> + /// <returns></returns> + public static unsafe Span2D<byte> GetDataByteSpan2D(this Mat mat) + { + if (!mat.IsSubmatrix) return new(mat.GetBytePointer(), mat.Height, mat.Step, 0); + var step = mat.GetRealStep(); + return new(mat.GetBytePointer(), mat.Height, step, mat.Step - step); + } + /// <summary> /// Gets the data span to manipulate or read pixels given a length and offset @@ -242,6 +272,7 @@ public static class EmguExtensions /// <returns></returns> public static unsafe Span<T> GetColSpan<T>(this Mat mat, int x, int length = 0, int offset = 0) { + // Fix with Span2D var colMat = mat.Col(x); return new(IntPtr.Add(colMat.DataPointer, offset).ToPointer(), length <= 0 ? mat.Height : length); } diff --git a/UVtools.Core/Layers/Layer.cs b/UVtools.Core/Layers/Layer.cs index 6493a53..3c5071a 100644 --- a/UVtools.Core/Layers/Layer.cs +++ b/UVtools.Core/Layers/Layer.cs @@ -762,13 +762,12 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint> case LayerCompressionCodec.GZip: { mat = new(SlicerFile.Resolution, DepthType.Cv8U, 1); - var matSpan = mat.GetDataByteSpan(); unsafe { fixed (byte* pBuffer = _compressedBytes) { using var compressedStream = new UnmanagedMemoryStream(pBuffer, _compressedBytes!.Length); - using var matStream = new UnmanagedMemoryStream(mat.GetBytePointer(), matSpan.Length, matSpan.Length, FileAccess.Write); + using var matStream = mat.GetUnmanagedMemoryStream(FileAccess.Write); using var gZipStream = new GZipStream(compressedStream, CompressionMode.Decompress); gZipStream.CopyTo(matStream); } @@ -779,13 +778,12 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint> case LayerCompressionCodec.Deflate: { mat = new(SlicerFile.Resolution, DepthType.Cv8U, 1); - var matSpan = mat.GetDataByteSpan(); unsafe { fixed (byte* pBuffer = _compressedBytes) { using var compressedStream = new UnmanagedMemoryStream(pBuffer, _compressedBytes!.Length); - using var matStream = new UnmanagedMemoryStream(mat.GetBytePointer(), matSpan.Length, matSpan.Length, FileAccess.Write); + using var matStream = mat.GetUnmanagedMemoryStream(FileAccess.Write); using var deflateStream = new DeflateStream(compressedStream, CompressionMode.Decompress); deflateStream.CopyTo(matStream); } @@ -1625,30 +1623,20 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint> } case LayerCompressionCodec.GZip: { - /*var matSpan = mat.GetDataByteSpan(); - var compressedBytes = new byte[matSpan.Length]; - unsafe - { - fixed (byte* pBuffer = compressedBytes) - { - using var compressedStream = new UnmanagedMemoryStream(pBuffer, compressedBytes.Length, compressedBytes.Length, FileAccess.Write); - using var gZipStream = new GZipStream(compressedStream, CompressionLevel.Fastest); - gZipStream.Write(mat.GetDataByteSpan()); - //return compressedBytes; - } - }*/ - - using var compressedStream = new MemoryStream(); - using var gZipStream = new GZipStream(compressedStream, CompressionLevel.Fastest); - gZipStream.Write(mat.GetDataByteSpan()); - return compressedStream.ToArray(); + return CompressionExtensions.GZipCompressToBytes(mat.GetBytes(), CompressionLevel.Fastest); + /*using var compressedStream = new MemoryStream(); + using var matStream = mat.GetUnmanagedMemoryStream(FileAccess.Read); + using var gzipStream = new GZipStream(compressedStream, CompressionLevel.Fastest); + matStream.CopyTo(gzipStream); + return compressedStream.ToArray();*/ } case LayerCompressionCodec.Deflate: { - using var compressedStream = new MemoryStream(); + return CompressionExtensions.DeflateCompressToBytes(mat.GetBytes(), CompressionLevel.Fastest); + /*using var compressedStream = new MemoryStream(); using var deflateStream = new DeflateStream(compressedStream, CompressionLevel.Fastest); deflateStream.Write(mat.GetDataByteSpan()); - return compressedStream.ToArray(); + return compressedStream.ToArray();*/ } /*case LayerCompressionMethod.None: return mat.GetBytes();*/ diff --git a/UVtools.Core/Operations/OperationPattern.cs b/UVtools.Core/Operations/OperationPattern.cs index b4a2127..d38df67 100644 --- a/UVtools.Core/Operations/OperationPattern.cs +++ b/UVtools.Core/Operations/OperationPattern.cs @@ -234,6 +234,7 @@ public class OperationPattern : Operation { ROI = srcRoi; + if (srcRoi.IsEmpty) return; MaxCols = (ushort)(ImageWidth / srcRoi.Width); MaxRows = (ushort)(ImageHeight / srcRoi.Height); diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index 7c95a6a..6c235f7 100644 --- a/UVtools.Core/UVtools.Core.csproj +++ b/UVtools.Core/UVtools.Core.csproj @@ -10,7 +10,7 @@ <RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl> <PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl> <Description>MSLA/DLP, file analysis, calibration, repair, conversion and manipulation</Description> - <Version>3.4.2</Version> + <Version>3.4.3</Version> <Copyright>Copyright © 2020 PTRTECH</Copyright> <PackageIcon>UVtools.png</PackageIcon> <Platforms>AnyCPU;x64</Platforms> @@ -67,6 +67,7 @@ <PackageReference Include="K4os.Compression.LZ4" Version="1.2.16" /> <PackageReference Include="KdTree" Version="1.4.1" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.2.0" /> + <PackageReference Include="Microsoft.Toolkit.HighPerformance" Version="7.1.2" /> <PackageReference Include="Portable.BouncyCastle" Version="1.9.0" /> <PackageReference Include="System.Memory" Version="4.5.4" /> <PackageReference Include="System.Reflection.TypeExtensions" Version="4.7.0" /> diff --git a/UVtools.InstallerMM/UVtools.InstallerMM.wxs b/UVtools.InstallerMM/UVtools.InstallerMM.wxs index 5e61ad8..181c00e 100644 --- a/UVtools.InstallerMM/UVtools.InstallerMM.wxs +++ b/UVtools.InstallerMM/UVtools.InstallerMM.wxs @@ -2,7 +2,7 @@ <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <?define ComponentRules="OneToOne"?> <!-- SourceDir instructs IsWiX the location of the directory that contains files for this merge module --> - <?define SourceDir="..\publish\UVtools_win-x64_v3.4.2"?> + <?define SourceDir="..\publish\UVtools_win-x64_v3.4.3"?> <Module Id="UVtools" Language="1033" Version="1.0.0.0"> <Package Id="12aaa1cf-ff06-4a02-abd5-2ac01ac4f83b" Manufacturer="PTRTECH" InstallerVersion="200" Keywords="MSLA, DLP" Description="MSLA/DLP, file analysis, repair, conversion and manipulation" InstallScope="perMachine" Platform="x64" /> <Directory Id="TARGETDIR" Name="SourceDir"> @@ -1557,6 +1557,9 @@ <Component Id="owc5D9B7363F82B4971A54B614C6E9F5EF1" Guid="5D9B7363-F82B-4971-A54B-614C6E9F5EF1"> <File Id="owf5D9B7363F82B4971A54B614C6E9F5EF1" Source="$(var.SourceDir)\mscordaccore_amd64_amd64_6.0.522.21309.dll" KeyPath="yes" /> </Component> + <Component Id="owc3110926C9437495884D1A256F611E7C5" Guid="3110926C-9437-4958-84D1-A256F611E7C5"> + <File Id="owf3110926C9437495884D1A256F611E7C5" Source="$(var.SourceDir)\Microsoft.Toolkit.HighPerformance.dll" KeyPath="yes" /> + </Component> </Directory> <Directory Id="ProgramMenuFolder"> <Directory Id="scd220707349D4C8FA275285514283F3E2A" Name="UVtools" /> diff --git a/UVtools.WPF/App.axaml.cs b/UVtools.WPF/App.axaml.cs index 0558025..892f5a9 100644 --- a/UVtools.WPF/App.axaml.cs +++ b/UVtools.WPF/App.axaml.cs @@ -206,7 +206,7 @@ public class App : Application if (Program.IsCrashReport) { - //Program.Args = new[] {"--crash-report", "test2", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum." }; + //Program.Args = new[] {"--crash-report", "Debug", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum." }; if (string.IsNullOrWhiteSpace(Program.Args[1])) return; if(string.IsNullOrWhiteSpace(Program.Args[2])) return; var category = Program.Args[1]; diff --git a/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs index f748c32..fc09ad4 100644 --- a/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs +++ b/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs @@ -1,7 +1,5 @@ -using System; -using System.ComponentModel; +using System.ComponentModel; using System.Globalization; -using System.Threading; using Avalonia; using Avalonia.Controls; using Avalonia.Interactivity; @@ -10,7 +8,6 @@ using Avalonia.Markup.Xaml; using UVtools.Core.Extensions; using UVtools.Core.FileFormats; using UVtools.Core.Operations; -using UVtools.WPF.Extensions; using UVtools.WPF.Windows; namespace UVtools.WPF.Controls.Tools; @@ -127,7 +124,7 @@ public class ToolEditParametersControl : ToolControl public void PopulateGrid() { - const byte cols = 5; + const byte cols = 4; if (grid.Children.Count > cols) { grid.Children.RemoveRange(cols, grid.Children.Count - cols); @@ -212,12 +209,12 @@ public class ToolEditParametersControl : ToolControl { if (Operation.PerLayerOverride) { - Operation.Modifiers = App.SlicerFile.PrintParameterPerLayerModifiers; + Operation.Modifiers = SlicerFile.PrintParameterPerLayerModifiers; SlicerFile.RefreshPrintParametersPerLayerModifiersValues(Operation.LayerIndexStart); } else { - Operation.Modifiers = App.SlicerFile.PrintParameterModifiers; + Operation.Modifiers = SlicerFile.PrintParameterModifiers; SlicerFile.RefreshPrintParametersModifiersValues(); } diff --git a/UVtools.WPF/Controls/WindowEx.cs b/UVtools.WPF/Controls/WindowEx.cs index 2b0099f..4fc1601 100644 --- a/UVtools.WPF/Controls/WindowEx.cs +++ b/UVtools.WPF/Controls/WindowEx.cs @@ -120,12 +120,19 @@ public class WindowEx : Window, INotifyPropertyChanged, IStyleable //TransparencyLevelHint = WindowTransparencyLevel.AcrylicBlur; } - protected override void OnOpened(EventArgs e) + protected override void OnInitialized() { - base.OnOpened(e); AutoConstainsWindowMaxSize(); + base.OnInitialized(); } + /*protected override void OnOpened(EventArgs e) + { + base.OnOpened(e); + Debug.WriteLine("OnOpened"); + AutoConstainsWindowMaxSize(); + }*/ + /*protected override Size MeasureOverride(Size availableSize) { var result = base.MeasureOverride(availableSize); @@ -145,6 +152,11 @@ public class WindowEx : Window, INotifyPropertyChanged, IStyleable public void AutoConstainsWindowMaxSize() { + if (WindowStartupLocation == WindowStartupLocation.CenterOwner && Owner is null) + { + WindowStartupLocation = WindowStartupLocation.CenterScreen; + } + if (!CanResize && WindowState == WindowState.Normal && WindowConstrainMaxSize != WindowConstrainsMaxSizeType.None) { switch (WindowConstrainMaxSize) diff --git a/UVtools.WPF/MainWindow.axaml.cs b/UVtools.WPF/MainWindow.axaml.cs index aa65ff6..2c4c2ec 100644 --- a/UVtools.WPF/MainWindow.axaml.cs +++ b/UVtools.WPF/MainWindow.axaml.cs @@ -22,7 +22,6 @@ using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using Org.BouncyCastle.Operators; using UVtools.AvaloniaControls; using UVtools.Core; using UVtools.Core.Extensions; @@ -1585,6 +1584,16 @@ public partial class MainWindow : WindowEx MenuFileConvertItems = menuItems.ToArray(); } + foreach (var menuItem in new[] { MenuTools, MenuCalibration, LayerActionsMenu }) + { + foreach (var menuTool in menuItem) + { + if (menuTool.Tag is not Operation operation) continue; + operation.SlicerFile = SlicerFile; + menuTool.IsEnabled = operation.CanSpawn && (SlicerFile.DecodeType == FileFormat.FileDecodeType.Full || (SlicerFile.DecodeType == FileFormat.FileDecodeType.Partial && operation.CanRunInPartialMode)); + } + } + using var mat = SlicerFile.FirstLayer?.LayerMat; VisibleThumbnailIndex = 1; diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj index 3be333b..9ddca17 100644 --- a/UVtools.WPF/UVtools.WPF.csproj +++ b/UVtools.WPF/UVtools.WPF.csproj @@ -12,7 +12,7 @@ <PackageLicenseFile>LICENSE</PackageLicenseFile> <RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl> <RepositoryType>Git</RepositoryType> - <Version>3.4.2</Version> + <Version>3.4.3</Version> <Platforms>AnyCPU;x64</Platforms> <PackageIcon>UVtools.png</PackageIcon> <PackageReadmeFile>README.md</PackageReadmeFile> diff --git a/UVtools.WPF/Windows/AboutWindow.axaml.cs b/UVtools.WPF/Windows/AboutWindow.axaml.cs index 420f8f0..98826e0 100644 --- a/UVtools.WPF/Windows/AboutWindow.axaml.cs +++ b/UVtools.WPF/Windows/AboutWindow.axaml.cs @@ -147,6 +147,11 @@ public class AboutWindow : WindowEx message.AppendLine(); message.AppendLine($"Path: {App.ApplicationPath}"); message.AppendLine($"Executable: {App.AppExecutable}"); + if (App.SlicerFile is not null) + { + message.AppendLine($"Loaded file: {App.SlicerFile.Filename} [Version: {App.SlicerFile.Version}] [Class: {App.SlicerFile.GetType().Name}]"); + } + return message.ToString(); } @@ -168,6 +173,11 @@ public class AboutWindow : WindowEx message.AppendLine(); message.AppendLine($"Path: {App.ApplicationPath}"); message.AppendLine($"Executable: {App.AppExecutable}"); + if (SlicerFile is not null) + { + message.AppendLine($"Loaded file: {SlicerFile.Filename} [Version: {SlicerFile.Version}] [Class: {SlicerFile.GetType().Name}]"); + } + return message.ToString(); } diff --git a/UVtools.WPF/Windows/MessageWindow.axaml.cs b/UVtools.WPF/Windows/MessageWindow.axaml.cs index 407fd80..718721c 100644 --- a/UVtools.WPF/Windows/MessageWindow.axaml.cs +++ b/UVtools.WPF/Windows/MessageWindow.axaml.cs @@ -61,12 +61,6 @@ namespace UVtools.WPF.Windows InitializeComponent(); CanResize = Settings.General.WindowsCanResize; - if (WindowStartupLocation == WindowStartupLocation.CenterOwner && Owner is null) - { - WindowStartupLocation = WindowStartupLocation.CenterScreen; - } - - AutoConstainsWindowMaxSize(); _buttonsRightPanel = this.FindControl<StackPanel>("ButtonsRightPanel"); DataContext = this; |