1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Profile editor - Added layer renaming

Profile editor - Added undo/redo notification (for now)
This commit is contained in:
Robert 2022-01-10 21:19:35 +01:00
parent 0b905cca2e
commit 5802855eb1
17 changed files with 492 additions and 249 deletions

View File

@ -8,8 +8,8 @@ using FluentAvalonia.UI.Controls;
using ReactiveUI; using ReactiveUI;
using Button = Avalonia.Controls.Button; using Button = Avalonia.Controls.Button;
namespace Artemis.UI.Shared.Services.Builders namespace Artemis.UI.Shared.Services.Builders;
{
/// <summary> /// <summary>
/// Represents a builder that can be used to create notifications. /// Represents a builder that can be used to create notifications.
/// </summary> /// </summary>
@ -117,10 +117,12 @@ namespace Artemis.UI.Shared.Services.Builders
/// <summary> /// <summary>
/// Shows the notification. /// Shows the notification.
/// </summary> /// </summary>
public void Show() /// <returns>An action that can be called to hide the notification.</returns>
/// <exception cref="ArtemisSharedUIException" />
public Action Show()
{ {
if (_parent.Content is not Panel panel) if (_parent.Content is not Panel panel)
return; throw new ArtemisSharedUIException("Can't display a notification on a window without a panel at its root.");
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
{ {
@ -134,6 +136,8 @@ namespace Artemis.UI.Shared.Services.Builders
await Task.Delay(_timeout); await Task.Delay(_timeout);
Dispatcher.UIThread.Post(() => _infoBar.IsOpen = false); Dispatcher.UIThread.Post(() => _infoBar.IsOpen = false);
}); });
return () => Dispatcher.UIThread.Post(() => _infoBar.IsOpen = false);
} }
private void InfoBarOnClosed(InfoBar sender, InfoBarClosedEventArgs args) private void InfoBarOnClosed(InfoBar sender, InfoBarClosedEventArgs args)
@ -153,8 +157,8 @@ namespace Artemis.UI.Shared.Services.Builders
{ {
private Action? _action; private Action? _action;
private ICommand? _command; private ICommand? _command;
private string _text = "Text";
private object? _commandParameter; private object? _commandParameter;
private string _text = "Text";
/// <summary> /// <summary>
/// Changes text message of the button. /// Changes text message of the button.
@ -237,4 +241,3 @@ namespace Artemis.UI.Shared.Services.Builders
/// </summary> /// </summary>
Error Error
} }
}

View File

@ -0,0 +1,51 @@
using System;
using Artemis.Core;
namespace Artemis.UI.Shared.Services.ProfileEditor.Commands;
/// <summary>
/// Represents a profile editor command that can be used to rename a profile element.
/// </summary>
public class RenameProfileElement : IProfileEditorCommand
{
private readonly string? _name;
private readonly string? _originalName;
private readonly ProfileElement _subject;
/// <summary>
/// Creates a new instance of the <see cref="RenameProfileElement" /> class.
/// </summary>
public RenameProfileElement(ProfileElement subject, string? name)
{
_subject = subject;
_name = name;
_originalName = subject.Name;
DisplayName = subject switch
{
Layer => "Rename layer",
Folder => "Rename folder",
_ => throw new ArgumentException("Type of subject is not supported")
};
}
#region Implementation of IProfileEditorCommand
/// <inheritdoc />
public string DisplayName { get; }
/// <inheritdoc />
public void Execute()
{
_subject.Name = _name;
}
/// <inheritdoc />
public void Undo()
{
_subject.Name = _originalName;
}
#endregion
}

View File

@ -30,8 +30,8 @@ namespace Artemis.UI.Shared.Services.ProfileEditor
public IObservable<bool> CanRedo => _canRedo.AsObservable().DistinctUntilChanged(); public IObservable<bool> CanRedo => _canRedo.AsObservable().DistinctUntilChanged();
public ReactiveCommand<IProfileEditorCommand, Unit> Execute { get; } public ReactiveCommand<IProfileEditorCommand, Unit> Execute { get; }
public ReactiveCommand<Unit, Unit> Undo { get; } public ReactiveCommand<Unit, IProfileEditorCommand?> Undo { get; }
public ReactiveCommand<Unit, Unit> Redo { get; } public ReactiveCommand<Unit, IProfileEditorCommand?> Redo { get; }
public void Clear() public void Clear()
{ {
@ -67,24 +67,28 @@ namespace Artemis.UI.Shared.Services.ProfileEditor
_undoCommands.Clear(); _undoCommands.Clear();
} }
private void ExecuteUndo() private IProfileEditorCommand? ExecuteUndo()
{ {
if (!_undoCommands.TryPop(out IProfileEditorCommand? command)) if (!_undoCommands.TryPop(out IProfileEditorCommand? command))
return; return null;
command.Undo(); command.Undo();
_redoCommands.Push(command); _redoCommands.Push(command);
UpdateSubjects(); UpdateSubjects();
return command;
} }
private void ExecuteRedo() private IProfileEditorCommand? ExecuteRedo()
{ {
if (!_redoCommands.TryPop(out IProfileEditorCommand? command)) if (!_redoCommands.TryPop(out IProfileEditorCommand? command))
return; return null;
command.Execute(); command.Execute();
_undoCommands.Push(command); _undoCommands.Push(command);
UpdateSubjects(); UpdateSubjects();
return command;
} }
private void UpdateSubjects() private void UpdateSubjects()

View File

@ -22,8 +22,8 @@ internal class ProfileEditorService : IProfileEditorService
{ {
_profileService = profileService; _profileService = profileService;
_windowService = windowService; _windowService = windowService;
ProfileConfiguration = _profileConfigurationSubject.AsObservable().DistinctUntilChanged(); ProfileConfiguration = _profileConfigurationSubject.AsObservable();
ProfileElement = _profileElementSubject.AsObservable().DistinctUntilChanged(); ProfileElement = _profileElementSubject.AsObservable();
History = Observable.Defer(() => Observable.Return(GetHistory(_profileConfigurationSubject.Value))).Concat(ProfileConfiguration.Select(GetHistory)); History = Observable.Defer(() => Observable.Return(GetHistory(_profileConfigurationSubject.Value))).Concat(ProfileConfiguration.Select(GetHistory));
} }

View File

@ -25,6 +25,7 @@
<StyleInclude Source="/Styles/Border.axaml" /> <StyleInclude Source="/Styles/Border.axaml" />
<StyleInclude Source="/Styles/Button.axaml" /> <StyleInclude Source="/Styles/Button.axaml" />
<StyleInclude Source="/Styles/TextBlock.axaml" /> <StyleInclude Source="/Styles/TextBlock.axaml" />
<StyleInclude Source="/Styles/TextBox.axaml" />
<StyleInclude Source="/Styles/Sidebar.axaml" /> <StyleInclude Source="/Styles/Sidebar.axaml" />
<StyleInclude Source="/Styles/InfoBar.axaml" /> <StyleInclude Source="/Styles/InfoBar.axaml" />
<StyleInclude Source="/Styles/TreeView.axaml" /> <StyleInclude Source="/Styles/TreeView.axaml" />

View File

@ -0,0 +1,28 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Design.PreviewWith>
<Border Padding="50">
<StackPanel Spacing="5">
<TextBox />
<TextBox Classes="condensed" />
<TextBox Text="Hello Down there" />
<TextBox Classes="condensed" Text="Hello Down there" />
<TextBox Watermark="Watermark" />
<TextBox Classes="condensed" Watermark="Watermark" />
<TextBox Text="Test" IsEnabled="False" />
<TextBox Classes="condensed" Text="Test" IsEnabled="False" />
<TextBox Text="Test Clear" Classes="clearButton" />
<TextBox Classes="condensed clearButton" Text="Test Clear" />
<TextBox Text="Test Password" Classes="revealPasswordButton" PasswordChar="*" />
<TextBox Classes="condensed revealPasswordButton" Text="Test Password" PasswordChar="*" />
</StackPanel>
</Border>
</Design.PreviewWith>
<!-- Add Styles Here -->
<Style Selector="TextBox.condensed">
<Setter Property="Padding" Value="4 2" />
<Setter Property="FontSize" Value="14"></Setter>
<Setter Property="MinHeight" Value="25" />
</Style>
</Styles>

View File

@ -1,6 +1,9 @@
using System; using System;
using System.Reactive;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Reactive.Linq;
using Artemis.UI.Shared; using Artemis.UI.Shared;
using Artemis.UI.Shared.Services.Interfaces;
using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor;
using ReactiveUI; using ReactiveUI;
@ -8,11 +11,40 @@ namespace Artemis.UI.Screens.ProfileEditor.MenuBar
{ {
public class MenuBarViewModel : ActivatableViewModelBase public class MenuBarViewModel : ActivatableViewModelBase
{ {
private readonly INotificationService _notificationService;
private ProfileEditorHistory? _history; private ProfileEditorHistory? _history;
private Action? _lastMessage;
public MenuBarViewModel(IProfileEditorService profileEditorService) public MenuBarViewModel(IProfileEditorService profileEditorService, INotificationService notificationService)
{ {
_notificationService = notificationService;
this.WhenActivated(d => profileEditorService.History.Subscribe(history => History = history).DisposeWith(d)); this.WhenActivated(d => profileEditorService.History.Subscribe(history => History = history).DisposeWith(d));
this.WhenAnyValue(x => x.History)
.Select(h => h?.Undo ?? Observable.Never<IProfileEditorCommand?>())
.Switch()
.Subscribe(DisplayUndo);
this.WhenAnyValue(x => x.History)
.Select(h => h?.Redo ?? Observable.Never<IProfileEditorCommand?>())
.Switch()
.Subscribe(DisplayRedo);
}
private void DisplayUndo(IProfileEditorCommand? command)
{
if (command == null || History == null)
return;
_lastMessage?.Invoke();
_lastMessage = _notificationService.CreateNotification().WithMessage($"Undid '{command.DisplayName}'.").HavingButton(b => b.WithText("Redo").WithCommand(History.Redo)).Show();
}
private void DisplayRedo(IProfileEditorCommand? command)
{
if (command == null || History == null)
return;
_lastMessage?.Invoke();
_notificationService.CreateNotification().WithMessage($"Redid '{command.DisplayName}'.").HavingButton(b => b.WithText("Undo").WithCommand(History.Undo)).Show(); ;
} }
public ProfileEditorHistory? History public ProfileEditorHistory? History

View File

@ -14,17 +14,31 @@
<converters:PropertyTreeMarginConverter x:Key="PropertyTreeMarginConverter" /> <converters:PropertyTreeMarginConverter x:Key="PropertyTreeMarginConverter" />
<sharedConverters:EnumToBooleanConverter x:Key="EnumBoolConverter" /> <sharedConverters:EnumToBooleanConverter x:Key="EnumBoolConverter" />
</UserControl.Resources> </UserControl.Resources>
<UserControl.Styles>
<Style Selector="avalonia|MaterialIcon.chevron-collapsed">
<Setter Property="RenderTransform" Value="rotate(180deg)" />
</Style>
</UserControl.Styles>
<StackPanel> <StackPanel>
<Border Name="Bd" <Border Name="Bd"
BorderBrush="{DynamicResource MaterialDesignDivider}" BorderBrush="{DynamicResource MaterialDesignDivider}"
BorderThickness="0,0,0,1" BorderThickness="0,0,0,1"
Height="25"> Height="25">
<Grid Margin="{Binding Converter={StaticResource PropertyTreeMarginConverter}}" ColumnDefinitions="19,*"> <Grid Margin="{Binding Converter={StaticResource PropertyTreeMarginConverter}}" ColumnDefinitions="19,*">
<ToggleButton x:Name="Expander"
Foreground="{DynamicResource MaterialDesignBody}" <avalonia:MaterialIcon Classes.chevron-collapsed="{Binding !ProfileElementPropertyGroupViewModel.IsExpanded}"
IsChecked="{Binding Path=LayerPropertyGroupViewModel.IsExpanded}" IsVisible="{Binding ProfileElementPropertyGroupViewModel.HasChildren}"
IsVisible="{Binding LayerPropertyGroupViewModel.HasChildren}" Kind="ChevronUp"
ClickMode="Press" /> Grid.Column="0"
Margin="5 0"
PointerPressed="InputElement_OnPointerPressed"
Background="Transparent">
<avalonia:MaterialIcon.Transitions>
<Transitions>
<TransformOperationsTransition Property="RenderTransform" Duration="0:0:0.2" />
</Transitions>
</avalonia:MaterialIcon.Transitions>
</avalonia:MaterialIcon>
<StackPanel Grid.Column="1"> <StackPanel Grid.Column="1">
<!-- Type: None --> <!-- Type: None -->
@ -164,11 +178,11 @@
</Border> </Border>
<!-- <!--
Do not bind directly to the LayerPropertyGroupViewModel.Children collection Do not bind directly to the ProfileElementPropertyGroupViewModel.Children collection
Instead use a reference provided by the VM that is null when collapsed, virtualization for noobs Instead use a reference provided by the VM that is null when collapsed, virtualization for noobs
--> -->
<ItemsControl Items="{Binding Children}" <ItemsControl Items="{Binding Children}"
IsVisible="{Binding LayerPropertyGroupViewModel.IsExpanded}" IsVisible="{Binding ProfileElementPropertyGroupViewModel.IsExpanded}"
HorizontalAlignment="Stretch"> HorizontalAlignment="Stretch">
<ItemsControl.DataTemplates> <ItemsControl.DataTemplates>
<DataTemplate DataType="profileElementProperties:ProfileElementPropertyGroupViewModel"> <DataTemplate DataType="profileElementProperties:ProfileElementPropertyGroupViewModel">

View File

@ -1,3 +1,4 @@
using Avalonia.Input;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
@ -14,5 +15,11 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileElementProperties.Tree
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
} }
private void InputElement_OnPointerPressed(object? sender, PointerPressedEventArgs e)
{
if (ViewModel != null)
ViewModel.ProfileElementPropertyGroupViewModel.IsExpanded = !ViewModel.ProfileElementPropertyGroupViewModel.IsExpanded;
}
} }
} }

View File

@ -25,7 +25,15 @@
Kind="FolderOpen" Kind="FolderOpen"
Margin="0 0 5 0" Margin="0 0 5 0"
IsVisible="{Binding IsExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}}" /> IsVisible="{Binding IsExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}}" />
<TextBlock Grid.Column="2" Text="{Binding Folder.Name}" VerticalAlignment="Center" /> <TextBox Grid.Column="2"
Margin="-5 0 0 0"
Classes="condensed"
IsVisible="{Binding Renaming}"
Text="{Binding RenameValue}"
x:Name="Input"
KeyUp="InputElement_OnKeyUp"
LostFocus="InputElement_OnLostFocus"/>
<TextBlock Grid.Column="2" IsVisible="{Binding !Renaming}" Text="{Binding Folder.Name}" VerticalAlignment="Center" />
<ToggleButton Grid.Column="3" <ToggleButton Grid.Column="3"
Classes="icon-button icon-button-small" Classes="icon-button icon-button-small"
ToolTip.Tip="Toggle suspended state" ToolTip.Tip="Toggle suspended state"

View File

@ -1,6 +1,10 @@
using System;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using ReactiveUI;
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
{ {
@ -14,6 +18,24 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
private void InitializeComponent() private void InitializeComponent()
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
this.WhenActivated(_ => ViewModel?.Rename.Subscribe(_ =>
{
this.Get<TextBox>("Input").Focus();
this.Get<TextBox>("Input").SelectAll();
}));
}
private void InputElement_OnKeyUp(object? sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
ViewModel?.SubmitRename();
else if (e.Key == Key.Escape)
ViewModel?.CancelRename();
}
private void InputElement_OnLostFocus(object? sender, RoutedEventArgs e)
{
ViewModel?.CancelRename();
} }
} }
} }

View File

@ -14,5 +14,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
} }
public Folder Folder { get; } public Folder Folder { get; }
} }
} }

View File

@ -16,7 +16,15 @@
<avalonia:MaterialIcon Kind="AlertCircle" /> <avalonia:MaterialIcon Kind="AlertCircle" />
</Button> </Button>
<avalonia:MaterialIcon Grid.Column="1" Kind="{Binding Layer.LayerBrush.Descriptor.Icon}" Margin="0 0 5 0" /> <avalonia:MaterialIcon Grid.Column="1" Kind="{Binding Layer.LayerBrush.Descriptor.Icon}" Margin="0 0 5 0" />
<TextBlock Grid.Column="2" Text="{Binding Layer.Name}" VerticalAlignment="Center" /> <TextBox Grid.Column="2"
Margin="-5 0 0 0"
Classes="condensed"
x:Name="Input"
IsVisible="{Binding Renaming}"
Text="{Binding RenameValue}"
KeyUp="InputElement_OnKeyUp"
LostFocus="InputElement_OnLostFocus"></TextBox>
<TextBlock Grid.Column="2" IsVisible="{Binding !Renaming}" Text="{Binding Layer.Name}" VerticalAlignment="Center" />
<ToggleButton Grid.Column="3" <ToggleButton Grid.Column="3"
Classes="icon-button icon-button-small" Classes="icon-button icon-button-small"
ToolTip.Tip="Toggle suspended state" ToolTip.Tip="Toggle suspended state"

View File

@ -1,6 +1,10 @@
using System;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using ReactiveUI;
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
{ {
@ -14,6 +18,24 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
private void InitializeComponent() private void InitializeComponent()
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
this.WhenActivated(_ => ViewModel?.Rename.Subscribe(_ =>
{
this.Get<TextBox>("Input").Focus();
this.Get<TextBox>("Input").SelectAll();
}));
}
private void InputElement_OnKeyUp(object? sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
ViewModel?.SubmitRename();
else if (e.Key == Key.Escape)
ViewModel?.CancelRename();
}
private void InputElement_OnLostFocus(object? sender, RoutedEventArgs e)
{
ViewModel?.CancelRename();
} }
} }
} }

View File

@ -13,11 +13,11 @@
</Style> </Style>
</TreeView.Styles> </TreeView.Styles>
<TreeView.KeyBindings> <TreeView.KeyBindings>
<KeyBinding Gesture="F2" Command="{Binding RenameElement}" CommandParameter="{Binding SelectedTreeItem}" /> <KeyBinding Gesture="F2" Command="{Binding SelectedChild.Rename}" />
<KeyBinding Gesture="Delete" Command="{Binding DeleteElement}" CommandParameter="{Binding SelectedTreeItem}" /> <KeyBinding Gesture="Delete" Command="{Binding Delete}" CommandParameter="{Binding SelectedTreeItem}" />
<KeyBinding Gesture="Ctrl+D" Command="{Binding DuplicateElement}" CommandParameter="{Binding SelectedTreeItem}" /> <KeyBinding Gesture="Ctrl+D" Command="{Binding Duplicate}" CommandParameter="{Binding SelectedTreeItem}" />
<KeyBinding Gesture="Ctrl+C" Command="{Binding CopyElement}" CommandParameter="{Binding SelectedTreeItem}" /> <KeyBinding Gesture="Ctrl+C" Command="{Binding Copy}" CommandParameter="{Binding SelectedTreeItem}" />
<KeyBinding Gesture="Ctrl+V" Command="{Binding PasteElement}" CommandParameter="{Binding SelectedTreeItem}" /> <KeyBinding Gesture="Ctrl+V" Command="{Binding Paste}" CommandParameter="{Binding SelectedTreeItem}" />
</TreeView.KeyBindings> </TreeView.KeyBindings>
<TreeView.ItemTemplate> <TreeView.ItemTemplate>
<TreeDataTemplate ItemsSource="{Binding Children}"> <TreeDataTemplate ItemsSource="{Binding Children}">
@ -35,28 +35,28 @@
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<Separator /> <Separator />
<MenuItem Header="Duplicate" Command="{Binding DuplicateElement}" InputGesture="Ctrl+D" IsEnabled="False"> <MenuItem Header="Duplicate" Command="{Binding Duplicate}" InputGesture="Ctrl+D" IsEnabled="False">
<MenuItem.Icon> <MenuItem.Icon>
<avalonia:MaterialIcon Kind="ContentDuplicate" /> <avalonia:MaterialIcon Kind="ContentDuplicate" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem Header="Copy" Command="{Binding CopyElement}" InputGesture="Ctrl+C" IsEnabled="False"> <MenuItem Header="Copy" Command="{Binding Copy}" InputGesture="Ctrl+C" IsEnabled="False">
<MenuItem.Icon> <MenuItem.Icon>
<avalonia:MaterialIcon Kind="ContentCopy" /> <avalonia:MaterialIcon Kind="ContentCopy" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem Header="Paste" Command="{Binding PasteElement}" InputGesture="Ctrl+V"> <MenuItem Header="Paste" Command="{Binding Paste}" InputGesture="Ctrl+V">
<MenuItem.Icon> <MenuItem.Icon>
<avalonia:MaterialIcon Kind="ContentPaste" /> <avalonia:MaterialIcon Kind="ContentPaste" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<Separator /> <Separator />
<MenuItem Header="Rename" Command="{Binding RenameElement}" InputGesture="F2" IsEnabled="False"> <MenuItem Header="Rename" Command="{Binding Rename}" InputGesture="F2">
<MenuItem.Icon> <MenuItem.Icon>
<avalonia:MaterialIcon Kind="RenameBox" /> <avalonia:MaterialIcon Kind="RenameBox" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem Header="Delete" Command="{Binding DeleteElement}" InputGesture="Delete" IsEnabled="False"> <MenuItem Header="Delete" Command="{Binding Delete}" InputGesture="Delete" IsEnabled="False">
<MenuItem.Icon> <MenuItem.Icon>
<avalonia:MaterialIcon Kind="TrashCan" /> <avalonia:MaterialIcon Kind="TrashCan" />
</MenuItem.Icon> </MenuItem.Icon>

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Reactive;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using Artemis.Core; using Artemis.Core;
using Artemis.UI.Ninject.Factories; using Artemis.UI.Ninject.Factories;
@ -41,6 +42,8 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
if (model?.ProfileElement is RenderProfileElement renderProfileElement) if (model?.ProfileElement is RenderProfileElement renderProfileElement)
profileEditorService.ChangeCurrentProfileElement(renderProfileElement); profileEditorService.ChangeCurrentProfileElement(renderProfileElement);
}); });
} }
public TreeItemViewModel? SelectedChild public TreeItemViewModel? SelectedChild

View File

@ -24,6 +24,8 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
private bool _isExpanded; private bool _isExpanded;
private ProfileElement? _profileElement; private ProfileElement? _profileElement;
private RenderProfileElement? _currentProfileElement; private RenderProfileElement? _currentProfileElement;
private bool _renaming;
private string? _renameValue;
protected TreeItemViewModel(TreeItemViewModel? parent, ProfileElement? profileElement, IWindowService windowService, IProfileEditorService profileEditorService, protected TreeItemViewModel(TreeItemViewModel? parent, ProfileElement? profileElement, IWindowService windowService, IProfileEditorService profileEditorService,
IProfileEditorVmFactory profileEditorVmFactory) IProfileEditorVmFactory profileEditorVmFactory)
@ -51,6 +53,12 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
profileEditorService.ExecuteCommand(new AddProfileElement(new Folder(ProfileElement, "New folder"), ProfileElement, 0)); profileEditorService.ExecuteCommand(new AddProfileElement(new Folder(ProfileElement, "New folder"), ProfileElement, 0));
}); });
Rename = ReactiveCommand.Create(() =>
{
Renaming = true;
RenameValue = ProfileElement?.Name;
});
this.WhenActivated(d => this.WhenActivated(d =>
{ {
_profileEditorService.ProfileElement.Subscribe(element => _currentProfileElement = element).DisposeWith(d); _profileEditorService.ProfileElement.Subscribe(element => _currentProfileElement = element).DisposeWith(d);
@ -71,11 +79,24 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
set => this.RaiseAndSetIfChanged(ref _isExpanded, value); set => this.RaiseAndSetIfChanged(ref _isExpanded, value);
} }
public bool Renaming
{
get => _renaming;
set => this.RaiseAndSetIfChanged(ref _renaming, value);
}
public TreeItemViewModel? Parent { get; set; } public TreeItemViewModel? Parent { get; set; }
public ObservableCollection<TreeItemViewModel> Children { get; } = new(); public ObservableCollection<TreeItemViewModel> Children { get; } = new();
public ReactiveCommand<Unit, Unit> AddLayer { get; } public ReactiveCommand<Unit, Unit> AddLayer { get; }
public ReactiveCommand<Unit, Unit> AddFolder { get; } public ReactiveCommand<Unit, Unit> AddFolder { get; }
public ReactiveCommand<Unit, Unit> Rename { get; }
public string? RenameValue
{
get => _renameValue;
set => this.RaiseAndSetIfChanged(ref _renameValue, value);
}
public async Task ShowBrokenStateExceptions() public async Task ShowBrokenStateExceptions()
{ {
@ -93,6 +114,23 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
} }
} }
public void SubmitRename()
{
if (ProfileElement == null)
{
Renaming = false;
return;
}
_profileEditorService.ExecuteCommand(new RenameProfileElement(ProfileElement, RenameValue));
Renaming = false;
}
public void CancelRename()
{
Renaming = false;
}
protected void SubscribeToProfileElement(CompositeDisposable d) protected void SubscribeToProfileElement(CompositeDisposable d)
{ {
if (ProfileElement == null) if (ProfileElement == null)