1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-31 01:42:02 +00:00

Color properties - Redesigned input

This commit is contained in:
Robert 2022-02-19 23:24:00 +01:00
parent 2a6ed8cc7f
commit 09e7bb5168
11 changed files with 149 additions and 82 deletions

View File

@ -58,7 +58,7 @@ namespace Artemis.UI.Shared.Controls
private void OnSelectionChanged(object? sender, SelectionChangedEventArgs e) private void OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
{ {
if (_enumComboBox == null) if (_enumComboBox == null || _enumComboBox.SelectedIndex == -1)
return; return;
(Enum enumValue, _) = _currentValues[_enumComboBox.SelectedIndex]; (Enum enumValue, _) = _currentValues[_enumComboBox.SelectedIndex];

View File

@ -17,10 +17,8 @@ namespace Artemis.UI.Shared.Services.PropertyInput;
/// <typeparam name="T">The type of property this input view model supports</typeparam> /// <typeparam name="T">The type of property this input view model supports</typeparam>
public abstract class PropertyInputViewModel<T> : PropertyInputViewModel public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
{ {
private T _dragStartValue;
private bool _inputDragging;
[AllowNull] private T _inputValue; [AllowNull] private T _inputValue;
private LayerPropertyPreview<T>? _preview;
private TimeSpan _time; private TimeSpan _time;
private bool _updating; private bool _updating;
@ -35,7 +33,6 @@ public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
PropertyInputService = propertyInputService; PropertyInputService = propertyInputService;
_inputValue = default!; _inputValue = default!;
_dragStartValue = default!;
this.WhenActivated(d => this.WhenActivated(d =>
{ {
@ -55,8 +52,6 @@ public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
.Subscribe(_ => UpdateDataBinding()) .Subscribe(_ => UpdateDataBinding())
.DisposeWith(d); .DisposeWith(d);
}); });
ValidationContext.ValidationStatusChange.Subscribe(s => Console.WriteLine(s));
} }
/// <summary> /// <summary>
@ -80,17 +75,13 @@ public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
public IPropertyInputService PropertyInputService { get; } public IPropertyInputService PropertyInputService { get; }
/// <summary> /// <summary>
/// Gets or sets a boolean indicating whether the input is currently being dragged /// Gets or boolean indicating whether the current input is being previewed, the value won't be applied until
/// <para> /// <para>
/// Only applicable when using something like a <see cref="DraggableFloat" />, see /// Only applicable when using something like a <see cref="DraggableFloat" />, see
/// <see cref="InputDragStarted" /> and <see cref="InputDragEnded" /> /// <see cref="StartPreview" /> and <see cref="ApplyPreview" />
/// </para> /// </para>
/// </summary> /// </summary>
public bool InputDragging public bool IsPreviewing => _preview != null;
{
get => _inputDragging;
private set => this.RaiseAndSetIfChanged(ref _inputDragging, value);
}
/// <summary> /// <summary>
/// Gets or sets the input value /// Gets or sets the input value
@ -119,27 +110,37 @@ public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
internal override object InternalGuard { get; } = new(); internal override object InternalGuard { get; } = new();
/// <summary> /// <summary>
/// Called by the view input drag has started /// Starts the preview of the current property, allowing updates without causing real changes to the property.
/// <para>
/// To use, add the following to DraggableFloat in your xaml: <c>DragStarted="{s:Action InputDragStarted}"</c>
/// </para>
/// </summary> /// </summary>
public void InputDragStarted(object sender, EventArgs e) public void StartPreview()
{ {
InputDragging = true; _preview?.DiscardPreview();
_dragStartValue = GetDragStartValue(); _preview = new LayerPropertyPreview<T>(LayerProperty, _time);
} }
/// <summary> /// <summary>
/// Called by the view when input drag has ended /// Applies the current preview to the property.
/// <para>
/// To use, add the following to DraggableFloat in your xaml: <c>DragEnded="{s:Action InputDragEnded}"</c>
/// </para>
/// </summary> /// </summary>
public void InputDragEnded(object sender, EventArgs e) public void ApplyPreview()
{ {
InputDragging = false; if (_preview == null)
ProfileEditorService.ExecuteCommand(new UpdateLayerProperty<T>(LayerProperty, _inputValue, _dragStartValue, _time)); return;
if (_preview.DiscardPreview() && _preview.PreviewValue != null)
ProfileEditorService.ExecuteCommand(new UpdateLayerProperty<T>(LayerProperty, _inputValue, _preview.PreviewValue, _time));
_preview = null;
}
/// <summary>
/// Discard the preview of the property.
/// </summary>
public void DiscardPreview()
{
if (_preview == null)
return;
_preview.DiscardPreview();
_preview = null;
} }
/// <summary> /// <summary>
@ -157,37 +158,31 @@ public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
} }
/// <summary> /// <summary>
/// Called when dragging starts to get the initial value before dragging begun /// Applies the input value to the layer property or the currently active preview.
/// </summary>
/// <returns>The initial value before dragging begun</returns>
protected virtual T? GetDragStartValue()
{
return InputValue;
}
/// <summary>
/// Applies the input value to the layer property using an <see cref="IProfileEditorCommand" />.
/// </summary> /// </summary>
protected virtual void ApplyInputValue() protected virtual void ApplyInputValue()
{ {
if (_updating) // Avoid reapplying the latest value by checking if we're currently updating
if (_updating || !ValidationContext.IsValid)
return; return;
if (InputDragging) if (_preview != null)
ProfileEditorService.ChangeTime(_time); _preview.Preview(_inputValue);
else if (ValidationContext.IsValid) else
ProfileEditorService.ExecuteCommand(new UpdateLayerProperty<T>(LayerProperty, _inputValue, _time)); ProfileEditorService.ExecuteCommand(new UpdateLayerProperty<T>(LayerProperty, _inputValue, _time));
} }
private void UpdateInputValue() private void UpdateInputValue()
{ {
// Always run this on the UI thread to avoid race conditions with ApplyInputValue
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
{ {
try try
{ {
_updating = true; _updating = true;
// Avoid unnecessary UI updates and validator cycles // Avoid unnecessary UI updates and validator cycles
if (_inputValue != null && _inputValue.Equals(LayerProperty.CurrentValue) || _inputValue == null && LayerProperty.CurrentValue == null) if (Equals(_inputValue, LayerProperty.CurrentValue))
return; return;
// Override the input value // Override the input value
@ -202,7 +197,6 @@ public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
_updating = false; _updating = false;
} }
}); });
} }
private void UpdateDataBinding() private void UpdateDataBinding()

View File

@ -5,25 +5,56 @@
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:converters="clr-namespace:Artemis.UI.Converters" xmlns:converters="clr-namespace:Artemis.UI.Converters"
xmlns:propertyInput="clr-namespace:Artemis.UI.DefaultTypes.PropertyInput" xmlns:propertyInput="clr-namespace:Artemis.UI.DefaultTypes.PropertyInput"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="200" d:DesignHeight="450"
x:Class="Artemis.UI.DefaultTypes.PropertyInput.SKColorPropertyInputView" x:Class="Artemis.UI.DefaultTypes.PropertyInput.SKColorPropertyInputView"
x:DataType="propertyInput:SKColorPropertyInputViewModel"> x:DataType="propertyInput:SKColorPropertyInputViewModel">
<UserControl.Styles>
<Style Selector="controls|ColorPickerButton.contained-color-picker-button">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="4 0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="MinHeight" Value="00" />
<Setter Property="MinWidth" Value="0" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<controls:Button Name="MainButton"
Padding="0"
BorderThickness="0"
CornerRadius="{TemplateBinding CornerRadius}">
<Border BorderBrush="{DynamicResource ColorPickerButtonOutline}"
BorderThickness="1"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
MinWidth="18" MinHeight="18"
Background="{TemplateBinding Color, Converter={StaticResource ColorBrushConv}}"
CornerRadius="{TemplateBinding CornerRadius}">
<controls:ColorPicker Name="ColorPicker" IsVisible="False" />
</Border>
</controls:Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style Selector="controls|ColorPickerButton.contained-color-picker-button /template/ Viewbox">
<Setter Property="IsVisible" Value="False"></Setter>
</Style>
</UserControl.Styles>
<UserControl.Resources> <UserControl.Resources>
<converters:SKColorToStringConverter x:Key="SKColorToStringConverter" /> <converters:SKColorToStringConverter x:Key="SKColorToStringConverter" />
<converters:SKColorToColor2Converter x:Key="SKColorToColor2Converter" /> <converters:SKColorToColor2Converter x:Key="SKColorToColor2Converter" />
</UserControl.Resources> </UserControl.Resources>
<Grid Height="24" ColumnDefinitions="*,Auto"> <Grid Height="24" ColumnDefinitions="*">
<TextBox Classes="condensed" <TextBox Classes="condensed"
Grid.Row="0" Text="{CompiledBinding InputValue, Converter={StaticResource SKColorToStringConverter}}"
Grid.Column="0" Padding="2 2 30 2">
Text="{CompiledBinding InputValue, Converter={StaticResource SKColorToStringConverter}}" /> </TextBox>
<controls:ColorPickerButton Grid.Row="0" <controls:ColorPickerButton Classes="contained-color-picker-button"
Grid.Column="1"
Color="{CompiledBinding InputValue, Converter={StaticResource SKColorToColor2Converter}}" Color="{CompiledBinding InputValue, Converter={StaticResource SKColorToColor2Converter}}"
Classes="condensed" ShowAcceptDismissButtons="False" />
VerticalAlignment="Center"
HorizontalAlignment="Right"
Margin="-6 0 -8 0" />
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -1,5 +1,6 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
@ -17,4 +18,4 @@ namespace Artemis.UI.DefaultTypes.PropertyInput
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
} }
} }
} }

View File

@ -3,8 +3,10 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:menuBar="clr-namespace:Artemis.UI.Screens.ProfileEditor.MenuBar"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.ProfileEditor.MenuBar.MenuBarView"> x:Class="Artemis.UI.Screens.ProfileEditor.MenuBar.MenuBarView"
x:DataType="menuBar:MenuBarViewModel">
<Menu VerticalAlignment="Top"> <Menu VerticalAlignment="Top">
<MenuItem Header="_File"> <MenuItem Header="_File">
<MenuItem Header="New"> <MenuItem Header="New">
@ -38,11 +40,11 @@
<avalonia:MaterialIcon Kind="Magic" /> <avalonia:MaterialIcon Kind="Magic" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem Header="Suspend Profile"> <MenuItem Header="Suspend Profile" IsSelected="{CompiledBinding IsSuspended}">
<MenuItem.Icon> <MenuItem.Icon>
<CheckBox BorderThickness="0" <CheckBox BorderThickness="0"
IsHitTestVisible="False" IsHitTestVisible="False"
IsChecked="{Binding ProfileConfiguration.IsSuspended}" /> IsChecked="{CompiledBinding IsSuspended}"/>
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<Separator /> <Separator />

View File

@ -1,5 +1,8 @@
using System; using System;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Reactive.Linq;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Shared; using Artemis.UI.Shared;
using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor;
using ReactiveUI; using ReactiveUI;
@ -8,11 +11,24 @@ namespace Artemis.UI.Screens.ProfileEditor.MenuBar;
public class MenuBarViewModel : ActivatableViewModelBase public class MenuBarViewModel : ActivatableViewModelBase
{ {
private readonly IProfileService _profileService;
private ProfileEditorHistory? _history; private ProfileEditorHistory? _history;
private ObservableAsPropertyHelper<ProfileConfiguration?>? _profileConfiguration;
private ObservableAsPropertyHelper<bool>? _isSuspended;
public MenuBarViewModel(IProfileEditorService profileEditorService) public MenuBarViewModel(IProfileEditorService profileEditorService, IProfileService profileService)
{ {
this.WhenActivated(d => profileEditorService.History.Subscribe(history => History = history).DisposeWith(d)); _profileService = profileService;
this.WhenActivated(d =>
{
profileEditorService.History.Subscribe(history => History = history).DisposeWith(d);
_profileConfiguration = profileEditorService.ProfileConfiguration.ToProperty(this, vm => vm.ProfileConfiguration);
_isSuspended = profileEditorService.ProfileConfiguration
.Select(p => p?.WhenAnyValue(c => c.IsSuspended) ?? Observable.Never<bool>())
.Switch()
.ToProperty(this, vm => vm.IsSuspended)
.DisposeWith(d);
});
} }
public ProfileEditorHistory? History public ProfileEditorHistory? History
@ -20,4 +36,19 @@ public class MenuBarViewModel : ActivatableViewModelBase
get => _history; get => _history;
set => RaiseAndSetIfChanged(ref _history, value); set => RaiseAndSetIfChanged(ref _history, value);
} }
public ProfileConfiguration? ProfileConfiguration => _profileConfiguration?.Value;
public bool IsSuspended
{
get => _isSuspended?.Value ?? false;
set
{
if (ProfileConfiguration == null)
return;
ProfileConfiguration.IsSuspended = value;
_profileService.SaveProfileCategory(ProfileConfiguration.Category);
}
}
} }

View File

@ -52,15 +52,17 @@ public class VisualEditorViewModel : ActivatableViewModelBase
Tools = tools; Tools = tools;
this.WhenAnyValue(vm => vm.ProfileConfiguration) this.WhenAnyValue(vm => vm.ProfileConfiguration)
.Select(p => p?.Profile != null .Select(p => p?.Profile)
? Observable.FromEventPattern<ProfileElementEventArgs>(x => p.Profile.DescendentAdded += x, x => p.Profile.DescendentAdded -= x) .Select(p => p != null
? Observable.FromEventPattern<ProfileElementEventArgs>(x => p.DescendentAdded += x, x => p.DescendentAdded -= x)
: Observable.Never<EventPattern<ProfileElementEventArgs>>()) : Observable.Never<EventPattern<ProfileElementEventArgs>>())
.Switch() .Switch()
.Subscribe(AddElement) .Subscribe(AddElement)
.DisposeWith(d); .DisposeWith(d);
this.WhenAnyValue(vm => vm.ProfileConfiguration) this.WhenAnyValue(vm => vm.ProfileConfiguration)
.Select(p => p?.Profile != null .Select(p => p?.Profile)
? Observable.FromEventPattern<ProfileElementEventArgs>(x => p.Profile.DescendentRemoved += x, x => p.Profile.DescendentRemoved -= x) .Select(p => p != null
? Observable.FromEventPattern<ProfileElementEventArgs>(x => p.DescendentRemoved += x, x => p.DescendentRemoved -= x)
: Observable.Never<EventPattern<ProfileElementEventArgs>>()) : Observable.Never<EventPattern<ProfileElementEventArgs>>())
.Switch() .Switch()
.Subscribe(RemoveElement) .Subscribe(RemoveElement)

View File

@ -14,7 +14,7 @@
ExtendClientAreaToDecorationsHint="True" ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaTitleBarHeightHint="450"> ExtendClientAreaTitleBarHeightHint="450">
<Grid RowDefinitions="250,50,Auto,*" IsHitTestVisible="False"> <Grid RowDefinitions="250,50,Auto,*" IsHitTestVisible="False">
<Image Grid.Column="0" Stretch="Uniform"> <Image Grid.Column="0" Stretch="Uniform" Width="200">
<Image.Source> <Image.Source>
<svg:SvgImage Source="/Assets/Images/Logo/bow.svg" /> <svg:SvgImage Source="/Assets/Images/Logo/bow.svg" />
</Image.Source> </Image.Source>
@ -22,7 +22,6 @@
<TextBlock Grid.Row="1" <TextBlock Grid.Row="1"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
FontSize="16"
TextWrapping="Wrap"> TextWrapping="Wrap">
Artemis is initializing... Artemis is initializing...
</TextBlock> </TextBlock>

View File

@ -83,7 +83,7 @@
</Button> </Button>
<ToggleButton Classes="category-button icon-button icon-button-small" <ToggleButton Classes="category-button icon-button icon-button-small"
Grid.Column="3" Grid.Column="3"
ToolTip.Tip="Suspend profile" ToolTip.Tip="Suspend category"
Margin="5 0" Margin="5 0"
IsChecked="{Binding IsSuspended}"> IsChecked="{Binding IsSuspended}">
<avalonia:MaterialIcon Kind="Pause" /> <avalonia:MaterialIcon Kind="Pause" />

View File

@ -5,8 +5,10 @@
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:converters="clr-namespace:Artemis.UI.Converters" xmlns:converters="clr-namespace:Artemis.UI.Converters"
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared" xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
xmlns:sidebar="clr-namespace:Artemis.UI.Screens.Sidebar"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Sidebar.SidebarProfileConfigurationView"> x:Class="Artemis.UI.Screens.Sidebar.SidebarProfileConfigurationView"
x:DataType="sidebar:SidebarProfileConfigurationViewModel">
<UserControl.Resources> <UserControl.Resources>
<converters:ValuesAdditionConverter x:Key="ValuesAddition" /> <converters:ValuesAdditionConverter x:Key="ValuesAddition" />
</UserControl.Resources> </UserControl.Resources>
@ -65,17 +67,11 @@
</MenuItem> </MenuItem>
</ContextMenu> </ContextMenu>
</UserControl.ContextMenu> </UserControl.ContextMenu>
<Grid> <Grid ColumnDefinitions="Auto,*,Auto,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<controls:ProfileConfigurationIcon Grid.Column="0" <controls:ProfileConfigurationIcon Grid.Column="0"
x:Name="ProfileIcon" x:Name="ProfileIcon"
VerticalAlignment="Center" VerticalAlignment="Center"
ConfigurationIcon="{Binding ProfileConfiguration.Icon}" ConfigurationIcon="{CompiledBinding ProfileConfiguration.Icon}"
Width="20" Width="20"
Height="20" /> Height="20" />
@ -85,7 +81,7 @@
Margin="10 0 0 0" Margin="10 0 0 0"
VerticalAlignment="Center" VerticalAlignment="Center"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Text="{Binding ProfileConfiguration.Name}" Text="{CompiledBinding ProfileConfiguration.Name}"
TextTrimming="CharacterEllipsis" /> TextTrimming="CharacterEllipsis" />
<Border Grid.Column="0" <Border Grid.Column="0"
@ -117,7 +113,7 @@
Grid.Column="3" Grid.Column="3"
ToolTip.Tip="Suspend profile" ToolTip.Tip="Suspend profile"
Margin="2 0 0 0" Margin="2 0 0 0"
IsChecked="{Binding IsSuspended}"> IsChecked="{CompiledBinding IsSuspended}">
<avalonia:MaterialIcon Kind="Pause" /> <avalonia:MaterialIcon Kind="Pause" />
</ToggleButton> </ToggleButton>
</Grid> </Grid>

View File

@ -1,16 +1,20 @@
using System.Threading.Tasks; using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.Services; using Artemis.Core.Services;
using Artemis.UI.Shared; using Artemis.UI.Shared;
using Artemis.UI.Shared.Services.Interfaces; using Artemis.UI.Shared.Services.Interfaces;
using ReactiveUI;
namespace Artemis.UI.Screens.Sidebar namespace Artemis.UI.Screens.Sidebar
{ {
public class SidebarProfileConfigurationViewModel : ViewModelBase public class SidebarProfileConfigurationViewModel : ActivatableViewModelBase
{ {
private readonly SidebarViewModel _sidebarViewModel; private readonly SidebarViewModel _sidebarViewModel;
private readonly IProfileService _profileService; private readonly IProfileService _profileService;
private readonly IWindowService _windowService; private readonly IWindowService _windowService;
private ObservableAsPropertyHelper<bool>? _isSuspended;
public ProfileConfiguration ProfileConfiguration { get; } public ProfileConfiguration ProfileConfiguration { get; }
public SidebarProfileConfigurationViewModel(SidebarViewModel sidebarViewModel, ProfileConfiguration profileConfiguration, IProfileService profileService, IWindowService windowService) public SidebarProfileConfigurationViewModel(SidebarViewModel sidebarViewModel, ProfileConfiguration profileConfiguration, IProfileService profileService, IWindowService windowService)
@ -18,8 +22,15 @@ namespace Artemis.UI.Screens.Sidebar
_sidebarViewModel = sidebarViewModel; _sidebarViewModel = sidebarViewModel;
_profileService = profileService; _profileService = profileService;
_windowService = windowService; _windowService = windowService;
ProfileConfiguration = profileConfiguration; ProfileConfiguration = profileConfiguration;
this.WhenActivated(d =>
{
_isSuspended = ProfileConfiguration.WhenAnyValue(c => c.IsSuspended)
.ToProperty(this, vm => vm.IsSuspended)
.DisposeWith(d);
});
_profileService.LoadProfileConfigurationIcon(ProfileConfiguration); _profileService.LoadProfileConfigurationIcon(ProfileConfiguration);
} }
@ -27,7 +38,7 @@ namespace Artemis.UI.Screens.Sidebar
public bool IsSuspended public bool IsSuspended
{ {
get => ProfileConfiguration.IsSuspended; get => _isSuspended?.Value ?? false;
set set
{ {
ProfileConfiguration.IsSuspended = value; ProfileConfiguration.IsSuspended = value;