Files
UVtools/UVtools.WPF/Controls/Tools/ToolPCBExposureControl.axaml.cs
Tiago Conceição 2c7ad09dc0 v3.13.1
- (Change) `Layer.IsBottomLayer` no longer calculate the value using the position of the layer, a new property `IsBottomLayerByHeight` is now used to get that result
- (Improvement) Tool - Double exposure: Increase the bottom layer count per cloned bottom layer
- (Improvement) Calibration - Exposure time finder: Set the absolute bottom layer count accordingly when also testing for bottom time
- (Improvement) Goo: Enforce Wait times or Light-off-delay flag based on property set
- (Fix) AnyCubic and Goo: `PerLayerSetting` flag was set inverted causing printer not to follow layer settings when it should and also the otherwise (#689)
- (Fix) Tool - Scripting: Prevent from reload UI multiple times when using profiles (#694)
2023-04-27 22:58:05 +01:00

243 lines
8.0 KiB
C#

using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Markup.Xaml;
using Avalonia.Threading;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Timers;
using UVtools.Core.Excellon;
using UVtools.Core.Extensions;
using UVtools.Core.Operations;
using UVtools.WPF.Extensions;
using UVtools.WPF.Windows;
using Bitmap = Avalonia.Media.Imaging.Bitmap;
namespace UVtools.WPF.Controls.Tools
{
public partial class ToolPCBExposureControl : ToolControl
{
public OperationPCBExposure Operation => BaseOperation as OperationPCBExposure;
private readonly Timer _timer;
private DataGrid FilesDataGrid;
private Bitmap _previewImage;
private OperationPCBExposure.PCBExposureFile _selectedFile;
private bool _cropPreview = true;
public Bitmap PreviewImage
{
get => _previewImage;
set => RaiseAndSetIfChanged(ref _previewImage, value);
}
public OperationPCBExposure.PCBExposureFile SelectedFile
{
get => _selectedFile;
set
{
if (!RaiseAndSetIfChanged(ref _selectedFile, value)) return;
UpdatePreview();
}
}
public bool CropPreview
{
get => _cropPreview;
set
{
if(!RaiseAndSetIfChanged(ref _cropPreview, value)) return;
UpdatePreview();
}
}
public ToolPCBExposureControl()
{
BaseOperation = new OperationPCBExposure(SlicerFile);
if (!ValidateSpawn()) return;
InitializeComponent();
FilesDataGrid = this.Find<DataGrid>("FilesDataGrid");
AddHandler(DragDrop.DropEvent, (sender, args) =>
{
Operation.AddFiles(args.Data.GetFileNames()?.ToArray() ?? Array.Empty<string>());
});
_timer = new Timer(50)
{
AutoReset = false
};
_timer.Elapsed += (sender, e) =>
{
Dispatcher.UIThread.InvokeAsync(UpdatePreview);
};
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
public override void Callback(ToolWindow.Callbacks callback)
{
if (App.SlicerFile is null) return;
switch (callback)
{
case ToolWindow.Callbacks.Init:
case ToolWindow.Callbacks.AfterLoadProfile:
Operation.PropertyChanged += (sender, e) =>
{
_timer.Stop();
_timer.Start();
};
Operation.Files.CollectionChanged += (sender, e) =>
{
if (e.NewItems is null) return;
foreach (OperationPCBExposure.PCBExposureFile file in e.NewItems)
{
file.PropertyChanged += (o, args) =>
{
if (!ReferenceEquals(_selectedFile, file)) return;
_timer.Stop();
_timer.Start();
};
}
};
_timer.Stop();
_timer.Start();
if(ParentWindow is not null) ParentWindow.ButtonOkEnabled = Operation.FileCount > 0;
Operation.Files.CollectionChanged += (sender, e) => ParentWindow.ButtonOkEnabled = Operation.FileCount > 0;
break;
}
}
public void UpdatePreview()
{
try
{
PreviewImage = null;
if (_selectedFile is null)
{
return;
}
if (!OperationPCBExposure.ValidExtensions.Any(extension => _selectedFile.IsExtension(extension)) || !_selectedFile.Exists) return;
var file = (OperationPCBExposure.PCBExposureFile)_selectedFile.Clone();
file._invertPolarity = ExcellonDrillFormat.Extensions.Any(extension => file.IsExtension(extension));
_previewImage?.Dispose();
using var mat = Operation.GetMat(file);
if (_cropPreview)
{
using var matCropped = mat.CropByBounds(20);
PreviewImage = matCropped.ToBitmapParallel();
}
else
{
PreviewImage = mat.ToBitmapParallel();
}
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
public async void AddFiles()
{
var dialog = new OpenFileDialog
{
AllowMultiple = true,
Filters = new List<FileDialogFilter>
{
new()
{
Name = "Gerber files",
Extensions = new List<string>(OperationPCBExposure.ValidExtensions)
},
},
};
var files = await dialog.ShowAsync(ParentWindow);
if (files is null || files.Length == 0) return;
Operation.AddFiles(files);
}
public async void AddFilesFromZip()
{
var dialog = new OpenFileDialog
{
AllowMultiple = false,
Filters = Helpers.ZipFileFilter
};
var files = await dialog.ShowAsync(ParentWindow);
if (files is null || files.Length == 0) return;
Operation.AddFilesFromZip(files[0]);
}
public void RemoveFiles()
{
Operation.Files.RemoveRange(FilesDataGrid.SelectedItems.OfType<OperationPCBExposure.PCBExposureFile>());
}
public void MoveFileTop()
{
if (FilesDataGrid.SelectedIndex <= 0) return;
var selectedFile = SelectedFile;
Operation.Files.RemoveAt(FilesDataGrid.SelectedIndex);
Operation.Files.Insert(0, selectedFile);
FilesDataGrid.SelectedIndex = 0;
FilesDataGrid.ScrollIntoView(selectedFile, FilesDataGrid.Columns[0]);
}
public void MoveFileUp()
{
if (FilesDataGrid.SelectedIndex <= 0) return;
var selectedFile = SelectedFile;
var newIndex = FilesDataGrid.SelectedIndex - 1;
Operation.Files.RemoveAt(FilesDataGrid.SelectedIndex);
Operation.Files.Insert(newIndex, selectedFile);
FilesDataGrid.SelectedIndex = newIndex;
FilesDataGrid.ScrollIntoView(selectedFile, FilesDataGrid.Columns[0]);
}
public void MoveFileDown()
{
if (FilesDataGrid.SelectedIndex == -1 || FilesDataGrid.SelectedIndex == Operation.FileCount - 1) return;
var selectedFile = SelectedFile;
var newIndex = FilesDataGrid.SelectedIndex + 1;
Operation.Files.RemoveAt(FilesDataGrid.SelectedIndex);
Operation.Files.Insert(newIndex, selectedFile);
FilesDataGrid.SelectedIndex = newIndex;
FilesDataGrid.ScrollIntoView(selectedFile, FilesDataGrid.Columns[0]);
}
public void MoveFileBottom()
{
var lastIndex = Operation.Files.Count - 1;
if (FilesDataGrid.SelectedIndex == -1 || FilesDataGrid.SelectedIndex == lastIndex) return;
var selectedFile = SelectedFile;
Operation.Files.RemoveAt(FilesDataGrid.SelectedIndex);
Operation.Files.Insert(lastIndex, selectedFile);
FilesDataGrid.SelectedIndex = lastIndex;
FilesDataGrid.ScrollIntoView(selectedFile, FilesDataGrid.Columns[0]);
}
public void ClearFiles()
{
Operation.Files.Clear();
PreviewImage = null;
}
}
}