mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
UI - Added keyboard layout selection UI
This commit is contained in:
parent
ea1633c322
commit
46d3a288e9
@ -306,7 +306,7 @@ namespace Artemis.Core
|
||||
{
|
||||
// Take out invalid file name chars, may not be perfect but neither are you
|
||||
string fileName = System.IO.Path.GetInvalidFileNameChars().Aggregate(RgbDevice.DeviceInfo.Model, (current, c) => current.Replace(c, '-'));
|
||||
if (RgbDevice is IKeyboard)
|
||||
if (RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Keyboard)
|
||||
fileName = $"{fileName}-{PhysicalLayout.ToString().ToUpper()}";
|
||||
if (includeExtension)
|
||||
fileName = $"{fileName}.xml";
|
||||
@ -388,9 +388,10 @@ namespace Artemis.Core
|
||||
|
||||
private void ApplyKeyboardLayout()
|
||||
{
|
||||
if (!(RgbDevice is IKeyboard keyboard))
|
||||
if (RgbDevice.DeviceInfo.DeviceType != RGBDeviceType.Keyboard)
|
||||
return;
|
||||
|
||||
IKeyboard keyboard = (IKeyboard) RgbDevice;
|
||||
// If supported, detect the device layout so that we can load the correct one
|
||||
if (DeviceProvider.CanDetectLogicalLayout)
|
||||
LogicalLayout = DeviceProvider.GetLogicalLayout(keyboard);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using RGB.NET.Core;
|
||||
|
||||
|
||||
@ -12,9 +12,12 @@ namespace Artemis.UI.Shared
|
||||
{
|
||||
internal class DeviceVisualizerLed
|
||||
{
|
||||
private const byte Dimmed = 100;
|
||||
private const byte NonDimmed = 255;
|
||||
|
||||
private SolidColorBrush? _renderColorBrush;
|
||||
private Color _renderColor;
|
||||
|
||||
|
||||
public DeviceVisualizerLed(ArtemisLed led)
|
||||
{
|
||||
Led = led;
|
||||
@ -49,6 +52,7 @@ namespace Artemis.UI.Shared
|
||||
byte b = Led.RgbLed.Color.GetB();
|
||||
|
||||
_renderColor.A = (byte)(isDimmed ? 100 : 255);
|
||||
_renderColor.A = isDimmed ? Dimmed : NonDimmed;
|
||||
_renderColor.R = r;
|
||||
_renderColor.G = g;
|
||||
_renderColor.B = b;
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
Text="{Binding Text}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 8 0 0">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="16">
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Focusable="False"
|
||||
IsCancel="True"
|
||||
|
||||
@ -126,6 +126,11 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Cursors\aero_rotate.cur" />
|
||||
<Resource Include="Resources\Images\PhysicalLayouts\abnt.png" />
|
||||
<Resource Include="Resources\Images\PhysicalLayouts\ansi.png" />
|
||||
<Resource Include="Resources\Images\PhysicalLayouts\iso.png" />
|
||||
<Resource Include="Resources\Images\PhysicalLayouts\jis.png" />
|
||||
<Resource Include="Resources\Images\PhysicalLayouts\ks.png" />
|
||||
<Resource Include="Resources\Images\Sidebar\sidebar-header.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -306,6 +311,11 @@
|
||||
<None Remove="Resources\Fonts\RobotoMono-Regular.ttf" />
|
||||
<None Remove="Resources\Images\Logo\bow.svg" />
|
||||
<None Remove="Resources\Images\Logo\logo-512.ico" />
|
||||
<None Remove="Resources\Images\PhysicalLayouts\abnt.png" />
|
||||
<None Remove="Resources\Images\PhysicalLayouts\ansi.png" />
|
||||
<None Remove="Resources\Images\PhysicalLayouts\iso.png" />
|
||||
<None Remove="Resources\Images\PhysicalLayouts\jis.png" />
|
||||
<None Remove="Resources\Images\PhysicalLayouts\ks.png" />
|
||||
<None Remove="Resources\Images\Sidebar\sidebar-header.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
BIN
src/Artemis.UI/Resources/Images/PhysicalLayouts/abnt.png
Normal file
BIN
src/Artemis.UI/Resources/Images/PhysicalLayouts/abnt.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
BIN
src/Artemis.UI/Resources/Images/PhysicalLayouts/ansi.png
Normal file
BIN
src/Artemis.UI/Resources/Images/PhysicalLayouts/ansi.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
BIN
src/Artemis.UI/Resources/Images/PhysicalLayouts/iso.png
Normal file
BIN
src/Artemis.UI/Resources/Images/PhysicalLayouts/iso.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
BIN
src/Artemis.UI/Resources/Images/PhysicalLayouts/jis.png
Normal file
BIN
src/Artemis.UI/Resources/Images/PhysicalLayouts/jis.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
BIN
src/Artemis.UI/Resources/Images/PhysicalLayouts/ks.png
Normal file
BIN
src/Artemis.UI/Resources/Images/PhysicalLayouts/ks.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
@ -27,10 +27,12 @@
|
||||
<TextBlock Grid.Column="0">
|
||||
This image shows what is being rendered and dispatched to RGB.NET
|
||||
</TextBlock>
|
||||
<TextBlock Grid.Column="1" HorizontalAlignment="Right" Margin="0,0,5,0" FontWeight="Bold">
|
||||
FPS:
|
||||
<TextBlock Grid.Column="1" HorizontalAlignment="Right" Margin="0,0,5,0">
|
||||
<Run Text="FPS: "></Run>
|
||||
<Run FontWeight="Bold" Text="{Binding CurrentFps}"></Run>
|
||||
<Run Text=" at "></Run>
|
||||
<Run Text="{Binding RenderWidth}"/><Run Text="x"></Run><Run Text="{Binding RenderHeight}"/>
|
||||
</TextBlock>
|
||||
<TextBlock Grid.Column="2" HorizontalAlignment="Right" Text="{Binding CurrentFps}" />
|
||||
</Grid>
|
||||
|
||||
<materialDesign:Card Grid.Row="2" Margin="0,5,0,0" Background="{StaticResource Checkerboard}">
|
||||
|
||||
@ -15,6 +15,8 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
private readonly ICoreService _coreService;
|
||||
private double _currentFps;
|
||||
private ImageSource _currentFrame;
|
||||
private int _renderWidth;
|
||||
private int _renderHeight;
|
||||
|
||||
public RenderDebugViewModel(ICoreService coreService)
|
||||
{
|
||||
@ -34,6 +36,18 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
set => SetAndNotify(ref _currentFps, value);
|
||||
}
|
||||
|
||||
public int RenderWidth
|
||||
{
|
||||
get => _renderWidth;
|
||||
set => SetAndNotify(ref _renderWidth, value);
|
||||
}
|
||||
|
||||
public int RenderHeight
|
||||
{
|
||||
get => _renderHeight;
|
||||
set => SetAndNotify(ref _renderHeight, value);
|
||||
}
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
_coreService.FrameRendered += CoreServiceOnFrameRendered;
|
||||
@ -56,6 +70,8 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
return;
|
||||
|
||||
SKImageInfo bitmapInfo = e.Texture.Bitmap.Info;
|
||||
RenderHeight = bitmapInfo.Height;
|
||||
RenderWidth = bitmapInfo.Width;
|
||||
|
||||
if (!(CurrentFrame is WriteableBitmap writeableBitmap) ||
|
||||
writeableBitmap.Width != bitmapInfo.Width ||
|
||||
|
||||
@ -0,0 +1,187 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.Settings.Device.DeviceLayoutDialogView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Artemis.UI.Screens.Settings.Device"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:mde="https://spiegelp.github.io/MaterialDesignExtensions/winfx/xaml"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="1200" d:DesignWidth="1200"
|
||||
d:DataContext="{d:DesignInstance local:DeviceLayoutDialogViewModel}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0" Margin="16" Width="1200" Height="800" Visibility="{Binding SelectPhysicalLayout, Converter={x:Static s:BoolToVisibilityConverter.Instance}}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0">
|
||||
<TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}" TextWrapping="Wrap" Margin="0 0 0 20">
|
||||
Select a physical layout
|
||||
</TextBlock>
|
||||
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}"
|
||||
Foreground="{DynamicResource MaterialDesignBodyLight}"
|
||||
TextWrapping="Wrap">
|
||||
Artemis couldn't automatically determine the physical layout of your <Run Text="{Binding Device.RgbDevice.DeviceInfo.DeviceName, Mode=OneWay}" />. <LineBreak />
|
||||
In order for Artemis to know which keys are on your keyboard and where they're located, select the matching layout below.
|
||||
<LineBreak />
|
||||
<LineBreak />
|
||||
P.S. Don't worry about missing special keys like num keys/function keys or macro keys, they aren't important here.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<ScrollViewer Grid.Row="1" Margin="0 25">
|
||||
<WrapPanel HorizontalAlignment="Center">
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Foreground="{DynamicResource MaterialDesignBody}"
|
||||
Command="{s:Action ApplyPhysicalLayout}"
|
||||
CommandParameter="ISO"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0 0 10 0"
|
||||
Width="550"
|
||||
Height="280">
|
||||
<StackPanel>
|
||||
<Image Source="/Resources/Images/PhysicalLayouts/iso.png" />
|
||||
<TextBlock TextAlignment="Center" Style="{StaticResource MaterialDesignHeadline6TextBlock}" Margin="0 10 0 0">
|
||||
ISO
|
||||
</TextBlock>
|
||||
<TextBlock TextAlignment="Center" Style="{StaticResource MaterialDesignBody2TextBlock}" TextWrapping="Wrap">
|
||||
Most commonly used in the EU (tall enter)
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Foreground="{DynamicResource MaterialDesignBody}"
|
||||
Command="{s:Action ApplyPhysicalLayout}"
|
||||
CommandParameter="ANSI"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0 0 10 0"
|
||||
Width="550"
|
||||
Height="280">
|
||||
<StackPanel>
|
||||
<Image Source="/Resources/Images/PhysicalLayouts/ansi.png" />
|
||||
<TextBlock TextAlignment="Center" Style="{StaticResource MaterialDesignHeadline6TextBlock}" Margin="0 10 0 0">
|
||||
ANSI
|
||||
</TextBlock>
|
||||
<TextBlock TextAlignment="Center" Style="{StaticResource MaterialDesignBody2TextBlock}" TextWrapping="Wrap">
|
||||
Most commonly used in the US (short enter)
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Foreground="{DynamicResource MaterialDesignBody}"
|
||||
Command="{s:Action ApplyPhysicalLayout}"
|
||||
CommandParameter="ABNT"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0 0 10 0"
|
||||
Width="550"
|
||||
Height="280">
|
||||
<StackPanel>
|
||||
<Image Source="/Resources/Images/PhysicalLayouts/abnt.png" />
|
||||
<TextBlock TextAlignment="Center" Style="{StaticResource MaterialDesignHeadline6TextBlock}" Margin="0 10 0 0">
|
||||
ABNT
|
||||
</TextBlock>
|
||||
<TextBlock TextAlignment="Center" Style="{StaticResource MaterialDesignBody2TextBlock}" TextWrapping="Wrap">
|
||||
Most commonly used in Brazil/Portugal (based on ISO)
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Foreground="{DynamicResource MaterialDesignBody}"
|
||||
Command="{s:Action ApplyPhysicalLayout}"
|
||||
CommandParameter="KS"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0 0 10 0"
|
||||
Width="550"
|
||||
Height="280">
|
||||
<StackPanel>
|
||||
<Image Source="/Resources/Images/PhysicalLayouts/ks.png" />
|
||||
<TextBlock TextAlignment="Center" Style="{StaticResource MaterialDesignHeadline6TextBlock}" Margin="0 10 0 0">
|
||||
KS
|
||||
</TextBlock>
|
||||
<TextBlock TextAlignment="Center" Style="{StaticResource MaterialDesignBody2TextBlock}" TextWrapping="Wrap">
|
||||
Most commonly used in South Korea
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Foreground="{DynamicResource MaterialDesignBody}"
|
||||
Command="{s:Action ApplyPhysicalLayout}"
|
||||
CommandParameter="JIS"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0 0 10 0"
|
||||
Width="550"
|
||||
Height="280">
|
||||
<StackPanel>
|
||||
<Image Source="/Resources/Images/PhysicalLayouts/jis.png" />
|
||||
<TextBlock TextAlignment="Center" Style="{StaticResource MaterialDesignHeadline6TextBlock}" Margin="0 10 0 0">
|
||||
JIS
|
||||
</TextBlock>
|
||||
<TextBlock TextAlignment="Center" Style="{StaticResource MaterialDesignBody2TextBlock}" TextWrapping="Wrap">
|
||||
Most commonly used in Japan (based on ISO)
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
</WrapPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Grid.Row="0" Margin="16" Width="800" Visibility="{Binding SelectPhysicalLayout, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}}">
|
||||
<StackPanel>
|
||||
<TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}" TextWrapping="Wrap" Margin="0 0 0 20">
|
||||
Select a logical layout
|
||||
</TextBlock>
|
||||
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}"
|
||||
Foreground="{DynamicResource MaterialDesignBodyLight}"
|
||||
TextWrapping="Wrap">
|
||||
Artemis couldn't automatically determine the logical layout of your <Run Text="{Binding Device.RgbDevice.DeviceInfo.DeviceName, Mode=OneWay}" />. <LineBreak /><LineBreak />
|
||||
While not as important as the physical layout, setting the correct logical layout will allow Artemis to show the right keycaps (if a matching layout file is present)
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<mde:Autocomplete Style="{StaticResource MaterialDesignAutocomplete}"
|
||||
AutocompleteSource="{Binding Path=AutocompleteSource}"
|
||||
SearchOnInitialFocus="True"
|
||||
SelectedItem="{Binding SelectedRegion, Mode=TwoWay}"
|
||||
Hint="Select a logical layout"
|
||||
Margin="0,16,0,0"
|
||||
FontSize="15"
|
||||
Foreground="{DynamicResource MaterialDesignBody}"
|
||||
Background="{DynamicResource MaterialDesignPaper}">
|
||||
<mde:Autocomplete.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock FontSize="14" VerticalAlignment="Center">
|
||||
<Run Text="{Binding EnglishName, Mode=OneWay}" />
|
||||
(<Run FontWeight="SemiBold" Text="{Binding TwoLetterISORegionName, Mode=OneWay}" />)
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</mde:Autocomplete.ItemTemplate>
|
||||
</mde:Autocomplete>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="16">
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Focusable="False"
|
||||
IsCancel="True"
|
||||
Command="{s:Action Cancel}"
|
||||
Content="CANCEL" />
|
||||
<Button x:Name="ConfirmButton"
|
||||
Style="{StaticResource MaterialDesignFlatButton}"
|
||||
IsDefault="True"
|
||||
Focusable="True"
|
||||
Command="{s:Action Confirm}"
|
||||
Content="CONFIRM" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
||||
@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using MaterialDesignExtensions.Model;
|
||||
|
||||
namespace Artemis.UI.Screens.Settings.Device
|
||||
{
|
||||
public class DeviceLayoutDialogViewModel : DialogViewModelBase
|
||||
{
|
||||
private readonly IRgbService _rgbService;
|
||||
private bool _selectPhysicalLayout;
|
||||
private RegionInfoAutocompleteSource _autocompleteSource;
|
||||
private RegionInfo _selectedRegion;
|
||||
|
||||
public DeviceLayoutDialogViewModel(ArtemisDevice device, IRgbService rgbService)
|
||||
{
|
||||
_rgbService = rgbService;
|
||||
Device = device;
|
||||
SelectPhysicalLayout = !device.DeviceProvider.CanDetectPhysicalLayout;
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
AutocompleteSource = new RegionInfoAutocompleteSource();
|
||||
SelectedRegion = AutocompleteSource.Regions.FirstOrDefault(r => r.TwoLetterISORegionName == Device.LogicalLayout ||
|
||||
r.TwoLetterISORegionName == "US" && Device.LogicalLayout == "NA");
|
||||
});
|
||||
}
|
||||
|
||||
public ArtemisDevice Device { get; }
|
||||
|
||||
public RegionInfoAutocompleteSource AutocompleteSource
|
||||
{
|
||||
get => _autocompleteSource;
|
||||
set => SetAndNotify(ref _autocompleteSource, value);
|
||||
}
|
||||
|
||||
public RegionInfo SelectedRegion
|
||||
{
|
||||
get => _selectedRegion;
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _selectedRegion, value);
|
||||
NotifyOfPropertyChange(nameof(CanConfirm));
|
||||
}
|
||||
}
|
||||
|
||||
public bool SelectPhysicalLayout
|
||||
{
|
||||
get => _selectPhysicalLayout;
|
||||
set => SetAndNotify(ref _selectPhysicalLayout, value);
|
||||
}
|
||||
|
||||
public bool CanConfirm => SelectedRegion != null;
|
||||
|
||||
public void ApplyPhysicalLayout(string physicalLayout)
|
||||
{
|
||||
Device.PhysicalLayout = Enum.Parse<KeyboardLayoutType>(physicalLayout);
|
||||
|
||||
_rgbService.SaveDevice(Device);
|
||||
_rgbService.ApplyBestDeviceLayout(Device);
|
||||
|
||||
SelectPhysicalLayout = false;
|
||||
}
|
||||
|
||||
private void ApplyLogicalLayout(string logicalLayout)
|
||||
{
|
||||
Device.LogicalLayout = logicalLayout;
|
||||
|
||||
_rgbService.SaveDevice(Device);
|
||||
_rgbService.ApplyBestDeviceLayout(Device);
|
||||
}
|
||||
|
||||
public void Confirm()
|
||||
{
|
||||
if (!CanConfirm || Session == null || Session.IsEnded)
|
||||
return;
|
||||
|
||||
ApplyLogicalLayout(SelectedRegion.TwoLetterISORegionName);
|
||||
Session?.Close(true);
|
||||
}
|
||||
}
|
||||
|
||||
public class RegionInfoAutocompleteSource : IAutocompleteSource<RegionInfo>
|
||||
{
|
||||
public List<RegionInfo> Regions { get; set; }
|
||||
|
||||
public RegionInfoAutocompleteSource()
|
||||
{
|
||||
Regions = CultureInfo.GetCultures(CultureTypes.SpecificCultures).ToList()
|
||||
.Select(c => new RegionInfo(c.LCID))
|
||||
.GroupBy(r => r.EnglishName)
|
||||
.Select(g => g.First())
|
||||
.OrderBy(r => r.EnglishName)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
IEnumerable<RegionInfo> IAutocompleteSource<RegionInfo>.Search(string searchTerm)
|
||||
{
|
||||
if (searchTerm == null)
|
||||
return Regions;
|
||||
|
||||
searchTerm = searchTerm.ToLower();
|
||||
return Regions.Where(r => r.EnglishName.ToLower().Contains(searchTerm) ||
|
||||
r.NativeName.ToLower().Contains(searchTerm) ||
|
||||
r.TwoLetterISORegionName.ToLower().Contains(searchTerm));
|
||||
}
|
||||
|
||||
public IEnumerable Search(string searchTerm)
|
||||
{
|
||||
if (searchTerm == null)
|
||||
return Regions;
|
||||
|
||||
searchTerm = searchTerm.ToLower();
|
||||
return Regions.Where(r => r.EnglishName.ToLower().Contains(searchTerm) ||
|
||||
r.NativeName.ToLower().Contains(searchTerm) ||
|
||||
r.TwoLetterISORegionName.ToLower().Contains(searchTerm));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,7 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
||||
DisplayName = "INFO";
|
||||
}
|
||||
|
||||
public bool IsKeyboard => Device.RgbDevice is IKeyboard;
|
||||
public bool IsKeyboard => Device.RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Keyboard;
|
||||
public ArtemisDevice Device { get; }
|
||||
}
|
||||
}
|
||||
@ -174,6 +174,10 @@
|
||||
</StackPanel>
|
||||
</materialDesign:HintAssist.Hint>
|
||||
</TextBox>
|
||||
|
||||
<Button Style="{StaticResource MaterialDesignRaisedButton}" Margin="0 8 8 0" Command="{s:Action SelectPhysicalLayout}">
|
||||
SELECT PHYSICAL LAYOUT (PLACEHOLDER)
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Buttons -->
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System.ComponentModel;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
@ -15,6 +16,7 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
||||
{
|
||||
private readonly ICoreService _coreService;
|
||||
private readonly IMessageService _messageService;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly IRgbService _rgbService;
|
||||
private float _blueScale;
|
||||
private SKColor _currentColor;
|
||||
@ -33,11 +35,13 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
||||
ICoreService coreService,
|
||||
IRgbService rgbService,
|
||||
IMessageService messageService,
|
||||
IDialogService dialogService,
|
||||
IModelValidator<DevicePropertiesTabViewModel> validator) : base(validator)
|
||||
{
|
||||
_coreService = coreService;
|
||||
_rgbService = rgbService;
|
||||
_messageService = messageService;
|
||||
_dialogService = dialogService;
|
||||
|
||||
Device = device;
|
||||
DisplayName = "PROPERTIES";
|
||||
@ -126,6 +130,11 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SelectPhysicalLayout()
|
||||
{
|
||||
await _dialogService.ShowDialog<DeviceLayoutDialogViewModel>(new Dictionary<string, object> {{"device", Device}});
|
||||
}
|
||||
|
||||
public async Task Apply()
|
||||
{
|
||||
await ValidateAsync();
|
||||
@ -167,12 +176,21 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
||||
_initialGreenScale = Device.GreenScale;
|
||||
_initialBlueScale = Device.BlueScale;
|
||||
CurrentColor = SKColors.White;
|
||||
|
||||
_coreService.FrameRendering += OnFrameRendering;
|
||||
Device.PropertyChanged += DeviceOnPropertyChanged;
|
||||
|
||||
base.OnActivate();
|
||||
}
|
||||
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
_coreService.FrameRendering -= OnFrameRendering;
|
||||
Device.PropertyChanged -= DeviceOnPropertyChanged;
|
||||
|
||||
base.OnDeactivate();
|
||||
}
|
||||
|
||||
#region Event handlers
|
||||
|
||||
private void DeviceOnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
|
||||
@ -84,7 +84,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Devices
|
||||
|
||||
public void ViewProperties()
|
||||
{
|
||||
_windowManager.ShowDialog(_deviceDebugVmFactory.DeviceDialogViewModel(Device));
|
||||
_windowManager.ShowWindow(_deviceDebugVmFactory.DeviceDialogViewModel(Device));
|
||||
}
|
||||
private async Task UpdateIsDeviceEnabled(bool value)
|
||||
{
|
||||
|
||||
@ -241,7 +241,7 @@ namespace Artemis.UI.Screens.SurfaceEditor
|
||||
|
||||
public void ViewProperties(ArtemisDevice device)
|
||||
{
|
||||
_windowManager.ShowDialog(_deviceDebugVmFactory.DeviceDialogViewModel(device));
|
||||
_windowManager.ShowWindow(_deviceDebugVmFactory.DeviceDialogViewModel(device));
|
||||
}
|
||||
|
||||
public async Task DetectInput(ArtemisDevice device)
|
||||
|
||||
80
src/Artemis.UI/Services/DeviceLayoutService.cs
Normal file
80
src/Artemis.UI/Services/DeviceLayoutService.cs
Normal file
@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Screens.Settings.Device;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Layout;
|
||||
using KeyboardLayoutType = Artemis.Core.KeyboardLayoutType;
|
||||
|
||||
namespace Artemis.UI.Services
|
||||
{
|
||||
public class DeviceLayoutService : IDeviceLayoutService
|
||||
{
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly IRgbService _rgbService;
|
||||
private readonly IWindowService _windowService;
|
||||
private readonly IMessageService _messageService;
|
||||
private readonly List<ArtemisDevice> _ignoredDevices;
|
||||
|
||||
public DeviceLayoutService(IDialogService dialogService, IRgbService rgbService, IWindowService windowService, IMessageService messageService)
|
||||
{
|
||||
_dialogService = dialogService;
|
||||
_rgbService = rgbService;
|
||||
_windowService = windowService;
|
||||
_messageService = messageService;
|
||||
_ignoredDevices = new List<ArtemisDevice>();
|
||||
|
||||
rgbService.DeviceAdded += RgbServiceOnDeviceAdded;
|
||||
windowService.MainWindowOpened += async (_, _) => await RequestLayoutInput();
|
||||
}
|
||||
|
||||
private async Task RequestLayoutInput()
|
||||
{
|
||||
List<ArtemisDevice> devices = _rgbService.Devices.Where(device => DeviceNeedsLayout(device) && !_ignoredDevices.Contains(device)).ToList();
|
||||
foreach (ArtemisDevice artemisDevice in devices)
|
||||
{
|
||||
bool configure = await _dialogService.ShowConfirmDialog(
|
||||
"Device requires layout info",
|
||||
$"Artemis could not detect the layout of your {artemisDevice.RgbDevice.DeviceInfo.DeviceName}. Please configure out manually",
|
||||
"Configure",
|
||||
"Ignore for now"
|
||||
);
|
||||
|
||||
if (!configure)
|
||||
{
|
||||
_ignoredDevices.Add(artemisDevice);
|
||||
continue;
|
||||
}
|
||||
|
||||
await _dialogService.ShowDialog<DeviceLayoutDialogViewModel>(new Dictionary<string, object> {{"device", artemisDevice}});
|
||||
}
|
||||
}
|
||||
|
||||
private void RgbServiceOnDeviceAdded(object sender, DeviceEventArgs e)
|
||||
{
|
||||
if (!DeviceNeedsLayout(e.Device))
|
||||
return;
|
||||
|
||||
if (!_windowService.IsMainWindowOpen)
|
||||
{
|
||||
_messageService.ShowNotification("New device detected", "Detected a new device that needs layout setup", PackIconKind.Keyboard);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private bool DeviceNeedsLayout(ArtemisDevice d) => d.RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Keyboard &&
|
||||
d.LogicalLayout == null ||
|
||||
d.PhysicalLayout == KeyboardLayoutType.Unknown &&
|
||||
(!d.DeviceProvider.CanDetectLogicalLayout || !d.DeviceProvider.CanDetectPhysicalLayout);
|
||||
}
|
||||
|
||||
public interface IDeviceLayoutService : IArtemisUIService
|
||||
{
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user