OverviewFilesCommitsIssuesDocsReleasesPeers

ifsrenderer-linux / WpfDisplay / ViewModels / PostFxPanelViewModel.cs

128 lines · csharp ref:
#nullable enable
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

using IFSEngine.Model;

using WpfDisplay.Models;

namespace WpfDisplay.ViewModels;

public partial class PostFxPanelViewModel : ObservableObject
{
    private readonly Workspace _workspace;

    [ObservableProperty] public partial ObservableCollection<PostFxLayerViewModel> PostEffectLayers { get; set; } = [];

    /// <summary>
    /// All loaded posteffect plugins available to add as layer.
    /// </summary>
    public IEnumerable<EffectPlugin> LoadedEffects => _workspace.LoadedEffects;

    public PostFxPanelViewModel(Workspace workspace)
    {
        _workspace = workspace;
        workspace.LoadedParamsChanged += (s, e) => RefreshInstances();
        RefreshInstances();
    }

    private void RefreshInstances()
    {
        PostEffectLayers.Clear();
        foreach (var instance in _workspace.Ifs.PostEffects)
        {
            PostEffectLayers.Add(new PostFxLayerViewModel(instance, _workspace));
        }
        OnPropertyChanged(nameof(PostEffectLayers));
    }

    [RelayCommand]
    private void AddLayer(EffectPlugin? effectPlugin)
    {
        if (effectPlugin == null) return;
        _workspace.TakeSnapshot();
        _workspace.Ifs.AddPostEffectLayer(new EffectLayer(effectPlugin));
        _workspace.Renderer.InvalidateDisplay();
        RefreshInstances();
    }

    [RelayCommand]
    private void RemoveLayer(PostFxLayerViewModel vm)
    {
        _workspace.TakeSnapshot();
        _workspace.Ifs.RemovePostEffectLayer(vm.Instance);
        _workspace.Renderer.InvalidateDisplay();
        RefreshInstances();
        _workspace.OnParamSourceRemoved(vm.Instance.Id);
    }

    [RelayCommand]
    private void MoveUp(PostFxLayerViewModel vm)
    {
        var list = _workspace.Ifs.PostEffects.ToList();
        int index = list.IndexOf(vm.Instance);
        if (index > 0)
        {
            _workspace.TakeSnapshot();
            _workspace.Ifs.MovePostEffectLayer(vm.Instance, index - 1);
            _workspace.Renderer.InvalidateDisplay();
            RefreshInstances();
        }
    }

    [RelayCommand]
    private void MoveDown(PostFxLayerViewModel vm)
    {
        var list = _workspace.Ifs.PostEffects.ToList();
        int index = list.IndexOf(vm.Instance);
        if (index < _workspace.Ifs.PostEffects.Count - 1)
        {
            _workspace.TakeSnapshot();
            _workspace.Ifs.MovePostEffectLayer(vm.Instance, index + 1);
            _workspace.Renderer.InvalidateDisplay();
            RefreshInstances();
        }
    }

    [RelayCommand]
    private async Task ReloadEffects()
    {
        try
        {
            await _workspace.ReloadPlugins();
            RefreshInstances();
            OnPropertyChanged(nameof(LoadedEffects));
        }
        catch (System.Exception ex)
        {
            _workspace.UpdateStatusText("Failed to reload effect plugins.");
            System.Windows.MessageBox.Show($"Failed to reload postfx plugins.\r\n{ex.Message}", "Plugin error");
        }
    }

    [RelayCommand]
    private static void OpenPostFxDirectory()
    {
        System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
        {
            FileName = App.PostEffectsDirectoryPath,
            UseShellExecute = true
        });
    }

    [RelayCommand]
    private static void EditPostFxSource(string filePath)
    {
        System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
        {
            FileName = filePath,
            UseShellExecute = true
        });
    }
}