diff --git a/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/ChangeElementDisplayCondition.cs b/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/ChangeElementDisplayCondition.cs new file mode 100644 index 000000000..6241db06a --- /dev/null +++ b/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/ChangeElementDisplayCondition.cs @@ -0,0 +1,53 @@ +using System; +using Artemis.Core; + +namespace Artemis.UI.Shared.Services.ProfileEditor.Commands; + +/// +/// Represents a profile editor command that can be used to change the display condition of a profile element. +/// +public class ChangeElementDisplayCondition : IProfileEditorCommand, IDisposable +{ + private readonly ICondition? _condition; + private readonly ICondition? _oldCondition; + private readonly RenderProfileElement _profileElement; + private bool _executed; + + /// + /// Creates a new instance of the class. + /// + /// The render profile element whose display condition to change. + /// The new display condition. + public ChangeElementDisplayCondition(RenderProfileElement profileElement, ICondition? condition) + { + _profileElement = profileElement; + _condition = condition; + _oldCondition = profileElement.DisplayCondition; + } + + /// + public void Dispose() + { + if (_executed) + _oldCondition?.Dispose(); + else + _condition?.Dispose(); + } + + /// + public string DisplayName => "Change display condition mode"; + + /// + public void Execute() + { + _profileElement.DisplayCondition = _condition; + _executed = true; + } + + /// + public void Undo() + { + _profileElement.DisplayCondition = _oldCondition; + _executed = false; + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/MoveProfileEElement.cs b/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/MoveProfileElement.cs similarity index 100% rename from src/Artemis.UI.Shared/Services/ProfileEditor/Commands/MoveProfileEElement.cs rename to src/Artemis.UI.Shared/Services/ProfileEditor/Commands/MoveProfileElement.cs diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index ba43a89b1..c750a6d1a 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -65,6 +65,9 @@ DragCableView.axaml + + NodeScriptWindowView.axaml + diff --git a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs index 4e17b0e38..a5ce59884 100644 --- a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs +++ b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs @@ -92,7 +92,7 @@ namespace Artemis.UI.Ninject.Factories public interface INodeVmFactory : IVmFactory { - NodeScriptViewModel NodeScriptViewModel(NodeScript nodeScript); + NodeScriptViewModel NodeScriptViewModel(NodeScript nodeScript, bool isPreview); NodePickerViewModel NodePickerViewModel(NodeScript nodeScript); NodeViewModel NodeViewModel(NodeScriptViewModel nodeScriptViewModel, INode node); CableViewModel CableViewModel(NodeScriptViewModel nodeScriptViewModel, IPin from, IPin to); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptView.axaml new file mode 100644 index 000000000..50fd86945 --- /dev/null +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptView.axaml @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptView.axaml.cs new file mode 100644 index 000000000..f493916d0 --- /dev/null +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptView.axaml.cs @@ -0,0 +1,18 @@ +using Avalonia.Markup.Xaml; +using Avalonia.ReactiveUI; + +namespace Artemis.UI.Screens.ProfileEditor.DisplayCondition +{ + public partial class DisplayConditionScriptView : ReactiveUserControl + { + public DisplayConditionScriptView() + { + InitializeComponent(); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + } +} diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptViewModel.cs new file mode 100644 index 000000000..dc541873a --- /dev/null +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptViewModel.cs @@ -0,0 +1,58 @@ +using System; +using System.Reactive.Linq; +using System.Threading.Tasks; +using Artemis.Core; +using Artemis.UI.Ninject.Factories; +using Artemis.UI.Screens.VisualScripting; +using Artemis.UI.Shared; +using Artemis.UI.Shared.Services.Interfaces; +using Artemis.UI.Shared.Services.ProfileEditor; +using Artemis.UI.Shared.Services.ProfileEditor.Commands; +using Avalonia.Controls.Mixins; +using ReactiveUI; + +namespace Artemis.UI.Screens.ProfileEditor.DisplayCondition; + +public class DisplayConditionScriptViewModel : ActivatableViewModelBase +{ + private readonly IProfileEditorService _profileEditorService; + private readonly IWindowService _windowService; + private ObservableAsPropertyHelper? _nodeScriptViewModel; + private RenderProfileElement? _profileElement; + + public DisplayConditionScriptViewModel(IProfileEditorService profileEditorService, INodeVmFactory nodeVmFactory, IWindowService windowService) + { + _profileEditorService = profileEditorService; + _windowService = windowService; + this.WhenActivated(d => + { + profileEditorService.ProfileElement.Subscribe(p => _profileElement = p).DisposeWith(d); + _nodeScriptViewModel = profileEditorService.ProfileElement + .Select(p => p?.WhenAnyValue(element => element.DisplayCondition) ?? Observable.Never()) + .Switch() + .Select(c => c is StaticCondition staticCondition ? nodeVmFactory.NodeScriptViewModel(staticCondition.Script, true) : null) + .ToProperty(this, vm => vm.NodeScriptViewModel) + .DisposeWith(d); + }); + } + + public NodeScriptViewModel? NodeScriptViewModel => _nodeScriptViewModel?.Value; + + public async Task EnableConditions() + { + bool confirmed = await _windowService.ShowConfirmContentDialog( + "Display conditions", + "Do you want to enable display conditions for this element? \r\n" + + "Using display conditions you can dynamically hide or show layers and folders depending on certain parameters." + ); + + if (confirmed && _profileElement != null) + _profileEditorService.ExecuteCommand(new ChangeElementDisplayCondition(_profileElement, new StaticCondition(_profileElement))); + } + + public async Task OpenEditor() + { + if (_profileElement?.DisplayCondition is StaticCondition staticCondition) + await _windowService.ShowDialogAsync(("nodeScript", staticCondition.Script)); + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml index 17cd88467..4a929734c 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml @@ -97,7 +97,7 @@ - Conditions + diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs index bba6fe5c9..f886c6a2d 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs @@ -3,6 +3,7 @@ using System.Collections.ObjectModel; 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; @@ -29,6 +30,7 @@ public class ProfileEditorViewModel : MainScreenViewModel ProfileTreeViewModel profileTreeViewModel, ProfileEditorTitleBarViewModel profileEditorTitleBarViewModel, PropertiesViewModel propertiesViewModel, + DisplayConditionScriptViewModel displayConditionScriptViewModel, StatusBarViewModel statusBarViewModel) : base(hostScreen, "profile-editor") { @@ -36,9 +38,10 @@ public class ProfileEditorViewModel : MainScreenViewModel VisualEditorViewModel = visualEditorViewModel; ProfileTreeViewModel = profileTreeViewModel; PropertiesViewModel = propertiesViewModel; + DisplayConditionScriptViewModel = displayConditionScriptViewModel; StatusBarViewModel = statusBarViewModel; TitleBarViewModel = profileEditorTitleBarViewModel; - + this.WhenActivated(d => { _profileConfiguration = profileEditorService.ProfileConfiguration.ToProperty(this, vm => vm.ProfileConfiguration).DisposeWith(d); @@ -56,6 +59,7 @@ public class ProfileEditorViewModel : MainScreenViewModel public VisualEditorViewModel VisualEditorViewModel { get; } public ProfileTreeViewModel ProfileTreeViewModel { get; } public PropertiesViewModel PropertiesViewModel { get; } + public DisplayConditionScriptViewModel DisplayConditionScriptViewModel { get; } public StatusBarViewModel StatusBarViewModel { get; } public ReadOnlyObservableCollection? Tools @@ -70,6 +74,7 @@ public class ProfileEditorViewModel : MainScreenViewModel public PluginSetting ConditionsHeight => _settingsService.GetSetting("ProfileEditor.ConditionsHeight", 300.0); public PluginSetting PropertiesHeight => _settingsService.GetSetting("ProfileEditor.PropertiesHeight", 300.0); + public void OpenUrl(string url) { Utilities.OpenUrl(url); diff --git a/src/Artemis.UI/Screens/VisualScripting/NodeScriptView.axaml b/src/Artemis.UI/Screens/VisualScripting/NodeScriptView.axaml index 6c49d2018..6d6f12d9e 100644 --- a/src/Artemis.UI/Screens/VisualScripting/NodeScriptView.axaml +++ b/src/Artemis.UI/Screens/VisualScripting/NodeScriptView.axaml @@ -7,7 +7,8 @@ xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Screens.VisualScripting.NodeScriptView" - x:DataType="visualScripting:NodeScriptViewModel"> + x:DataType="visualScripting:NodeScriptViewModel" + IsHitTestVisible="{CompiledBinding !IsPreview}">