From af363ebb9a2874eabf5357cbacb6e39e77f0f626 Mon Sep 17 00:00:00 2001 From: unclshura Date: Mon, 25 May 2026 12:34:36 +0100 Subject: [PATCH] Video processing implemented. --- Splitter-UI/App.axaml.cs | 4 +- Splitter-UI/Converters/BoolInvertConverter.cs | 15 ++++ .../ConsoleColorToBrushConverter.cs | 1 - Splitter-UI/Program.cs | 2 + Splitter-UI/Services/GlobalLogger.cs | 6 +- Splitter-UI/ViewModels/FileListViewModel.cs | 17 +++++ .../ViewModels/InspectorPaneViewModel.cs | 11 +++ Splitter-UI/ViewModels/JobViewModel.cs | 5 +- Splitter-UI/ViewModels/MainViewModel.cs | 71 ++++++++++++++----- Splitter-UI/ViewModels/ProgressViewModel.cs | 43 +++++++++++ Splitter-UI/ViewModels/StatusBarViewModel.cs | 2 - Splitter-UI/Views/FileListView.axaml | 4 +- Splitter-UI/Views/FileListView.axaml.cs | 8 +++ Splitter-UI/Views/InspectorPane.axaml | 19 +++-- Splitter-UI/Views/MainWindow.axaml | 35 ++++++--- Splitter-UI/Views/ProgressView.axaml | 50 +++++++++++++ Splitter-UI/Views/ProgressView.axaml.cs | 12 ++++ Splitter-UI/Views/StatusBarView.axaml | 8 +-- 18 files changed, 268 insertions(+), 45 deletions(-) create mode 100644 Splitter-UI/Converters/BoolInvertConverter.cs create mode 100644 Splitter-UI/ViewModels/ProgressViewModel.cs create mode 100644 Splitter-UI/Views/ProgressView.axaml create mode 100644 Splitter-UI/Views/ProgressView.axaml.cs diff --git a/Splitter-UI/App.axaml.cs b/Splitter-UI/App.axaml.cs index 95bf3a3..b23a589 100644 --- a/Splitter-UI/App.axaml.cs +++ b/Splitter-UI/App.axaml.cs @@ -8,7 +8,9 @@ namespace Splitter_UI; public partial class App : Application { - private readonly ServiceProvider _provider; + private readonly ServiceProvider _provider = null!; + + public App() { } public App(ServiceProvider provider) { diff --git a/Splitter-UI/Converters/BoolInvertConverter.cs b/Splitter-UI/Converters/BoolInvertConverter.cs new file mode 100644 index 0000000..f3a3953 --- /dev/null +++ b/Splitter-UI/Converters/BoolInvertConverter.cs @@ -0,0 +1,15 @@ +using System.Globalization; +using Avalonia.Data.Converters; + +namespace Splitter_UI.Converters; + +public sealed class BoolInvertConverter : IValueConverter +{ + public static readonly BoolInvertConverter Instance = new(); + + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + => value is bool b ? !b : value; + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => value is bool b ? !b : value; +} diff --git a/Splitter-UI/Converters/ConsoleColorToBrushConverter.cs b/Splitter-UI/Converters/ConsoleColorToBrushConverter.cs index 1074df1..e7e6091 100644 --- a/Splitter-UI/Converters/ConsoleColorToBrushConverter.cs +++ b/Splitter-UI/Converters/ConsoleColorToBrushConverter.cs @@ -1,6 +1,5 @@ using Avalonia.Data.Converters; using Avalonia.Media; -using System; using System.Globalization; namespace Splitter_UI.Converters; diff --git a/Splitter-UI/Program.cs b/Splitter-UI/Program.cs index 684cec3..a80cf06 100644 --- a/Splitter-UI/Program.cs +++ b/Splitter-UI/Program.cs @@ -30,6 +30,7 @@ internal sealed class Program services.AddTransient(); services.AddTransient(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(logPaveVM); services.AddSingleton(logPaveVM); @@ -48,6 +49,7 @@ internal sealed class Program }; }); services.AddSingleton(); + services.AddSingleton(); // Domain services (your pipeline) services.AddTransient(); diff --git a/Splitter-UI/Services/GlobalLogger.cs b/Splitter-UI/Services/GlobalLogger.cs index 100e3ca..46fc118 100644 --- a/Splitter-UI/Services/GlobalLogger.cs +++ b/Splitter-UI/Services/GlobalLogger.cs @@ -1,16 +1,20 @@ namespace Splitter_UI.Services; -internal class GlobalLogger(ILogService _logService, StatusBarViewModel _statusBar) : ILogger +internal class GlobalLogger(ILogService _logService, StatusBarViewModel _statusBar, ProgressViewModel _progress) : ILogger { public void ClearProgress(string name, int progressLine) { if (progressLine == 0) _statusBar.Percent = 0; + else + _progress.ClearProgress(name, progressLine-1); } public void DrawProgress(string name, int progressLine, double progress, TimeSpan eta, double speed) { if (progressLine == 0) _statusBar.Percent = progress; + else + _progress.DrawProgress(name, progressLine - 1, progress, eta, speed); } public void Log(string prefix, ConsoleColor color, string msg) diff --git a/Splitter-UI/ViewModels/FileListViewModel.cs b/Splitter-UI/ViewModels/FileListViewModel.cs index d969837..3fa2a55 100644 --- a/Splitter-UI/ViewModels/FileListViewModel.cs +++ b/Splitter-UI/ViewModels/FileListViewModel.cs @@ -39,4 +39,21 @@ public partial class FileListViewModel : ObservableObject Selected = Files.LastOrDefault(); } + + internal void DeleteSelected() + { + if (SelectedFiles.Any()) + { + var toDelete = SelectedFiles.ToList(); + foreach (var item in toDelete) + Files.Remove(item); + } + else if ( Selected != null) + { + var sel = Selected; + Files.Remove(sel); + } + + Selected = Files.LastOrDefault(); + } } diff --git a/Splitter-UI/ViewModels/InspectorPaneViewModel.cs b/Splitter-UI/ViewModels/InspectorPaneViewModel.cs index 9bf3a05..c25e80c 100644 --- a/Splitter-UI/ViewModels/InspectorPaneViewModel.cs +++ b/Splitter-UI/ViewModels/InspectorPaneViewModel.cs @@ -16,6 +16,13 @@ public partial class InspectorPaneViewModel : ObservableObject "face", "body", "none" ]; + [RelayCommand] + private void TransformAll() + { + _ = _main.Start(); + } + + [RelayCommand] private void ApplyOverrides() { @@ -43,12 +50,16 @@ public partial class InspectorPaneViewModel : ObservableObject public IRelayCommand RotateLeftCommand { get; } public IRelayCommand RotateRightCommand { get; } + private MainViewModel _main = null!; + public InspectorPaneViewModel() { RotateLeftCommand = new RelayCommand(() => AdjustRotation(-90)); RotateRightCommand = new RelayCommand(() => AdjustRotation(+90)); } + public void SetMain(MainViewModel main) => _main = main; + private void AdjustRotation(int delta) { if ( Selected == null) diff --git a/Splitter-UI/ViewModels/JobViewModel.cs b/Splitter-UI/ViewModels/JobViewModel.cs index 3bd74ab..5ffbbab 100644 --- a/Splitter-UI/ViewModels/JobViewModel.cs +++ b/Splitter-UI/ViewModels/JobViewModel.cs @@ -11,7 +11,9 @@ namespace Splitter_UI.ViewModels; public partial class JobViewModel : ObservableObject { private SingleJob Job { get; } - + + public SingleJob GetJob() => Job; + [ObservableProperty] private VideoInfo? _probe; [ObservableProperty] private PreviewData? _preview = new(null, [], null, new(0.5f, 0.5f)); [ObservableProperty] private Bitmap? _thumbnail; @@ -366,4 +368,5 @@ public partial class JobViewModel : ObservableObject { Task.Run(CreatePreview); } + } diff --git a/Splitter-UI/ViewModels/MainViewModel.cs b/Splitter-UI/ViewModels/MainViewModel.cs index 1d9ef5c..f80db4f 100644 --- a/Splitter-UI/ViewModels/MainViewModel.cs +++ b/Splitter-UI/ViewModels/MainViewModel.cs @@ -1,4 +1,4 @@ -using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.Mvvm.ComponentModel; namespace Splitter_UI.ViewModels; @@ -9,41 +9,74 @@ public partial class MainViewModel : ViewModelBase public InspectorPaneViewModel Inspector { get; } public StatusBarViewModel StatusBar { get; } public LogPaneViewModel LogPane { get; } + public ProgressViewModel Progress { get; } + private IJobProcessor _processor = null!; + + [ObservableProperty] private bool _transformMode = false; + private ILogger _logger; public MainViewModel( - IFileJobFactory fileJobFactory, - IAutoDecisionService autoDecisionService, + FileListViewModel fileListVM, PreviewPaneViewModel ppVM, InspectorPaneViewModel iVM, LogPaneViewModel lpVM, - StatusBarViewModel sbVM + StatusBarViewModel sbVM, + ProgressViewModel pVM, + IJobProcessor processor, + ILogger logger ) { - FileList = new FileListViewModel(fileJobFactory, autoDecisionService); - Preview = ppVM; - Inspector = iVM; - LogPane = lpVM; - StatusBar = sbVM; - // Wire selection → preview + inspector + FileList = fileListVM; + Preview = ppVM; + Inspector = iVM; + LogPane = lpVM; + StatusBar = sbVM; + Progress = pVM; + _processor = processor; + _logger = logger; + + // Wire selection -> preview + inspector FileList.SelectedFileChanged += file => { Preview.Selected = file; Inspector.Selected = file; }; + Inspector.SetMain(this); Inspector.Files = FileList.Files; } - [RelayCommand] - private void Start() + public async Task Start() { - StatusBar.StatusText = "Processing…"; - // call IProcessingService here + try + { + StatusBar.StatusText = "Processing…"; + StatusBar.Percent = 0; + TransformMode = true; + + var files = FileList.Files.ToList(); + var jobs = new List(); + + foreach (var file in files) + { + var fileJobs = await _processor.GenerateJobs(file.GetJob(), false); + jobs.AddRange(fileJobs); + } + + await _processor.ProcessJobs(jobs, false); + } + catch (Exception ex) + { + // Handle exception + StatusBar.StatusText = "Error occurred…"; + _logger.LogError($"Error: {ex.Message}"); + } + finally + { + StatusBar.StatusText = "Ready…"; + StatusBar.Percent = 0; + TransformMode = false; + } } - [RelayCommand] - private void Stop() - { - StatusBar.StatusText = "Stopped"; - } } diff --git a/Splitter-UI/ViewModels/ProgressViewModel.cs b/Splitter-UI/ViewModels/ProgressViewModel.cs new file mode 100644 index 0000000..5c96263 --- /dev/null +++ b/Splitter-UI/ViewModels/ProgressViewModel.cs @@ -0,0 +1,43 @@ +using System.Collections.ObjectModel; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace Splitter_UI.ViewModels; + +public record ProgressInfo(string Name, int ProgressLine, double Progress, TimeSpan Eta, double Speed); + +public partial class ProgressViewModel : ObservableObject +{ + [ObservableProperty] private int _numberOfProcesses = 0; + public ObservableCollection Processes { get; } = []; + + private Lock _lock = new(); + public void ClearProgress(string name, int progressLine) + { + lock (_lock) + { + if (progressLine < 0 || progressLine > Processes.Count) + return; + + NumberOfProcesses -= 1; + Processes[progressLine] = new ProgressInfo("", progressLine, 0, TimeSpan.Zero, 0); + } + } + public void DrawProgress(string name, int progressLine, double progress, TimeSpan eta, double speed) + { + lock (_lock) + { + if (progressLine < 0) + return; + + while (Processes.Count <= progressLine) + { + Processes.Add(new ProgressInfo("", Processes.Count, 0, TimeSpan.Zero, 0)); + } + + if (Processes[progressLine].Name == "") + NumberOfProcesses += 1; + Processes[progressLine] = new ProgressInfo(name, progressLine, progress, eta, speed); + } + } +} + diff --git a/Splitter-UI/ViewModels/StatusBarViewModel.cs b/Splitter-UI/ViewModels/StatusBarViewModel.cs index 0a8e3b3..c3cadbd 100644 --- a/Splitter-UI/ViewModels/StatusBarViewModel.cs +++ b/Splitter-UI/ViewModels/StatusBarViewModel.cs @@ -10,6 +10,4 @@ public partial class StatusBarViewModel : ObservableObject [ObservableProperty] private double _percent; - [ObservableProperty] - private string _threadInfo = "Threads: 0/0"; } diff --git a/Splitter-UI/Views/FileListView.axaml b/Splitter-UI/Views/FileListView.axaml index 071eb99..5a67627 100644 --- a/Splitter-UI/Views/FileListView.axaml +++ b/Splitter-UI/Views/FileListView.axaml @@ -5,7 +5,9 @@ xmlns:views="clr-namespace:Splitter_UI.Views" xmlns:conv="clr-namespace:Splitter_UI.Converters" x:Class="Splitter_UI.Views.FileListView" - x:DataType="vm:FileListViewModel"> + x:DataType="vm:FileListViewModel" + KeyDown="OnKeyDown" + Focusable="True"> diff --git a/Splitter-UI/Views/FileListView.axaml.cs b/Splitter-UI/Views/FileListView.axaml.cs index 92223b3..d03e7b4 100644 --- a/Splitter-UI/Views/FileListView.axaml.cs +++ b/Splitter-UI/Views/FileListView.axaml.cs @@ -21,6 +21,14 @@ public partial class FileListView : UserControl InitializeComponent(); } + private void OnKeyDown(object? sender, KeyEventArgs e) + { + if (e.Key == Key.Delete) + { + if (DataContext is FileListViewModel vm) + vm.DeleteSelected(); + } + } private void OnDragEnter(object? sender, DragEventArgs e) { IsDragActive = true; diff --git a/Splitter-UI/Views/InspectorPane.axaml b/Splitter-UI/Views/InspectorPane.axaml index dbc714e..b51356e 100644 --- a/Splitter-UI/Views/InspectorPane.axaml +++ b/Splitter-UI/Views/InspectorPane.axaml @@ -147,10 +147,21 @@ x:DataType="vm:InspectorPaneViewModel"> -