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

Sidebar - Moved VMs and views

Sidebar - Implemented profile selection
Windows - Fix designer breaking due to the input provider
This commit is contained in:
Robert 2021-12-09 23:32:59 +01:00
parent 971e32f7a5
commit 0c3f84cbeb
31 changed files with 244 additions and 60 deletions

View File

@ -95,6 +95,7 @@ namespace Artemis.Core.Services
MouseMoveDataReceived?.Invoke(this, new InputProviderMouseMoveEventArgs(device, cursorX, cursorY, deltaX, deltaY));
}
// TODO: Remove this as the core should handle this in GetDeviceByIdentifier
/// <summary>
/// Invokes the <see cref="IdentifierReceived" /> event which the <see cref="IInputService" /> listens to as long as
/// this provider is registered

View File

@ -98,6 +98,7 @@ namespace Artemis.Core.Services
BustIdentifierCache();
}
// TODO: Move the OnIdentifierReceived logic into here and get rid of OnIdentifierReceived, this and OnIdentifierReceived are always called in combination with each other
public ArtemisDevice? GetDeviceByIdentifier(InputProvider provider, object identifier, InputDeviceType type)
{
if (provider == null) throw new ArgumentNullException(nameof(provider));

View File

@ -4,6 +4,7 @@ using Artemis.Core;
using Artemis.Core.Services;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
@ -91,7 +92,7 @@ namespace Artemis.UI.Shared.Controls
/// to an SVG
/// </summary>
public static readonly StyledProperty<Hotkey?> HotkeyProperty =
AvaloniaProperty.Register<HotkeyBox, Hotkey?>(nameof(Hotkey), notifying: HotkeyChanging);
AvaloniaProperty.Register<HotkeyBox, Hotkey?>(nameof(Hotkey), defaultBindingMode: BindingMode.TwoWay, notifying: HotkeyChanging);
public static readonly StyledProperty<string?> WatermarkProperty =
AvaloniaProperty.Register<HotkeyBox, string?>(nameof(Watermark));

View File

@ -1,5 +1,4 @@
using Artemis.Core.Services;
using Artemis.UI.Windows.Providers;
using Artemis.UI.Windows.Providers.Input;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
@ -17,15 +16,17 @@ namespace Artemis.UI.Windows
_kernel = ArtemisBootstrapper.Bootstrap(this);
RxApp.MainThreadScheduler = AvaloniaScheduler.Instance;
AvaloniaXamlLoader.Load(this);
RegisterProviders(_kernel);
}
public override void OnFrameworkInitializationCompleted()
{
ArtemisBootstrapper.Initialize();
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
_applicationStateManager = new ApplicationStateManager(_kernel!, desktop.Args);
RegisterProviders(_kernel!);
}
}
private void RegisterProviders(StandardKernel standardKernel)

View File

@ -185,7 +185,7 @@ namespace Artemis.UI.Windows.Providers.Input
if (identifier != null)
try
{
device = _inputService.GetDeviceByIdentifier(this, identifier, InputDeviceType.Keyboard);
device = _inputService.GetDeviceByIdentifier(this, identifier, InputDeviceType.Mouse);
}
catch (Exception e)
{

View File

@ -51,10 +51,10 @@
<Compile Update="Screens\Debugger\Tabs\Settings\DebugSettingsView.axaml.cs">
<DependentUpon>DebugSettingsView.axaml</DependentUpon>
</Compile>
<Compile Update="Screens\Root\Sidebar\ContentDialogs\SidebarCategoryEditView.axaml.cs">
<Compile Update="Screens\Sidebar\ContentDialogs\SidebarCategoryEditView.axaml.cs">
<DependentUpon>SidebarCategoryEditView.axaml</DependentUpon>
</Compile>
<Compile Update="Screens\Root\Sidebar\Dialogs\ProfileConfigurationEditView.axaml.cs">
<Compile Update="Screens\Sidebar\Dialogs\ProfileConfigurationEditView.axaml.cs">
<DependentUpon>ProfileConfigurationEditView.axaml</DependentUpon>
</Compile>
</ItemGroup>

View File

@ -3,9 +3,11 @@ using Artemis.Core;
using Artemis.UI.Screens.Device;
using Artemis.UI.Screens.Device.Tabs;
using Artemis.UI.Screens.Plugins;
using Artemis.UI.Screens.Root.Sidebar;
using Artemis.UI.Screens.ProfileEditor;
using Artemis.UI.Screens.Settings.Tabs;
using Artemis.UI.Screens.Sidebar;
using Artemis.UI.Screens.SurfaceEditor;
using Artemis.UI.Services;
using ReactiveUI;
namespace Artemis.UI.Ninject.Factories
@ -49,4 +51,9 @@ namespace Artemis.UI.Ninject.Factories
{
PluginPrerequisiteViewModel PluginPrerequisiteViewModel(PluginPrerequisite pluginPrerequisite, bool uninstall);
}
public interface IProfileEditorVmFactory : IVmFactory
{
ProfileEditorViewModel ProfileEditorViewModel(IScreen hostScreen);
}
}

View File

@ -4,5 +4,10 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.ProfileEditor.ProfileEditorView">
Welcome to Avalonia!
<StackPanel Orientation="Horizontal">
<TextBlock Classes="h4 subtitle" Text="Wow, you're editing "/>
<TextBlock Classes="h4" Text="{Binding Profile.Name}"/>
<TextBlock Classes="h4 subtitle" Text=". That's amazing! keep it up man, you can do it!!!!11!11"/>
</StackPanel>
</UserControl>

View File

@ -1,8 +1,28 @@
using Artemis.UI.Shared;
using System;
using System.Reactive.Disposables;
using Artemis.Core;
using Artemis.UI.Services;
using ReactiveUI;
namespace Artemis.UI.Screens.ProfileEditor
{
public class ProfileEditorViewModel : ActivatableViewModelBase
public class ProfileEditorViewModel : MainScreenViewModel
{
private ProfileConfiguration? _profile;
/// <inheritdoc />
public ProfileEditorViewModel(IScreen hostScreen, IProfileEditorService profileEditorService) : base(hostScreen, "profile-editor")
{
this.WhenActivated(disposables =>
{
profileEditorService.CurrentProfileConfiguration.WhereNotNull().Subscribe(p => Profile = p).DisposeWith(disposables);
});
}
public ProfileConfiguration? Profile
{
get => _profile;
set => this.RaiseAndSetIfChanged(ref _profile, value);
}
}
}

View File

@ -4,7 +4,7 @@ using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Root.Sidebar;
using Artemis.UI.Screens.Sidebar;
using Artemis.UI.Services.Interfaces;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services.Interfaces;

View File

@ -3,7 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Root.Sidebar.Dialogs.SidebarCategoryEditView">
x:Class="Artemis.UI.Screens.Sidebar.ContentDialogs.SidebarCategoryEditView">
<StackPanel>
<StackPanel.KeyBindings>
<KeyBinding Gesture="Enter" Command="{Binding Confirm}" />

View File

@ -3,7 +3,7 @@ using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using ReactiveUI;
namespace Artemis.UI.Screens.Root.Sidebar.Dialogs
namespace Artemis.UI.Screens.Sidebar.ContentDialogs
{
public class SidebarCategoryEditView : ReactiveUserControl<SidebarCategoryEditViewModel>
{

View File

@ -6,7 +6,7 @@ using FluentAvalonia.UI.Controls;
using ReactiveUI;
using ReactiveUI.Validation.Extensions;
namespace Artemis.UI.Screens.Root.Sidebar.Dialogs
namespace Artemis.UI.Screens.Sidebar.ContentDialogs
{
public class SidebarCategoryEditViewModel : ContentDialogViewModelBase
{

View File

@ -4,15 +4,16 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core"
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
xmlns:local="clr-namespace:Artemis.UI.Screens.Root.Sidebar.Dialogs"
xmlns:converters="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:svg="clr-namespace:Avalonia.Svg.Skia;assembly=Avalonia.Svg.Skia"
xmlns:local="clr-namespace:Artemis.UI.Screens.Sidebar.Dialogs"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="850"
x:Class="Artemis.UI.Screens.Root.Sidebar.Dialogs.ProfileConfigurationEditView"
x:Class="Artemis.UI.Screens.Sidebar.Dialogs.ProfileConfigurationEditView"
Title="{Binding DisplayName}"
Icon="/Assets/Images/Logo/bow.ico"
Width="800"
MinWidth="420"
Height="850">
<Window.Resources>
<converters:EnumToBooleanConverter x:Key="EnumBoolConverter" />
@ -24,6 +25,14 @@
<Style Selector="TextBlock.label">
<Setter Property="Margin" Value="0 10 0 5" />
</Style>
<Style Selector="TextBlock.section-header">
<Setter Property="Margin" Value="0 0 5 0" />
</Style>
<Style Selector="TextBlock.section-subtitle">
<Setter Property="VerticalAlignment" Value="Bottom" />
<Setter Property="Margin" Value="0 0 0 1" />
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</StackPanel.Styles>
<Grid>
@ -31,12 +40,10 @@
<TextBlock Classes="h4" IsVisible="{Binding !IsNew}" Text="{Binding ProfileConfiguration.Name}" />
</Grid>
<TextBlock Classes="h5">General</TextBlock>
<Border Classes="card" Margin="0 0 0 15">
<StackPanel>
<TextBlock Classes="label">Profile name</TextBlock>
<TextBox Text="{Binding ProfileName}" />
<TextBox Watermark="Name" Text="{Binding ProfileName}" />
<TextBlock Classes="label">Module</TextBlock>
<ComboBox SelectedItem="{Binding SelectedModule}" IsEnabled="{Binding Modules.Count}" Items="{Binding Modules}" HorizontalAlignment="Stretch">
<ComboBox.ItemsPanel>
@ -71,7 +78,7 @@
<TextBlock Classes="label">Icon</TextBlock>
<StackPanel Orientation="Horizontal"
IsVisible="{Binding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.BitmapImage}}">
<Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="98" Height="98">
<Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="78" Height="78">
<Image Source="{Binding SelectedBitmapSource}" Margin="10" />
</Border>
<Button Command="{Binding BrowseBitmapFile}"
@ -83,7 +90,7 @@
</StackPanel>
<StackPanel Orientation="Horizontal"
IsVisible="{Binding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.SvgImage}}">
<Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="98" Height="98">
<Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="78" Height="78">
<Image Margin="10" Source="{Binding SelectedSvgSource}" />
</Border>
<Button Command="{Binding BrowseSvgFile}"
@ -95,8 +102,8 @@
</StackPanel>
<StackPanel Orientation="Horizontal"
IsVisible="{Binding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.MaterialIcon}}">
<Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="98" Height="98">
<avalonia:MaterialIcon Kind="{Binding SelectedMaterialIcon.Icon}" Width="65" Height="65" />
<Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="78" Height="78">
<avalonia:MaterialIcon Kind="{Binding SelectedMaterialIcon.Icon}" Width="45" Height="45" />
</Border>
<ComboBox Items="{Binding MaterialIcons}"
SelectedItem="{Binding SelectedMaterialIcon}"
@ -124,16 +131,44 @@
</StackPanel>
</Border>
<TextBlock Classes="h5">Keybindings</TextBlock>
<TextBlock Classes="subtitle">You may set up hotkeys to activate/deactivate the profile</TextBlock>
<StackPanel Orientation="Horizontal">
<TextBlock Classes="h5 section-header">Keybindings</TextBlock>
<TextBlock Classes="subtitle section-subtitle">You may set up hotkeys to activate/deactivate the profile</TextBlock>
</StackPanel>
<Border Classes="card" Margin="0 5 0 15">
<TextBlock>TODO</TextBlock>
<StackPanel>
<TextBlock>Hotkey mode</TextBlock>
<WrapPanel Orientation="Horizontal">
<RadioButton Content="None"
IsChecked="{Binding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.None}}" />
<RadioButton Content="Toggle"
IsChecked="{Binding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.Toggle}}" />
<RadioButton Content="Separate enable/disable"
IsChecked="{Binding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.EnableDisable}}" />
</WrapPanel>
<controls:HotkeyBox Watermark="Toggle hotkey"
Hotkey="{Binding EnableHotkey}"
IsVisible="{Binding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.Toggle}}"
HorizontalAlignment="Left"
Width="200"
Margin="0 5 0 0"/>
<StackPanel Orientation="Horizontal"
IsVisible="{Binding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.EnableDisable}}"
HorizontalAlignment="Left"
Margin="0 5 0 0">
<controls:HotkeyBox Watermark="Enable hotkey" Hotkey="{Binding EnableHotkey}" Margin="0 0 4 0" Width="200"/>
<controls:HotkeyBox Watermark="Disable hotkey" Hotkey="{Binding DisableHotkey}" Margin="4 0 0 0" Width="200"/>
</StackPanel>
</StackPanel>
</Border>
<TextBlock Classes="h5">Activation conditions</TextBlock>
<TextBlock Classes="subtitle">If you only want this profile to be active under certain conditions, configure those conditions below</TextBlock>
<StackPanel Orientation="Horizontal">
<TextBlock Classes="h5 section-header">Activation conditions</TextBlock>
<TextBlock Classes="subtitle section-subtitle">Set up certain conditions under which the profile should be active</TextBlock>
</StackPanel>
<Border Classes="card" Margin="0 5 0 15">
<TextBlock>TODO</TextBlock>
<TextBlock TextWrapping="Wrap">Here you'll find the node editor layer at some point, use your imagination for now.</TextBlock>
</Border>
</StackPanel>
</ScrollViewer>

View File

@ -1,9 +1,8 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Root.Sidebar.Dialogs
namespace Artemis.UI.Screens.Sidebar.Dialogs
{
public partial class ProfileConfigurationEditView : ReactiveWindow<ProfileConfigurationEditViewModel>
{

View File

@ -11,12 +11,11 @@ using Artemis.UI.Shared.Services.Interfaces;
using Avalonia.Media.Imaging;
using Avalonia.Svg.Skia;
using Avalonia.Threading;
using Castle.Core.Resource;
using Material.Icons;
using Newtonsoft.Json;
using ReactiveUI;
namespace Artemis.UI.Screens.Root.Sidebar.Dialogs
namespace Artemis.UI.Screens.Sidebar.Dialogs
{
public class ProfileConfigurationEditViewModel : DialogViewModelBase<bool>
{
@ -24,6 +23,7 @@ namespace Artemis.UI.Screens.Root.Sidebar.Dialogs
private readonly IProfileService _profileService;
private readonly IWindowService _windowService;
private ProfileConfigurationIconType _iconType;
private ProfileConfigurationHotkeyMode _hotkeyMode;
private ObservableCollection<ProfileIconViewModel>? _materialIcons;
private ProfileConfiguration _profileConfiguration;
private string _profileName;
@ -32,6 +32,8 @@ namespace Artemis.UI.Screens.Root.Sidebar.Dialogs
private ProfileModuleViewModel? _selectedModule;
private string? _selectedIconPath;
private SvgImage? _selectedSvgSource;
private Hotkey? _enableHotkey;
private Hotkey? _disableHotkey;
public ProfileConfigurationEditViewModel(ProfileCategory profileCategory, ProfileConfiguration? profileConfiguration, IWindowService windowService,
IProfileService profileService, IPluginManagementService pluginManagementService)
@ -42,6 +44,11 @@ namespace Artemis.UI.Screens.Root.Sidebar.Dialogs
_profileConfiguration = profileConfiguration ?? profileService.CreateProfileConfiguration(profileCategory, "New profile", Enum.GetValues<MaterialIconKind>().First().ToString());
_profileName = _profileConfiguration.Name;
_iconType = _profileConfiguration.Icon.IconType;
_hotkeyMode = _profileConfiguration.HotkeyMode;
if (_profileConfiguration.EnableHotkey != null)
_enableHotkey = new Hotkey() {Key = _profileConfiguration.EnableHotkey.Key, Modifiers = profileConfiguration.EnableHotkey.Modifiers};
if (_profileConfiguration.DisableHotkey != null)
_disableHotkey = new Hotkey() {Key = _profileConfiguration.DisableHotkey.Key, Modifiers = profileConfiguration.DisableHotkey.Modifiers};
IsNew = profileConfiguration == null;
DisplayName = IsNew ? "Artemis | Add profile" : "Artemis | Edit profile";
@ -66,6 +73,24 @@ namespace Artemis.UI.Screens.Root.Sidebar.Dialogs
set => this.RaiseAndSetIfChanged(ref _profileName, value);
}
public ProfileConfigurationHotkeyMode HotkeyMode
{
get => _hotkeyMode;
set => this.RaiseAndSetIfChanged(ref _hotkeyMode, value);
}
public Hotkey? EnableHotkey
{
get => _enableHotkey;
set => this.RaiseAndSetIfChanged(ref _enableHotkey, value);
}
public Hotkey? DisableHotkey
{
get => _disableHotkey;
set => this.RaiseAndSetIfChanged(ref _disableHotkey, value);
}
public ObservableCollection<ProfileModuleViewModel> Modules { get; }
public ProfileModuleViewModel? SelectedModule
@ -126,6 +151,10 @@ namespace Artemis.UI.Screens.Root.Sidebar.Dialogs
{
ProfileConfiguration.Name = ProfileName;
ProfileConfiguration.Module = SelectedModule?.Module;
ProfileConfiguration.HotkeyMode = HotkeyMode;
ProfileConfiguration.EnableHotkey = EnableHotkey;
ProfileConfiguration.DisableHotkey = DisableHotkey;
await SaveIcon();
_profileService.SaveProfileConfigurationIcon(ProfileConfiguration);

View File

@ -1,7 +1,7 @@
using Artemis.UI.Shared;
using Material.Icons;
namespace Artemis.UI.Screens.Root.Sidebar.Dialogs
namespace Artemis.UI.Screens.Sidebar.Dialogs
{
public class ProfileIconViewModel : ViewModelBase
{

View File

@ -2,7 +2,7 @@
using Artemis.UI.Shared;
using Material.Icons;
namespace Artemis.UI.Screens.Root.Sidebar.Dialogs
namespace Artemis.UI.Screens.Sidebar.Dialogs
{
public class ProfileModuleViewModel : ViewModelBase
{

View File

@ -3,10 +3,10 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:local="clr-namespace:Artemis.UI.Screens.Root.Sidebar"
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
xmlns:local="clr-namespace:Artemis.UI.Screens.Sidebar"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Root.Sidebar.SidebarCategoryView">
x:Class="Artemis.UI.Screens.Sidebar.SidebarCategoryView">
<UserControl.Styles>
<Style Selector=":is(Button).category-button">
<Setter Property="IsVisible" Value="False" />

View File

@ -2,7 +2,7 @@
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Root.Sidebar
namespace Artemis.UI.Screens.Sidebar
{
public class SidebarCategoryView : ReactiveUserControl<SidebarCategoryViewModel>
{

View File

@ -1,18 +1,21 @@
using System.Collections.ObjectModel;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Disposables;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Root.Sidebar.Dialogs;
using Artemis.UI.Screens.Sidebar.ContentDialogs;
using Artemis.UI.Screens.Sidebar.Dialogs;
using Artemis.UI.Services;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services.Interfaces;
using FluentAvalonia.UI.Controls;
using ReactiveUI;
namespace Artemis.UI.Screens.Root.Sidebar
namespace Artemis.UI.Screens.Sidebar
{
public class SidebarCategoryViewModel : ViewModelBase
public class SidebarCategoryViewModel : ActivatableViewModelBase
{
private readonly SidebarViewModel _sidebarViewModel;
private readonly IProfileService _profileService;
@ -20,7 +23,7 @@ namespace Artemis.UI.Screens.Root.Sidebar
private readonly ISidebarVmFactory _vmFactory;
private SidebarProfileConfigurationViewModel? _selectedProfileConfiguration;
public SidebarCategoryViewModel(SidebarViewModel sidebarViewModel, ProfileCategory profileCategory, IProfileService profileService, IWindowService windowService, ISidebarVmFactory vmFactory)
public SidebarCategoryViewModel(SidebarViewModel sidebarViewModel, ProfileCategory profileCategory, IProfileService profileService, IWindowService windowService, IProfileEditorService profileEditorService, ISidebarVmFactory vmFactory)
{
_sidebarViewModel = sidebarViewModel;
_profileService = profileService;
@ -31,6 +34,16 @@ namespace Artemis.UI.Screens.Root.Sidebar
if (ShowItems)
CreateProfileViewModels();
this.WhenActivated(disposables =>
{
profileEditorService.CurrentProfileConfiguration
.Subscribe(p => SelectedProfileConfiguration = ProfileConfigurations.FirstOrDefault(c => ReferenceEquals(c.ProfileConfiguration, p)))
.DisposeWith(disposables);
this.WhenAnyValue(vm => vm.SelectedProfileConfiguration)
.WhereNotNull()
.Subscribe(s => profileEditorService.ChangeCurrentProfileConfiguration(s.ProfileConfiguration));
});
}
public ProfileCategory ProfileCategory { get; }

View File

@ -6,7 +6,7 @@
xmlns:converters="clr-namespace:Artemis.UI.Converters"
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.Root.Sidebar.SidebarProfileConfigurationView">
x:Class="Artemis.UI.Screens.Sidebar.SidebarProfileConfigurationView">
<UserControl.Resources>
<converters:ValuesAdditionConverter x:Key="ValuesAddition" />
</UserControl.Resources>

View File

@ -1,7 +1,7 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Root.Sidebar
namespace Artemis.UI.Screens.Sidebar
{
public class SidebarProfileConfigurationView : UserControl
{

View File

@ -1,11 +1,11 @@
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Screens.Root.Sidebar.Dialogs;
using Artemis.UI.Screens.Sidebar.Dialogs;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services.Interfaces;
namespace Artemis.UI.Screens.Root.Sidebar
namespace Artemis.UI.Screens.Sidebar
{
public class SidebarProfileConfigurationViewModel : ViewModelBase
{

View File

@ -4,7 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Root.Sidebar.SidebarScreenView">
x:Class="Artemis.UI.Screens.Sidebar.SidebarScreenView">
<StackPanel Orientation="Horizontal">
<avalonia:MaterialIcon Kind="{Binding Icon}" Width="16" Height="16" />
<TextBlock FontSize="12" Margin="10 0" VerticalAlignment="Center" Text="{Binding DisplayName}" />

View File

@ -1,7 +1,7 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Root.Sidebar
namespace Artemis.UI.Screens.Sidebar
{
public partial class SidebarScreenView : UserControl
{

View File

@ -5,7 +5,7 @@ using Ninject;
using Ninject.Parameters;
using ReactiveUI;
namespace Artemis.UI.Screens.Root.Sidebar
namespace Artemis.UI.Screens.Sidebar
{
public class SidebarScreenViewModel<T> : SidebarScreenViewModel where T : MainScreenViewModel
{

View File

@ -6,7 +6,7 @@
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:svg="clr-namespace:Avalonia.Svg.Skia;assembly=Avalonia.Svg.Skia"
mc:Ignorable="d" d:DesignWidth="240" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Root.Sidebar.SidebarView">
x:Class="Artemis.UI.Screens.Sidebar.SidebarView">
<Grid RowDefinitions="60,Auto,Auto,*,Auto,Auto">
<Grid Grid.Row="0" IsHitTestVisible="False" ColumnDefinitions="Auto,*">
<Image Grid.Column="0">

View File

@ -1,7 +1,7 @@
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Root.Sidebar
namespace Artemis.UI.Screens.Sidebar
{
public class SidebarView : ReactiveUserControl<SidebarViewModel>
{

View File

@ -2,15 +2,18 @@
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;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Home;
using Artemis.UI.Screens.Root.Sidebar.Dialogs;
using Artemis.UI.Screens.ProfileEditor;
using Artemis.UI.Screens.Settings;
using Artemis.UI.Screens.Sidebar.ContentDialogs;
using Artemis.UI.Screens.SurfaceEditor;
using Artemis.UI.Screens.Workshop;
using Artemis.UI.Services;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services.Interfaces;
using FluentAvalonia.UI.Controls;
@ -19,7 +22,7 @@ using Ninject;
using ReactiveUI;
using RGB.NET.Core;
namespace Artemis.UI.Screens.Root.Sidebar
namespace Artemis.UI.Screens.Sidebar
{
public class SidebarViewModel : ActivatableViewModelBase
{
@ -28,17 +31,21 @@ namespace Artemis.UI.Screens.Root.Sidebar
private readonly IRgbService _rgbService;
private readonly ISidebarVmFactory _sidebarVmFactory;
private readonly IWindowService _windowService;
private readonly IProfileEditorService _profileEditorService;
private ArtemisDevice? _headerDevice;
private SidebarScreenViewModel? _selectedSidebarScreen;
public SidebarViewModel(IScreen hostScreen, IKernel kernel, IProfileService profileService, IRgbService rgbService, ISidebarVmFactory sidebarVmFactory, IWindowService windowService)
public SidebarViewModel(IScreen hostScreen, IKernel kernel, IProfileService profileService, IRgbService rgbService, IWindowService windowService,
IProfileEditorService profileEditorService, ISidebarVmFactory sidebarVmFactory, IProfileEditorVmFactory profileEditorVmFactory)
{
_hostScreen = hostScreen;
_profileService = profileService;
_rgbService = rgbService;
_sidebarVmFactory = sidebarVmFactory;
_windowService = windowService;
_profileEditorService = profileEditorService;
_sidebarVmFactory = sidebarVmFactory;
SidebarScreens = new ObservableCollection<SidebarScreenViewModel>
{
@ -58,9 +65,23 @@ namespace Artemis.UI.Screens.Root.Sidebar
.WhereNotNull()
.Subscribe(c => SelectedSidebarScreen = SidebarScreens.FirstOrDefault(s => s.ScreenType == c.GetType()))
.DisposeWith(disposables);
this.WhenAnyValue(vm => vm.SelectedSidebarScreen)
.WhereNotNull()
.Subscribe(s => _hostScreen.Router.Navigate.Execute(s.CreateInstance(kernel, _hostScreen)));
.Subscribe(s =>
{
_hostScreen.Router.Navigate.Execute(s.CreateInstance(kernel, _hostScreen));
profileEditorService.ChangeCurrentProfileConfiguration(null);
});
this.WhenAnyObservable(vm => vm._profileEditorService.CurrentProfileConfiguration)
.WhereNotNull()
.Subscribe(_ =>
{
if (_hostScreen.Router.GetCurrentViewModel() is not ProfileEditorViewModel)
_hostScreen.Router.Navigate.Execute(profileEditorVmFactory.ProfileEditorViewModel(_hostScreen));
})
.DisposeWith(disposables);
});
}
@ -92,7 +113,7 @@ namespace Artemis.UI.Screens.Root.Sidebar
.WithTitle("Add new category")
.WithViewModel<SidebarCategoryEditViewModel>(out var vm, ("category", null))
.HavingPrimaryButton(b => b.WithText("Confirm").WithCommand(vm.Confirm))
.WithCloseButtonText("Cancel")
.WithCloseButtonText("Cancel")
.WithDefaultButton(ContentDialogButton.Primary)
.ShowAsync();

View File

@ -0,0 +1,51 @@
using System;
using System.Diagnostics;
using System.Reactive.Linq;
using Artemis.Core;
using Artemis.UI.Services.Interfaces;
using ReactiveUI;
namespace Artemis.UI.Services
{
public class ProfileEditorService : IProfileEditorService
{
private readonly ReactiveCommand<ProfileConfiguration?, ProfileConfiguration?> _changeCurrentProfileConfiguration;
private readonly ReactiveCommand<RenderProfileElement?, RenderProfileElement?> _changeCurrentProfileElement;
private ProfileConfiguration? _currentProfileConfiguration;
private RenderProfileElement? _currentProfileElement;
public ProfileEditorService()
{
_changeCurrentProfileConfiguration = ReactiveCommand.CreateFromObservable<ProfileConfiguration?, ProfileConfiguration?>(Observable.Return);
_changeCurrentProfileElement = ReactiveCommand.CreateFromObservable<RenderProfileElement?, RenderProfileElement?>(Observable.Return);
CurrentProfileConfiguration = Observable.Defer(() => Observable.Return(_currentProfileConfiguration)).Concat(_changeCurrentProfileConfiguration);
CurrentProfileElement = Observable.Defer(() => Observable.Return(_currentProfileElement)).Concat(_changeCurrentProfileElement);
}
public IObservable<ProfileConfiguration?> CurrentProfileConfiguration { get; }
public IObservable<RenderProfileElement?> CurrentProfileElement { get; }
public void ChangeCurrentProfileConfiguration(ProfileConfiguration? profileConfiguration)
{
_currentProfileConfiguration = profileConfiguration;
_changeCurrentProfileConfiguration.Execute(profileConfiguration).Subscribe();
}
public void ChangeCurrentProfileElement(RenderProfileElement? renderProfileElement)
{
_currentProfileElement = renderProfileElement;
_changeCurrentProfileElement.Execute(renderProfileElement).Subscribe();
}
}
public interface IProfileEditorService : IArtemisUIService
{
IObservable<ProfileConfiguration?> CurrentProfileConfiguration { get; }
IObservable<RenderProfileElement?> CurrentProfileElement { get; }
void ChangeCurrentProfileConfiguration(ProfileConfiguration? profileConfiguration);
void ChangeCurrentProfileElement(RenderProfileElement? renderProfileElement);
}
}