diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml index 7889634a4..b9301627e 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml @@ -7,7 +7,7 @@ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.FolderTreeItemView" x:DataType="profileTree:FolderTreeItemViewModel"> - + - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeViewModel.cs index 48d2d1248..fbefb7505 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeViewModel.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Reactive.Disposables; +using System.Reactive.Linq; using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.Services; @@ -17,8 +18,11 @@ public class ProfileTreeViewModel : TreeItemViewModel { private readonly IProfileEditorService _profileEditorService; private TreeItemViewModel? _selectedChild; + private ObservableAsPropertyHelper? _focusNone; + private ObservableAsPropertyHelper? _focusFolder; + private ObservableAsPropertyHelper? _focusSelection; - public ProfileTreeViewModel(IWindowService windowService, IProfileEditorService profileEditorService, IProfileEditorVmFactory profileEditorVmFactory, ISettingsService settingsService) + public ProfileTreeViewModel(IWindowService windowService, IProfileEditorService profileEditorService, IProfileEditorVmFactory profileEditorVmFactory) : base(null, null, windowService, profileEditorService, profileEditorVmFactory) { _profileEditorService = profileEditorService; @@ -38,6 +42,10 @@ public class ProfileTreeViewModel : TreeItemViewModel }).DisposeWith(d); profileEditorService.ProfileElement.Subscribe(SelectCurrentProfileElement).DisposeWith(d); + + _focusNone = profileEditorService.FocusMode.Select(f => f == ProfileEditorFocusMode.None).ToProperty(this, vm => vm.FocusNone).DisposeWith(d); + _focusFolder = profileEditorService.FocusMode.Select(f => f == ProfileEditorFocusMode.Folder).ToProperty(this, vm => vm.FocusFolder).DisposeWith(d); + _focusSelection = profileEditorService.FocusMode.Select(f => f == ProfileEditorFocusMode.Selection).ToProperty(this, vm => vm.FocusSelection).DisposeWith(d); }); this.WhenAnyValue(vm => vm.SelectedChild).Subscribe(model => @@ -45,11 +53,12 @@ public class ProfileTreeViewModel : TreeItemViewModel if (model?.ProfileElement is RenderProfileElement renderProfileElement) profileEditorService.ChangeCurrentProfileElement(renderProfileElement); }); - - FocusMode = settingsService.GetSetting("ProfileEditor.FocusMode", ProfileEditorFocusMode.Folder); } - public PluginSetting FocusMode { get; } + public bool FocusNone => _focusNone?.Value ?? false; + public bool FocusFolder => _focusFolder?.Value ?? false; + public bool FocusSelection => _focusSelection?.Value ?? false; + public TreeItemViewModel? SelectedChild { get => _selectedChild; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs index a9ad9f829..12860f09e 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs @@ -32,6 +32,7 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase private string? _renameValue; private bool _renaming; private TimeSpan _time; + private ObservableAsPropertyHelper? _isFocused; protected TreeItemViewModel(TreeItemViewModel? parent, ProfileElement? profileElement, @@ -57,6 +58,11 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase this.WhenActivated(d => { + _isFocused = ProfileEditorService.FocusMode + .CombineLatest(ProfileEditorService.ProfileElement) + .Select(tuple => GetIsFocused(tuple.First, tuple.Second)) + .ToProperty(this, vm => vm.IsFocused); + ProfileEditorService.Time.Subscribe(t => _time = t).DisposeWith(d); ProfileEditorService.ProfileElement.Subscribe(element => _currentProfileElement = element).DisposeWith(d); SubscribeToProfileElement(d); @@ -66,6 +72,8 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase this.WhenAnyValue(vm => vm.IsFlyoutOpen).Subscribe(UpdateCanPaste); } + public bool IsFocused => _isFocused?.Value ?? false; + public ProfileElement? ProfileElement { get => _profileElement; @@ -256,7 +264,7 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase if (ProfileElement != null) ProfileEditorService.CreateAndAddLayer(ProfileElement); } - + private async Task ExecuteOpenAdaptionHints() { if (ProfileElement is not Layer layer) @@ -277,4 +285,19 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase string[] formats = await Application.Current.Clipboard.GetFormatsAsync(); CanPaste = formats.Contains(ProfileElementExtensions.ClipboardDataFormat); } + + private bool GetIsFocused(ProfileEditorFocusMode focusMode, RenderProfileElement? currentProfileElement) + { + if (focusMode == ProfileEditorFocusMode.None || currentProfileElement == null) + return false; + if (focusMode == ProfileEditorFocusMode.Selection) + return currentProfileElement == ProfileElement; + if (focusMode == ProfileEditorFocusMode.Folder && currentProfileElement?.Parent != null) + { + // Any direct parent or direct siblings cause focus + return currentProfileElement.Parent == ProfileElement?.Parent || currentProfileElement.Parent.GetAllRenderElements().Any(e => e == ProfileElement); + } + + return false; + } } \ No newline at end of file