Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/sn4k3/UVtools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Conceição <Tiago_caza@hotmail.com>2021-05-09 01:37:59 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2021-05-09 01:37:59 +0300
commitdc0e90a61311b2d78104e46ac34c8faf382dcbd3 (patch)
tree03afc3cceb7dbacbddea34c535700f042d42502e /UVtools.WPF
parentea410468fcb8c8ba93c955b3a69e6654e48f0b2f (diff)
v2.11.0v2.11.0
- **Tools:** - (Add) Pixel Arithmetic - (Add) Layer arithmetic: Operator $ to perform a absolute difference - (Add) Allow to save and auto restore operation settings per session (#195) - (Add) Allow to auto select the print volume ROI - (Add) Allow to export and import operation settings from files - (Improvement) Calculator - LightOff delay: Hide the bottom properties or the tab if the file format don't support them (#193) - (Change) 'Arithmetic' to 'Layer arithmetic' - (Remove) 'Threshold pixels' - (Fix) Solidfy was unable to save profiles - (Fix) A redo operation (Ctrl + Shift + Z) wasn't restoring the settings when a default profile is set - **Operations:** - (Fix) Passing a roi mat to `ApplyMask` would cause unwanted results - (Improvement) Allow pass a full/original size mask to `ApplyMask` - **Scripting:** - (Add) an script to create an printable file to clean the VAT (#170) - (Improvement) Allow to change user input properties outside the initialization - (Improvement) Auto format numerical input box with the fixed decimal cases - (Add) Settings: Section 'Tools' - (Improvement) GUI: The 'Lift, Retract and Light-off' at status bar now only shows for the supported formats - (Fix) Print time estimation calculation was wrong since v2.9.3 due a lacking of parentheses on the logic
Diffstat (limited to 'UVtools.WPF')
-rw-r--r--UVtools.WPF/Assets/Icons/file-export-16x16.pngbin0 -> 161 bytes
-rw-r--r--UVtools.WPF/Controls/Helpers.cs32
-rw-r--r--UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml30
-rw-r--r--UVtools.WPF/Controls/Tools/ToolLayerArithmeticControl.axaml (renamed from UVtools.WPF/Controls/Tools/ToolArithmeticControl.axaml)2
-rw-r--r--UVtools.WPF/Controls/Tools/ToolLayerArithmeticControl.axaml.cs (renamed from UVtools.WPF/Controls/Tools/ToolArithmeticControl.axaml.cs)8
-rw-r--r--UVtools.WPF/Controls/Tools/ToolPixelArithmeticControl.axaml99
-rw-r--r--UVtools.WPF/Controls/Tools/ToolPixelArithmeticControl.axaml.cs20
-rw-r--r--UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs15
-rw-r--r--UVtools.WPF/MainWindow.Clipboard.cs4
-rw-r--r--UVtools.WPF/MainWindow.axaml77
-rw-r--r--UVtools.WPF/MainWindow.axaml.cs18
-rw-r--r--UVtools.WPF/Structures/OperationProfiles.cs30
-rw-r--r--UVtools.WPF/UVtools.WPF.csproj5
-rw-r--r--UVtools.WPF/UserSettings.cs39
-rw-r--r--UVtools.WPF/Windows/SettingsWindow.axaml34
-rw-r--r--UVtools.WPF/Windows/ToolWindow.axaml41
-rw-r--r--UVtools.WPF/Windows/ToolWindow.axaml.cs164
17 files changed, 501 insertions, 117 deletions
diff --git a/UVtools.WPF/Assets/Icons/file-export-16x16.png b/UVtools.WPF/Assets/Icons/file-export-16x16.png
new file mode 100644
index 0000000..885e637
--- /dev/null
+++ b/UVtools.WPF/Assets/Icons/file-export-16x16.png
Binary files differ
diff --git a/UVtools.WPF/Controls/Helpers.cs b/UVtools.WPF/Controls/Helpers.cs
index ca66103..61046f2 100644
--- a/UVtools.WPF/Controls/Helpers.cs
+++ b/UVtools.WPF/Controls/Helpers.cs
@@ -15,7 +15,7 @@ namespace UVtools.WPF.Controls
{
public static readonly List<FileDialogFilter> ImagesFileFilter = new()
{
- new FileDialogFilter
+ new()
{
Name = "Image Files",
Extensions = new List<string>
@@ -29,9 +29,9 @@ namespace UVtools.WPF.Controls
}
};
- public static readonly List<FileDialogFilter> PngFileFilter = new List<FileDialogFilter>
+ public static readonly List<FileDialogFilter> PngFileFilter = new()
{
- new FileDialogFilter
+ new()
{
Name = "Image Files",
Extensions = new List<string>
@@ -41,9 +41,9 @@ namespace UVtools.WPF.Controls
}
};
- public static readonly List<FileDialogFilter> TxtFileFilter = new List<FileDialogFilter>
+ public static readonly List<FileDialogFilter> TxtFileFilter = new()
{
- new FileDialogFilter
+ new()
{
Name = "Text Files",
Extensions = new List<string>
@@ -53,9 +53,9 @@ namespace UVtools.WPF.Controls
}
};
- public static readonly List<FileDialogFilter> IniFileFilter = new List<FileDialogFilter>
+ public static readonly List<FileDialogFilter> IniFileFilter = new()
{
- new FileDialogFilter
+ new()
{
Name = "Ini Files",
Extensions = new List<string>
@@ -65,9 +65,21 @@ namespace UVtools.WPF.Controls
}
};
+ public static readonly List<FileDialogFilter> OperationSettingFileFilter = new()
+ {
+ new()
+ {
+ Name = "UVtools operation settings",
+ Extensions = new List<string>
+ {
+ "uvtop",
+ }
+ }
+ };
+
public static readonly List<FileDialogFilter> ScriptsFileFilter = new()
{
- new FileDialogFilter
+ new()
{
Name = "Script Files",
Extensions = new List<string>
@@ -87,9 +99,9 @@ namespace UVtools.WPF.Controls
public static List<FileDialogFilter> ToAvaloniaFilter(string name, string extension)
{
- return new List<FileDialogFilter>(1)
+ return new(1)
{
- new FileDialogFilter {Name = name, Extensions = new List<string>(1) {extension}}
+ new() {Name = name, Extensions = new List<string>(1) {extension}}
};
}
}
diff --git a/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml b/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml
index c179b3b..37a6410 100644
--- a/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml
+++ b/UVtools.WPF/Controls/Tools/ToolCalculatorControl.axaml
@@ -232,7 +232,7 @@
</TabItem>
- <TabItem Header="Light-off delay">
+ <TabItem Header="Light-off delay" IsVisible="{Binding SlicerFile.CanUseAnyLightOffDelay}">
<Grid RowDefinitions="Auto,10,Auto">
<Border
@@ -403,12 +403,16 @@
<TextBlock
Grid.Row="0"
Grid.Column="6"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Text="Bottom lift height:"/>
<NumericUpDown
Grid.Row="0"
Grid.Column="8"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
VerticalAlignment="Center"
Minimum="0"
Maximum="1000"
@@ -418,18 +422,24 @@
<TextBlock
Grid.Row="0"
Grid.Column="10"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
VerticalAlignment="Center"
Text="mm"/>
<TextBlock
Grid.Row="2"
Grid.Column="6"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Text="Bottom lift speed:"/>
<NumericUpDown
Grid.Row="2"
Grid.Column="8"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
VerticalAlignment="Center"
Minimum="0"
Maximum="1000"
@@ -439,18 +449,24 @@
<TextBlock
Grid.Row="2"
Grid.Column="10"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
VerticalAlignment="Center"
Text="mm/min"/>
<TextBlock
Grid.Row="6"
Grid.Column="6"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Text="Bottom desired wait time:"/>
<NumericUpDown
Grid.Row="6"
Grid.Column="8"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
VerticalAlignment="Center"
Minimum="0"
Maximum="1000"
@@ -460,12 +476,16 @@
<TextBlock
Grid.Row="6"
Grid.Column="10"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
VerticalAlignment="Center"
Text="s"/>
<TextBlock
Grid.Row="8"
Grid.Column="6"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
VerticalAlignment="Center"
HorizontalAlignment="Right"
FontWeight="Bold"
@@ -473,6 +493,8 @@
<TextBox
Grid.Row="8"
Grid.Column="8"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
VerticalAlignment="Center"
IsReadOnly="true"
FontWeight="Bold"
@@ -480,6 +502,8 @@
<TextBlock
Grid.Row="8"
Grid.Column="10"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
FontWeight="Bold"
VerticalAlignment="Center"
Text="s"/>
@@ -488,6 +512,8 @@
Grid.Row="10"
Grid.Column="6"
Grid.ColumnSpan="3"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Padding="10"
@@ -499,6 +525,8 @@
Grid.Row="12"
Grid.Column="6"
Grid.ColumnSpan="5"
+ IsVisible="{Binding SlicerFile.CanUseBottomLightOffDelay}"
+ IsEnabled="{Binding SlicerFile.CanUseBottomLightOffDelay}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="{Binding SlicerFile.BottomLightOffDelay, StringFormat=Current value: \{0\}}"/>
diff --git a/UVtools.WPF/Controls/Tools/ToolArithmeticControl.axaml b/UVtools.WPF/Controls/Tools/ToolLayerArithmeticControl.axaml
index 9239816..87dff5c 100644
--- a/UVtools.WPF/Controls/Tools/ToolArithmeticControl.axaml
+++ b/UVtools.WPF/Controls/Tools/ToolLayerArithmeticControl.axaml
@@ -3,7 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
- x:Class="UVtools.WPF.Controls.Tools.ToolArithmeticControl"
+ x:Class="UVtools.WPF.Controls.Tools.ToolLayerArithmeticControl"
Width="720"
>
diff --git a/UVtools.WPF/Controls/Tools/ToolArithmeticControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolLayerArithmeticControl.axaml.cs
index 18ad8ff..fc07e66 100644
--- a/UVtools.WPF/Controls/Tools/ToolArithmeticControl.axaml.cs
+++ b/UVtools.WPF/Controls/Tools/ToolLayerArithmeticControl.axaml.cs
@@ -4,14 +4,14 @@ using UVtools.WPF.Windows;
namespace UVtools.WPF.Controls.Tools
{
- public class ToolArithmeticControl : ToolControl
+ public class ToolLayerArithmeticControl : ToolControl
{
- public OperationArithmetic Operation => BaseOperation as OperationArithmetic;
+ public OperationLayerArithmetic Operation => BaseOperation as OperationLayerArithmetic;
- public ToolArithmeticControl()
+ public ToolLayerArithmeticControl()
{
InitializeComponent();
- BaseOperation = new OperationArithmetic(SlicerFile);
+ BaseOperation = new OperationLayerArithmetic(SlicerFile);
}
private void InitializeComponent()
diff --git a/UVtools.WPF/Controls/Tools/ToolPixelArithmeticControl.axaml b/UVtools.WPF/Controls/Tools/ToolPixelArithmeticControl.axaml
new file mode 100644
index 0000000..c4ca28e
--- /dev/null
+++ b/UVtools.WPF/Controls/Tools/ToolPixelArithmeticControl.axaml
@@ -0,0 +1,99 @@
+<UserControl xmlns="https://github.com/avaloniaui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
+ x:Class="UVtools.WPF.Controls.Tools.ToolPixelArithmeticControl">
+
+ <StackPanel Spacing="10">
+ <Grid RowDefinitions="Auto,10,Auto,10,Auto,10,Auto"
+ ColumnDefinitions="Auto,10,Auto,20,Auto,10,Auto,20,Auto,10,Auto">
+
+ <TextBlock Grid.Row="0" Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Operator:"/>
+
+ <ComboBox Grid.Row="0" Grid.Column="2"
+ Grid.ColumnSpan="9"
+ Width="610"
+ Items="{Binding Operation.Operator, Converter={StaticResource EnumToCollectionConverter}, Mode=OneTime}"
+ SelectedItem="{Binding Operation.Operator, Converter={StaticResource FromValueDescriptionToEnumConverter}}"/>
+
+ <TextBlock Grid.Row="2" Grid.Column="0"
+ VerticalAlignment="Center"
+ IsVisible="{Binding Operation.ValueEnabled}"
+ IsEnabled="{Binding Operation.ValueEnabled}"
+ Text="Brightness:"/>
+
+ <StackPanel Grid.Row="2" Grid.Column="2"
+ VerticalAlignment="Center"
+ Orientation="Horizontal" Spacing="5"
+ IsVisible="{Binding Operation.ValueEnabled}"
+ IsEnabled="{Binding Operation.ValueEnabled}">
+
+ <NumericUpDown
+ Minimum="0"
+ Maximum="255"
+ Value="{Binding Operation.Value}"/>
+
+ <TextBlock VerticalAlignment="Center"
+ Text="{Binding Operation.ValuePercent, StringFormat={}{0}%}"/>
+
+ </StackPanel>
+
+ <CheckBox Grid.Row="2" Grid.Column="4"
+ Content="Affect empty/black pixels"
+ IsVisible="{Binding Operation.AffectBackPixelsEnabled}"
+ IsChecked="{Binding Operation.AffectBackPixels}"/>
+
+ <TextBlock Grid.Row="2" Grid.Column="4"
+ VerticalAlignment="Center"
+ HorizontalAlignment="Right"
+ IsVisible="{Binding Operation.ThresholdEnabled}"
+ IsEnabled="{Binding Operation.ThresholdEnabled}"
+ Text="Max.:"/>
+
+ <NumericUpDown Grid.Row="2" Grid.Column="6"
+ Minimum="0"
+ Maximum="255"
+ IsVisible="{Binding Operation.ThresholdEnabled}"
+ IsEnabled="{Binding Operation.ThresholdEnabled}"
+ Value="{Binding Operation.ThresholdMaxValue}"/>
+
+ <TextBlock Grid.Row="2" Grid.Column="8"
+ VerticalAlignment="Center"
+ HorizontalAlignment="Right"
+ IsVisible="{Binding Operation.ThresholdEnabled}"
+ IsEnabled="{Binding Operation.ThresholdEnabled}"
+ Text="Threshold:"/>
+
+ <ComboBox Grid.Row="2" Grid.Column="10"
+ Width="130"
+ IsVisible="{Binding Operation.ThresholdEnabled}"
+ IsEnabled="{Binding Operation.ThresholdEnabled}"
+ Items="{Binding Operation.ThresholdType, Converter={StaticResource EnumToCollectionConverter}, Mode=OneTime}"
+ SelectedItem="{Binding Operation.ThresholdType, Converter={StaticResource FromValueDescriptionToEnumConverter}}"/>
+
+
+ <TextBlock Grid.Row="4" Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Presets:"/>
+
+ <StackPanel Grid.Row="4" Grid.Column="2"
+ Grid.ColumnSpan="9"
+ VerticalAlignment="Center"
+ Orientation="Horizontal" Spacing="5">
+ <Button
+ Command="{Binding Operation.PresetStripAntiAliasing}"
+ Content="Strip anti-aliasing"/>
+
+ <Button
+ IsVisible="{Binding Operation.ValueEnabled}"
+ Command="{Binding Operation.PresetHalfBrightness}"
+ Content="Half brightness"/>
+ </StackPanel>
+
+ </Grid>
+ </StackPanel>
+
+</UserControl>
diff --git a/UVtools.WPF/Controls/Tools/ToolPixelArithmeticControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolPixelArithmeticControl.axaml.cs
new file mode 100644
index 0000000..eda6fcd
--- /dev/null
+++ b/UVtools.WPF/Controls/Tools/ToolPixelArithmeticControl.axaml.cs
@@ -0,0 +1,20 @@
+using Avalonia.Markup.Xaml;
+using UVtools.Core.Operations;
+
+namespace UVtools.WPF.Controls.Tools
+{
+ public partial class ToolPixelArithmeticControl : ToolControl
+ {
+ public OperationPixelArithmetic Operation => BaseOperation as OperationPixelArithmetic;
+ public ToolPixelArithmeticControl()
+ {
+ InitializeComponent();
+ BaseOperation = new OperationPixelArithmetic(SlicerFile);
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs b/UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs
index eaff935..f68e6f2 100644
--- a/UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs
+++ b/UVtools.WPF/Controls/Tools/ToolScriptingControl.axaml.cs
@@ -383,6 +383,11 @@ namespace UVtools.WPF.Controls.Tools
MinWidth = 150
};
+ if (numFLOAT.DecimalPlates > 0)
+ {
+ control.FormatString = $"F{numFLOAT.DecimalPlates}";
+ }
+
var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
valueProperty.Subscribe(value =>
{
@@ -407,6 +412,11 @@ namespace UVtools.WPF.Controls.Tools
MinWidth = 150
};
+ if (numDOUBLE.DecimalPlates > 0)
+ {
+ control.FormatString = $"F{numDOUBLE.DecimalPlates}";
+ }
+
var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
valueProperty.Subscribe(value =>
{
@@ -431,6 +441,11 @@ namespace UVtools.WPF.Controls.Tools
MinWidth = 150
};
+ if (numDECIMAL.DecimalPlates > 0)
+ {
+ control.FormatString = $"F{numDECIMAL.DecimalPlates}";
+ }
+
var valueProperty = control.GetObservable(NumericUpDown.ValueProperty);
valueProperty.Subscribe(value =>
{
diff --git a/UVtools.WPF/MainWindow.Clipboard.cs b/UVtools.WPF/MainWindow.Clipboard.cs
index bcbf66c..32784c7 100644
--- a/UVtools.WPF/MainWindow.Clipboard.cs
+++ b/UVtools.WPF/MainWindow.Clipboard.cs
@@ -70,7 +70,7 @@ namespace UVtools.WPF
return;
}
if (clip?.Operation is null) return;
- if (clip.Operation.HaveROI)
+ /*if (clip.Operation.HaveROI)
{
ROI = GetTransposedRectangle(clip.Operation.ROI);
}
@@ -78,7 +78,7 @@ namespace UVtools.WPF
if (clip.Operation.HaveMask)
{
AddMaskPoints(clip.Operation.MaskPoints);
- }
+ }*/
var operation = await ShowRunOperation(clip.Operation.GetType(), clip.Operation);
if (operation is null)
diff --git a/UVtools.WPF/MainWindow.axaml b/UVtools.WPF/MainWindow.axaml
index 019700e..01577b8 100644
--- a/UVtools.WPF/MainWindow.axaml
+++ b/UVtools.WPF/MainWindow.axaml
@@ -284,67 +284,24 @@
VerticalAlignment="Center">
<TextBlock Text="{Binding SlicerFile.LayerHeight, StringFormat=Layer height: \{0\}mm}"/>
- <TextBlock Text=" | Bottom layers: "/>
- <TextBlock Text="{Binding SlicerFile.BottomLayerCount}"/>
-
- <TextBlock Text=" | Exposures: "/>
-
- <TextBlock>
- <TextBlock.Text>
- <MultiBinding StringFormat="\{0\}s/\{1\}s">
- <Binding Path="SlicerFile.BottomExposureTime"/>
- <Binding Path="SlicerFile.ExposureTime"/>
- </MultiBinding>
- </TextBlock.Text>
- </TextBlock>
-
- <TextBlock IsVisible="{Binding SlicerFile.BottomLiftHeight}" Text=" | Lift: "/>
- <TextBlock IsVisible="{Binding SlicerFile.BottomLiftHeight}">
- <TextBlock.Text>
- <MultiBinding StringFormat="\{0\}/\{1\}mm @ \{2\}/\{3\}mm/min">
- <Binding Path="SlicerFile.BottomLiftHeight"/>
- <Binding Path="SlicerFile.LiftHeight"/>
- <Binding Path="SlicerFile.BottomLiftSpeed"/>
- <Binding Path="SlicerFile.LiftSpeed"/>
- </MultiBinding>
- </TextBlock.Text>
- </TextBlock>
+ <TextBlock Text=" | "/>
+ <TextBlock Text="{Binding SlicerFile.BottomLayerCount, StringFormat=Bottom layers: {0}}"/>
- <!--
- <TextBlock IsVisible="{Binding SlicerFile.BottomLiftHeight}" Text="| Bottom lift:"/>
- <TextBlock IsVisible="{Binding SlicerFile.BottomLiftHeight}">
- <TextBlock.Text>
- <MultiBinding StringFormat="\{0\}mm @ \{1\}mm/min">
- <Binding Path="SlicerFile.BottomLiftHeight"/>
- <Binding Path="SlicerFile.BottomLiftSpeed"/>
- </MultiBinding>
- </TextBlock.Text>
- </TextBlock>
-
- <TextBlock IsVisible="{Binding SlicerFile.LiftHeight}" Text="| Lift:"/>
- <TextBlock IsVisible="{Binding SlicerFile.LiftHeight}">
- <TextBlock.Text>
- <MultiBinding StringFormat="\{0\}mm @ \{1\}mm/min">
- <Binding Path="SlicerFile.LiftHeight"/>
- <Binding Path="SlicerFile.LiftSpeed"/>
- </MultiBinding>
- </TextBlock.Text>
- </TextBlock>
- !-->
-
- <TextBlock IsVisible="{Binding SlicerFile.RetractSpeed}" Text=" | "/>
- <TextBlock IsVisible="{Binding SlicerFile.RetractSpeed}"
- Text="{Binding SlicerFile.RetractSpeed, StringFormat=Retract Speed: \{0\}mm/min}"/>
-
- <TextBlock IsVisible="{Binding SlicerFile.LightOffDelay}" Text=" | Light-off: "/>
- <TextBlock IsVisible="{Binding SlicerFile.LightOffDelay}">
- <TextBlock.Text>
- <MultiBinding StringFormat="\{0\}s/\{1\}s">
- <Binding Path="SlicerFile.BottomLightOffDelay"/>
- <Binding Path="SlicerFile.LightOffDelay"/>
- </MultiBinding>
- </TextBlock.Text>
- </TextBlock>
+ <TextBlock Text=" | "/>
+ <TextBlock Text="{Binding SlicerFile.ExposureRepresentation, StringFormat=Exposure: {0}}"/>
+
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyLiftHeight}" Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyLiftHeight}"
+ Text="{Binding SlicerFile.LiftRepresentation, StringFormat=Lift: {0}}"/>
+
+
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseRetractSpeed}" Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseRetractSpeed}"
+ Text="{Binding SlicerFile.RetractRepresentation, StringFormat=Retract: {0}}"/>
+
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyLightOffDelay}" Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyLightOffDelay}"
+ Text="{Binding SlicerFile.LightOffDelayRepresentation, StringFormat=Light-off: {0}}"/>
<TextBlock IsVisible="{Binding SlicerFile.PrintTimeHours}" Text=" | "/>
<TextBlock IsVisible="{Binding SlicerFile.PrintTimeHours}"
diff --git a/UVtools.WPF/MainWindow.axaml.cs b/UVtools.WPF/MainWindow.axaml.cs
index 84d074a..fd456c1 100644
--- a/UVtools.WPF/MainWindow.axaml.cs
+++ b/UVtools.WPF/MainWindow.axaml.cs
@@ -132,17 +132,25 @@ namespace UVtools.WPF
Source = new Bitmap(App.GetAsset("/Assets/Icons/code-branch-16x16.png"))
}
},
- new()
+ /*new()
{
Tag = new OperationThreshold(),
Icon = new Avalonia.Controls.Image
{
Source = new Bitmap(App.GetAsset("/Assets/Icons/th-16x16.png"))
}
+ },*/
+ new()
+ {
+ Tag = new OperationLayerArithmetic(),
+ Icon = new Avalonia.Controls.Image
+ {
+ Source = new Bitmap(App.GetAsset("/Assets/Icons/square-root-16x16.png"))
+ }
},
new()
{
- Tag = new OperationArithmetic(),
+ Tag = new OperationPixelArithmetic(),
Icon = new Avalonia.Controls.Image
{
Source = new Bitmap(App.GetAsset("/Assets/Icons/square-root-16x16.png"))
@@ -792,6 +800,9 @@ namespace UVtools.WPF
ClearROIAndMask();
+ if(!Settings.Tools.LastUsedSettingsKeepOnCloseFile)
+ OperationSessionManager.Instance.Clear();
+
ResetDataContext();
}
@@ -1550,7 +1561,8 @@ namespace UVtools.WPF
return false;
});
-
+ OperationSessionManager.Instance.Add(baseOperation);
+
IsGUIEnabled = true;
if (result)
diff --git a/UVtools.WPF/Structures/OperationProfiles.cs b/UVtools.WPF/Structures/OperationProfiles.cs
index ff1e78e..b7fd8e2 100644
--- a/UVtools.WPF/Structures/OperationProfiles.cs
+++ b/UVtools.WPF/Structures/OperationProfiles.cs
@@ -24,31 +24,25 @@ namespace UVtools.WPF.Structures
/// </summary>
private static string FilePath => Path.Combine(UserSettings.SettingsFolder, "operation_profiles.xml");
- [XmlElement(typeof(OperationArithmetic))]
- [XmlElement(typeof(OperationBlur))]
- //[XmlElement(typeof(OperationCalculator))]
- [XmlElement(typeof(OperationChangeResolution))]
- //[XmlElement(typeof(OperationEditParameters))]
+ [XmlElement(typeof(OperationResize))]
[XmlElement(typeof(OperationFlip))]
- //[XmlElement(typeof(OperationLayerClone))]
- //[XmlElement(typeof(OperationLayerImport))]
- [XmlElement(typeof(OperationDynamicLayerHeight))]
- [XmlElement(typeof(OperationDynamicLifts))]
- //[XmlElement(typeof(OperationLayerReHeight))]
- //[XmlElement(typeof(OperationLayerRemove))]
- //[XmlElement(typeof(OperationMask))]
+ [XmlElement(typeof(OperationRotate))]
+ [XmlElement(typeof(OperationSolidify))]
[XmlElement(typeof(OperationMorph))]
[XmlElement(typeof(OperationRaftRelief))]
[XmlElement(typeof(OperationRedrawModel))]
- //[XmlElement(typeof(OperationMove))]
- //[XmlElement(typeof(OperationPattern))]
+ [XmlElement(typeof(OperationThreshold))]
+ [XmlElement(typeof(OperationLayerArithmetic))]
+ [XmlElement(typeof(OperationPixelArithmetic))]
[XmlElement(typeof(OperationPixelDimming))]
[XmlElement(typeof(OperationInfill))]
- //[XmlElement(typeof(OperationRepairLayers))]
- [XmlElement(typeof(OperationResize))]
- [XmlElement(typeof(OperationRotate))]
- [XmlElement(typeof(OperationThreshold))]
+ [XmlElement(typeof(OperationBlur))]
+ [XmlElement(typeof(OperationDynamicLayerHeight))]
+ [XmlElement(typeof(OperationDynamicLifts))]
+ [XmlElement(typeof(OperationChangeResolution))]
+
[XmlElement(typeof(OperationLayerExportGif))]
+
[XmlElement(typeof(OperationCalibrateExposureFinder))]
[XmlElement(typeof(OperationCalibrateElephantFoot))]
[XmlElement(typeof(OperationCalibrateXYZAccuracy))]
diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj
index e0bae71..1793bcc 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>2.10.0</Version>
+ <Version>2.11.0</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -74,6 +74,9 @@
<AvaloniaResource Include="Assets\Icons\*" />
</ItemGroup>
<ItemGroup>
+ <Compile Update="Controls\Tools\ToolLayerArithmeticControl.axaml.cs">
+ <DependentUpon>ToolLayerArithmeticControl.axaml</DependentUpon>
+ </Compile>
<Compile Update="Windows\PrusaSlicerManagerWindow.axaml.cs">
<DependentUpon>PrusaSlicerManagerWindow.axaml</DependentUpon>
</Compile>
diff --git a/UVtools.WPF/UserSettings.cs b/UVtools.WPF/UserSettings.cs
index 2ce94f2..26fc181 100644
--- a/UVtools.WPF/UserSettings.cs
+++ b/UVtools.WPF/UserSettings.cs
@@ -22,7 +22,7 @@ namespace UVtools.WPF
public sealed class UserSettings : BindableBase
{
#region Constants
- public const ushort SETTINGS_VERSION = 2;
+ public const ushort SETTINGS_VERSION = 3;
#endregion
#region Sub classes
@@ -1122,6 +1122,36 @@ namespace UVtools.WPF
}
#endregion
+ #region Tools
+
+ [Serializable]
+ public sealed class ToolsUserSettings : BindableBase
+ {
+ private bool _restoreLastUsedSettings;
+ private bool _lastUsedSettingsKeepOnCloseFile = true;
+ private bool _lastUsedSettingsPriorityOverDefaultProfile = true;
+
+ public bool RestoreLastUsedSettings
+ {
+ get => _restoreLastUsedSettings;
+ set => RaiseAndSetIfChanged(ref _restoreLastUsedSettings, value);
+ }
+
+ public bool LastUsedSettingsKeepOnCloseFile
+ {
+ get => _lastUsedSettingsKeepOnCloseFile;
+ set => RaiseAndSetIfChanged(ref _lastUsedSettingsKeepOnCloseFile, value);
+ }
+
+ public bool LastUsedSettingsPriorityOverDefaultProfile
+ {
+ get => _lastUsedSettingsPriorityOverDefaultProfile;
+ set => RaiseAndSetIfChanged(ref _lastUsedSettingsPriorityOverDefaultProfile, value);
+ }
+ }
+
+ #endregion
+
#region Automations
[Serializable]
@@ -1214,6 +1244,7 @@ namespace UVtools.WPF
private IssuesUserSettings _issues;
private PixelEditorUserSettings _pixelEditor;
private LayerRepairUserSettings _layerRepair;
+ private ToolsUserSettings _tools;
private AutomationsUserSettings _automations;
private ushort _settingsVersion = SETTINGS_VERSION;
private string _appVersion;
@@ -1255,6 +1286,12 @@ namespace UVtools.WPF
set => _layerRepair = value;
}
+ public ToolsUserSettings Tools
+ {
+ get => _tools ??= new ToolsUserSettings();
+ set => _tools = value;
+ }
+
public AutomationsUserSettings Automations
{
get => _automations ??= new AutomationsUserSettings();
diff --git a/UVtools.WPF/Windows/SettingsWindow.axaml b/UVtools.WPF/Windows/SettingsWindow.axaml
index a300e3f..c12fcb8 100644
--- a/UVtools.WPF/Windows/SettingsWindow.axaml
+++ b/UVtools.WPF/Windows/SettingsWindow.axaml
@@ -1413,7 +1413,7 @@
</ScrollViewer>
</TabItem>
- <TabItem Header="Automations" VerticalContentAlignment="Center">
+ <TabItem Header="Tools" VerticalContentAlignment="Center">
<ScrollViewer Name="ScrollViewer5">
<StackPanel Orientation="Vertical" Spacing="5">
<Border
@@ -1423,6 +1423,36 @@
<StackPanel Orientation="Vertical">
<TextBlock Padding="10" Background="LightBlue" FontWeight="Bold" Text="Common"/>
<StackPanel Margin="10" Orientation="Vertical" Spacing="10">
+ <CheckBox IsChecked="{Binding Settings.Tools.RestoreLastUsedSettings}"
+ Content="Keep and restore the last used settings on operations per user session/instance"/>
+
+ <ToggleSwitch IsChecked="{Binding Settings.Tools.LastUsedSettingsKeepOnCloseFile}"
+ OffContent="Discard the session when closing or loading files"
+ OnContent="Keep the session when closing or loading files"/>
+
+ <ToggleSwitch IsChecked="{Binding Settings.Tools.LastUsedSettingsPriorityOverDefaultProfile}"
+ IsEnabled="{Binding Settings.Tools.RestoreLastUsedSettings}"
+ OffContent="Default profile will priority over the session"
+ OnContent="Session will priority over the default profile"/>
+ </StackPanel>
+
+ </StackPanel>
+ </Border>
+
+ </StackPanel>
+ </ScrollViewer>
+ </TabItem>
+
+ <TabItem Header="Automations" VerticalContentAlignment="Center">
+ <ScrollViewer Name="ScrollViewer6">
+ <StackPanel Orientation="Vertical" Spacing="5">
+ <Border
+ Classes="GroupBox"
+ Margin="5">
+
+ <StackPanel Orientation="Vertical">
+ <TextBlock Padding="10" Background="LightBlue" FontWeight="Bold" Text="Common"/>
+ <StackPanel Margin="10" Orientation="Vertical" Spacing="10">
<CheckBox IsChecked="{Binding Settings.Automations.SaveFileAfterModifications}" Content="Auto save the file after apply any automation(s)"/>
</StackPanel>
@@ -1513,6 +1543,8 @@
</ScrollViewer>
</TabItem>
+
+
</TabControl>
<Border Grid.Row="1" Classes="FooterActions">
diff --git a/UVtools.WPF/Windows/ToolWindow.axaml b/UVtools.WPF/Windows/ToolWindow.axaml
index 7e8f766..ff1936d 100644
--- a/UVtools.WPF/Windows/ToolWindow.axaml
+++ b/UVtools.WPF/Windows/ToolWindow.axaml
@@ -365,6 +365,44 @@
<Grid RowDefinitions="Auto"
ColumnDefinitions="*">
<StackPanel Spacing="10" Orientation="Horizontal">
+ <Button
+ Command="{Binding #OptionsContextMenu.Open}"
+ Padding="10"
+ Content="☰">
+ <Button.ContextMenu>
+ <ContextMenu Name="OptionsContextMenu" PlacementMode="Top">
+ <MenuItem
+ IsVisible="{Binding CanROI}"
+ Command="{Binding SelectVolumeBoundingRectangle}"
+ Header="Select print volume ROI">
+ <MenuItem.Icon>
+ <Image Source="/Assets/Icons/expand-16x16.png"/>
+ </MenuItem.Icon>
+ </MenuItem>
+
+ <Separator IsVisible="{Binding CanROI}"/>
+
+ <MenuItem
+ IsVisible="{Binding CanHaveProfiles}"
+ Command="{Binding ImportSettings}"
+ Header="Import settings">
+ <MenuItem.Icon>
+ <Image Source="/Assets/Icons/file-import-16x16.png"/>
+ </MenuItem.Icon>
+ </MenuItem>
+
+ <MenuItem
+ IsVisible="{Binding CanHaveProfiles}"
+ Command="{Binding ExportSettings}"
+ Header="Export settings">
+ <MenuItem.Icon>
+ <Image Source="/Assets/Icons/file-export-16x16.png"/>
+ </MenuItem.Icon>
+ </MenuItem>
+ </ContextMenu>
+ </Button.ContextMenu>
+ </Button>
+
<Button
Padding="10"
IsDefault="True"
@@ -388,7 +426,8 @@
Spacing="10"
HorizontalAlignment="Right"
Orientation="Horizontal">
- <Button
+
+ <Button
Padding="10"
IsDefault="True"
IsVisible="{Binding ButtonOkVisible}"
diff --git a/UVtools.WPF/Windows/ToolWindow.axaml.cs b/UVtools.WPF/Windows/ToolWindow.axaml.cs
index eba5086..de40575 100644
--- a/UVtools.WPF/Windows/ToolWindow.axaml.cs
+++ b/UVtools.WPF/Windows/ToolWindow.axaml.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.ObjectModel;
using System.Drawing;
+using System.IO;
+using System.Xml.Serialization;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
@@ -9,12 +11,13 @@ using Avalonia.Threading;
using MessageBox.Avalonia.Enums;
using UVtools.Core;
using UVtools.Core.Extensions;
+using UVtools.Core.Managers;
using UVtools.Core.Operations;
using UVtools.WPF.Controls;
using UVtools.WPF.Controls.Tools;
using UVtools.WPF.Extensions;
using UVtools.WPF.Structures;
-using Point = Avalonia.Point;
+using Helpers = UVtools.WPF.Controls.Helpers;
namespace UVtools.WPF.Windows
{
@@ -285,7 +288,20 @@ namespace UVtools.WPF.Windows
}
}
- public Rectangle ROI => App.MainWindow.ROI;
+ public bool CanROI => ToolControl.BaseOperation.CanROI;
+
+ public Rectangle ROI
+ {
+ get => App.MainWindow.ROI;
+ set
+ {
+ App.MainWindow.ROI = App.MainWindow.GetTransposedRectangle(value);
+ ToolControl.BaseOperation.ROI = value;
+ IsROIVisible = !value.IsEmpty;
+ RaisePropertyChanged();
+ }
+ }
+
public System.Drawing.Point[][] Masks => App.MainWindow.MaskPoints?.ToArray();
public bool ClearROIAndMaskAfterOperation
@@ -299,8 +315,8 @@ namespace UVtools.WPF.Windows
if (await this.MessageBoxQuestion("Are you sure you want to clear the current ROI?\n" +
"This action can not be reverted, to select another ROI you must quit this window and select it on layer preview.",
"Clear the current ROI?") != ButtonResult.Yes) return;
- IsROIVisible = false;
- App.MainWindow.ClearROI();
+
+ ROI = Rectangle.Empty;
ToolControl?.Callback(Callbacks.ClearROI);
}
@@ -311,12 +327,21 @@ namespace UVtools.WPF.Windows
"Clear the all masks?") != ButtonResult.Yes) return;
IsMasksVisible = false;
App.MainWindow.ClearMask();
+ ToolControl.BaseOperation.ClearMasks();
ToolControl?.Callback(Callbacks.ClearROI);
}
+ public void SelectVolumeBoundingRectangle()
+ {
+ ROI = SlicerFile.BoundingRectangle;
+ }
+
#endregion
#region Profiles
+
+ public bool CanHaveProfiles => ToolControl.BaseOperation.CanHaveProfiles;
+
public bool IsProfilesVisible
{
get => _isProfilesVisible;
@@ -565,8 +590,42 @@ namespace UVtools.WPF.Windows
_buttonOkText = toolControl.BaseOperation.ButtonOkText;
_buttonOkVisible = ButtonOkEnabled = toolControl.BaseOperation.HaveAction;
- if (toolControl.BaseOperation.HaveExecuted) // Come from a redo or something
+ bool fromSession = false;
+ if (!toolControl.BaseOperation.HaveExecuted && Settings.Tools.RestoreLastUsedSettings)
+ {
+ var operation = OperationSessionManager.Instance.Find(toolControl.BaseOperation.GetType());
+ if (operation is not null)
+ {
+ toolControl.BaseOperation = operation.Clone();
+ toolControl.BaseOperation.ClearROIandMasks();
+
+ switch (operation.LayerRangeSelection)
+ {
+ case Enumerations.LayerRangeSelection.None:
+ LayerIndexStart = operation.LayerIndexStart;
+ LayerIndexEnd = operation.LayerIndexEnd;
+ break;
+ default:
+ SelectLayers(operation.LayerRangeSelection);
+ break;
+ }
+
+ fromSession = true;
+ }
+ }
+
+ if (toolControl.BaseOperation.HaveExecuted) // Come from a redo or session
{
+ if (toolControl.BaseOperation.HaveROI)
+ {
+ ROI = toolControl.BaseOperation.ROI;
+ }
+
+ if (toolControl.BaseOperation.HaveMask)
+ {
+ App.MainWindow.AddMaskPoints(toolControl.BaseOperation.MaskPoints);
+ }
+
LayerIndexStart = toolControl.BaseOperation.LayerIndexStart;
LayerIndexEnd = toolControl.BaseOperation.LayerIndexEnd;
}
@@ -575,25 +634,38 @@ namespace UVtools.WPF.Windows
SelectLayers(toolControl.BaseOperation.StartLayerRangeSelection);
}
- //RaisePropertyChanged(nameof(IsContentVisible));
- //RaisePropertyChanged(nameof(IsROIVisible));
-
if (ToolControl.BaseOperation.CanHaveProfiles)
{
+ _isProfilesVisible = true;
var profiles = OperationProfiles.GetOperations(ToolControl.BaseOperation.GetType());
- Profiles.AddRange(profiles);
- IsProfilesVisible = true;
+ _profiles.AddRange(profiles);
- foreach (var operation in Profiles)
+ if (!toolControl.BaseOperation.HaveExecuted ||
+ (toolControl.BaseOperation.HaveExecuted && fromSession && !Settings.Tools.LastUsedSettingsPriorityOverDefaultProfile))
{
- if (operation.ProfileIsDefault)
+ //Operation profile = _profiles.FirstOrDefault(operation => operation.ProfileIsDefault);
+ foreach (var operation in Profiles)
{
- SelectedProfileItem = operation;
- break;
+ if (operation.ProfileIsDefault)
+ {
+ SelectedProfileItem = operation;
+ break;
+ }
}
}
}
+ if (!ReferenceEquals(toolControl.BaseOperation.SlicerFile, SlicerFile)) // Sanitize
+ {
+ toolControl.BaseOperation.SlicerFile = SlicerFile;
+ }
+
+
+ //RaisePropertyChanged(nameof(IsContentVisible));
+ //RaisePropertyChanged(nameof(IsROIVisible));
+
+
+
// Ensure the description don't stretch window
DispatcherTimer.Run(() =>
{
@@ -729,5 +801,69 @@ namespace UVtools.WPF.Windows
if (parent is null) return;
menu.Open(parent);
}
+
+ public async void ExportSettings()
+ {
+ if (ToolControl.BaseOperation is null) return;
+ var dialog = new SaveFileDialog
+ {
+ Filters = Helpers.OperationSettingFileFilter,
+ InitialFileName = ToolControl.BaseOperation.Id
+ };
+
+ var file = await dialog.ShowAsync(this);
+
+ if (string.IsNullOrWhiteSpace(file)) return;
+
+ try
+ {
+ XmlSerializer serializer = new(ToolControl.BaseOperation.GetType());
+ await using StreamWriter writer = new(file);
+ serializer.Serialize(writer, ToolControl.BaseOperation);
+ }
+ catch (Exception e)
+ {
+ await this.MessageBoxError(e.ToString(), "Error while trying to export the settings");
+ }
+ }
+
+ public async void ImportSettings()
+ {
+ var dialog = new OpenFileDialog
+ {
+ AllowMultiple = false,
+ Filters = Helpers.OperationSettingFileFilter
+ };
+
+ var files = await dialog.ShowAsync(this);
+
+ if (files is null || files.Length == 0) return;
+
+ try
+ {
+ XmlSerializer serializer = new(ToolControl.BaseOperation.GetType());
+ await using var stream = File.OpenRead(files[0]);
+ var operation = (Operation)serializer.Deserialize(stream);
+
+ operation.SlicerFile = SlicerFile;
+ ToolControl.BaseOperation = operation;
+ switch (operation.LayerRangeSelection)
+ {
+ case Enumerations.LayerRangeSelection.None:
+ LayerIndexStart = operation.LayerIndexStart;
+ LayerIndexEnd = operation.LayerIndexEnd;
+ break;
+ default:
+ SelectLayers(operation.LayerRangeSelection);
+ break;
+ }
+
+ ToolControl.Callback(Callbacks.ProfileLoaded);
+ }
+ catch (Exception e)
+ {
+ await this.MessageBoxError(e.ToString(), "Error while trying to import the settings");
+ }
+ }
}
}