mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Profile editor - Added focusing indicator
This commit is contained in:
parent
1f311d2295
commit
9602934342
@ -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">
|
||||
<Grid ColumnDefinitions="Auto,Auto,*,Auto">
|
||||
<Grid ColumnDefinitions="Auto,Auto,*,Auto,Auto">
|
||||
<Button Grid.Column="0"
|
||||
ToolTip.Tip="{CompiledBinding ProfileElement.BrokenState}"
|
||||
IsVisible="{CompiledBinding ProfileElement.BrokenState, Converter={x:Static ObjectConverters.IsNotNull}}"
|
||||
@ -35,8 +35,10 @@
|
||||
x:Name="Input"
|
||||
KeyUp="InputElement_OnKeyUp"
|
||||
LostFocus="InputElement_OnLostFocus" />
|
||||
<TextBlock Grid.Column="2" IsVisible="{CompiledBinding !Renaming}" Text="{Binding Folder.Name}" VerticalAlignment="Center" />
|
||||
<ToggleButton Grid.Column="3"
|
||||
<TextBlock Grid.Column="2" IsVisible="{CompiledBinding !Renaming}" Text="{CompiledBinding Folder.Name}" VerticalAlignment="Center" />
|
||||
|
||||
<avalonia:MaterialIcon Grid.Column="3" Kind="Eye" IsVisible="{CompiledBinding IsFocused}" ToolTip.Tip="This element is visible because of the current focus mode" Margin="0 0 5 0"/>
|
||||
<ToggleButton Grid.Column="4"
|
||||
Classes="icon-button icon-button-small"
|
||||
ToolTip.Tip="Toggle suspended state"
|
||||
IsChecked="{CompiledBinding Folder.Suspended}"
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Reactive.Disposables;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.LogicalTree;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using ReactiveUI;
|
||||
@ -13,16 +15,19 @@ public class FolderTreeItemView : ReactiveUserControl<FolderTreeItemViewModel>
|
||||
public FolderTreeItemView()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
ViewModel?.Rename.Subscribe(_ =>
|
||||
{
|
||||
this.Get<TextBox>("Input").Focus();
|
||||
this.Get<TextBox>("Input").SelectAll();
|
||||
}).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
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)
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.LayerTreeItemView"
|
||||
x:DataType="profileTree:LayerTreeItemViewModel">
|
||||
<Grid ColumnDefinitions="Auto,Auto,*,Auto">
|
||||
<Grid ColumnDefinitions="Auto,Auto,*,Auto,Auto">
|
||||
<Button Grid.Column="0"
|
||||
ToolTip.Tip="{CompiledBinding ProfileElement.BrokenState}"
|
||||
IsVisible="{CompiledBinding ProfileElement.BrokenState, Converter={x:Static ObjectConverters.IsNotNull}}"
|
||||
@ -27,7 +27,9 @@
|
||||
KeyUp="InputElement_OnKeyUp"
|
||||
LostFocus="InputElement_OnLostFocus" />
|
||||
<TextBlock Grid.Column="2" IsVisible="{CompiledBinding !Renaming}" Text="{CompiledBinding Layer.Name}" VerticalAlignment="Center" />
|
||||
<ToggleButton Grid.Column="3"
|
||||
|
||||
<avalonia:MaterialIcon Grid.Column="3" Kind="Eye" IsVisible="{CompiledBinding IsFocused}" ToolTip.Tip="This element is visible because of the current focus mode" Margin="0 0 5 0"/>
|
||||
<ToggleButton Grid.Column="4"
|
||||
Classes="icon-button icon-button-small"
|
||||
ToolTip.Tip="Toggle suspended state"
|
||||
IsChecked="{CompiledBinding Layer.Suspended}"
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Reactive.Disposables;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.LogicalTree;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using ReactiveUI;
|
||||
@ -13,16 +15,19 @@ public class LayerTreeItemView : ReactiveUserControl<LayerTreeItemViewModel>
|
||||
public LayerTreeItemView()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
ViewModel?.Rename.Subscribe(_ =>
|
||||
{
|
||||
this.Get<TextBox>("Input").Focus();
|
||||
this.Get<TextBox>("Input").SelectAll();
|
||||
}).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
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)
|
||||
|
||||
@ -152,14 +152,18 @@
|
||||
</TreeDataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
</TreeView>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center" Spacing="5" ToolTip.Tip="Focus Mode - Use to disable parts of the profile you're not working on (F to change)">
|
||||
<avalonia:MaterialIcon Kind="ImageFilterCenterFocusStrong" />
|
||||
<TextBlock Text="{CompiledBinding FocusMode.Value}" />
|
||||
<Grid Grid.Row="1" ColumnDefinitions="*,*">
|
||||
<StackPanel Grid.Column="0"
|
||||
Orientation="Horizontal"
|
||||
VerticalAlignment="Center"
|
||||
Spacing="5"
|
||||
Background="Transparent"
|
||||
ToolTip.Tip="Focus Mode - Use to disable parts of the profile you're not working on (F to change)">
|
||||
<avalonia:MaterialIcon Kind="EyeOff" IsVisible="{CompiledBinding FocusNone}" />
|
||||
<avalonia:MaterialIcon Kind="Eye" IsVisible="{CompiledBinding !FocusNone}" />
|
||||
<TextBlock Text="Focus disabled" IsVisible="{CompiledBinding FocusNone}" />
|
||||
<TextBlock Text="Focus on folder" IsVisible="{CompiledBinding FocusFolder}" />
|
||||
<TextBlock Text="Focus on selection" IsVisible="{CompiledBinding FocusSelection}" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Right">
|
||||
<Button Classes="icon-button" ToolTip.Tip="Add new folder to root" Command="{CompiledBinding AddFolder}">
|
||||
@ -170,7 +174,5 @@
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
||||
@ -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<bool>? _focusNone;
|
||||
private ObservableAsPropertyHelper<bool>? _focusFolder;
|
||||
private ObservableAsPropertyHelper<bool>? _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<ProfileEditorFocusMode> 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;
|
||||
|
||||
@ -32,6 +32,7 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase
|
||||
private string? _renameValue;
|
||||
private bool _renaming;
|
||||
private TimeSpan _time;
|
||||
private ObservableAsPropertyHelper<bool>? _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;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user