From 7b4c393f4fbf643f8a22162ad06e7bddae17b054 Mon Sep 17 00:00:00 2001 From: branchpanic <3802908+branchpanic@users.noreply.github.com> Date: Sun, 5 Feb 2023 12:54:17 -0800 Subject: [PATCH 1/4] Reformat + break up main view --- .editorconfig | 129 ++++++++++++ src/Vdcrpt.Desktop/App.axaml | 4 + src/Vdcrpt.Desktop/App.axaml.cs | 4 +- src/Vdcrpt.Desktop/DelegateCommand.cs | 2 +- src/Vdcrpt.Desktop/Preset.cs | 2 +- src/Vdcrpt.Desktop/Program.cs | 2 +- src/Vdcrpt.Desktop/Vdcrpt.Desktop.csproj | 13 +- src/Vdcrpt.Desktop/ViewLocator.cs | 28 +++ src/Vdcrpt.Desktop/ViewModelBase.cs | 28 +++ .../ViewModels/EffectSettingsViewModel.cs | 105 ++++++++++ .../{ => ViewModels}/MainWindowViewModel.cs | 195 +++--------------- .../ViewModels/OutputSettingsViewModel.cs | 19 ++ .../Views/EffectSettingsView.axaml | 49 +++++ .../Views/EffectSettingsView.axaml.cs | 11 + .../{ => Views}/MainWindow.axaml | 52 +---- .../{ => Views}/MainWindow.axaml.cs | 4 +- .../Views/OutputSettingsView.axaml | 16 ++ .../Views/OutputSettingsView.axaml.cs | 11 + 18 files changed, 458 insertions(+), 216 deletions(-) create mode 100644 .editorconfig create mode 100644 src/Vdcrpt.Desktop/ViewLocator.cs create mode 100644 src/Vdcrpt.Desktop/ViewModelBase.cs create mode 100644 src/Vdcrpt.Desktop/ViewModels/EffectSettingsViewModel.cs rename src/Vdcrpt.Desktop/{ => ViewModels}/MainWindowViewModel.cs (58%) create mode 100644 src/Vdcrpt.Desktop/ViewModels/OutputSettingsViewModel.cs create mode 100644 src/Vdcrpt.Desktop/Views/EffectSettingsView.axaml create mode 100644 src/Vdcrpt.Desktop/Views/EffectSettingsView.axaml.cs rename src/Vdcrpt.Desktop/{ => Views}/MainWindow.axaml (64%) rename src/Vdcrpt.Desktop/{ => Views}/MainWindow.axaml.cs (97%) create mode 100644 src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml create mode 100644 src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml.cs diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..502aa1c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,129 @@ + +[*.{cs,vb}] +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 4 +indent_size = 4 +end_of_line = crlf +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion +dotnet_style_namespace_match_folder = true:suggestion +insert_final_newline = true +dotnet_style_readonly_field = true:suggestion +dotnet_style_predefined_type_for_member_access = true:silent +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent +dotnet_style_allow_multiple_blank_lines_experimental = true:silent +dotnet_style_allow_statement_immediately_after_block_experimental = true:silent +dotnet_code_quality_unused_parameters = all:suggestion +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_property = false:silent +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_event = false:silent + +[*.cs] +csharp_indent_labels = one_less_than_current +csharp_using_directive_placement = outside_namespace:silent +csharp_prefer_simple_using_statement = true:suggestion +csharp_prefer_braces = true:silent +csharp_style_namespace_declarations = block_scoped:silent +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_top_level_statements = true:silent +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_throw_expression = true:suggestion +csharp_style_prefer_null_check_over_type_check = true:suggestion +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_prefer_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion +csharp_style_prefer_tuple_swap = true:suggestion +csharp_style_prefer_utf8_string_literals = true:suggestion +csharp_space_around_binary_operators = before_and_after +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent +csharp_style_prefer_readonly_struct = true:suggestion +csharp_prefer_static_local_function = true:suggestion +csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent +csharp_style_conditional_delegate_call = true:suggestion +csharp_style_prefer_switch_expression = true:suggestion +csharp_style_prefer_pattern_matching = true:silent +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_extended_property_pattern = true:suggestion +csharp_style_var_for_built_in_types = true:silent +csharp_style_var_when_type_is_apparent = true:silent +csharp_style_var_elsewhere = true:silent \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/App.axaml b/src/Vdcrpt.Desktop/App.axaml index 8c292c1..35001d0 100644 --- a/src/Vdcrpt.Desktop/App.axaml +++ b/src/Vdcrpt.Desktop/App.axaml @@ -1,7 +1,11 @@ + + + diff --git a/src/Vdcrpt.Desktop/App.axaml.cs b/src/Vdcrpt.Desktop/App.axaml.cs index beff838..e024094 100644 --- a/src/Vdcrpt.Desktop/App.axaml.cs +++ b/src/Vdcrpt.Desktop/App.axaml.cs @@ -1,6 +1,8 @@ using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; +using Vdcrpt.Desktop.ViewModels; +using Vdcrpt.Desktop.Views; namespace Vdcrpt.Desktop; @@ -23,4 +25,4 @@ public override void OnFrameworkInitializationCompleted() base.OnFrameworkInitializationCompleted(); } -} \ No newline at end of file +} diff --git a/src/Vdcrpt.Desktop/DelegateCommand.cs b/src/Vdcrpt.Desktop/DelegateCommand.cs index 7f6e431..848383e 100644 --- a/src/Vdcrpt.Desktop/DelegateCommand.cs +++ b/src/Vdcrpt.Desktop/DelegateCommand.cs @@ -23,4 +23,4 @@ public DelegateCommand(Func doCanExecute, Action doExecu public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty); public event EventHandler? CanExecuteChanged; -} \ No newline at end of file +} diff --git a/src/Vdcrpt.Desktop/Preset.cs b/src/Vdcrpt.Desktop/Preset.cs index 09f7a46..516e52c 100644 --- a/src/Vdcrpt.Desktop/Preset.cs +++ b/src/Vdcrpt.Desktop/Preset.cs @@ -43,4 +43,4 @@ public class Preset UseLengthRange = true, Iterations = 50 }, }; -} \ No newline at end of file +} diff --git a/src/Vdcrpt.Desktop/Program.cs b/src/Vdcrpt.Desktop/Program.cs index 7357d69..e051c47 100644 --- a/src/Vdcrpt.Desktop/Program.cs +++ b/src/Vdcrpt.Desktop/Program.cs @@ -17,4 +17,4 @@ public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure() .UsePlatformDetect() .LogToTrace(); -} \ No newline at end of file +} diff --git a/src/Vdcrpt.Desktop/Vdcrpt.Desktop.csproj b/src/Vdcrpt.Desktop/Vdcrpt.Desktop.csproj index fb02ec7..63b6653 100644 --- a/src/Vdcrpt.Desktop/Vdcrpt.Desktop.csproj +++ b/src/Vdcrpt.Desktop/Vdcrpt.Desktop.csproj @@ -1,4 +1,4 @@ - + WinExe net6.0 @@ -11,9 +11,9 @@ false true true - true - enable - + true + enable + branchpanic vdcrpt @@ -40,7 +40,10 @@ - + + EffectSettingsView.axaml + + MainWindow.axaml Code diff --git a/src/Vdcrpt.Desktop/ViewLocator.cs b/src/Vdcrpt.Desktop/ViewLocator.cs new file mode 100644 index 0000000..b1c356c --- /dev/null +++ b/src/Vdcrpt.Desktop/ViewLocator.cs @@ -0,0 +1,28 @@ +using System; +using Avalonia.Controls; +using Avalonia.Controls.Templates; + +namespace Vdcrpt.Desktop; + +public class ViewLocator : IDataTemplate +{ + public bool SupportsRecycling => false; + + public IControl Build(object data) + { + var name = data.GetType().FullName.Replace("ViewModel", "View"); + var type = Type.GetType(name); + + if (type != null) + { + return (Control)Activator.CreateInstance(type); + } + + return new TextBlock { Text = "Not Found: " + name }; + } + + public bool Match(object data) + { + return data is ViewModelBase; + } +} diff --git a/src/Vdcrpt.Desktop/ViewModelBase.cs b/src/Vdcrpt.Desktop/ViewModelBase.cs new file mode 100644 index 0000000..b3f9600 --- /dev/null +++ b/src/Vdcrpt.Desktop/ViewModelBase.cs @@ -0,0 +1,28 @@ +using JetBrains.Annotations; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace Vdcrpt.Desktop; + +public abstract class ViewModelBase : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + [NotifyPropertyChangedInvocator] + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected void RaiseAndSetIfChanged(ref T field, T value, [CallerMemberName] string? propertyName = null) + { + if (EqualityComparer.Default.Equals(field, value)) + { + return; + } + + field = value; + OnPropertyChanged(propertyName); + } +} diff --git a/src/Vdcrpt.Desktop/ViewModels/EffectSettingsViewModel.cs b/src/Vdcrpt.Desktop/ViewModels/EffectSettingsViewModel.cs new file mode 100644 index 0000000..87cbbb7 --- /dev/null +++ b/src/Vdcrpt.Desktop/ViewModels/EffectSettingsViewModel.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Vdcrpt.BuiltIns.Effects; + +namespace Vdcrpt.Desktop.ViewModels +{ + public class EffectSettingsViewModel : ViewModelBase + { + private Preset _preset; + private int _burstSize; + private int _minBurstLength; + private int _maxBurstLength; + private int _iterations; + private bool _useBurstLengthRange; + + // TODO: User-defined presets + public List Presets { get; } = Preset.DefaultPresets; + + public Preset CurrentPreset + { + get => _preset; + set + { + RaiseAndSetIfChanged(ref _preset, value); + + BurstSize = _preset.BurstSize; + MinBurstLength = _preset.MinBurstLength; + + UseBurstLengthRange = _preset.UseLengthRange; + if (_preset.UseLengthRange) MaxBurstLength = _preset.MaxBurstLength; + + Iterations = _preset.Iterations; + } + } + + [Range(1, int.MaxValue)] + public int BurstSize + { + get => _burstSize; + set => RaiseAndSetIfChanged(ref _burstSize, value); + } + + [Range(1, int.MaxValue)] + public int MinBurstLength + { + get => _minBurstLength; + set + { + RaiseAndSetIfChanged(ref _minBurstLength, value); + + if (_maxBurstLength < _minBurstLength) _maxBurstLength = _minBurstLength; + OnPropertyChanged(nameof(MaxBurstLength)); + } + } + + [Range(1, int.MaxValue)] + public int MaxBurstLength + { + get => _maxBurstLength; + set + { + RaiseAndSetIfChanged(ref _maxBurstLength, value); + + if (_minBurstLength > _maxBurstLength) _minBurstLength = _maxBurstLength; + OnPropertyChanged(nameof(MinBurstLength)); + } + } + + [Range(1, int.MaxValue)] + public int Iterations + { + get => _iterations; + set => RaiseAndSetIfChanged(ref _iterations, value); + } + + public bool UseBurstLengthRange + { + get => _useBurstLengthRange; + set + { + if (value == _useBurstLengthRange) return; + _useBurstLengthRange = value; + + OnPropertyChanged(); + OnPropertyChanged(nameof(MinBurstLengthColumnSpan)); + } + } + + public int MinBurstLengthColumnSpan => _useBurstLengthRange ? 1 : 3; + + public EffectSettingsViewModel() + { + _preset = CurrentPreset = Presets[0]; + } + + public BinaryRepeatEffect MakeEffect() => new() + { + BurstSize = _burstSize, + MinBurstLength = _minBurstLength, + MaxBurstLength = _useBurstLengthRange ? _maxBurstLength : _minBurstLength, + Iterations = _iterations, + }; + } +} diff --git a/src/Vdcrpt.Desktop/MainWindowViewModel.cs b/src/Vdcrpt.Desktop/ViewModels/MainWindowViewModel.cs similarity index 58% rename from src/Vdcrpt.Desktop/MainWindowViewModel.cs rename to src/Vdcrpt.Desktop/ViewModels/MainWindowViewModel.cs index 2e2cfe2..3bdb9af 100644 --- a/src/Vdcrpt.Desktop/MainWindowViewModel.cs +++ b/src/Vdcrpt.Desktop/ViewModels/MainWindowViewModel.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.IO; using System.Reflection; -using System.Runtime.CompilerServices; using System.Threading.Tasks; using System.Windows.Input; using Avalonia; @@ -13,48 +11,26 @@ using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Data; using FFMpegCore.Exceptions; -using JetBrains.Annotations; -using Vdcrpt; -using Vdcrpt.BuiltIns.Effects; -namespace Vdcrpt.Desktop; +namespace Vdcrpt.Desktop.ViewModels; -// TODO: This should be broken into smaller components -public sealed class MainWindowViewModel : INotifyPropertyChanged +public sealed class MainWindowViewModel : ViewModelBase { private const string DefaultProgressMessage = "Ready!"; private readonly BackgroundWorker _corruptWorker; private string _inputPath = string.Empty; - private Preset _currentPreset; - private int _burstSize = 5000; - private int _iterations = 5; - private int _minTrailLength = 10; - private int _maxTrailLength = 20; + private EffectSettingsViewModel _effectSettings; + private OutputSettingsViewModel _outputSettings; // TODO: Avalonia lets us bind directly to methods, commands not always necessary private DelegateCommand _onOpenResultPressed; - private bool _openWhenComplete = false; - private bool _askForFilename = true; private string _outputPath = string.Empty; private int _progressAmount; private string _progressMessage = DefaultProgressMessage; - #region Properties - - public ICommand OpenUrl { get; } = new DelegateCommand(url => - { - if (url is not string urlString) return; - - Process.Start(new ProcessStartInfo - { - FileName = urlString, - UseShellExecute = true - }); - }); - public bool CanStartCorrupting => File.Exists(InputPath) && !IsBusy; public bool IsBusy => _corruptWorker.IsBusy; @@ -64,105 +40,31 @@ public string InputPath get => _inputPath; set { - if (value == _inputPath) return; + if (value == _inputPath) + { + return; + } _inputPath = value; OnPropertyChanged(); OnPropertyChanged(nameof(CanStartCorrupting)); - if (!File.Exists(_inputPath)) throw new DataValidationException("File does not exist."); - } - } - - [Range(1, int.MaxValue)] - public int BurstSize - { - get => _burstSize; - set - { - if (value == _burstSize) return; - _burstSize = value; - OnPropertyChanged(); - } - } - - [Range(1, int.MaxValue)] - public int MinTrailLength - { - get => _minTrailLength; - set - { - if (value == _minTrailLength) return; - _minTrailLength = value; - OnPropertyChanged(); - - if (_maxTrailLength < _minTrailLength) _maxTrailLength = _minTrailLength; - OnPropertyChanged(nameof(MaxTrailLength)); - } - } - - [Range(1, int.MaxValue)] - public int MaxTrailLength - { - get => _maxTrailLength; - set - { - if (value == _maxTrailLength) return; - _maxTrailLength = value; - OnPropertyChanged(); - - if (_minTrailLength > _maxTrailLength) _minTrailLength = _maxTrailLength; - OnPropertyChanged(nameof(MinTrailLength)); - } - } - - private bool _useTrailLengthRange; - public int MinTrailLengthColumnSpan => _useTrailLengthRange ? 1 : 3; - - public bool UseTrailLengthRange - { - get => _useTrailLengthRange; - set - { - if (value == _useTrailLengthRange) return; - _useTrailLengthRange = value; - - OnPropertyChanged(); - OnPropertyChanged(nameof(MinTrailLengthColumnSpan)); - } - } - - [Range(1, int.MaxValue)] - public int Iterations - { - get => _iterations; - set - { - if (value == _iterations) return; - _iterations = value; - OnPropertyChanged(); + if (!File.Exists(_inputPath)) + { + throw new DataValidationException("File does not exist."); + } } } - public bool OpenWhenComplete + public EffectSettingsViewModel EffectViewModel { - get => _openWhenComplete; - set - { - if (value == _openWhenComplete) return; - _openWhenComplete = value; - OnPropertyChanged(); - } + get => _effectSettings; + set => RaiseAndSetIfChanged(ref _effectSettings, value); } - public bool AskForFilename + public OutputSettingsViewModel OutputSettingsViewModel { - get => _askForFilename; - set - { - if (value == _askForFilename) return; - _askForFilename = value; - OnPropertyChanged(); - } + get => _outputSettings; + set => RaiseAndSetIfChanged(ref _outputSettings, value); } public int ProgressAmount @@ -215,31 +117,6 @@ public string VersionText } } - // TODO: User-defined presets - public List Presets { get; } = Preset.DefaultPresets; - - public Preset CurrentPreset - { - get => _currentPreset; - set - { - if (value == _currentPreset) return; - _currentPreset = value; - OnPropertyChanged(); - - BurstSize = _currentPreset.BurstSize; - MinTrailLength = _currentPreset.MinBurstLength; - - UseTrailLengthRange = _currentPreset.UseLengthRange; - if (_currentPreset.UseLengthRange) MaxTrailLength = _currentPreset.MaxBurstLength; - - Iterations = _currentPreset.Iterations; - } - } - - #endregion - - public ICommand OnOpenResultPressed => _onOpenResultPressed; public ICommand OnExitPressed { get; } = new DelegateCommand(_ => @@ -257,7 +134,8 @@ public Preset CurrentPreset public MainWindowViewModel() { - _currentPreset = CurrentPreset = Presets[0]; + _effectSettings = new EffectSettingsViewModel(); + _outputSettings = new OutputSettingsViewModel(); _corruptWorker = new BackgroundWorker(); _corruptWorker.WorkerReportsProgress = true; @@ -302,7 +180,7 @@ public MainWindowViewModel() OnPropertyChanged(nameof(IsBusy)); OnPropertyChanged(nameof(CanStartCorrupting)); - if (args.Error is null && OpenWhenComplete) _onOpenResultPressed.Execute(null); + if (args.Error is null && _outputSettings.OpenWhenComplete) _onOpenResultPressed.Execute(null); }; } @@ -326,12 +204,12 @@ public async Task StartCorrupting() { if (Application.Current?.ApplicationLifetime is not ClassicDesktopStyleApplicationLifetime app) return; - if (!AskForFilename || string.IsNullOrEmpty(OutputPath)) + if (!_outputSettings.AskForFilename || string.IsNullOrEmpty(OutputPath)) { OutputPath = GenerateOutputPath(_inputPath); } - if (AskForFilename) + if (_outputSettings.AskForFilename) { var dialog = new SaveFileDialog { @@ -360,29 +238,24 @@ public async Task StartCorrupting() OnPropertyChanged(nameof(CanStartCorrupting)); } + public void OpenUrl(string url) + { + Process.Start(new ProcessStartInfo + { + FileName = url, + UseShellExecute = true + }); + } + private void DoBackgroundWork(object? sender, DoWorkEventArgs args) { if (sender is not BackgroundWorker worker) return; - var effect = new BinaryRepeatEffect - { - Iterations = _iterations, - BurstSize = _burstSize, - MinBurstLength = _minTrailLength, - MaxBurstLength = UseTrailLengthRange ? _maxTrailLength : _minTrailLength, - }; + var effect = _effectSettings.MakeEffect(); worker.ReportProgress(50, "Corrupting data..."); Session.ApplyEffects(_inputPath, _outputPath, effect); worker.ReportProgress(100, "Finishing up..."); } - - public event PropertyChangedEventHandler? PropertyChanged; - - [NotifyPropertyChangedInvocator] - private void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } -} \ No newline at end of file +} diff --git a/src/Vdcrpt.Desktop/ViewModels/OutputSettingsViewModel.cs b/src/Vdcrpt.Desktop/ViewModels/OutputSettingsViewModel.cs new file mode 100644 index 0000000..b103b10 --- /dev/null +++ b/src/Vdcrpt.Desktop/ViewModels/OutputSettingsViewModel.cs @@ -0,0 +1,19 @@ +namespace Vdcrpt.Desktop.ViewModels; + +public class OutputSettingsViewModel : ViewModelBase +{ + private bool _openWhenComplete = false; + private bool _askForFilename = true; + + public bool OpenWhenComplete + { + get => _openWhenComplete; + set => RaiseAndSetIfChanged(ref _openWhenComplete, value); + } + + public bool AskForFilename + { + get => _askForFilename; + set => RaiseAndSetIfChanged(ref _askForFilename, value); + } +} diff --git a/src/Vdcrpt.Desktop/Views/EffectSettingsView.axaml b/src/Vdcrpt.Desktop/Views/EffectSettingsView.axaml new file mode 100644 index 0000000..1de8e64 --- /dev/null +++ b/src/Vdcrpt.Desktop/Views/EffectSettingsView.axaml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Randomize + + + + + + + + + diff --git a/src/Vdcrpt.Desktop/Views/EffectSettingsView.axaml.cs b/src/Vdcrpt.Desktop/Views/EffectSettingsView.axaml.cs new file mode 100644 index 0000000..2ea41a9 --- /dev/null +++ b/src/Vdcrpt.Desktop/Views/EffectSettingsView.axaml.cs @@ -0,0 +1,11 @@ +using Avalonia.Controls; + +namespace Vdcrpt.Desktop.Views +{ + public partial class EffectSettingsView : UserControl + { + public EffectSettingsView() + { + } + } +} diff --git a/src/Vdcrpt.Desktop/MainWindow.axaml b/src/Vdcrpt.Desktop/Views/MainWindow.axaml similarity index 64% rename from src/Vdcrpt.Desktop/MainWindow.axaml rename to src/Vdcrpt.Desktop/Views/MainWindow.axaml index 536c506..18f5096 100644 --- a/src/Vdcrpt.Desktop/MainWindow.axaml +++ b/src/Vdcrpt.Desktop/Views/MainWindow.axaml @@ -2,11 +2,13 @@ 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" - xmlns:v="clr-namespace:Vdcrpt.Desktop" + xmlns:local="clr-namespace:Vdcrpt.Desktop" + xmlns:vm="clr-namespace:Vdcrpt.Desktop.ViewModels" + xmlns:v="clr-namespace:Vdcrpt.Desktop.Views" mc:Ignorable="d" Width="560" Height="700" MinWidth="350" MinHeight="500" - x:Class="Vdcrpt.Desktop.MainWindow" + x:Class="Vdcrpt.Desktop.Views.MainWindow" x:Name="Window" Icon="/Assets/Icon.ico" Title="vdcrpt"> @@ -17,7 +19,7 @@ - + @@ -60,47 +62,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - Randomize - - - - - - - - - - Open video when done - Ask where to save every time - - + + + - - - - - - - - - - - - - - - - - - - - - + + + + + \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/Views/MainWindow.axaml.cs b/src/Vdcrpt.Desktop/Views/MainWindow.axaml.cs index 8b7a934..8d6fe29 100644 --- a/src/Vdcrpt.Desktop/Views/MainWindow.axaml.cs +++ b/src/Vdcrpt.Desktop/Views/MainWindow.axaml.cs @@ -6,59 +6,69 @@ using Avalonia.Interactivity; using Avalonia.Markup.Xaml; -namespace Vdcrpt.Desktop.Views; - -public partial class MainWindow : Window +namespace Vdcrpt.Desktop.Views { - private TextBox _inputPathTextBox; - - public MainWindow() + public class MainWindow : Window { - InitializeComponent(); + private readonly TextBox _inputPathTextBox; + + public MainWindow() + { + InitializeComponent(); #if DEBUG - this.AttachDevTools(); + this.AttachDevTools(); #endif - _inputPathTextBox = this.Find("InputPathTextBox"); + _inputPathTextBox = this.Find("InputPathTextBox"); - AddHandler(DragDrop.DropEvent, OnDrop); - } + AddHandler(DragDrop.DropEvent, OnDrop); + } - private void OnDrop(object? sender, DragEventArgs e) - { - var filenames = e.Data.GetFileNames(); - if (filenames == null) return; + private void OnDrop(object? sender, DragEventArgs e) + { + var filenames = e.Data.GetFileNames(); + if (filenames == null) + { + return; + } - var filenamesList = filenames.ToList(); - if (filenamesList.Count <= 0) return; + var filenamesList = filenames.ToList(); + if (filenamesList.Count <= 0) + { + return; + } - // Propagates to viewmodel - _inputPathTextBox.Text = filenamesList[0]; - } + // Propagates to viewmodel + _inputPathTextBox.Text = filenamesList[0]; + } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } - private async void OnOpenPressed(object? sender, RoutedEventArgs routedEventArgs) - { - var dialog = new OpenFileDialog + private async void OnOpenPressed(object? sender, RoutedEventArgs routedEventArgs) { - Directory = ".", - AllowMultiple = false, - Filters = new List + var dialog = new OpenFileDialog { - new FileDialogFilter { Name = "Common Video Files", Extensions = { "mp4", "avi", "mkv", "mov", "gif" } }, - new FileDialogFilter { Name = "All Files", Extensions = { "*" } }, - } - }; + Directory = ".", + AllowMultiple = false, + Filters = new List + { + new() { Name = "Common Video Files", Extensions = { "mp4", "avi", "mkv", "mov", "gif" } }, + new() { Name = "All Files", Extensions = { "*" } } + } + }; - var result = await dialog.ShowAsync(this); - if (result is not { Length: > 0 }) return; + var result = await dialog.ShowAsync(this); + if (result is not { Length: > 0 }) + { + return; + } - // Propagates to viewmodel - _inputPathTextBox.Text = result[0]; + // Propagates to viewmodel + _inputPathTextBox.Text = result[0]; + } } } diff --git a/src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml b/src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml index 7d345e7..b883e5a 100644 --- a/src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml +++ b/src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml @@ -2,15 +2,15 @@ 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" - xmlns:vm="clr-namespace:Vdcrpt.Desktop.ViewModels" + xmlns:vm="clr-namespace:Vdcrpt.Desktop.ViewModels" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Vdcrpt.Desktop.Views.OutputSettingsView"> - - - - - - Open video when done - Ask where to save every time - - + + + + + + Open video when done + Ask where to save every time + + \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml.cs b/src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml.cs index b32a4ab..f215709 100644 --- a/src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml.cs +++ b/src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml.cs @@ -2,10 +2,7 @@ namespace Vdcrpt.Desktop.Views { - public partial class OutputSettingsView : UserControl + public class OutputSettingsView : UserControl { - public OutputSettingsView() - { - } } } diff --git a/src/Vdcrpt.Desktop/Views/PresetEffectSettingsView.axaml b/src/Vdcrpt.Desktop/Views/PresetEffectSettingsView.axaml new file mode 100644 index 0000000..e50a140 --- /dev/null +++ b/src/Vdcrpt.Desktop/Views/PresetEffectSettingsView.axaml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/Views/PresetEffectSettingsView.axaml.cs b/src/Vdcrpt.Desktop/Views/PresetEffectSettingsView.axaml.cs new file mode 100644 index 0000000..42a2550 --- /dev/null +++ b/src/Vdcrpt.Desktop/Views/PresetEffectSettingsView.axaml.cs @@ -0,0 +1,20 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Vdcrpt.Desktop.Views +{ + public partial class PresetEffectSettingsView : UserControl + { + public PresetEffectSettingsView() + { + InitializeComponent(); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + } +} + diff --git a/src/Vdcrpt.Desktop/Views/ProjectView.axaml b/src/Vdcrpt.Desktop/Views/ProjectView.axaml new file mode 100644 index 0000000..ffb054a --- /dev/null +++ b/src/Vdcrpt.Desktop/Views/ProjectView.axaml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/Views/ProjectView.axaml.cs b/src/Vdcrpt.Desktop/Views/ProjectView.axaml.cs new file mode 100644 index 0000000..57905aa --- /dev/null +++ b/src/Vdcrpt.Desktop/Views/ProjectView.axaml.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using System.Linq; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Input; +using Avalonia.Interactivity; +using Avalonia.Markup.Xaml; + +namespace Vdcrpt.Desktop.Views +{ + public partial class ProjectView : UserControl + { + private readonly TextBox _inputPathTextBox; + + public ProjectView() + { + InitializeComponent(); + + _inputPathTextBox = this.Find("InputPathTextBox"); + AddHandler(DragDrop.DropEvent, OnDrop); + } + + private void OnDrop(object? sender, DragEventArgs e) + { + var filenames = e.Data.GetFileNames(); + if (filenames == null) + { + return; + } + + var filenamesList = filenames.ToList(); + if (filenamesList.Count <= 0) + { + return; + } + + // Propagates to viewmodel + _inputPathTextBox.Text = filenamesList[0]; + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + + // TODO: Rewrite this as a service + private async void OnOpenPressed(object? sender, RoutedEventArgs routedEventArgs) + { + if (Application.Current!.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktopLifetime) + { + return; + } + + var dialog = new OpenFileDialog + { + Directory = ".", + AllowMultiple = false, + Filters = new List + { + new() { Name = "Common Video Files", Extensions = { "mp4", "avi", "mkv", "mov", "gif" } }, + new() { Name = "All Files", Extensions = { "*" } } + } + }; + + var result = await dialog.ShowAsync(desktopLifetime.MainWindow); + if (result is not { Length: > 0 }) + { + return; + } + + // Propagates to viewmodel + _inputPathTextBox.Text = result[0]; + } + } +} diff --git a/src/Vdcrpt/Vdcrpt.csproj b/src/Vdcrpt/Vdcrpt.csproj index 8920b7f..91513dd 100644 --- a/src/Vdcrpt/Vdcrpt.csproj +++ b/src/Vdcrpt/Vdcrpt.csproj @@ -1,13 +1,13 @@ - - net6.0 - enable - enable - + + net6.0 + enable + enable + - - - + + + diff --git a/tests/Vdcrpt.Tests/Vdcrpt.Tests.csproj b/tests/Vdcrpt.Tests/Vdcrpt.Tests.csproj index b8602d0..6952770 100644 --- a/tests/Vdcrpt.Tests/Vdcrpt.Tests.csproj +++ b/tests/Vdcrpt.Tests/Vdcrpt.Tests.csproj @@ -1,28 +1,28 @@ - - net6.0 - enable - enable + + net6.0 + enable + enable - false - + false + - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + - - - + + + From defc5e9480260e8209904ef21be5f0acf743e4b1 Mon Sep 17 00:00:00 2001 From: branchpanic <3802908+branchpanic@users.noreply.github.com> Date: Sun, 19 Feb 2023 15:23:00 -0800 Subject: [PATCH 4/4] Reformat --- .editorconfig | 23 +++-- src/Vdcrpt.Desktop/App.axaml | 8 +- src/Vdcrpt.Desktop/App.axaml.cs | 2 +- src/Vdcrpt.Desktop/DelegateCommand.cs | 21 +++- .../Models/BinaryRepeatEffectSettings.cs | 78 ++++++++------- src/Vdcrpt.Desktop/Models/Preset.cs | 21 ++-- src/Vdcrpt.Desktop/Models/ProgramInfo.cs | 14 +-- src/Vdcrpt.Desktop/Models/Project.cs | 13 ++- src/Vdcrpt.Desktop/Models/UserConfig.cs | 35 ++++--- src/Vdcrpt.Desktop/Program.cs | 15 ++- src/Vdcrpt.Desktop/Vdcrpt.Desktop.csproj | 16 ++-- src/Vdcrpt.Desktop/ViewLocator.cs | 2 +- src/Vdcrpt.Desktop/ViewModelBase.cs | 2 +- .../ViewModels/EffectSettingsViewModel.cs | 17 ++-- .../ViewModels/MainWindowViewModel.cs | 33 ++++--- .../ViewModels/OutputSettingsViewModel.cs | 9 +- .../PresetEffectSettingsViewModel.cs | 14 ++- .../ViewModels/ProjectViewModel.cs | 27 +++--- .../Views/EffectSettingsView.axaml.cs | 9 +- src/Vdcrpt.Desktop/Views/MainWindow.axaml | 12 ++- src/Vdcrpt.Desktop/Views/MainWindow.axaml.cs | 91 +++++++++--------- .../Views/OutputSettingsView.axaml.cs | 9 +- .../Views/PresetEffectSettingsView.axaml.cs | 25 +++-- src/Vdcrpt.Desktop/Views/ProjectView.axaml | 2 +- src/Vdcrpt.Desktop/Views/ProjectView.axaml.cs | 95 +++++++++---------- 25 files changed, 300 insertions(+), 293 deletions(-) diff --git a/.editorconfig b/.editorconfig index 502aa1c..5056327 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,3 @@ - [*.{cs,vb}] #### Naming styles #### @@ -20,31 +19,31 @@ dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case dotnet_naming_symbols.interface.applicable_kinds = interface dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.interface.required_modifiers = +dotnet_naming_symbols.interface.required_modifiers = dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.types.required_modifiers = +dotnet_naming_symbols.types.required_modifiers = dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.non_field_members.required_modifiers = +dotnet_naming_symbols.non_field_members.required_modifiers = # Naming styles dotnet_naming_style.begins_with_i.required_prefix = I -dotnet_naming_style.begins_with_i.required_suffix = -dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = dotnet_naming_style.begins_with_i.capitalization = pascal_case -dotnet_naming_style.pascal_case.required_prefix = -dotnet_naming_style.pascal_case.required_suffix = -dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = dotnet_naming_style.pascal_case.capitalization = pascal_case -dotnet_naming_style.pascal_case.required_prefix = -dotnet_naming_style.pascal_case.required_suffix = -dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = dotnet_naming_style.pascal_case.capitalization = pascal_case dotnet_style_operator_placement_when_wrapping = beginning_of_line tab_width = 4 diff --git a/src/Vdcrpt.Desktop/App.axaml b/src/Vdcrpt.Desktop/App.axaml index 35001d0..f9dc199 100644 --- a/src/Vdcrpt.Desktop/App.axaml +++ b/src/Vdcrpt.Desktop/App.axaml @@ -1,12 +1,12 @@ - + - + - + \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/App.axaml.cs b/src/Vdcrpt.Desktop/App.axaml.cs index e024094..2c139b0 100644 --- a/src/Vdcrpt.Desktop/App.axaml.cs +++ b/src/Vdcrpt.Desktop/App.axaml.cs @@ -25,4 +25,4 @@ public override void OnFrameworkInitializationCompleted() base.OnFrameworkInitializationCompleted(); } -} +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/DelegateCommand.cs b/src/Vdcrpt.Desktop/DelegateCommand.cs index 848383e..2b0e59c 100644 --- a/src/Vdcrpt.Desktop/DelegateCommand.cs +++ b/src/Vdcrpt.Desktop/DelegateCommand.cs @@ -3,7 +3,7 @@ namespace Vdcrpt.Desktop; -class DelegateCommand : ICommand +internal class DelegateCommand : ICommand { private readonly Func _doCanExecute; private readonly Action _doExecute; @@ -18,9 +18,20 @@ public DelegateCommand(Func doCanExecute, Action doExecu _doExecute = doExecute; } - public bool CanExecute(object? parameter) => _doCanExecute(parameter); - public void Execute(object? parameter) => _doExecute(parameter); - public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty); + public bool CanExecute(object? parameter) + { + return _doCanExecute(parameter); + } + + public void Execute(object? parameter) + { + _doExecute(parameter); + } public event EventHandler? CanExecuteChanged; -} + + public void RaiseCanExecuteChanged() + { + CanExecuteChanged?.Invoke(this, EventArgs.Empty); + } +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/Models/BinaryRepeatEffectSettings.cs b/src/Vdcrpt.Desktop/Models/BinaryRepeatEffectSettings.cs index c486ec1..90f1ada 100644 --- a/src/Vdcrpt.Desktop/Models/BinaryRepeatEffectSettings.cs +++ b/src/Vdcrpt.Desktop/Models/BinaryRepeatEffectSettings.cs @@ -1,60 +1,58 @@ using System.ComponentModel.DataAnnotations; using CommunityToolkit.Mvvm.ComponentModel; using Vdcrpt.BuiltIns.Effects; -using Vdcrpt.Desktop.ViewModels; -namespace Vdcrpt.Desktop.Models +namespace Vdcrpt.Desktop.Models; + +public partial class BinaryRepeatEffectSettings : ObservableValidator { - public partial class BinaryRepeatEffectSettings : ObservableValidator - { - [ObservableProperty] [Range(1, int.MaxValue)] - private int _burstSize; + [ObservableProperty] [Range(1, int.MaxValue)] + private int _burstSize; - [ObservableProperty] [Range(1, int.MaxValue)] - private int _iterations; + [ObservableProperty] [Range(1, int.MaxValue)] + private int _iterations; - [ObservableProperty] [Range(1, int.MaxValue)] - private int _maxBurstLength; + [ObservableProperty] [Range(1, int.MaxValue)] + private int _maxBurstLength; - [ObservableProperty] [Range(1, int.MaxValue)] - private int _minBurstLength; + [ObservableProperty] [Range(1, int.MaxValue)] + private int _minBurstLength; - [ObservableProperty] private bool _useBurstLengthRange; + [ObservableProperty] private bool _useBurstLengthRange; - public BinaryRepeatEffect ToEffectInstance() + public BinaryRepeatEffect ToEffectInstance() + { + return new BinaryRepeatEffect { - return new() - { - Iterations = Iterations, - MinBurstLength = MinBurstLength, - MaxBurstLength = UseBurstLengthRange ? MaxBurstLength : MinBurstLength, - BurstSize = BurstSize - }; - } + Iterations = Iterations, + MinBurstLength = MinBurstLength, + MaxBurstLength = UseBurstLengthRange ? MaxBurstLength : MinBurstLength, + BurstSize = BurstSize + }; + } - public void CopyFrom(in BinaryRepeatEffectSettings other) - { - BurstSize = other.BurstSize; - Iterations = other.Iterations; - MaxBurstLength = other.MaxBurstLength; - MinBurstLength = other.MinBurstLength; - UseBurstLengthRange = other.UseBurstLengthRange; - } + public void CopyFrom(in BinaryRepeatEffectSettings other) + { + BurstSize = other.BurstSize; + Iterations = other.Iterations; + MaxBurstLength = other.MaxBurstLength; + MinBurstLength = other.MinBurstLength; + UseBurstLengthRange = other.UseBurstLengthRange; + } - partial void OnMinBurstLengthChanged(int value) + partial void OnMinBurstLengthChanged(int value) + { + if (value > MaxBurstLength) { - if (value > MaxBurstLength) - { - MaxBurstLength = value; - } + MaxBurstLength = value; } + } - partial void OnMaxBurstLengthChanged(int value) + partial void OnMaxBurstLengthChanged(int value) + { + if (value < MinBurstLength) { - if (value < MinBurstLength) - { - MinBurstLength = value; - } + MinBurstLength = value; } } } diff --git a/src/Vdcrpt.Desktop/Models/Preset.cs b/src/Vdcrpt.Desktop/Models/Preset.cs index c7f366e..6d121f8 100644 --- a/src/Vdcrpt.Desktop/Models/Preset.cs +++ b/src/Vdcrpt.Desktop/Models/Preset.cs @@ -1,14 +1,13 @@ -namespace Vdcrpt.Desktop.Models +namespace Vdcrpt.Desktop.Models; + +public class Preset { - public class Preset + public Preset() { - public Preset() - { - Name = string.Empty; - Settings = new BinaryRepeatEffectSettings(); - } - - public string Name { get; init; } - public BinaryRepeatEffectSettings Settings { get; set; } + Name = string.Empty; + Settings = new BinaryRepeatEffectSettings(); } -} + + public string Name { get; init; } + public BinaryRepeatEffectSettings Settings { get; set; } +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/Models/ProgramInfo.cs b/src/Vdcrpt.Desktop/Models/ProgramInfo.cs index 246404a..b79133d 100644 --- a/src/Vdcrpt.Desktop/Models/ProgramInfo.cs +++ b/src/Vdcrpt.Desktop/Models/ProgramInfo.cs @@ -9,6 +9,13 @@ public record ProgramInfo( string GitHubUrl ) { + public static readonly ProgramInfo Default = new( + "vdcrpt", + GetVersionFromAssembly(), + "https://branchpanic.itch.io/vdcrpt", + "https://github.com/branchpanic/vdcrpt" + ); + private static string GetVersionFromAssembly() { var version = Assembly.GetExecutingAssembly().GetName().Version; @@ -21,11 +28,4 @@ private static string GetVersionFromAssembly() return $"{versionString}"; } - - public static readonly ProgramInfo Default = new( - Name: "vdcrpt", - Version: GetVersionFromAssembly(), - ItchUrl: "https://branchpanic.itch.io/vdcrpt", - GitHubUrl: "https://github.com/branchpanic/vdcrpt" - ); } diff --git a/src/Vdcrpt.Desktop/Models/Project.cs b/src/Vdcrpt.Desktop/Models/Project.cs index a3670b9..00a4255 100644 --- a/src/Vdcrpt.Desktop/Models/Project.cs +++ b/src/Vdcrpt.Desktop/Models/Project.cs @@ -1,18 +1,14 @@ using System; -using CommunityToolkit.Mvvm.ComponentModel; using System.ComponentModel.DataAnnotations; using System.IO; -using System.Threading.Tasks; +using CommunityToolkit.Mvvm.ComponentModel; namespace Vdcrpt.Desktop.Models; public partial class Project : ObservableValidator { [ObservableProperty] [CustomValidation(typeof(Project), nameof(ValidateInputFile))] - string _inputFile; - - public UserConfig Config { get; set; } - public BinaryRepeatEffectSettings EffectSettings { get; set; } + private string _inputFile; public Project() { @@ -21,6 +17,9 @@ public Project() EffectSettings = new BinaryRepeatEffectSettings(); } + public UserConfig Config { get; set; } + public BinaryRepeatEffectSettings EffectSettings { get; set; } + public static ValidationResult ValidateInputFile(string inputFile, ValidationContext context) { if (!File.Exists(inputFile)) @@ -54,4 +53,4 @@ public static string GenerateOutputPath(string inputPath) return result; } -} +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/Models/UserConfig.cs b/src/Vdcrpt.Desktop/Models/UserConfig.cs index 8559c7f..5f49e9e 100644 --- a/src/Vdcrpt.Desktop/Models/UserConfig.cs +++ b/src/Vdcrpt.Desktop/Models/UserConfig.cs @@ -1,34 +1,33 @@ -using CommunityToolkit.Mvvm.ComponentModel; -using System.Collections.Generic; +using System.Collections.Generic; +using CommunityToolkit.Mvvm.ComponentModel; namespace Vdcrpt.Desktop.Models; public partial class UserConfig : ObservableObject { - [ObservableProperty] bool _openWhenComplete; - - [ObservableProperty] bool _askForFilename; - - public IReadOnlyList Presets { get; private set; } + [ObservableProperty] private bool _askForFilename; + [ObservableProperty] private bool _openWhenComplete; public UserConfig() { Presets = new List(); } + public IReadOnlyList Presets { get; private set; } + public static UserConfig CreateDefault() { - return new UserConfig() + return new UserConfig { OpenWhenComplete = false, AskForFilename = true, - Presets = new List() + Presets = new List { new() { Name = "Melting Chaos", - Settings = new() + Settings = new BinaryRepeatEffectSettings { BurstSize = 3000, MinBurstLength = 8, @@ -38,7 +37,7 @@ public static UserConfig CreateDefault() new() { Name = "Jittery", - Settings = new() + Settings = new BinaryRepeatEffectSettings { BurstSize = 20000, MinBurstLength = 1, @@ -50,7 +49,7 @@ public static UserConfig CreateDefault() new() { Name = "Source Engine", - Settings = new() + Settings = new BinaryRepeatEffectSettings { BurstSize = 45000, MinBurstLength = 2, @@ -62,7 +61,7 @@ public static UserConfig CreateDefault() new() { Name = "Subtle", - Settings = new() + Settings = new BinaryRepeatEffectSettings { BurstSize = 200, MinBurstLength = 2, @@ -72,7 +71,7 @@ public static UserConfig CreateDefault() new() { Name = "Many Artifacts", - Settings = new() + Settings = new BinaryRepeatEffectSettings { BurstSize = 500, MinBurstLength = 3, @@ -82,7 +81,7 @@ public static UserConfig CreateDefault() new() { Name = "Trash (unstable, breaks audio)", - Settings = new() + Settings = new BinaryRepeatEffectSettings { BurstSize = 1, MinBurstLength = 1, @@ -92,7 +91,7 @@ public static UserConfig CreateDefault() new() { Name = "Legacy", - Settings = new() + Settings = new BinaryRepeatEffectSettings { BurstSize = 1000, MinBurstLength = 10, @@ -100,8 +99,8 @@ public static UserConfig CreateDefault() UseBurstLengthRange = true, Iterations = 50 } - }, + } } }; } -} +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/Program.cs b/src/Vdcrpt.Desktop/Program.cs index e051c47..c6734eb 100644 --- a/src/Vdcrpt.Desktop/Program.cs +++ b/src/Vdcrpt.Desktop/Program.cs @@ -3,18 +3,23 @@ namespace Vdcrpt.Desktop; -class Program +internal class Program { // Initialization code. Don't use any Avalonia, third-party APIs or any // SynchronizationContext-reliant code before AppMain is called: things aren't initialized // yet and stuff might break. [STAThread] - public static void Main(string[] args) => BuildAvaloniaApp() - .StartWithClassicDesktopLifetime(args); + public static void Main(string[] args) + { + BuildAvaloniaApp() + .StartWithClassicDesktopLifetime(args); + } // Avalonia configuration, don't remove; also used by visual designer. public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure() + { + return AppBuilder.Configure() .UsePlatformDetect() .LogToTrace(); -} + } +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/Vdcrpt.Desktop.csproj b/src/Vdcrpt.Desktop/Vdcrpt.Desktop.csproj index b19fb2a..d3f33da 100644 --- a/src/Vdcrpt.Desktop/Vdcrpt.Desktop.csproj +++ b/src/Vdcrpt.Desktop/Vdcrpt.Desktop.csproj @@ -22,21 +22,21 @@ - - - - + + + + - + - - + + - + diff --git a/src/Vdcrpt.Desktop/ViewLocator.cs b/src/Vdcrpt.Desktop/ViewLocator.cs index b1c356c..6c69c17 100644 --- a/src/Vdcrpt.Desktop/ViewLocator.cs +++ b/src/Vdcrpt.Desktop/ViewLocator.cs @@ -25,4 +25,4 @@ public bool Match(object data) { return data is ViewModelBase; } -} +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/ViewModelBase.cs b/src/Vdcrpt.Desktop/ViewModelBase.cs index bf065b5..13fe348 100644 --- a/src/Vdcrpt.Desktop/ViewModelBase.cs +++ b/src/Vdcrpt.Desktop/ViewModelBase.cs @@ -4,4 +4,4 @@ namespace Vdcrpt.Desktop; public abstract class ViewModelBase : ObservableValidator { -} +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/ViewModels/EffectSettingsViewModel.cs b/src/Vdcrpt.Desktop/ViewModels/EffectSettingsViewModel.cs index 6ac7ec6..f625990 100644 --- a/src/Vdcrpt.Desktop/ViewModels/EffectSettingsViewModel.cs +++ b/src/Vdcrpt.Desktop/ViewModels/EffectSettingsViewModel.cs @@ -1,13 +1,9 @@ -using CommunityToolkit.Mvvm.ComponentModel; -using Vdcrpt.Desktop.Models; +using Vdcrpt.Desktop.Models; namespace Vdcrpt.Desktop.ViewModels; -public partial class EffectSettingsViewModel : ViewModelBase +public class EffectSettingsViewModel : ViewModelBase { - public BinaryRepeatEffectSettings Settings { get; } - public int MinBurstLengthColumnSpan => Settings.UseBurstLengthRange ? 1 : 3; - public EffectSettingsViewModel(BinaryRepeatEffectSettings settings) { Settings = settings; @@ -20,5 +16,10 @@ public EffectSettingsViewModel(BinaryRepeatEffectSettings settings) }; } - public EffectSettingsViewModel() : this(new BinaryRepeatEffectSettings()) { } -} + public EffectSettingsViewModel() : this(new BinaryRepeatEffectSettings()) + { + } + + public BinaryRepeatEffectSettings Settings { get; } + public int MinBurstLengthColumnSpan => Settings.UseBurstLengthRange ? 1 : 3; +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/ViewModels/MainWindowViewModel.cs b/src/Vdcrpt.Desktop/ViewModels/MainWindowViewModel.cs index e3f2b0a..d3042f5 100644 --- a/src/Vdcrpt.Desktop/ViewModels/MainWindowViewModel.cs +++ b/src/Vdcrpt.Desktop/ViewModels/MainWindowViewModel.cs @@ -1,6 +1,5 @@ using System; using System.Diagnostics; -using System.Reflection; using System.Windows.Input; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; @@ -12,10 +11,24 @@ namespace Vdcrpt.Desktop.ViewModels; public partial class MainWindowViewModel : ViewModelBase { [ObservableProperty] private Project _project; - + + public MainWindowViewModel() + { + var config = UserConfig.CreateDefault(); + + _project = new Project + { + InputFile = string.Empty, + Config = config, + EffectSettings = new BinaryRepeatEffectSettings() + }; + + ProjectViewModel = new ProjectViewModel(_project); + } + public ProgramInfo ProgramInfo => ProgramInfo.Default; public string VersionWithPrefix => string.Concat("Version ", ProgramInfo.Version); - + public ICommand OnExitPressed { get; } = new DelegateCommand(_ => { if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) @@ -31,20 +44,6 @@ public partial class MainWindowViewModel : ViewModelBase public ProjectViewModel ProjectViewModel { get; } - public MainWindowViewModel() - { - var config = UserConfig.CreateDefault(); - - _project = new Project() - { - InputFile = string.Empty, - Config = config, - EffectSettings = new BinaryRepeatEffectSettings() - }; - - ProjectViewModel = new ProjectViewModel(_project); - } - public void OpenUrl(string url) { Process.Start(new ProcessStartInfo diff --git a/src/Vdcrpt.Desktop/ViewModels/OutputSettingsViewModel.cs b/src/Vdcrpt.Desktop/ViewModels/OutputSettingsViewModel.cs index c7f91c6..58f7140 100644 --- a/src/Vdcrpt.Desktop/ViewModels/OutputSettingsViewModel.cs +++ b/src/Vdcrpt.Desktop/ViewModels/OutputSettingsViewModel.cs @@ -1,17 +1,18 @@ using CommunityToolkit.Mvvm.ComponentModel; -using System.ComponentModel; using Vdcrpt.Desktop.Models; namespace Vdcrpt.Desktop.ViewModels; public partial class OutputSettingsViewModel : ViewModelBase { - [ObservableProperty] UserConfig _userConfig; + [ObservableProperty] private UserConfig _userConfig; public OutputSettingsViewModel(UserConfig userConfig) { _userConfig = userConfig; } - public OutputSettingsViewModel() : this(new UserConfig()) { } -} + public OutputSettingsViewModel() : this(new UserConfig()) + { + } +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/ViewModels/PresetEffectSettingsViewModel.cs b/src/Vdcrpt.Desktop/ViewModels/PresetEffectSettingsViewModel.cs index 46bdc0a..02ae46a 100644 --- a/src/Vdcrpt.Desktop/ViewModels/PresetEffectSettingsViewModel.cs +++ b/src/Vdcrpt.Desktop/ViewModels/PresetEffectSettingsViewModel.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using CommunityToolkit.Mvvm.ComponentModel; using Vdcrpt.Desktop.Models; @@ -7,12 +6,8 @@ namespace Vdcrpt.Desktop.ViewModels; public partial class PresetEffectSettingsViewModel : ViewModelBase { - public IReadOnlyList Presets { get; } - public EffectSettingsViewModel EffectSettingsViewModel { get; } + [ObservableProperty] private Preset _currentPreset; - [ObservableProperty] - private Preset _currentPreset; - public PresetEffectSettingsViewModel(IReadOnlyList presets, BinaryRepeatEffectSettings settings) { Presets = presets; @@ -28,13 +23,16 @@ public PresetEffectSettingsViewModel(IReadOnlyList presets, BinaryRepeat { } + public IReadOnlyList Presets { get; } + public EffectSettingsViewModel EffectSettingsViewModel { get; } + partial void OnCurrentPresetChanged(Preset value) { if (value is null) { return; } - + EffectSettingsViewModel.Settings.CopyFrom(value.Settings); } } diff --git a/src/Vdcrpt.Desktop/ViewModels/ProjectViewModel.cs b/src/Vdcrpt.Desktop/ViewModels/ProjectViewModel.cs index bd8f9ab..c6a2ed8 100644 --- a/src/Vdcrpt.Desktop/ViewModels/ProjectViewModel.cs +++ b/src/Vdcrpt.Desktop/ViewModels/ProjectViewModel.cs @@ -14,19 +14,15 @@ namespace Vdcrpt.Desktop.ViewModels; public partial class ProjectViewModel : ViewModelBase { private const string DefaultProgressMessage = "Ready!"; - - public Project Project { get; } - public PresetEffectSettingsViewModel PresetEffectSettingsViewModel { get; } - public OutputSettingsViewModel OutputSettingsViewModel { get; } [ObservableProperty] private bool _isBusy; + + // TODO: Maybe part of model? + [ObservableProperty] private string _outputPath; [ObservableProperty] private double _progressAmount; [ObservableProperty] private string _progressMessage; [ObservableProperty] private bool _running; - // TODO: Maybe part of model? - [ObservableProperty] private string _outputPath; - public ProjectViewModel(Project project) { Project = project; @@ -47,6 +43,10 @@ public ProjectViewModel() : this(new Project()) { } + public Project Project { get; } + public PresetEffectSettingsViewModel PresetEffectSettingsViewModel { get; } + public OutputSettingsViewModel OutputSettingsViewModel { get; } + [RelayCommand(CanExecute = nameof(CanOpenResult))] private void OpenResult() { @@ -67,8 +67,11 @@ private bool CanOpenResult() [RelayCommand(CanExecute = nameof(CanStartCorrupting))] private async Task StartCorrupting() { - if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop) return; - + if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop) + { + return; + } + if (Project.Config.AskForFilename) { var dialog = new SaveFileDialog @@ -77,9 +80,9 @@ private async Task StartCorrupting() InitialFileName = Path.GetFileName(OutputPath), Filters = new List { - new() { Extensions = { "mp4" }, Name = "MP4 video" }, + new() { Extensions = { "mp4" }, Name = "MP4 video" } }, - DefaultExtension = "mp4", + DefaultExtension = "mp4" }; var chosenPath = await dialog.ShowAsync(desktop.MainWindow); @@ -96,7 +99,7 @@ private async Task StartCorrupting() { OutputPath = Project.GenerateOutputPath(Project.InputFile); } - + try { Running = true; diff --git a/src/Vdcrpt.Desktop/Views/EffectSettingsView.axaml.cs b/src/Vdcrpt.Desktop/Views/EffectSettingsView.axaml.cs index c357c0f..7fe3f39 100644 --- a/src/Vdcrpt.Desktop/Views/EffectSettingsView.axaml.cs +++ b/src/Vdcrpt.Desktop/Views/EffectSettingsView.axaml.cs @@ -1,8 +1,7 @@ using Avalonia.Controls; -namespace Vdcrpt.Desktop.Views +namespace Vdcrpt.Desktop.Views; + +public class EffectSettingsView : UserControl { - public class EffectSettingsView : UserControl - { - } -} +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/Views/MainWindow.axaml b/src/Vdcrpt.Desktop/Views/MainWindow.axaml index c347720..0ce6031 100644 --- a/src/Vdcrpt.Desktop/Views/MainWindow.axaml +++ b/src/Vdcrpt.Desktop/Views/MainWindow.axaml @@ -29,8 +29,10 @@ - - + + @@ -38,12 +40,12 @@ - + - - + + diff --git a/src/Vdcrpt.Desktop/Views/MainWindow.axaml.cs b/src/Vdcrpt.Desktop/Views/MainWindow.axaml.cs index 8d6fe29..0127bba 100644 --- a/src/Vdcrpt.Desktop/Views/MainWindow.axaml.cs +++ b/src/Vdcrpt.Desktop/Views/MainWindow.axaml.cs @@ -6,69 +6,68 @@ using Avalonia.Interactivity; using Avalonia.Markup.Xaml; -namespace Vdcrpt.Desktop.Views +namespace Vdcrpt.Desktop.Views; + +public class MainWindow : Window { - public class MainWindow : Window - { - private readonly TextBox _inputPathTextBox; + private readonly TextBox _inputPathTextBox; - public MainWindow() - { - InitializeComponent(); + public MainWindow() + { + InitializeComponent(); #if DEBUG - this.AttachDevTools(); + this.AttachDevTools(); #endif - _inputPathTextBox = this.Find("InputPathTextBox"); + _inputPathTextBox = this.Find("InputPathTextBox"); - AddHandler(DragDrop.DropEvent, OnDrop); - } + AddHandler(DragDrop.DropEvent, OnDrop); + } - private void OnDrop(object? sender, DragEventArgs e) + private void OnDrop(object? sender, DragEventArgs e) + { + var filenames = e.Data.GetFileNames(); + if (filenames == null) { - var filenames = e.Data.GetFileNames(); - if (filenames == null) - { - return; - } - - var filenamesList = filenames.ToList(); - if (filenamesList.Count <= 0) - { - return; - } - - // Propagates to viewmodel - _inputPathTextBox.Text = filenamesList[0]; + return; } - private void InitializeComponent() + var filenamesList = filenames.ToList(); + if (filenamesList.Count <= 0) { - AvaloniaXamlLoader.Load(this); + return; } - private async void OnOpenPressed(object? sender, RoutedEventArgs routedEventArgs) - { - var dialog = new OpenFileDialog - { - Directory = ".", - AllowMultiple = false, - Filters = new List - { - new() { Name = "Common Video Files", Extensions = { "mp4", "avi", "mkv", "mov", "gif" } }, - new() { Name = "All Files", Extensions = { "*" } } - } - }; + // Propagates to viewmodel + _inputPathTextBox.Text = filenamesList[0]; + } - var result = await dialog.ShowAsync(this); - if (result is not { Length: > 0 }) + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + + private async void OnOpenPressed(object? sender, RoutedEventArgs routedEventArgs) + { + var dialog = new OpenFileDialog + { + Directory = ".", + AllowMultiple = false, + Filters = new List { - return; + new() { Name = "Common Video Files", Extensions = { "mp4", "avi", "mkv", "mov", "gif" } }, + new() { Name = "All Files", Extensions = { "*" } } } + }; - // Propagates to viewmodel - _inputPathTextBox.Text = result[0]; + var result = await dialog.ShowAsync(this); + if (result is not { Length: > 0 }) + { + return; } + + // Propagates to viewmodel + _inputPathTextBox.Text = result[0]; } -} +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml.cs b/src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml.cs index f215709..8fbcd3b 100644 --- a/src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml.cs +++ b/src/Vdcrpt.Desktop/Views/OutputSettingsView.axaml.cs @@ -1,8 +1,7 @@ using Avalonia.Controls; -namespace Vdcrpt.Desktop.Views +namespace Vdcrpt.Desktop.Views; + +public class OutputSettingsView : UserControl { - public class OutputSettingsView : UserControl - { - } -} +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/Views/PresetEffectSettingsView.axaml.cs b/src/Vdcrpt.Desktop/Views/PresetEffectSettingsView.axaml.cs index 42a2550..6f396a1 100644 --- a/src/Vdcrpt.Desktop/Views/PresetEffectSettingsView.axaml.cs +++ b/src/Vdcrpt.Desktop/Views/PresetEffectSettingsView.axaml.cs @@ -1,20 +1,17 @@ -using Avalonia; -using Avalonia.Controls; +using Avalonia.Controls; using Avalonia.Markup.Xaml; -namespace Vdcrpt.Desktop.Views +namespace Vdcrpt.Desktop.Views; + +public class PresetEffectSettingsView : UserControl { - public partial class PresetEffectSettingsView : UserControl + public PresetEffectSettingsView() { - public PresetEffectSettingsView() - { - InitializeComponent(); - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } + InitializeComponent(); } -} + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } +} \ No newline at end of file diff --git a/src/Vdcrpt.Desktop/Views/ProjectView.axaml b/src/Vdcrpt.Desktop/Views/ProjectView.axaml index ffb054a..0508f16 100644 --- a/src/Vdcrpt.Desktop/Views/ProjectView.axaml +++ b/src/Vdcrpt.Desktop/Views/ProjectView.axaml @@ -27,7 +27,7 @@ - + diff --git a/src/Vdcrpt.Desktop/Views/ProjectView.axaml.cs b/src/Vdcrpt.Desktop/Views/ProjectView.axaml.cs index 57905aa..cccbaee 100644 --- a/src/Vdcrpt.Desktop/Views/ProjectView.axaml.cs +++ b/src/Vdcrpt.Desktop/Views/ProjectView.axaml.cs @@ -7,70 +7,69 @@ using Avalonia.Interactivity; using Avalonia.Markup.Xaml; -namespace Vdcrpt.Desktop.Views +namespace Vdcrpt.Desktop.Views; + +public class ProjectView : UserControl { - public partial class ProjectView : UserControl + private readonly TextBox _inputPathTextBox; + + public ProjectView() { - private readonly TextBox _inputPathTextBox; + InitializeComponent(); - public ProjectView() - { - InitializeComponent(); + _inputPathTextBox = this.Find("InputPathTextBox"); + AddHandler(DragDrop.DropEvent, OnDrop); + } - _inputPathTextBox = this.Find("InputPathTextBox"); - AddHandler(DragDrop.DropEvent, OnDrop); + private void OnDrop(object? sender, DragEventArgs e) + { + var filenames = e.Data.GetFileNames(); + if (filenames == null) + { + return; } - private void OnDrop(object? sender, DragEventArgs e) + var filenamesList = filenames.ToList(); + if (filenamesList.Count <= 0) { - var filenames = e.Data.GetFileNames(); - if (filenames == null) - { - return; - } + return; + } - var filenamesList = filenames.ToList(); - if (filenamesList.Count <= 0) - { - return; - } + // Propagates to viewmodel + _inputPathTextBox.Text = filenamesList[0]; + } - // Propagates to viewmodel - _inputPathTextBox.Text = filenamesList[0]; - } + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } - private void InitializeComponent() + // TODO: Rewrite this as a service + private async void OnOpenPressed(object? sender, RoutedEventArgs routedEventArgs) + { + if (Application.Current!.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktopLifetime) { - AvaloniaXamlLoader.Load(this); + return; } - // TODO: Rewrite this as a service - private async void OnOpenPressed(object? sender, RoutedEventArgs routedEventArgs) + var dialog = new OpenFileDialog { - if (Application.Current!.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktopLifetime) + Directory = ".", + AllowMultiple = false, + Filters = new List { - return; + new() { Name = "Common Video Files", Extensions = { "mp4", "avi", "mkv", "mov", "gif" } }, + new() { Name = "All Files", Extensions = { "*" } } } - - var dialog = new OpenFileDialog - { - Directory = ".", - AllowMultiple = false, - Filters = new List - { - new() { Name = "Common Video Files", Extensions = { "mp4", "avi", "mkv", "mov", "gif" } }, - new() { Name = "All Files", Extensions = { "*" } } - } - }; + }; - var result = await dialog.ShowAsync(desktopLifetime.MainWindow); - if (result is not { Length: > 0 }) - { - return; - } - - // Propagates to viewmodel - _inputPathTextBox.Text = result[0]; + var result = await dialog.ShowAsync(desktopLifetime.MainWindow); + if (result is not { Length: > 0 }) + { + return; } + + // Propagates to viewmodel + _inputPathTextBox.Text = result[0]; } -} +} \ No newline at end of file