WPF progress

This commit is contained in:
Tiago Conceição
2020-09-28 03:43:51 +01:00
parent 14a681e642
commit 3015a1d53f
16 changed files with 424 additions and 21 deletions
+4
View File
@@ -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
+13 -2
View File
@@ -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
@@ -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()
@@ -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)
@@ -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
+3
View File
@@ -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
}
}
@@ -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;
@@ -0,0 +1,51 @@
<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.ToolEditParametersControl">
<Grid
Name="grid"
RowDefinitions="Auto"
ColumnDefinitions="Auto,Auto,Auto,Auto,Auto"
VerticalAlignment="Center"
ShowGridLines="True"
>
<TextBlock
Grid.Column="0"
VerticalAlignment="Center"
FontWeight="Bold"
Padding="15"
Text="Property"/>
<TextBlock
Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontWeight="Bold"
Padding="15"
Text="Old value"/>
<TextBlock
Grid.Column="2"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontWeight="Bold"
Padding="15"
Text="New value"/>
<TextBlock
Grid.Column="3"
VerticalAlignment="Center"
FontWeight="Bold"
Padding="15"
Text="Unit"/>
<TextBlock
Grid.Column="4"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontWeight="Bold"
Padding="15"
Text="Reset"/>
</Grid>
</UserControl>
@@ -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>("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;
}
}
}
}
@@ -0,0 +1,20 @@
<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.ToolLayerReHeightControl">
<StackPanel Orientation="Vertical" Spacing="15">
<TextBlock VerticalAlignment="Center" Text="{Binding CurrentLayers}"/>
<StackPanel Orientation="Horizontal" Spacing="10">
<TextBlock VerticalAlignment="Center" Text="Modifier:"/>
<ComboBox
MinWidth="250"
SelectedItem="{Binding Operation.Item}"
Items="{Binding Presets}"
/>
</StackPanel>
</StackPanel>
</UserControl>
@@ -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);
}
}
}
+4 -3
View File
@@ -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<ButtonResult> 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<ButtonResult> 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<ButtonResult> 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)
+16 -2
View File
@@ -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;
+4 -1
View File
@@ -29,7 +29,7 @@
<PackageReference Include="Emgu.CV.runtime.raspbian" Version="4.4.0.4061" />
<PackageReference Include="Emgu.CV.runtime.ubuntu" Version="4.4.0.4061" />
<PackageReference Include="Emgu.CV.runtime.windows" Version="4.4.0.4061" />
<PackageReference Include="MessageBox.Avalonia" Version="0.10.0-prev2" />
<PackageReference Include="MessageBox.Avalonia" Version="0.10.1-night" />
<PackageReference Include="ThemeEditor.Controls.ColorPicker" Version="0.10.0-preview3" />
</ItemGroup>
<ItemGroup>
@@ -201,10 +201,13 @@
<None Update="x64\libcvextern.so">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\CHANGELOG.md" Link="CHANGELOG.md" />
<None Include="..\CREDITS.md" Link="CREDITS.md" />
<None Include="..\LICENSE">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
<None Include="..\README.md" Link="README.md" />
</ItemGroup>
<ItemGroup>
<Compile Update="Controls\Tools\ToolResizeControl.axaml.cs">
+17 -3
View File
@@ -206,11 +206,25 @@
<Border Margin="0,10,0,0" Padding="5,20" Background="LightGray">
<Grid ColumnDefinitions="*">
<StackPanel Orientation="Horizontal">
<StackPanel Spacing="10" Orientation="Horizontal">
<Button
Padding="10"
IsDefault="True"
IsVisible="{Binding IsButton1Visible}"
Command="{Binding OnButton1Click}">
<StackPanel
Orientation="Horizontal"
Spacing="10">
<Image Source="/Assets/Icons/undo-alt-16x16.png"/>
<TextBlock Text="{Binding Button1Text}"/>
</StackPanel>
</Button>
</StackPanel>
<StackPanel Spacing="10" HorizontalAlignment="Right" Orientation="Horizontal">
<StackPanel
Spacing="10"
HorizontalAlignment="Right"
Orientation="Horizontal">
<Button
Padding="10"
IsDefault="True"
+19
View File
@@ -15,6 +15,7 @@ namespace UVtools.WPF.Windows
{
public enum Callbacks : byte
{
Init,
ClearROI,
Button1, // Reset to defaults
Checkbox1, // Show Advanced
@@ -32,6 +33,8 @@ namespace UVtools.WPF.Windows
private bool _clearRoiAfterOperation;
private IControl _contentControl;
private bool _isButton1Visible;
private string _button1Text = "Reset to defaults";
#region Description
@@ -181,6 +184,20 @@ namespace UVtools.WPF.Windows
#region Actions
public bool IsButton1Visible
{
get => _isButton1Visible;
set => RaiseAndSetIfChanged(ref _isButton1Visible, value);
}
public string Button1Text
{
get => _button1Text;
set => RaiseAndSetIfChanged(ref _button1Text, value);
}
public void OnButton1Click() => ToolControl.Callback(Callbacks.Button1);
public bool ButtonOkEnabled
{
get => _buttonOkEnabled;
@@ -261,6 +278,8 @@ namespace UVtools.WPF.Windows
timer.Dispose();
};
timer.Start();
toolControl.Callback(Callbacks.Init);
}
private void InitializeComponent()