using System; using System.Collections.ObjectModel; using System.Reactive; using System.Reactive.Disposables; using Artemis.Core; using Artemis.Core.Services; using Artemis.UI.Screens.ProfileEditor.DisplayCondition; using Artemis.UI.Screens.ProfileEditor.ProfileTree; using Artemis.UI.Screens.ProfileEditor.Properties; using Artemis.UI.Screens.ProfileEditor.StatusBar; using Artemis.UI.Screens.ProfileEditor.VisualEditor; using Artemis.UI.Shared.Services.ProfileEditor; using Avalonia.Threading; using DynamicData; using DynamicData.Binding; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor; public class ProfileEditorViewModel : MainScreenViewModel { private readonly IProfileEditorService _profileEditorService; private readonly ISettingsService _settingsService; private ObservableAsPropertyHelper? _history; private ObservableAsPropertyHelper? _profileConfiguration; private ObservableAsPropertyHelper? _suspendedEditing; private ReadOnlyObservableCollection? _tools; private StatusBarViewModel _statusBarViewModel; private DisplayConditionScriptViewModel _displayConditionScriptViewModel; private PropertiesViewModel _propertiesViewModel; private ProfileTreeViewModel _profileTreeViewModel; private VisualEditorViewModel _visualEditorViewModel; /// public ProfileEditorViewModel(IScreen hostScreen, IProfileEditorService profileEditorService, ISettingsService settingsService, VisualEditorViewModel visualEditorViewModel, ProfileTreeViewModel profileTreeViewModel, ProfileEditorTitleBarViewModel profileEditorTitleBarViewModel, PropertiesViewModel propertiesViewModel, DisplayConditionScriptViewModel displayConditionScriptViewModel, StatusBarViewModel statusBarViewModel) : base(hostScreen, "profile-editor") { _profileEditorService = profileEditorService; _settingsService = settingsService; this.WhenActivated(d => { _profileConfiguration = profileEditorService.ProfileConfiguration.ToProperty(this, vm => vm.ProfileConfiguration).DisposeWith(d); _history = profileEditorService.History.ToProperty(this, vm => vm.History).DisposeWith(d); _suspendedEditing = profileEditorService.SuspendedEditing.ToProperty(this, vm => vm.SuspendedEditing).DisposeWith(d); profileEditorService.Tools .ToObservableChangeSet() .Filter(t => t.ShowInToolbar) .Sort(SortExpressionComparer.Ascending(vm => vm.Order)) .Bind(out ReadOnlyObservableCollection tools) .Subscribe() .DisposeWith(d); Tools = tools; // Slow and steady wins the race (and doesn't lock up the entire UI) Dispatcher.UIThread.Post(() => StatusBarViewModel = statusBarViewModel, DispatcherPriority.Loaded); Dispatcher.UIThread.Post(() => VisualEditorViewModel = visualEditorViewModel, DispatcherPriority.Loaded); Dispatcher.UIThread.Post(() => ProfileTreeViewModel = profileTreeViewModel, DispatcherPriority.Loaded); Dispatcher.UIThread.Post(() => PropertiesViewModel = propertiesViewModel, DispatcherPriority.Loaded); Dispatcher.UIThread.Post(() => DisplayConditionScriptViewModel = displayConditionScriptViewModel, DispatcherPriority.Loaded); }); TitleBarViewModel = profileEditorTitleBarViewModel; ToggleSuspend = ReactiveCommand.Create(ExecuteToggleSuspend); ToggleAutoSuspend = ReactiveCommand.Create(ExecuteToggleAutoSuspend); } public VisualEditorViewModel VisualEditorViewModel { get => _visualEditorViewModel; set => RaiseAndSetIfChanged(ref _visualEditorViewModel, value); } public ProfileTreeViewModel ProfileTreeViewModel { get => _profileTreeViewModel; set => RaiseAndSetIfChanged(ref _profileTreeViewModel, value); } public PropertiesViewModel PropertiesViewModel { get => _propertiesViewModel; set => RaiseAndSetIfChanged(ref _propertiesViewModel, value); } public DisplayConditionScriptViewModel DisplayConditionScriptViewModel { get => _displayConditionScriptViewModel; set => RaiseAndSetIfChanged(ref _displayConditionScriptViewModel, value); } public StatusBarViewModel StatusBarViewModel { get => _statusBarViewModel; set => RaiseAndSetIfChanged(ref _statusBarViewModel, value); } public ReadOnlyObservableCollection? Tools { get => _tools; set => RaiseAndSetIfChanged(ref _tools, value); } public ProfileConfiguration? ProfileConfiguration => _profileConfiguration?.Value; public ProfileEditorHistory? History => _history?.Value; public bool SuspendedEditing => _suspendedEditing?.Value ?? false; public PluginSetting TreeWidth => _settingsService.GetSetting("ProfileEditor.TreeWidth", 350.0); public PluginSetting ConditionsHeight => _settingsService.GetSetting("ProfileEditor.ConditionsHeight", 300.0); public PluginSetting PropertiesHeight => _settingsService.GetSetting("ProfileEditor.PropertiesHeight", 300.0); public ReactiveCommand ToggleSuspend { get; } public ReactiveCommand ToggleAutoSuspend { get; } public void OpenUrl(string url) { Utilities.OpenUrl(url); } private void ExecuteToggleSuspend() { _profileEditorService.ChangeSuspendedEditing(!SuspendedEditing); } private void ExecuteToggleAutoSuspend() { PluginSetting setting = _settingsService.GetSetting("ProfileEditor.AutoSuspend", true); setting.Value = !setting.Value; setting.Save(); } }