mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-12 13:28:33 +00:00
Adaption hints - Added single LED adaption hint
Adaption hints - Added more sections to keyboard section adaption hint
This commit is contained in:
parent
ca9ce948c5
commit
d96581f11c
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using Artemis.Storage.Entities.Profile.AdaptionHints;
|
||||
using RGB.NET.Core;
|
||||
@ -15,7 +16,12 @@ public class KeyboardSectionAdaptionHint : CorePropertyChanged, IAdaptionHint
|
||||
{
|
||||
{KeyboardSection.MacroKeys, Enum.GetValues<LedId>().Where(l => l >= LedId.Keyboard_Programmable1 && l <= LedId.Keyboard_Programmable32).ToList()},
|
||||
{KeyboardSection.LedStrips, Enum.GetValues<LedId>().Where(l => l >= LedId.LedStripe1 && l <= LedId.LedStripe128).ToList()},
|
||||
{KeyboardSection.Extra, Enum.GetValues<LedId>().Where(l => l >= LedId.Keyboard_Custom1 && l <= LedId.Keyboard_Custom64).ToList()}
|
||||
{KeyboardSection.Extra, Enum.GetValues<LedId>().Where(l => l >= LedId.Keyboard_Custom1 && l <= LedId.Keyboard_Custom64).ToList()},
|
||||
{KeyboardSection.FunctionKeys, Enum.GetValues<LedId>().Where(l => l >= LedId.Keyboard_F1 && l <= LedId.Keyboard_F12).ToList()},
|
||||
{KeyboardSection.NumberKeys, Enum.GetValues<LedId>().Where(l => l >= LedId.Keyboard_1 && l <= LedId.Keyboard_0).ToList()},
|
||||
{KeyboardSection.NumPad, Enum.GetValues<LedId>().Where(l => l >= LedId.Keyboard_NumLock && l <= LedId.Keyboard_NumPeriodAndDelete).ToList()},
|
||||
{KeyboardSection.ArrowKeys, Enum.GetValues<LedId>().Where(l => l >= LedId.Keyboard_PageDown && l <= LedId.Keyboard_ArrowRight).ToList()},
|
||||
{KeyboardSection.MediaKeys, Enum.GetValues<LedId>().Where(l => l >= LedId.Keyboard_MediaMute && l <= LedId.Keyboard_MediaNextTrack).ToList()},
|
||||
};
|
||||
|
||||
private KeyboardSection _section;
|
||||
@ -46,6 +52,12 @@ public class KeyboardSectionAdaptionHint : CorePropertyChanged, IAdaptionHint
|
||||
/// <inheritdoc />
|
||||
public void Apply(Layer layer, List<ArtemisDevice> devices)
|
||||
{
|
||||
if (Section == KeyboardSection.Movement)
|
||||
{
|
||||
ApplyMovement(layer, devices);
|
||||
return;
|
||||
}
|
||||
|
||||
// Only keyboards should have the LEDs we care about
|
||||
foreach (ArtemisDevice keyboard in devices.Where(d => d.DeviceType == RGBDeviceType.Keyboard))
|
||||
{
|
||||
@ -54,6 +66,26 @@ public class KeyboardSectionAdaptionHint : CorePropertyChanged, IAdaptionHint
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyMovement(Layer layer, List<ArtemisDevice> devices)
|
||||
{
|
||||
// Only keyboards should have the LEDs we care about
|
||||
foreach (ArtemisDevice keyboard in devices.Where(d => d.DeviceType == RGBDeviceType.Keyboard))
|
||||
{
|
||||
ArtemisLed? qLed = keyboard.Leds.FirstOrDefault(l => l.RgbLed.Id == LedId.Keyboard_Q);
|
||||
ArtemisLed? aLed = keyboard.Leds.FirstOrDefault(l => l.RgbLed.Id == LedId.Keyboard_A);
|
||||
if (qLed == null || aLed == null)
|
||||
continue;
|
||||
|
||||
// AZERTY keyboards will have their A above their Q
|
||||
bool isAzerty = aLed.Rectangle.MidX < qLed.Rectangle.MidX;
|
||||
|
||||
if (isAzerty)
|
||||
layer.AddLeds(keyboard.Leds.Where(l => l.RgbLed.Id is LedId.Keyboard_Z or LedId.Keyboard_Q or LedId.Keyboard_S or LedId.Keyboard_D));
|
||||
else
|
||||
layer.AddLeds(keyboard.Leds.Where(l => l.RgbLed.Id is LedId.Keyboard_W or LedId.Keyboard_A or LedId.Keyboard_S or LedId.Keyboard_D));
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IAdaptionHintEntity GetEntry()
|
||||
{
|
||||
@ -77,15 +109,45 @@ public enum KeyboardSection
|
||||
/// <summary>
|
||||
/// A region containing the macro keys of a keyboard
|
||||
/// </summary>
|
||||
MacroKeys,
|
||||
[Description("Macro Keys")] MacroKeys,
|
||||
|
||||
/// <summary>
|
||||
/// A region containing the LED strips of a keyboard
|
||||
/// </summary>
|
||||
LedStrips,
|
||||
[Description("LED Strips")] LedStrips,
|
||||
|
||||
/// <summary>
|
||||
/// A region containing extra non-standard LEDs of a keyboard
|
||||
/// A region containing the extra non-standard LEDs of a keyboard
|
||||
/// </summary>
|
||||
Extra
|
||||
[Description("Extra LEDs")] Extra,
|
||||
|
||||
/// <summary>
|
||||
/// A region containing the movement keys of a keyboard (WASD for QWERTY and ZQSD for AZERTY)
|
||||
/// </summary>
|
||||
[Description("Movement (WASD/ZQSD)")] Movement,
|
||||
|
||||
/// <summary>
|
||||
/// A region containing the F-keys of a keyboard
|
||||
/// </summary>
|
||||
[Description("F-keys")] FunctionKeys,
|
||||
|
||||
/// <summary>
|
||||
/// A region containing the numeric keys of a keyboard
|
||||
/// </summary>
|
||||
[Description("Numeric keys")] NumberKeys,
|
||||
|
||||
/// <summary>
|
||||
/// A region containing the Numpad of a keyboard
|
||||
/// </summary>
|
||||
[Description("Numpad")] NumPad,
|
||||
|
||||
/// <summary>
|
||||
/// A region containing the arrow keys of a keyboard
|
||||
/// </summary>
|
||||
[Description("Arrow keys")] ArrowKeys,
|
||||
|
||||
/// <summary>
|
||||
/// A region containing the media keys of a keyboard
|
||||
/// </summary>
|
||||
[Description("Media keys")] MediaKeys
|
||||
}
|
||||
@ -0,0 +1,102 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Storage.Entities.Profile.AdaptionHints;
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace Artemis.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a hint that adapts layers to a single LED of one or more devices
|
||||
/// </summary>
|
||||
public class SingleLedAdaptionHint : CorePropertyChanged, IAdaptionHint
|
||||
{
|
||||
private LedId _ledId;
|
||||
private int _skip;
|
||||
private bool _limitAmount;
|
||||
private int _amount;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="SingleLedAdaptionHint" /> class
|
||||
/// </summary>
|
||||
public SingleLedAdaptionHint()
|
||||
{
|
||||
}
|
||||
|
||||
internal SingleLedAdaptionHint(SingleLedAdaptionHintEntity entity)
|
||||
{
|
||||
LedId = (LedId) entity.LedId;
|
||||
Skip = entity.Skip;
|
||||
LimitAmount = entity.LimitAmount;
|
||||
Amount = entity.Amount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the LED ID to apply to.
|
||||
/// </summary>
|
||||
public LedId LedId
|
||||
{
|
||||
get => _ledId;
|
||||
set => SetAndNotify(ref _ledId, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the amount of devices to skip
|
||||
/// </summary>
|
||||
public int Skip
|
||||
{
|
||||
get => _skip;
|
||||
set => SetAndNotify(ref _skip, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether a limited amount of devices should be used
|
||||
/// </summary>
|
||||
public bool LimitAmount
|
||||
{
|
||||
get => _limitAmount;
|
||||
set => SetAndNotify(ref _limitAmount, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the amount of devices to limit to if <see cref="LimitAmount" /> is <see langword="true" />
|
||||
/// </summary>
|
||||
public int Amount
|
||||
{
|
||||
get => _amount;
|
||||
set => SetAndNotify(ref _amount, value);
|
||||
}
|
||||
|
||||
#region Implementation of IAdaptionHint
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Apply(Layer layer, List<ArtemisDevice> devices)
|
||||
{
|
||||
IEnumerable<ArtemisDevice> matches = devices
|
||||
.Where(d => d.Leds.Any(l => l.RgbLed.Id == LedId))
|
||||
.OrderBy(d => d.Rectangle.Top)
|
||||
.ThenBy(d => d.Rectangle.Left)
|
||||
.Skip(Skip);
|
||||
if (LimitAmount)
|
||||
matches = matches.Take(Amount);
|
||||
|
||||
foreach (ArtemisDevice artemisDevice in matches)
|
||||
{
|
||||
ArtemisLed led = artemisDevice.Leds.First(l => l.RgbLed.Id == LedId);
|
||||
layer.AddLed(led);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IAdaptionHintEntity GetEntry()
|
||||
{
|
||||
return new SingleLedAdaptionHintEntity {Amount = Amount, LimitAmount = LimitAmount, Skip = Skip, LedId = (int) LedId};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Single LED adaption - {nameof(LedId)}: {LedId}, {nameof(Skip)}: {Skip}, {nameof(LimitAmount)}: {LimitAmount}, {nameof(Amount)}: {Amount}";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -111,6 +111,15 @@ public class LayerAdapter : IStorageModel
|
||||
newHints.Add(hint);
|
||||
}
|
||||
}
|
||||
|
||||
// A single LED assignment is turned into a hint for one matching LED ID on the same device type
|
||||
if (Layer.Leds.Count == 1)
|
||||
{
|
||||
ArtemisLed led = Layer.Leds.Single();
|
||||
SingleLedAdaptionHint hint = new() {LedId = led.RgbLed.Id, Amount = 1, LimitAmount = true};
|
||||
Add(hint);
|
||||
newHints.Add(hint);
|
||||
}
|
||||
}
|
||||
|
||||
return newHints;
|
||||
@ -184,6 +193,9 @@ public class LayerAdapter : IStorageModel
|
||||
case KeyboardSectionAdaptionHintEntity entity:
|
||||
Add(new KeyboardSectionAdaptionHint(entity));
|
||||
break;
|
||||
case SingleLedAdaptionHintEntity entity:
|
||||
Add(new SingleLedAdaptionHint(entity));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
namespace Artemis.Storage.Entities.Profile.AdaptionHints;
|
||||
|
||||
public class SingleLedAdaptionHintEntity : IAdaptionHintEntity
|
||||
{
|
||||
public int LedId { get; set; }
|
||||
|
||||
public bool LimitAmount { get; set; }
|
||||
public int Skip { get; set; }
|
||||
public int Amount { get; set; }
|
||||
}
|
||||
@ -8,7 +8,7 @@
|
||||
<ComboBox x:Name="ChildEnumComboBox" HorizontalAlignment="Stretch">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:EnumComboBoxItem">
|
||||
<TextBlock Text="{CompiledBinding Value}" />
|
||||
<TextBlock Text="{CompiledBinding Description}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.UI.Shared.Services.ProfileEditor.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a profile editor command that can be used to apply adaption hints to a layer.
|
||||
/// </summary>
|
||||
public class ApplyAdaptionHints : IProfileEditorCommand
|
||||
{
|
||||
private readonly Layer _layer;
|
||||
private readonly List<ArtemisDevice> _devices;
|
||||
private readonly List<ArtemisLed> _originalLeds;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="ApplyAdaptionHints" /> class.
|
||||
/// </summary>
|
||||
public ApplyAdaptionHints(Layer layer, List<ArtemisDevice> devices)
|
||||
{
|
||||
_layer = layer;
|
||||
_devices = devices;
|
||||
_originalLeds = new List<ArtemisLed>(_layer.Leds);
|
||||
}
|
||||
|
||||
#region Implementation of IProfileEditorCommand
|
||||
|
||||
/// <inheritdoc />
|
||||
public string DisplayName => "Apply adaption hints";
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Execute()
|
||||
{
|
||||
_layer.ClearLeds();
|
||||
_layer.Adapter.Adapt(_devices);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Undo()
|
||||
{
|
||||
_layer.ClearLeds();
|
||||
_layer.AddLeds(_originalLeds);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -51,23 +51,4 @@
|
||||
<ItemGroup>
|
||||
<AvaloniaResource Include="Assets\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Screens\Workshop\Entries\Tabs\ProfileListView.axaml.cs">
|
||||
<DependentUpon>ProfileListView.axaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Screens\Workshop\Entries\Tabs\LayoutListView.axaml.cs">
|
||||
<DependentUpon>LayoutListView.axaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Screens\Workshop\Library\SubmissionDetailView.axaml.cs">
|
||||
<DependentUpon>SubmissionsDetailView.axaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<UpToDateCheckInput Remove="Screens\Workshop\Entries\Windows\MarkdownPreviewView.axaml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -430,6 +430,7 @@ public interface ILayerHintVmFactory : IVmFactory
|
||||
CategoryAdaptionHintViewModel CategoryAdaptionHintViewModel(Layer layer, CategoryAdaptionHint adaptionHint);
|
||||
DeviceAdaptionHintViewModel DeviceAdaptionHintViewModel(Layer layer, DeviceAdaptionHint adaptionHint);
|
||||
KeyboardSectionAdaptionHintViewModel KeyboardSectionAdaptionHintViewModel(Layer layer, KeyboardSectionAdaptionHint adaptionHint);
|
||||
SingleLedAdaptionHintViewModel SingleLedAdaptionHintViewModel(Layer layer, SingleLedAdaptionHint adaptionHint);
|
||||
}
|
||||
public class LayerHintVmFactory : ILayerHintVmFactory
|
||||
{
|
||||
@ -454,6 +455,11 @@ public class LayerHintVmFactory : ILayerHintVmFactory
|
||||
{
|
||||
return _container.Resolve<KeyboardSectionAdaptionHintViewModel>(new object[] { layer, adaptionHint });
|
||||
}
|
||||
|
||||
public SingleLedAdaptionHintViewModel SingleLedAdaptionHintViewModel(Layer layer, SingleLedAdaptionHint adaptionHint)
|
||||
{
|
||||
return _container.Resolve<SingleLedAdaptionHintViewModel>(new object[] { layer, adaptionHint });
|
||||
}
|
||||
}
|
||||
|
||||
public interface IScriptVmFactory : IVmFactory
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
</Button>
|
||||
|
||||
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal" Spacing="5">
|
||||
<shared:EnumComboBox Value="{CompiledBinding CategoryAdaptionHint.Category}" Width="130" Margin="0 0 10 0" />
|
||||
<shared:EnumComboBox Value="{CompiledBinding CategoryAdaptionHint.Category}" Width="200" Margin="0 0 10 0" />
|
||||
|
||||
<TextBlock VerticalAlignment="Center">Skip</TextBlock>
|
||||
<controls:NumberBox HorizontalAlignment="Stretch"
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
</Button>
|
||||
|
||||
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal" Spacing="5">
|
||||
<shared:EnumComboBox Value="{CompiledBinding DeviceAdaptionHint.DeviceType}" Width="130" Margin="0 0 10 0" />
|
||||
<shared:EnumComboBox Value="{CompiledBinding DeviceAdaptionHint.DeviceType}" Width="200" Margin="0 0 10 0" />
|
||||
|
||||
<TextBlock VerticalAlignment="Center">Skip</TextBlock>
|
||||
<controls:NumberBox HorizontalAlignment="Stretch"
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
</Button>
|
||||
|
||||
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal" Spacing="5">
|
||||
<shared:EnumComboBox Value="{CompiledBinding KeyboardSectionAdaptionHint.Section}" Width="130" Margin="0 0 10 0" />
|
||||
<shared:EnumComboBox Value="{CompiledBinding KeyboardSectionAdaptionHint.Section}" Width="200" Margin="0 0 10 0" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:adaptionHints="clr-namespace:Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints"
|
||||
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints.SingleLedAdaptionHintView"
|
||||
x:DataType="adaptionHints:SingleLedAdaptionHintViewModel">
|
||||
<Grid ColumnDefinitions="*,Auto" RowDefinitions="Auto,Auto">
|
||||
<StackPanel Grid.ColumnSpan="2" Margin="0 0 0 5">
|
||||
<TextBlock Classes="h5">Single LED hint</TextBlock>
|
||||
<TextBlock Classes="subtitle">Applies the layer to a single LED of one or more devices</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Classes="icon-button"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Right"
|
||||
ToolTip.Tip="Remove hint"
|
||||
Command="{CompiledBinding Remove}">
|
||||
<avalonia:MaterialIcon Kind="Delete" />
|
||||
</Button>
|
||||
|
||||
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal" Spacing="5">
|
||||
<controls:FAComboBox Width="200"
|
||||
Margin="0 0 10 0"
|
||||
ItemsSource="{CompiledBinding AdaptionLeds}"
|
||||
SelectedItem="{CompiledBinding SelectedLed}"
|
||||
DisplayMemberBinding="{CompiledBinding Description}"
|
||||
IsEditable="True"
|
||||
IsTextSearchEnabled="True"></controls:FAComboBox>
|
||||
<TextBlock VerticalAlignment="Center">Skip</TextBlock>
|
||||
<controls:NumberBox HorizontalAlignment="Stretch"
|
||||
Value="{CompiledBinding SingleLedAdaptionHint.Skip}"
|
||||
Minimum="0" />
|
||||
<TextBlock VerticalAlignment="Center">device(s)</TextBlock>
|
||||
|
||||
<TextBlock VerticalAlignment="Center">Take</TextBlock>
|
||||
<controls:NumberBox IsEnabled="{CompiledBinding SingleLedAdaptionHint.LimitAmount}"
|
||||
HorizontalAlignment="Stretch"
|
||||
Value="{CompiledBinding SingleLedAdaptionHint.Amount}"
|
||||
Minimum="1" />
|
||||
<TextBlock VerticalAlignment="Center">device(s)</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<CheckBox Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Content="Take all devices"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
IsChecked="{CompiledBinding !SingleLedAdaptionHint.LimitAmount}" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@ -0,0 +1,13 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints;
|
||||
|
||||
public partial class SingleLedAdaptionHintView : UserControl
|
||||
{
|
||||
public SingleLedAdaptionHintView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using ReactiveUI;
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints;
|
||||
|
||||
public class SingleLedAdaptionHintViewModel : AdaptionHintViewModelBase
|
||||
{
|
||||
private List<AdaptionLed> _adaptionLeds;
|
||||
private AdaptionLed? _selectedLed;
|
||||
|
||||
public SingleLedAdaptionHintViewModel(Layer layer, SingleLedAdaptionHint adaptionHint) : base(layer, adaptionHint)
|
||||
{
|
||||
SingleLedAdaptionHint = adaptionHint;
|
||||
|
||||
this.WhenAnyValue(vm => vm.SelectedLed).WhereNotNull().Subscribe(l => SingleLedAdaptionHint.LedId = l.Value);
|
||||
Task.Run(() =>
|
||||
{
|
||||
AdaptionLeds = Enum.GetValues<LedId>().Select(l => new AdaptionLed(l)).ToList();
|
||||
SelectedLed = AdaptionLeds.FirstOrDefault(l => l.Value == adaptionHint.LedId);
|
||||
});
|
||||
}
|
||||
|
||||
public List<AdaptionLed> AdaptionLeds
|
||||
{
|
||||
get => _adaptionLeds;
|
||||
set => RaiseAndSetIfChanged(ref _adaptionLeds, value);
|
||||
}
|
||||
|
||||
public AdaptionLed? SelectedLed
|
||||
{
|
||||
get => _selectedLed;
|
||||
set => RaiseAndSetIfChanged(ref _selectedLed, value);
|
||||
}
|
||||
|
||||
public SingleLedAdaptionHint SingleLedAdaptionHint { get; }
|
||||
}
|
||||
|
||||
public class AdaptionLed
|
||||
{
|
||||
public AdaptionLed(LedId led)
|
||||
{
|
||||
Value = led;
|
||||
Description = led.ToString();
|
||||
}
|
||||
|
||||
public LedId Value { get; }
|
||||
public string Description { get; }
|
||||
}
|
||||
@ -34,37 +34,34 @@
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
|
||||
<Border Grid.Row="1" Classes="card" Margin="0 15">
|
||||
<Panel>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden" IsVisible="{CompiledBinding AdaptionHints.Count}">
|
||||
<ItemsControl ItemsSource="{CompiledBinding AdaptionHints}" Classes="adaption-hints">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Spacing="10" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Classes="card-condensed">
|
||||
<ContentControl Content="{CompiledBinding}"></ContentControl>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
<Panel Grid.Row="1" Classes="card" Margin="0 15">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden" IsVisible="{CompiledBinding AdaptionHints.Count}">
|
||||
<ItemsControl ItemsSource="{CompiledBinding AdaptionHints}" Classes="adaption-hints">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Spacing="5" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Classes="card-condensed">
|
||||
<ContentControl Content="{CompiledBinding}"></ContentControl>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
|
||||
<StackPanel IsVisible="{CompiledBinding !AdaptionHints.Count}" VerticalAlignment="Center" HorizontalAlignment="Center">
|
||||
<avalonia:MaterialIcon Kind="AlertCircleOutline" HorizontalAlignment="Center" Width="48" Height="48" />
|
||||
<TextBlock Classes="h4" TextAlignment="Center" TextWrapping="Wrap">
|
||||
You haven't set up any adaption hints
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextAlignment="Center" TextWrapping="Wrap">
|
||||
Artemis will attempt to directly map the LEDs of this layer to different surfaces but results may vary.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
|
||||
</Border>
|
||||
<StackPanel IsVisible="{CompiledBinding !AdaptionHints.Count}" VerticalAlignment="Center" HorizontalAlignment="Center">
|
||||
<avalonia:MaterialIcon Kind="AlertCircleOutline" HorizontalAlignment="Center" Width="48" Height="48" />
|
||||
<TextBlock Classes="h4" TextAlignment="Center" TextWrapping="Wrap">
|
||||
You haven't set up any adaption hints
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextAlignment="Center" TextWrapping="Wrap">
|
||||
Artemis will attempt to directly map the LEDs of this layer to different surfaces but results may vary.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
|
||||
<Grid Grid.Row="2" ColumnDefinitions="*,Auto">
|
||||
<Button Grid.Row="0" Grid.Column="0" Command="{CompiledBinding AutoDetermineHints}">Auto-determine hints</Button>
|
||||
@ -87,6 +84,11 @@
|
||||
<avalonia:MaterialIcon Kind="Keyboard" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Single LED hint" Command="{CompiledBinding AddSingleLedHint}">
|
||||
<MenuItem.Icon>
|
||||
<avalonia:MaterialIcon Kind="LedVariantOn" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</MenuFlyout>
|
||||
</DropDownButton.Flyout>
|
||||
Add hint
|
||||
|
||||
@ -66,6 +66,12 @@ public class LayerHintsDialogViewModel : DialogViewModelBase<bool>
|
||||
{
|
||||
Layer.Adapter.Add(new KeyboardSectionAdaptionHint());
|
||||
}
|
||||
|
||||
public void AddSingleLedHint()
|
||||
{
|
||||
Layer.Adapter.Add(new SingleLedAdaptionHint());
|
||||
}
|
||||
|
||||
|
||||
public void RemoveAdaptionHint(IAdaptionHint hint)
|
||||
{
|
||||
@ -79,6 +85,7 @@ public class LayerHintsDialogViewModel : DialogViewModelBase<bool>
|
||||
CategoryAdaptionHint categoryAdaptionHint => _vmFactory.CategoryAdaptionHintViewModel(Layer, categoryAdaptionHint),
|
||||
DeviceAdaptionHint deviceAdaptionHint => _vmFactory.DeviceAdaptionHintViewModel(Layer, deviceAdaptionHint),
|
||||
KeyboardSectionAdaptionHint keyboardSectionAdaptionHint => _vmFactory.KeyboardSectionAdaptionHintViewModel(Layer, keyboardSectionAdaptionHint),
|
||||
SingleLedAdaptionHint singleLedAdaptionHint => _vmFactory.SingleLedAdaptionHintViewModel(Layer, singleLedAdaptionHint),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(hint))
|
||||
};
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ public class FolderTreeItemViewModel : TreeItemViewModel
|
||||
IProfileEditorService profileEditorService,
|
||||
IRgbService rgbService,
|
||||
IProfileEditorVmFactory profileEditorVmFactory)
|
||||
: base(parent, folder, windowService, profileEditorService, profileEditorVmFactory)
|
||||
: base(parent, folder, windowService, rgbService, profileEditorService, profileEditorVmFactory)
|
||||
{
|
||||
_rgbService = rgbService;
|
||||
Folder = folder;
|
||||
|
||||
@ -22,7 +22,7 @@ public class LayerTreeItemViewModel : TreeItemViewModel
|
||||
IProfileEditorService profileEditorService,
|
||||
IRgbService rgbService,
|
||||
IProfileEditorVmFactory profileEditorVmFactory)
|
||||
: base(parent, layer, windowService, profileEditorService, profileEditorVmFactory)
|
||||
: base(parent, layer, windowService, rgbService, profileEditorService, profileEditorVmFactory)
|
||||
{
|
||||
_rgbService = rgbService;
|
||||
Layer = layer;
|
||||
|
||||
@ -119,6 +119,11 @@
|
||||
<avalonia:MaterialIcon Kind="Magic" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Apply adaption hints" Command="{CompiledBinding ApplyAdaptionHints}">
|
||||
<MenuItem.Icon>
|
||||
<avalonia:MaterialIcon Kind="CogPlay" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="-" />
|
||||
<MenuItem Header="Duplicate" Command="{CompiledBinding Duplicate}" InputGesture="Ctrl+D">
|
||||
<MenuItem.Icon>
|
||||
|
||||
@ -7,6 +7,7 @@ using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.DryIoc.Factories;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Artemis.UI.Shared.Services.ProfileEditor;
|
||||
@ -22,8 +23,8 @@ public class ProfileTreeViewModel : TreeItemViewModel
|
||||
private ObservableAsPropertyHelper<bool>? _keyBindingsEnabled;
|
||||
private TreeItemViewModel? _selectedChild;
|
||||
|
||||
public ProfileTreeViewModel(IWindowService windowService, IProfileEditorService profileEditorService, IProfileEditorVmFactory profileEditorVmFactory)
|
||||
: base(null, null, windowService, profileEditorService, profileEditorVmFactory)
|
||||
public ProfileTreeViewModel(IWindowService windowService, IRgbService rgbService, IProfileEditorService profileEditorService, IProfileEditorVmFactory profileEditorVmFactory)
|
||||
: base(null, null, windowService, rgbService, profileEditorService, profileEditorVmFactory)
|
||||
{
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
|
||||
@ -5,8 +5,10 @@ using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.DryIoc.Factories;
|
||||
using Artemis.UI.Extensions;
|
||||
using Artemis.UI.Screens.ProfileEditor.ProfileTree.ContentDialogs;
|
||||
@ -26,6 +28,7 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase
|
||||
{
|
||||
private readonly IProfileEditorVmFactory _profileEditorVmFactory;
|
||||
private readonly IWindowService _windowService;
|
||||
private readonly IRgbService _rgbService;
|
||||
protected readonly IProfileEditorService ProfileEditorService;
|
||||
private bool _canPaste;
|
||||
private RenderProfileElement? _currentProfileElement;
|
||||
@ -38,11 +41,13 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase
|
||||
protected TreeItemViewModel(TreeItemViewModel? parent,
|
||||
ProfileElement? profileElement,
|
||||
IWindowService windowService,
|
||||
IRgbService rgbService,
|
||||
IProfileEditorService profileEditorService,
|
||||
IProfileEditorVmFactory profileEditorVmFactory)
|
||||
{
|
||||
ProfileEditorService = profileEditorService;
|
||||
_windowService = windowService;
|
||||
_rgbService = rgbService;
|
||||
_profileEditorVmFactory = profileEditorVmFactory;
|
||||
|
||||
Parent = parent;
|
||||
@ -51,6 +56,7 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase
|
||||
AddLayer = ReactiveCommand.Create(ExecuteAddLayer);
|
||||
AddFolder = ReactiveCommand.Create(ExecuteAddFolder);
|
||||
OpenAdaptionHints = ReactiveCommand.CreateFromTask(ExecuteOpenAdaptionHints, this.WhenAnyValue(vm => vm.ProfileElement).Select(p => p is Layer));
|
||||
ApplyAdaptionHints = ReactiveCommand.Create(ExecuteApplyAdaptionHints, this.WhenAnyValue(vm => vm.ProfileElement).Select(p => p is Layer));
|
||||
Rename = ReactiveCommand.CreateFromTask(ExecuteRename);
|
||||
Delete = ReactiveCommand.Create(ExecuteDelete);
|
||||
Duplicate = ReactiveCommand.CreateFromTask(ExecuteDuplicate);
|
||||
@ -109,6 +115,7 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase
|
||||
public ReactiveCommand<Unit, Unit> AddLayer { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddFolder { get; }
|
||||
public ReactiveCommand<Unit, Unit> OpenAdaptionHints { get; }
|
||||
public ReactiveCommand<Unit, Unit> ApplyAdaptionHints { get; }
|
||||
public ReactiveCommand<Unit, Unit> Rename { get; }
|
||||
public ReactiveCommand<Unit, Unit> Duplicate { get; }
|
||||
public ReactiveCommand<Unit, Unit> Copy { get; }
|
||||
@ -254,6 +261,14 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase
|
||||
await _windowService.ShowDialogAsync<LayerHintsDialogViewModel, bool>(layer);
|
||||
await ProfileEditorService.SaveProfileAsync();
|
||||
}
|
||||
|
||||
private void ExecuteApplyAdaptionHints()
|
||||
{
|
||||
if (ProfileElement is not Layer layer)
|
||||
return;
|
||||
|
||||
ProfileEditorService.ExecuteCommand(new ApplyAdaptionHints(layer, _rgbService.EnabledDevices.ToList()));
|
||||
}
|
||||
|
||||
private async void UpdateCanPaste(bool isFlyoutOpen)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user