diff --git a/CHANGELOG.md b/CHANGELOG.md
index ac1490d..19572f7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,13 +6,17 @@
* (Add) Themes support
* (Add) Fullscreen support (F11)
* (Change) GUI was rewritten from Windows Forms to WPF Avalonia, C#
+* (Improvement) Edit print parameters: Dedicated reset button hides when value is unchanged
+* (Improvement) Edit print parameters: Show changes on confirm dialog
* (Improvement) More detailed descriptions on error messages
* (Improvement) GUI is now scalable
+* (Fix) Some islands wont remove from list select select many and click remove
* (Fix) Many bug found and fixed during convertion
## ??/09/2020 - v0.8.2.5
* (Fix) Extract: Use trail zeros to layer filenames
+* (Improvement) Edit print parameters: Show changes on confirm dialog
## 22/09/2020 - v0.8.2.4
diff --git a/README.md b/README.md
index 5bdc404..9d1ffe5 100644
--- a/README.md
+++ b/README.md
@@ -92,6 +92,7 @@ But also, i need victims for test subject. Proceed at your own risk!
* Phrozen Shuffle 4K
* Phrozen Sonic
* Phrozen Sonic Mini
+* Phrozen Sonic Mini 4K
* Phrozen Transform
* Kelant S400
* Wanhao D7
@@ -146,10 +147,20 @@ After some tests without failure you can increase your confidence and ignore thi
1. 2 GB RAM or higher
-### Mac and Linux
+### Linux
-(Not supported yet)
+**Ubuntu**
+
+```bash
+wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
+sudo dpkg -i packages-microsoft-prod.deb
+rm packages-microsoft-prod.deb
+sudo apt-get update
+sudo apt-get install -y apt-transport-https
+sudo apt-get update
+sudo apt-get install -y libjpeg-dev libpng-dev libgeotiff-dev libdc1394-22 libavcodec-dev libavformat-dev libswscale-dev libopenexr24 libtbb-dev dotnet-runtime-3.1
+```
## How to use
diff --git a/UVtools.Core/Operations/OperationEditParameters.cs b/UVtools.Core/Operations/OperationEditParameters.cs
index 77e08c0..968c552 100644
--- a/UVtools.Core/Operations/OperationEditParameters.cs
+++ b/UVtools.Core/Operations/OperationEditParameters.cs
@@ -6,7 +6,10 @@
* of this license document, but changing it is not allowed.
*/
+using System.Linq;
+using System.Text;
using UVtools.Core.FileFormats;
+using UVtools.Core.Objects;
namespace UVtools.Core.Operations
{
@@ -21,12 +24,38 @@ namespace UVtools.Core.Operations
public override string Description =>
"Edits the available print parameters.";
- public override string ConfirmationText => "commit print parameter changes?";
+ public override string ConfirmationText
+ {
+ get
+ {
+ var sb = new StringBuilder();
+ foreach (var modifier in Modifiers)
+ {
+ if(!modifier.HasChanged) continue;
+ sb.AppendLine($"{modifier.Name}: {modifier.OldValue} » {modifier.NewValue}");
+ }
+ return $"commit print parameter changes?\n{sb}";
+ }
+ }
public override string ProgressTitle => null;
public override string ProgressAction => null;
+ public override StringTag Validate(params object[] parameters)
+ {
+ var sb = new StringBuilder();
+ var changed = Modifiers.Any(modifier => modifier.HasChanged);
+
+ if (!changed)
+ {
+ sb.AppendLine("Nothing changed\nDo some changes or cancel the operation.");
+ }
+
+
+ return new StringTag(sb.ToString());
+ }
+
public FileFormat.PrintParameterModifier[] Modifiers { get; set; }
public OperationEditParameters()
diff --git a/UVtools.Core/Operations/OperationLayerReHeight.cs b/UVtools.Core/Operations/OperationLayerReHeight.cs
index a7f4f8b..f5550c1 100644
--- a/UVtools.Core/Operations/OperationLayerReHeight.cs
+++ b/UVtools.Core/Operations/OperationLayerReHeight.cs
@@ -16,6 +16,8 @@ namespace UVtools.Core.Operations
{
public sealed class OperationLayerReHeight : Operation
{
+ private OperationLayerReHeightItem _item;
+
#region Overrides
public override Enumerations.LayerRangeSelection LayerRangeSelection => Enumerations.LayerRangeSelection.None;
@@ -51,7 +53,11 @@ namespace UVtools.Core.Operations
#endregion
- public OperationLayerReHeightItem Item { get; set; }
+ public OperationLayerReHeightItem Item
+ {
+ get => _item;
+ set => RaiseAndSetIfChanged(ref _item, value);
+ }
public static OperationLayerReHeightItem[] GetItems(uint layerCount, decimal layerHeight)
diff --git a/UVtools.GUI/Controls/Tools/CtrlToolLayerReHeight.cs b/UVtools.GUI/Controls/Tools/CtrlToolLayerReHeight.cs
index 4cb552d..656e87a 100644
--- a/UVtools.GUI/Controls/Tools/CtrlToolLayerReHeight.cs
+++ b/UVtools.GUI/Controls/Tools/CtrlToolLayerReHeight.cs
@@ -17,6 +17,10 @@ namespace UVtools.GUI.Controls.Tools
{
public OperationLayerReHeight Operation { get; }
+ public OperationLayerReHeight.OperationLayerReHeightItem[] Presets { get; } = OperationLayerReHeight.GetItems(
+ Program.SlicerFile.LayerCount,
+ (decimal) Program.SlicerFile.LayerHeight);
+
public CtrlToolLayerReHeight()
{
@@ -25,13 +29,10 @@ namespace UVtools.GUI.Controls.Tools
SetOperation(Operation);
lbCurrent.Text = $"Current layers: {Program.SlicerFile.LayerCount} at {Program.SlicerFile.LayerHeight}mm";
-
- var items = OperationLayerReHeight.GetItems(Program.SlicerFile.LayerCount,
- (decimal) Program.SlicerFile.LayerHeight);
-
- if (items.Length > 0)
+
+ if (Presets.Length > 0)
{
- cbMultiplier.Items.AddRange(items);
+ cbMultiplier.Items.AddRange(Presets);
cbMultiplier.SelectedIndex = 0;
}
else
diff --git a/UVtools.WPF/App.axaml.cs b/UVtools.WPF/App.axaml.cs
index 7faf6d8..0e99fdb 100644
--- a/UVtools.WPF/App.axaml.cs
+++ b/UVtools.WPF/App.axaml.cs
@@ -16,6 +16,7 @@ using System.Threading;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
+using Avalonia.Media.Imaging;
using Avalonia.Platform;
using Avalonia.ThemeManager;
using Emgu.CV;
@@ -159,6 +160,8 @@ namespace UVtools.WPF
return res;
}
+ public static Bitmap GetBitmapFromAsset(string url) => new Bitmap(GetAsset(url));
+
#endregion
}
}
diff --git a/UVtools.WPF/Controls/Tools/ToolChangeResolutionControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolChangeResolutionControl.axaml.cs
index 6254a2b..5ddac9a 100644
--- a/UVtools.WPF/Controls/Tools/ToolChangeResolutionControl.axaml.cs
+++ b/UVtools.WPF/Controls/Tools/ToolChangeResolutionControl.axaml.cs
@@ -1,4 +1,5 @@
-using System.Timers;
+using System.Diagnostics;
+using System.Timers;
using Avalonia.Markup.Xaml;
using UVtools.Core.Operations;
@@ -18,7 +19,9 @@ namespace UVtools.WPF.Controls.Tools
if (_selectedPresetItem is null || _selectedPresetItem.IsEmpty) return;
Operation.NewResolutionX = _selectedPresetItem.ResolutionX;
Operation.NewResolutionY = _selectedPresetItem.ResolutionY;
- Timer timer = new Timer(50);
+
+ //SelectedPresetItem = null;
+ Timer timer = new Timer(1);
timer.Elapsed += (sender, args) =>
{
SelectedPresetItem = null;
diff --git a/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml b/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml
new file mode 100644
index 0000000..35f4e0c
--- /dev/null
+++ b/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs
new file mode 100644
index 0000000..5d2dcde
--- /dev/null
+++ b/UVtools.WPF/Controls/Tools/ToolEditParametersControl.axaml.cs
@@ -0,0 +1,183 @@
+using System;
+using System.Globalization;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Interactivity;
+using Avalonia.Layout;
+using Avalonia.Markup.Xaml;
+using Avalonia.Media.Imaging;
+using UVtools.Core.Extensions;
+using UVtools.Core.FileFormats;
+using UVtools.Core.Operations;
+using UVtools.WPF.Windows;
+
+namespace UVtools.WPF.Controls.Tools
+{
+ public class ToolEditParametersControl : ToolControl
+ {
+ public OperationEditParameters Operation { get; }
+
+ public RowControl[] RowControls;
+
+ public sealed class RowControl
+ {
+ public FileFormat.PrintParameterModifier Modifier { get; }
+
+ public TextBlock Name { get; }
+ public TextBlock OldValue { get; }
+ public NumericUpDown NewValue { get; }
+ public TextBlock Unit { get; }
+ public Button ResetButton { get; }
+
+ public RowControl(FileFormat.PrintParameterModifier modifier)
+ {
+ Modifier = modifier;
+
+ modifier.NewValue = modifier.OldValue.Clamp(modifier.Minimum, modifier.Maximum);
+
+ Name = new TextBlock
+ {
+ Text = $"{modifier.Name}:",
+ VerticalAlignment = VerticalAlignment.Center,
+ Padding = new Thickness(15, 0),
+ Tag = this,
+ };
+
+ OldValue = new TextBlock
+ {
+ Text = modifier.OldValue.ToString(CultureInfo.InvariantCulture),
+ VerticalAlignment = VerticalAlignment.Center,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ //Padding = new Thickness(15, 0),
+ Tag = this
+ };
+
+ NewValue = new NumericUpDown
+ {
+ //DecimalPlaces = modifier.DecimalPlates,
+ VerticalAlignment = VerticalAlignment.Center,
+ Minimum = (double) modifier.Minimum,
+ Maximum = (double) modifier.Maximum,
+ Increment = modifier.DecimalPlates == 0 ? 1 : 0.01,
+ Value = (double)modifier.NewValue,
+ Tag = this,
+ Width = 100,
+ };
+ if (modifier.DecimalPlates > 0)
+ {
+ NewValue.FormatString = "{0:#,0.00}";
+ }
+
+ Unit = new TextBlock
+ {
+ Text = modifier.ValueUnit,
+ VerticalAlignment = VerticalAlignment.Center,
+ Padding = new Thickness(10, 0, 15, 0),
+ Tag = this
+ };
+
+ ResetButton = new Button
+ {
+ IsVisible = false,
+ IsEnabled = false,
+ VerticalAlignment = VerticalAlignment.Center,
+ Tag = this,
+ Padding = new Thickness(5),
+ Content = new Image {Source = App.GetBitmapFromAsset("/Assets/Icons/undo-16x16.png")}
+ };
+ ResetButton.Click += ResetButtonOnClick;
+ NewValue.ValueChanged += NewValueOnValueChanged;
+ }
+
+ private void NewValueOnValueChanged(object? sender, NumericUpDownValueChangedEventArgs e)
+ {
+ Modifier.NewValue = (decimal) NewValue.Value;
+ ResetButton.IsVisible = ResetButton.IsEnabled = Modifier.HasChanged;
+ }
+
+ private void ResetButtonOnClick(object? sender, RoutedEventArgs e)
+ {
+ NewValue.Value = (double) Modifier.OldValue;
+ NewValue.Focus();
+ }
+ }
+
+ public ToolEditParametersControl()
+ {
+ InitializeComponent();
+
+ App.SlicerFile.RefreshPrintParametersModifiersValues();
+ BaseOperation = Operation = new OperationEditParameters(App.SlicerFile.PrintParameterModifiers);
+
+ if (Operation.Modifiers is null || Operation.Modifiers.Length == 0)
+ {
+ CanRun = false;
+ return;
+ }
+
+ Grid grid = this.FindControl("grid");
+
+ int rowIndex = 1;
+ RowControls = new RowControl[Operation.Modifiers.Length];
+ //table.RowCount = Operation.Modifiers.Length+1;
+ foreach (var modifier in Operation.Modifiers)
+ {
+ grid.RowDefinitions.Add(new RowDefinition());
+ byte column = 0;
+
+ var rowControl = new RowControl(modifier);
+ grid.Children.Add(rowControl.Name);
+ grid.Children.Add(rowControl.OldValue);
+ grid.Children.Add(rowControl.NewValue);
+ grid.Children.Add(rowControl.Unit);
+ grid.Children.Add(rowControl.ResetButton);
+ Grid.SetRow(rowControl.Name, rowIndex);
+ Grid.SetColumn(rowControl.Name, column++);
+
+ Grid.SetRow(rowControl.OldValue, rowIndex);
+ Grid.SetColumn(rowControl.OldValue, column++);
+
+ Grid.SetRow(rowControl.NewValue, rowIndex);
+ Grid.SetColumn(rowControl.NewValue, column++);
+
+ Grid.SetRow(rowControl.Unit, rowIndex);
+ Grid.SetColumn(rowControl.Unit, column++);
+
+ Grid.SetRow(rowControl.ResetButton, rowIndex);
+ Grid.SetColumn(rowControl.ResetButton, column++);
+ /*table.Controls.Add(rowControl.Name, column++, rowIndex);
+ table.Controls.Add(rowControl.OldValue, column++, rowIndex);
+ table.Controls.Add(rowControl.NewValue, column++, rowIndex);
+ table.Controls.Add(rowControl.Unit, column++, rowIndex);
+ table.Controls.Add(rowControl.ResetButton, column++, rowIndex);
+ */
+ RowControls[rowIndex - 1] = rowControl;
+
+ rowIndex++;
+ }
+
+ DataContext = this;
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ public override void Callback(ToolWindow.Callbacks callback)
+ {
+ switch (callback)
+ {
+ case ToolWindow.Callbacks.Init:
+ ParentWindow.IsButton1Visible = true;
+ break;
+ case ToolWindow.Callbacks.Button1:
+ foreach (var rowControl in RowControls)
+ {
+ rowControl.NewValue.Value = (double) rowControl.Modifier.OldValue;
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml b/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml
new file mode 100644
index 0000000..21c0e98
--- /dev/null
+++ b/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml.cs
new file mode 100644
index 0000000..aa96ac7
--- /dev/null
+++ b/UVtools.WPF/Controls/Tools/ToolLayerReHeightControl.axaml.cs
@@ -0,0 +1,41 @@
+using Avalonia.Markup.Xaml;
+using UVtools.Core.Operations;
+using UVtools.WPF.Extensions;
+
+namespace UVtools.WPF.Controls.Tools
+{
+ public class ToolLayerReHeightControl : ToolControl
+ {
+ public OperationLayerReHeight Operation { get; }
+
+ public OperationLayerReHeight.OperationLayerReHeightItem[] Presets { get; } = OperationLayerReHeight.GetItems(
+ App.SlicerFile.LayerCount,
+ (decimal)App.SlicerFile.LayerHeight);
+
+ public string CurrentLayers => $"Current layers: {App.SlicerFile.LayerCount} at {App.SlicerFile.LayerHeight}mm";
+
+ public ToolLayerReHeightControl()
+ {
+ InitializeComponent();
+ BaseOperation = Operation = new OperationLayerReHeight();
+
+ if (Presets.Length == 0)
+ {
+ App.MainWindow.MessageBoxInfo("No valid configuration to be able to re-height, closing this tool now.", "Not possible to re-height");
+ CanRun = false;
+ }
+ else
+ {
+ Operation.Item = Presets[0];
+ }
+
+
+ DataContext = this;
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/UVtools.WPF/Extensions/WindowExtensions.cs b/UVtools.WPF/Extensions/WindowExtensions.cs
index 1e1f157..3a8ddd9 100644
--- a/UVtools.WPF/Extensions/WindowExtensions.cs
+++ b/UVtools.WPF/Extensions/WindowExtensions.cs
@@ -26,6 +26,7 @@ namespace UVtools.WPF.Extensions
ContentMessage = message,
Icon = icon,
Style = style,
+ WindowIcon = new WindowIcon(App.GetAsset("/Assets/Icons/UVtools.ico")),
WindowStartupLocation = location,
CanResize = false
});
@@ -34,13 +35,13 @@ namespace UVtools.WPF.Extensions
}
public static async Task MessageBoxInfo(this Window window, string message, string title = null, ButtonEnum buttons = ButtonEnum.Ok, Style style = Style.None)
- => await window.MessageBoxGeneric(message, title ?? $"{window.Title} Information", buttons, Icon.Info, WindowStartupLocation.CenterOwner, style);
+ => await window.MessageBoxGeneric(message, title ?? $"{window.Title} - Information", buttons, Icon.Info, WindowStartupLocation.CenterOwner, style);
public static async Task MessageBoxError(this Window window, string message, string title = null, ButtonEnum buttons = ButtonEnum.Ok, Style style = Style.None)
- => await window.MessageBoxGeneric(message, title ?? $"{window.Title} Error", buttons, Icon.Error, WindowStartupLocation.CenterOwner, style);
+ => await window.MessageBoxGeneric(message, title ?? $"{window.Title} - Error", buttons, Icon.Error, WindowStartupLocation.CenterOwner, style);
public static async Task MessageBoxQuestion(this Window window, string message, string title = null, ButtonEnum buttons = ButtonEnum.YesNo, Style style = Style.None)
- => await window.MessageBoxGeneric(message, title ?? $"{window.Title} Question", buttons, Icon.Setting, WindowStartupLocation.CenterOwner, style);
+ => await window.MessageBoxGeneric(message, title ?? $"{window.Title} - Question", buttons, Icon.Setting, WindowStartupLocation.CenterOwner, style);
public static void ResetDataContext(this Window window)
diff --git a/UVtools.WPF/MainWindow.axaml.cs b/UVtools.WPF/MainWindow.axaml.cs
index 493c684..c18a6af 100644
--- a/UVtools.WPF/MainWindow.axaml.cs
+++ b/UVtools.WPF/MainWindow.axaml.cs
@@ -44,6 +44,7 @@ using Bitmap = Avalonia.Media.Imaging.Bitmap;
using Color = UVtools.WPF.Structures.Color;
using Helpers = UVtools.WPF.Controls.Helpers;
using Point = Avalonia.Point;
+using Timer = System.Timers.Timer;
namespace UVtools.WPF
{
@@ -237,6 +238,7 @@ namespace UVtools.WPF
#region Members
public Stopwatch LastStopWatch;
+ private Timer _layerNavigationTooltipTimer = new Timer(1){AutoReset = false};
private uint _actualLayer;
private bool _isGUIEnabled = true;
private uint _savesCount;
@@ -1137,9 +1139,10 @@ namespace UVtools.WPF
RaisePropertyChanged(nameof(CanGoDown));
RaisePropertyChanged(nameof(CanGoUp));
RaisePropertyChanged(nameof(ActualLayerTooltip));
- RaisePropertyChanged(nameof(LayerNavigationTooltipMargin));
+ //RaisePropertyChanged(nameof(LayerNavigationTooltipMargin));
RaisePropertyChanged(nameof(LayerPixelCountStr));
RaisePropertyChanged(nameof(LayerBoundsStr));
+ _layerNavigationTooltipTimer.Start();
}
public Thickness LayerNavigationTooltipMargin
@@ -1219,7 +1222,13 @@ namespace UVtools.WPF
{
ProcessFiles(e.Data.GetFileNames().ToArray());
});
-
+
+ _layerNavigationTooltipTimer.Elapsed += (sender, args) =>
+ {
+ Dispatcher.UIThread.InvokeAsync(() => RaisePropertyChanged(nameof(LayerNavigationTooltipMargin)));
+ };
+
+
UpdateTitle();
if (Settings.General.StartMaximized)
@@ -1231,6 +1240,10 @@ namespace UVtools.WPF
ProcessFiles(Program.Args);
}
+ private void _layerSliderTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
+ {
+ throw new NotImplementedException();
+ }
private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
@@ -2407,6 +2420,7 @@ namespace UVtools.WPF
}*/
SlicerFile.SetValuesFromPrintParametersModifiers();
RefreshProperties();
+ ResetDataContext();
CanSave = true;
diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj
index aec357e..9128a3a 100644
--- a/UVtools.WPF/UVtools.WPF.csproj
+++ b/UVtools.WPF/UVtools.WPF.csproj
@@ -29,7 +29,7 @@
-
+
@@ -201,10 +201,13 @@
PreserveNewest
+
+
True
+
diff --git a/UVtools.WPF/Windows/ToolWindow.axaml b/UVtools.WPF/Windows/ToolWindow.axaml
index dd213ae..bd23100 100644
--- a/UVtools.WPF/Windows/ToolWindow.axaml
+++ b/UVtools.WPF/Windows/ToolWindow.axaml
@@ -206,11 +206,25 @@
-
-
+
+
-
+