diff --git a/src/Artemis.UI/Behaviors/SimpleContextDragBehavior.cs b/src/Artemis.UI/Behaviors/SimpleContextDragBehavior.cs index bd3ef036c..066d40f72 100644 --- a/src/Artemis.UI/Behaviors/SimpleContextDragBehavior.cs +++ b/src/Artemis.UI/Behaviors/SimpleContextDragBehavior.cs @@ -132,7 +132,7 @@ public class SimpleContextDragBehavior : Behavior private async void AssociatedObject_PointerMoved(object? sender, PointerEventArgs e) { PointerPointProperties properties = e.GetCurrentPoint(AssociatedObject).Properties; - if (!properties.IsLeftButtonPressed) + if (!properties.IsLeftButtonPressed || FocusManager.Instance?.Current is TextBox) return; if (_triggerEvent is null) diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarViewModel.cs index a4b059083..d3cf9eb06 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarViewModel.cs @@ -34,6 +34,7 @@ public class MenuBarViewModel : ActivatableViewModelBase private ObservableAsPropertyHelper? _focusNone; private ObservableAsPropertyHelper? _focusFolder; private ObservableAsPropertyHelper? _focusSelection; + private ObservableAsPropertyHelper? _keyBindingsEnabled; public MenuBarViewModel(ILogger logger, IProfileEditorService profileEditorService, IProfileService profileService, ISettingsService settingsService, IWindowService windowService) { @@ -57,6 +58,7 @@ public class MenuBarViewModel : ActivatableViewModelBase _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); + _keyBindingsEnabled = profileEditorService.SuspendedKeybindings.Select(s => !s).ToProperty(this, vm => vm.KeyBindingsEnabled).DisposeWith(d); }); AddFolder = ReactiveCommand.Create(ExecuteAddFolder); @@ -71,8 +73,8 @@ public class MenuBarViewModel : ActivatableViewModelBase ToggleSuspendedEditing = ReactiveCommand.Create(ExecuteToggleSuspendedEditing); OpenUri = ReactiveCommand.Create(s => Process.Start(new ProcessStartInfo(s) {UseShellExecute = true, Verb = "open"})); ToggleBooleanSetting = ReactiveCommand.Create>(ExecuteToggleBooleanSetting); - CycleFocusMode = ReactiveCommand.Create(ExecuteCycleFocusMode); ChangeFocusMode = ReactiveCommand.Create(ExecuteChangeFocusMode); + CycleFocusMode = ReactiveCommand.Create(ExecuteCycleFocusMode, this.WhenAnyValue(vm => vm.KeyBindingsEnabled)); } public ReactiveCommand AddFolder { get; } @@ -87,9 +89,9 @@ public class MenuBarViewModel : ActivatableViewModelBase public ReactiveCommand, Unit> ToggleBooleanSetting { get; } public ReactiveCommand OpenUri { get; } public ReactiveCommand ToggleSuspendedEditing { get; } - public ReactiveCommand CycleFocusMode { get; } public ReactiveCommand ChangeFocusMode { get; } - + public ReactiveCommand CycleFocusMode { get; } + public ProfileConfiguration? ProfileConfiguration => _profileConfiguration?.Value; public RenderProfileElement? ProfileElement => _profileElement?.Value; public bool IsSuspended => _isSuspended?.Value ?? false; @@ -97,6 +99,7 @@ public class MenuBarViewModel : ActivatableViewModelBase public bool FocusNone => _focusNone?.Value ?? false; public bool FocusFolder => _focusFolder?.Value ?? false; public bool FocusSelection => _focusSelection?.Value ?? false; + public bool KeyBindingsEnabled => _keyBindingsEnabled?.Value ?? false; public PluginSetting AutoSuspend => _settingsService.GetSetting("ProfileEditor.AutoSuspend", true); public PluginSetting ShowDataModelValues => _settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackViewModel.cs index e0c8bba80..9690417a2 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackViewModel.cs @@ -17,14 +17,13 @@ public class PlaybackViewModel : ActivatableViewModelBase private readonly ISettingsService _settingsService; private ObservableAsPropertyHelper? _currentTime; private ObservableAsPropertyHelper? _formattedCurrentTime; - private DateTime _lastUpdate; + private ObservableAsPropertyHelper? _keyBindingsEnabled; private ObservableAsPropertyHelper? _playing; private RenderProfileElement? _profileElement; private bool _repeating; private bool _repeatSegment; private bool _repeatTimeline; - private ReactiveCommand? _togglePlay; - private ReactiveCommand? _playFromStart; + private DateTime _lastUpdate; public PlaybackViewModel(IProfileEditorService profileEditorService, ISettingsService settingsService) { @@ -38,15 +37,16 @@ public class PlaybackViewModel : ActivatableViewModelBase _currentTime = _profileEditorService.Time.ToProperty(this, vm => vm.CurrentTime).DisposeWith(d); _formattedCurrentTime = _profileEditorService.Time.Select(t => $"{Math.Floor(t.TotalSeconds):00}.{t.Milliseconds:000}").ToProperty(this, vm => vm.FormattedCurrentTime).DisposeWith(d); _playing = _profileEditorService.Playing.ToProperty(this, vm => vm.Playing).DisposeWith(d); + _keyBindingsEnabled = _profileEditorService.SuspendedKeybindings.Select(s => !s).ToProperty(this, vm => vm.KeyBindingsEnabled).DisposeWith(d); + _lastUpdate = DateTime.MinValue; DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(60.0 / 1000), DispatcherPriority.Render, Update); updateTimer.Start(); Disposable.Create(() => updateTimer.Stop()).DisposeWith(d); - - PlayFromStart = ReactiveCommand.Create(ExecutePlayFromStart, _profileEditorService.SuspendedKeybindings.Select(s => !s)).DisposeWith(d); - TogglePlay = ReactiveCommand.Create(ExecuteTogglePlay, _profileEditorService.SuspendedKeybindings.Select(s => !s)).DisposeWith(d); }); + PlayFromStart = ReactiveCommand.Create(ExecutePlayFromStart, this.WhenAnyValue(vm => vm.KeyBindingsEnabled)); + TogglePlay = ReactiveCommand.Create(ExecuteTogglePlay, this.WhenAnyValue(vm => vm.KeyBindingsEnabled)); GoToStart = ReactiveCommand.Create(ExecuteGoToStart); GoToEnd = ReactiveCommand.Create(ExecuteGoToEnd); GoToPreviousFrame = ReactiveCommand.Create(ExecuteGoToPreviousFrame); @@ -57,7 +57,8 @@ public class PlaybackViewModel : ActivatableViewModelBase public TimeSpan CurrentTime => _currentTime?.Value ?? TimeSpan.Zero; public string? FormattedCurrentTime => _formattedCurrentTime?.Value; public bool Playing => _playing?.Value ?? false; - + public bool KeyBindingsEnabled => _keyBindingsEnabled?.Value ?? false; + public bool Repeating { get => _repeating; @@ -76,18 +77,8 @@ public class PlaybackViewModel : ActivatableViewModelBase set => RaiseAndSetIfChanged(ref _repeatSegment, value); } - public ReactiveCommand? PlayFromStart - { - get => _playFromStart; - set => RaiseAndSetIfChanged(ref _playFromStart, value); - } - - public ReactiveCommand? TogglePlay - { - get => _togglePlay; - set => RaiseAndSetIfChanged(ref _togglePlay, value); - } - + public ReactiveCommand PlayFromStart { get; } + public ReactiveCommand TogglePlay { get; } public ReactiveCommand GoToStart { get; } public ReactiveCommand GoToEnd { get; } public ReactiveCommand GoToPreviousFrame { get; } diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml index 976a59f01..f2438acb5 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml @@ -12,12 +12,12 @@ x:DataType="profileTree:ProfileTreeViewModel"> - - - - - - + + + + + + diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeViewModel.cs index fbefb7505..afa41bd3f 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeViewModel.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Reactive; using System.Reactive.Disposables; using System.Reactive.Linq; using System.Threading.Tasks; @@ -16,16 +17,15 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree; public class ProfileTreeViewModel : TreeItemViewModel { - private readonly IProfileEditorService _profileEditorService; private TreeItemViewModel? _selectedChild; private ObservableAsPropertyHelper? _focusNone; private ObservableAsPropertyHelper? _focusFolder; private ObservableAsPropertyHelper? _focusSelection; + private ObservableAsPropertyHelper? _keyBindingsEnabled; public ProfileTreeViewModel(IWindowService windowService, IProfileEditorService profileEditorService, IProfileEditorVmFactory profileEditorVmFactory) : base(null, null, windowService, profileEditorService, profileEditorVmFactory) { - _profileEditorService = profileEditorService; this.WhenActivated(d => { profileEditorService.ProfileConfiguration.WhereNotNull().Subscribe(configuration => @@ -46,8 +46,16 @@ public class ProfileTreeViewModel : TreeItemViewModel _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); + _keyBindingsEnabled = profileEditorService.SuspendedKeybindings.Select(s => !s).ToProperty(this, vm => vm.KeyBindingsEnabled).DisposeWith(d); }); + ClearSelection = ReactiveCommand.Create(() => profileEditorService.ChangeCurrentProfileElement(null), this.WhenAnyValue(vm => vm.KeyBindingsEnabled)); + RenameSelected = ReactiveCommand.Create(() => { SelectedChild?.Rename.Execute().Subscribe(); }, this.WhenAnyValue(vm => vm.KeyBindingsEnabled)); + DeleteSelected = ReactiveCommand.Create(() => { SelectedChild?.Delete.Execute().Subscribe(); }, this.WhenAnyValue(vm => vm.KeyBindingsEnabled)); + DuplicateSelected = ReactiveCommand.Create(() => { SelectedChild?.Duplicate.Execute().Subscribe(); }, this.WhenAnyValue(vm => vm.KeyBindingsEnabled)); + CopySelected = ReactiveCommand.Create(() => { SelectedChild?.Copy.Execute().Subscribe(); }, this.WhenAnyValue(vm => vm.KeyBindingsEnabled)); + PasteSelected = ReactiveCommand.Create(() => { SelectedChild?.Paste.Execute().Subscribe(); }, this.WhenAnyValue(vm => vm.KeyBindingsEnabled)); + this.WhenAnyValue(vm => vm.SelectedChild).Subscribe(model => { if (model?.ProfileElement is RenderProfileElement renderProfileElement) @@ -58,45 +66,23 @@ public class ProfileTreeViewModel : TreeItemViewModel public bool FocusNone => _focusNone?.Value ?? false; public bool FocusFolder => _focusFolder?.Value ?? false; public bool FocusSelection => _focusSelection?.Value ?? false; - + public bool KeyBindingsEnabled => _keyBindingsEnabled?.Value ?? false; + public TreeItemViewModel? SelectedChild { get => _selectedChild; set => RaiseAndSetIfChanged(ref _selectedChild, value); } + public ReactiveCommand ClearSelection { get; } + public ReactiveCommand RenameSelected { get; } + public ReactiveCommand DeleteSelected { get; } + public ReactiveCommand DuplicateSelected { get; } + public ReactiveCommand CopySelected { get; } + public ReactiveCommand PasteSelected { get; } + public override bool SupportsChildren => true; - public void ClearSelection() - { - _profileEditorService.ChangeCurrentProfileElement(null); - } - - public void RenameSelected() - { - SelectedChild?.Rename.Execute().Subscribe(); - } - - public void DeleteSelected() - { - SelectedChild?.Delete.Execute().Subscribe(); - } - - public void DuplicateSelected() - { - SelectedChild?.Duplicate.Execute().Subscribe(); - } - - public void CopySelected() - { - SelectedChild?.Copy.Execute().Subscribe(); - } - - public void PasteSelected() - { - SelectedChild?.Paste.Execute().Subscribe(); - } - public void UpdateCanPaste() { throw new NotImplementedException(); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs index 12860f09e..da04e073f 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs @@ -55,7 +55,8 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase Duplicate = ReactiveCommand.CreateFromTask(ExecuteDuplicate); Copy = ReactiveCommand.CreateFromTask(ExecuteCopy); Paste = ReactiveCommand.CreateFromTask(ExecutePaste, this.WhenAnyValue(vm => vm.CanPaste)); - + AbsorbCommand = ReactiveCommand.Create(() => true); + this.WhenActivated(d => { _isFocused = ProfileEditorService.FocusMode @@ -72,6 +73,8 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase this.WhenAnyValue(vm => vm.IsFlyoutOpen).Subscribe(UpdateCanPaste); } + public ReactiveCommand AbsorbCommand { get; } + public bool IsFocused => _isFocused?.Value ?? false; public ProfileElement? ProfileElement