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

Made devices aware of the plugin that loaded them

Fixed Corsair LL Fans layout
Expanded render events
Added identify option to device settings, must move this to be reusable though
This commit is contained in:
SpoinkyNL 2019-11-03 11:38:28 +01:00
parent ae41c6cac3
commit 05eed5ba00
23 changed files with 400 additions and 229 deletions

View File

@ -144,7 +144,8 @@
<Compile Include="Constants.cs" />
<Compile Include="Events\DeviceConfigurationEventArgs.cs" />
<Compile Include="Events\DeviceEventArgs.cs" />
<Compile Include="Events\FrameEventArgs.cs" />
<Compile Include="Events\FrameRenderedEventArgs.cs" />
<Compile Include="Events\FrameRenderingEventArgs.cs" />
<Compile Include="Exceptions\ArtemisCoreException.cs" />
<Compile Include="Extensions\DirectoryInfoExtensions.cs" />
<Compile Include="Extensions\RgbColorExtensions.cs" />

View File

@ -0,0 +1,18 @@
using System;
using System.Drawing;
using RGB.NET.Core;
namespace Artemis.Core.Events
{
public class FrameRenderedEventArgs : EventArgs
{
public FrameRenderedEventArgs(Bitmap bitmap, RGBSurface rgbSurface)
{
Bitmap = bitmap;
RgbSurface = rgbSurface;
}
public Bitmap Bitmap { get; }
public RGBSurface RgbSurface { get; }
}
}

View File

@ -6,9 +6,9 @@ using RGB.NET.Core;
namespace Artemis.Core.Events
{
public class FrameEventArgs : EventArgs
public class FrameRenderingEventArgs : EventArgs
{
public FrameEventArgs(List<Module> modules, Bitmap bitmap, double deltaTime, RGBSurface rgbSurface)
public FrameRenderingEventArgs(List<Module> modules, Bitmap bitmap, double deltaTime, RGBSurface rgbSurface)
{
Modules = modules;
Bitmap = bitmap;

View File

@ -1,18 +1,23 @@
using System;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using Artemis.Core.Extensions;
using Artemis.Core.Plugins.Abstract;
using Artemis.Storage.Entities;
using RGB.NET.Core;
using Point = RGB.NET.Core.Point;
using Rectangle = System.Drawing.Rectangle;
namespace Artemis.Core.Models.Surface
{
public class Device
{
internal Device(IRGBDevice rgbDevice, Surface surface)
internal Device(IRGBDevice rgbDevice, Plugin plugin, Surface surface)
{
RgbDevice = rgbDevice;
Plugin = plugin;
Surface = surface;
Configuration = new DeviceEntity();
Leds = rgbDevice.Select(l => new DeviceLed(l, this)).ToList().AsReadOnly();
@ -24,9 +29,10 @@ namespace Artemis.Core.Models.Surface
CalculateRenderRectangle();
}
internal Device(IRGBDevice rgbDevice, Surface surface, DeviceEntity configuration)
internal Device(IRGBDevice rgbDevice, Plugin plugin, Surface surface, DeviceEntity configuration)
{
RgbDevice = rgbDevice;
Plugin = plugin;
Surface = surface;
Configuration = configuration;
Leds = rgbDevice.Select(l => new DeviceLed(l, this)).ToList().AsReadOnly();
@ -36,8 +42,10 @@ namespace Artemis.Core.Models.Surface
}
public Rectangle RenderRectangle { get; private set; }
public GraphicsPath RenderPath { get; private set; }
public IRGBDevice RgbDevice { get; private set; }
public Plugin Plugin { get; }
public Surface Surface { get; private set; }
public DeviceEntity Configuration { get; private set; }
public ReadOnlyCollection<DeviceLed> Leds { get; set; }
@ -93,6 +101,10 @@ namespace Artemis.Core.Models.Surface
foreach (var led in Leds)
led.CalculateRenderRectangle();
var path = new GraphicsPath();
path.AddRectangles(Leds.Select(l => l.AbsoluteRenderRectangle).ToArray());
RenderPath = path;
}
internal void Destroy()

View File

@ -33,16 +33,6 @@ namespace Artemis.Core.Models.Surface
Name = surfaceEntity.Name;
IsActive = surfaceEntity.IsActive;
Devices = new List<Device>();
if (surfaceEntity.DeviceEntities == null)
return;
foreach (var position in surfaceEntity.DeviceEntities)
{
var device = rgbSurface.Devices.FirstOrDefault(d => d.GetDeviceHashCode() == position.DeviceHashCode);
if (device != null)
Devices.Add(new Device(device, this, position));
}
}
public RGBSurface RgbSurface { get; }

View File

@ -1,4 +1,6 @@
using Artemis.Core.Plugins.Models;
using System;
using Artemis.Core.Plugins.Models;
using RGB.NET.Core;
namespace Artemis.Core.Plugins.Abstract
{
@ -8,8 +10,11 @@ namespace Artemis.Core.Plugins.Abstract
/// </summary>
public abstract class Device : Plugin
{
protected Device(PluginInfo pluginInfo) : base(pluginInfo)
public IRGBDeviceProvider DeviceProvider { get; }
protected Device(PluginInfo pluginInfo, IRGBDeviceProvider deviceProvider) : base(pluginInfo)
{
DeviceProvider = deviceProvider ?? throw new ArgumentNullException(nameof(deviceProvider));
}
}
}

View File

@ -12,7 +12,7 @@ namespace Artemis.Core.Plugins.Abstract
{
internal Plugin(PluginInfo pluginInfo)
{
PluginInfo = pluginInfo;
PluginInfo = pluginInfo ?? throw new ArgumentNullException(nameof(pluginInfo));
}
public PluginInfo PluginInfo { get; internal set; }

View File

@ -29,7 +29,7 @@ namespace Artemis.Core.Services
_rgbService = rgbService;
_surfaceService = surfaceService;
_rgbService.Surface.Updating += SurfaceOnUpdating;
_rgbService.Surface.Updated += SurfaceOnUpdated;
Task.Run(Initialize);
}
@ -87,7 +87,7 @@ namespace Artemis.Core.Services
module.Render(args.DeltaTime, _surfaceService.ActiveSurface, g);
}
OnFrameRendered(new FrameEventArgs(modules, _rgbService.GraphicsDecorator.GetBitmap(), args.DeltaTime, _rgbService.Surface));
OnFrameRendering(new FrameRenderingEventArgs(modules, _rgbService.GraphicsDecorator.GetBitmap(), args.DeltaTime, _rgbService.Surface));
}
catch (Exception e)
{
@ -95,10 +95,16 @@ namespace Artemis.Core.Services
}
}
private void SurfaceOnUpdated(UpdatedEventArgs args)
{
OnFrameRendered(new FrameRenderedEventArgs(_rgbService.GraphicsDecorator.GetBitmap(), _rgbService.Surface));
}
#region Events
public event EventHandler Initialized;
public event EventHandler<FrameEventArgs> FrameRendered;
public event EventHandler<FrameRenderingEventArgs> FrameRendering;
public event EventHandler<FrameRenderedEventArgs> FrameRendered;
private void OnInitialized()
{
@ -108,7 +114,12 @@ namespace Artemis.Core.Services
#endregion
protected virtual void OnFrameRendered(FrameEventArgs e)
protected virtual void OnFrameRendering(FrameRenderingEventArgs e)
{
FrameRendering?.Invoke(this, e);
}
protected virtual void OnFrameRendered(FrameRenderedEventArgs e)
{
FrameRendered?.Invoke(this, e);
}

View File

@ -16,8 +16,13 @@ namespace Artemis.Core.Services.Interfaces
event EventHandler Initialized;
/// <summary>
/// Occurs whenever a frame has finished rendering
/// Occurs whenever a frame is rendering, after modules have rendered
/// </summary>
event EventHandler<FrameEventArgs> FrameRendered;
event EventHandler<FrameRenderingEventArgs> FrameRendering;
/// <summary>
/// Occurs whenever a frame is finished rendering and processed by RGB.NET
/// </summary>
event EventHandler<FrameRenderedEventArgs> FrameRendered;
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using Artemis.Core.Events;
using Artemis.Core.Plugins.Abstract;
using Artemis.Core.Plugins.Models;
using RGB.NET.Core;
namespace Artemis.Core.Services.Interfaces
{
@ -91,5 +92,7 @@ namespace Artemis.Core.Services.Interfaces
event EventHandler<PluginEventArgs> PluginDisabled;
#endregion
Plugin GetDevicePlugin(IRGBDevice device);
}
}

View File

@ -14,6 +14,7 @@ using Newtonsoft.Json;
using Ninject;
using Ninject.Extensions.ChildKernel;
using Ninject.Parameters;
using RGB.NET.Core;
namespace Artemis.Core.Services
{
@ -282,6 +283,11 @@ namespace Artemis.Core.Services
}
}
public Plugin GetDevicePlugin(IRGBDevice rgbDevice)
{
return GetPluginsOfType<Device>().First(d => d.DeviceProvider.Devices.Contains(rgbDevice));
}
public void Dispose()
{
UnloadPlugins();

View File

@ -18,15 +18,17 @@ namespace Artemis.Core.Services.Storage
{
private readonly ILogger _logger;
private readonly IRgbService _rgbService;
private readonly IPluginService _pluginService;
private readonly List<Surface> _surfaceConfigurations;
private readonly ISurfaceRepository _surfaceRepository;
private readonly PluginSetting<double> _renderScaleSetting;
internal SurfaceService(ILogger logger, ISurfaceRepository surfaceRepository, IRgbService rgbService, ISettingsService settingsService)
internal SurfaceService(ILogger logger, ISurfaceRepository surfaceRepository, IRgbService rgbService, IPluginService pluginService, ISettingsService settingsService)
{
_logger = logger;
_surfaceRepository = surfaceRepository;
_rgbService = rgbService;
_pluginService = pluginService;
_surfaceConfigurations = new List<Surface>();
_renderScaleSetting = settingsService.GetSetting("RenderScale", 1.0);
@ -36,8 +38,6 @@ namespace Artemis.Core.Services.Storage
_renderScaleSetting.SettingChanged += RenderScaleSettingOnSettingChanged;
}
public Surface ActiveSurface { get; private set; }
public ReadOnlyCollection<Surface> SurfaceConfigurations => _surfaceConfigurations.AsReadOnly();
@ -48,7 +48,10 @@ namespace Artemis.Core.Services.Storage
// Add all current devices
foreach (var rgbDevice in _rgbService.LoadedDevices)
configuration.Devices.Add(new Device(rgbDevice, configuration));
{
var plugin = _pluginService.GetDevicePlugin(rgbDevice);
configuration.Devices.Add(new Device(rgbDevice, plugin, configuration));
}
lock (_surfaceConfigurations)
{
@ -142,7 +145,6 @@ namespace Artemis.Core.Services.Storage
{
foreach (var surfaceConfiguration in SurfaceConfigurations)
surfaceConfiguration.UpdateScale(_renderScaleSetting.Value);
}
#endregion
@ -156,6 +158,15 @@ namespace Artemis.Core.Services.Storage
{
// Create the surface entity
var surfaceConfiguration = new Surface(_rgbService.Surface, surfaceEntity, _renderScaleSetting.Value);
foreach (var position in surfaceEntity.DeviceEntities)
{
var device = _rgbService.Surface.Devices.FirstOrDefault(d => d.GetDeviceHashCode() == position.DeviceHashCode);
if (device != null)
{
var plugin = _pluginService.GetDevicePlugin(device);
surfaceConfiguration.Devices.Add(new Device(device, plugin, surfaceConfiguration, position));
}
}
// Finally, add the surface config to the collection
lock (_surfaceConfigurations)
@ -193,7 +204,10 @@ namespace Artemis.Core.Services.Storage
// Find an existing device config and use that
var existingDeviceConfig = surface.SurfaceEntity.DeviceEntities.FirstOrDefault(d => d.DeviceHashCode == deviceHashCode);
if (existingDeviceConfig != null)
device = new Device(rgbDevice,surface, existingDeviceConfig);
{
var plugin = _pluginService.GetDevicePlugin(rgbDevice);
device = new Device(rgbDevice, plugin, surface, existingDeviceConfig);
}
// Fall back on creating a new device
else
{
@ -202,7 +216,8 @@ namespace Artemis.Core.Services.Storage
rgbDevice.DeviceInfo,
deviceHashCode
);
device = new Device(rgbDevice, surface);
var plugin = _pluginService.GetDevicePlugin(rgbDevice);
device = new Device(rgbDevice, plugin, surface);
}
surface.Devices.Add(device);

View File

@ -13,7 +13,7 @@ namespace Artemis.Plugins.Devices.Corsair
{
private readonly IRgbService _rgbService;
public CorsairDevice(PluginInfo pluginInfo, IRgbService rgbService) : base(pluginInfo)
public CorsairDevice(PluginInfo pluginInfo, IRgbService rgbService) : base(pluginInfo, CorsairDeviceProvider.Instance)
{
_rgbService = rgbService;
}
@ -23,7 +23,7 @@ namespace Artemis.Plugins.Devices.Corsair
PathHelper.ResolvingAbsolutePath += ResolveCorsairPath;
CorsairDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "CUESDK.dll"));
CorsairDeviceProvider.PossibleX86NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x86", "CUESDK.dll"));
_rgbService.AddDeviceProvider(CorsairDeviceProvider.Instance);
_rgbService.AddDeviceProvider(DeviceProvider);
}
private void ResolveCorsairPath(object sender, ResolvePathEventArgs e)

View File

@ -32,22 +32,43 @@
<X>-</X>
<Y>-</Y>
</Led>
<Led Id="Fan5">
<Shape>Circle</Shape>
<X>59.5</X>
<Y>0</Y>
</Led>
<Led Id="Fan16">
<Shape>Circle</Shape>
<X>90.5</X>
<Y>7.6</Y>
</Led>
<Led Id="Fan15">
<Shape>Circle</Shape>
<X>113</X>
<X>7.9</X>
<Y>29.8</Y>
</Led>
<Led Id="Fan14">
<Led Id="Fan6">
<Shape>Circle</Shape>
<X>0.4</X>
<Y>59.9</Y>
</Led>
<Led Id="Fan7">
<Shape>Circle</Shape>
<X>8</X>
<Y>90.4</Y>
</Led>
<Led Id="Fan8">
<Shape>Circle</Shape>
<X>30.7</X>
<Y>113.1</Y>
</Led>
<Led Id="Fan9">
<Shape>Circle</Shape>
<X>59.5</X>
<Y>120.5</Y>
</Led>
<Led Id="Fan10">
<Shape>Circle</Shape>
<X>90.5</X>
<Y>113.1</Y>
</Led>
<Led Id="Fan11">
<Shape>Circle</Shape>
<X>113</X>
<Y>90.4</Y>
</Led>
<Led Id="Fan12">
<Shape>Circle</Shape>
<X>120.5</X>
<Y>59.9</Y>
@ -55,39 +76,19 @@
<Led Id="Fan13">
<Shape>Circle</Shape>
<X>113</X>
<Y>90.4</Y>
</Led>
<Led Id="Fan12">
<Shape>Circle</Shape>
<X>90.5</X>
<Y>113.1</Y>
</Led>
<Led Id="Fan11">
<Shape>Circle</Shape>
<X>59.5</X>
<Y>120.5</Y>
</Led>
<Led Id="Fan10">
<Shape>Circle</Shape>
<X>30.7</X>
<Y>113.1</Y>
</Led>
<Led Id="Fan9">
<Shape>Circle</Shape>
<X>8</X>
<Y>90.4</Y>
</Led>
<Led Id="Fan8">
<Shape>Circle</Shape>
<X>0.4</X>
<Y>59.9</Y>
</Led>
<Led Id="Fan7">
<Shape>Circle</Shape>
<X>7.9</X>
<Y>29.8</Y>
</Led>
<Led Id="Fan6">
<Led Id="Fan14">
<Shape>Circle</Shape>
<X>90.5</X>
<Y>7.6</Y>
</Led>
<Led Id="Fan15">
<Shape>Circle</Shape>
<X>59.5</X>
<Y>0</Y>
</Led>
<Led Id="Fan16">
<Shape>Circle</Shape>
<X>28</X>
<Y>7.6</Y>

View File

@ -1,17 +1,20 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using Artemis.Core.Models.Surface;
using Artemis.Core.Plugins.Abstract;
using Artemis.Core.Plugins.Models;
using Artemis.Plugins.Modules.General.ViewModels;
using Stylet;
using Device = Artemis.Core.Models.Surface.Device;
namespace Artemis.Plugins.Modules.General
{
public class GeneralModule : Module
{
private readonly PluginSettings _settings;
private readonly ColorBlend _rainbowColorBlend;
public GeneralModule(PluginInfo pluginInfo, PluginSettings settings) : base(pluginInfo)
{
@ -24,9 +27,20 @@ namespace Artemis.Plugins.Modules.General
Hues = new int[1000];
for (var i = 0; i < 1000; i++)
Hues[i] = ColorHelpers.GetRandomHue();
_rainbowColorBlend = new ColorBlend(9);
for (var i = 0; i < 9; i++)
{
_rainbowColorBlend.Positions[i] = i / 8f;
if (i != 8)
_rainbowColorBlend.Colors[i] = ColorHelpers.ColorFromHSV(i * 32, 1, 1);
else
_rainbowColorBlend.Colors[i] = ColorHelpers.ColorFromHSV(0, 1, 1);
}
}
public int[] Hues { get; set; }
public int MovePercentage { get; set; }
public override void EnablePlugin()
{
@ -44,15 +58,20 @@ namespace Artemis.Plugins.Modules.General
if (Hues[i] > 360)
Hues[i] = 0;
}
MovePercentage++;
if (MovePercentage > 100)
MovePercentage = 0;
}
public override void Render(double deltaTime, Surface surface, Graphics graphics)
{
// Per-device coloring, slower
RenderPerDevice(surface, graphics);
// RenderPerDevice(surface, graphics);
// Per-LED coloring, slowest
// RenderPerLed(surface, graphics);
RenderPerLed(surface, graphics);
}
public void RenderFullSurface(Surface surface, Graphics graphics)
@ -61,13 +80,33 @@ namespace Artemis.Plugins.Modules.General
public void RenderPerDevice(Surface surface, Graphics graphics)
{
var index = 0;
foreach (var device in surface.Devices)
{
graphics.FillRectangle(new SolidBrush(ColorHelpers.ColorFromHSV(Hues[index], 1, 1)), device.RenderRectangle);
index++;
using (var gradient = RenderGradientForDevice(device))
{
using (var brush = new TextureBrush(gradient, WrapMode.Tile))
{
brush.TranslateTransform((int) Math.Round(device.RenderRectangle.Width / 100.0 * MovePercentage), 0);
graphics.FillPath(brush, device.RenderPath);
}
}
}
}
private Image RenderGradientForDevice(Device device)
{
var brush = new LinearGradientBrush(device.RenderRectangle, Color.Black, Color.Black, 0, false)
{
InterpolationColors = _rainbowColorBlend
};
var bitmap = new Bitmap(device.RenderRectangle.Width, device.RenderRectangle.Height);
using (var g = Graphics.FromImage(bitmap))
{
g.FillRectangle(brush, 0, 0, device.RenderRectangle.Width, device.RenderRectangle.Height);
}
return bitmap;
}
public void RenderPerLed(Surface surface, Graphics graphics)
{

View File

@ -184,7 +184,7 @@
<Compile Include="ViewModels\Screens\DebugViewModel.cs" />
<Compile Include="ViewModels\Screens\SurfaceEditorViewModel.cs" />
<Compile Include="ViewModels\Interfaces\IEditorViewModel.cs" />
<Compile Include="ViewModels\Controls\Settings\RgbDeviceSettingsViewModel.cs" />
<Compile Include="ViewModels\Controls\Settings\DeviceSettingsViewModel.cs" />
<Compile Include="ViewModels\Interfaces\IHomeViewModel.cs" />
<Compile Include="ViewModels\Interfaces\IScreenViewModel.cs" />
<Compile Include="ViewModels\Screens\HomeViewModel.cs" />
@ -235,7 +235,7 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\Controls\Settings\RgbDeviceSettingsView.xaml">
<Page Include="Views\Controls\Settings\DeviceSettingsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>

View File

@ -0,0 +1,76 @@
using System.Diagnostics;
using System.Drawing;
using System.Threading.Tasks;
using Artemis.Core.Events;
using Artemis.Core.Models.Surface;
using Artemis.Core.Services.Interfaces;
using Humanizer;
namespace Artemis.UI.ViewModels.Controls.Settings
{
public class DeviceSettingsViewModel
{
private readonly ICoreService _coreService;
public DeviceSettingsViewModel(Device device, ICoreService coreService)
{
_coreService = coreService;
Device = device;
Type = Device.RgbDevice.DeviceInfo.DeviceType.ToString().Humanize();
Name = Device.RgbDevice.DeviceInfo.Model;
Manufacturer = Device.RgbDevice.DeviceInfo.Manufacturer;
IsDeviceEnabled = true;
}
public Device Device { get; }
public string Type { get; set; }
public string Name { get; set; }
public string Manufacturer { get; set; }
public bool IsDeviceEnabled { get; set; }
public void Identify()
{
BlinkDevice(0);
}
private void BlinkDevice(int blinkCount)
{
// Draw a white overlay over the device
void DrawOverlay(object sender, FrameRenderingEventArgs args)
{
using (var g = Graphics.FromImage(args.Bitmap))
{
g.FillPath(new SolidBrush(Color.White), Device.RenderPath);
}
}
_coreService.FrameRendering += DrawOverlay;
// After 200ms, stop drawing the overlay
Task.Run(async () =>
{
await Task.Delay(200);
_coreService.FrameRendering -= DrawOverlay;
if (blinkCount < 5)
{
// After another 200ms, draw the overlay again, repeat six times
await Task.Delay(200);
BlinkDevice(blinkCount + 1);
}
});
}
public void ShowDeviceDebugger()
{
}
public void OpenPluginDirectory()
{
Process.Start(Device.Plugin.PluginInfo.Directory.FullName);
}
}
}

View File

@ -1,25 +0,0 @@
using Humanizer;
using RGB.NET.Core;
namespace Artemis.UI.ViewModels.Controls.Settings
{
public class RgbDeviceSettingsViewModel
{
public IRGBDevice Device { get; }
public RgbDeviceSettingsViewModel(IRGBDevice device)
{
Device = device;
Type = Device.DeviceInfo.DeviceType.ToString().Humanize();
Name = Device.DeviceInfo.Model;
Manufacturer = Device.DeviceInfo.Manufacturer;
Enabled = true;
}
public string Type { get; set; }
public string Name { get; set; }
public string Manufacturer { get; set; }
public bool Enabled { get; set; }
}
}

View File

@ -22,6 +22,7 @@ namespace Artemis.UI.ViewModels.Screens
_rgbService = rgbService;
_coreService.FrameRendered += CoreServiceOnFrameRendered;
_coreService.FrameRendering += CoreServiceOnFrameRendering;
}
public ImageSource CurrentFrame { get; set; }
@ -33,20 +34,25 @@ namespace Artemis.UI.ViewModels.Screens
GC.WaitForPendingFinalizers();
}
private void CoreServiceOnFrameRendered(object sender, FrameEventArgs e)
private void CoreServiceOnFrameRendered(object sender, FrameRenderedEventArgs e)
{
var imageSource = ImageSourceFromBitmap(e.Bitmap);
imageSource.Freeze();
CurrentFps = Math.Round(1.0 / e.DeltaTime, 2);
Execute.OnUIThread(() =>
{
CurrentFrame = imageSource;
});
}
private void CoreServiceOnFrameRendering(object sender, FrameRenderingEventArgs e)
{
CurrentFps = Math.Round(1.0 / e.DeltaTime, 2);
}
protected override void OnClose()
{
_coreService.FrameRendered -= CoreServiceOnFrameRendered;
_coreService.FrameRendering -= CoreServiceOnFrameRendering;
base.OnClose();
}

View File

@ -1,6 +1,7 @@
using Artemis.Core.Events;
using System.Windows.Media;
using Artemis.Core.Services;
using Artemis.Core.Services.Interfaces;
using Artemis.Core.Services.Storage;
using Artemis.UI.ViewModels.Controls.Settings;
using Artemis.UI.ViewModels.Interfaces;
using Ninject;
@ -11,30 +12,42 @@ namespace Artemis.UI.ViewModels.Screens
public class SettingsViewModel : Screen, ISettingsViewModel
{
private readonly IKernel _kernel;
private readonly ICoreService _coreService;
private readonly ISurfaceService _surfaceService;
private readonly IWindowManager _windowManager;
private readonly ISettingsService _settingsService;
public SettingsViewModel(IKernel kernel, IRgbService rgbService, IWindowManager windowManager, ISettingsService settingsService)
public SettingsViewModel(IKernel kernel, ICoreService coreService, ISurfaceService surfaceService, IWindowManager windowManager, ISettingsService settingsService)
{
_kernel = kernel;
_coreService = coreService;
_surfaceService = surfaceService;
_windowManager = windowManager;
DeviceSettingsViewModels = new BindableCollection<RgbDeviceSettingsViewModel>();
foreach (var device in rgbService.LoadedDevices)
DeviceSettingsViewModels.Add(new RgbDeviceSettingsViewModel(device));
_settingsService = settingsService;
rgbService.DeviceLoaded += UpdateDevices;
DeviceSettingsViewModels = new BindableCollection<DeviceSettingsViewModel>();
RenderScale = _settingsService.GetSetting("RenderScale", 1.0).Value;
TargetFrameRate = _settingsService.GetSetting("FrameRate", 25).Value;
}
public BindableCollection<RgbDeviceSettingsViewModel> DeviceSettingsViewModels { get; set; }
public BindableCollection<DeviceSettingsViewModel> DeviceSettingsViewModels { get; set; }
public string Title => "Settings";
public double RenderScale { get; set; }
public int TargetFrameRate { get; set; }
protected override void OnActivate()
{
DeviceSettingsViewModels.Clear();
foreach (var device in _surfaceService.ActiveSurface.Devices)
DeviceSettingsViewModels.Add(new DeviceSettingsViewModel(device, _coreService));
base.OnActivate();
}
public void ShowDebugger()
{
_windowManager.ShowWindow(_kernel.Get<DebugViewModel>());
}
private void UpdateDevices(object sender, DeviceEventArgs deviceEventArgs)
{
DeviceSettingsViewModels.Add(new RgbDeviceSettingsViewModel(deviceEventArgs.Device));
}
}
}

View File

@ -0,0 +1,60 @@
<UserControl x:Class="Artemis.UI.Views.Controls.Settings.DeviceSettingsView"
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:settings="clr-namespace:Artemis.UI.ViewModels.Controls.Settings"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
d:DataContext="{d:DesignInstance settings:DeviceSettingsViewModel}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Button.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.TextBlock.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<materialDesign:Card Width="200">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="140" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Height="140" Width="196" Fill="{DynamicResource MaterialDesignPaper}" />
<Image Grid.Row="0" Source="{Binding Device.RgbDevice.DeviceInfo.Image}" Height="130" Width="190" RenderOptions.BitmapScalingMode="HighQuality" />
<Button Grid.Row="0"
Style="{StaticResource MaterialDesignFloatingActionMiniButton}"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="0 0 16 -20"
ToolTip="Identify"
Command="{s:Action Identify}">
<materialDesign:PackIcon Kind="AlarmLight" />
</Button>
<StackPanel Grid.Row="1" Margin="8 24 8 0">
<TextBlock FontWeight="Bold" Text="{Binding Device.RgbDevice.DeviceInfo.Model}" />
<TextBlock TextWrapping="Wrap" VerticalAlignment="Center">
<Run Text="{Binding Device.RgbDevice.DeviceInfo.Manufacturer, Mode=OneWay}" />
-
<Run Text="{Binding Device.RgbDevice.DeviceInfo.DeviceType, Mode=OneWay}" />
</TextBlock>
</StackPanel>
<StackPanel HorizontalAlignment="Right" Grid.Row="2" Orientation="Horizontal" Margin="8">
<CheckBox Style="{StaticResource MaterialDesignCheckBox}" IsChecked="{Binding IsDeviceEnabled}">
Device enabled
</CheckBox>
<materialDesign:PopupBox Style="{StaticResource MaterialDesignToolPopupBox}" Padding="2 0 2 0">
<StackPanel>
<Button Content="Show device debugger" Command="{s:Action ShowDeviceDebugger}" />
<Button Content="Open plugin directory" Command="{s:Action OpenPluginDirectory}" />
</StackPanel>
</materialDesign:PopupBox>
</StackPanel>
</Grid>
</materialDesign:Card>
</UserControl>

View File

@ -1,94 +0,0 @@
<UserControl x:Class="Artemis.UI.Views.Controls.Settings.RgbDeviceSettingsView"
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:settings="clr-namespace:Artemis.UI.ViewModels.Controls.Settings"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
d:DataContext="{d:DesignInstance settings:RgbDeviceSettingsViewModel}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Button.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.TextBlock.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<materialDesign:Card
Width="200">
<Grid>
<Grid.RowDefinitions>
<RowDefinition
Height="140" />
<RowDefinition
Height="*" />
<RowDefinition
Height="Auto" />
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Height="140" Width="196" Fill="{DynamicResource MaterialDesignPaper}"></Rectangle>
<Image
Grid.Row="0"
Source="{Binding Device.DeviceInfo.Image}"
Height="130"
Width="190" RenderOptions.BitmapScalingMode="HighQuality"/>
<Button
Grid.Row="0"
Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="0 0 16 -20"
ToolTip="Identify"
Command="{s:Action Identity}">
<materialDesign:PackIcon Kind="AlarmLight" />
</Button>
<StackPanel
Grid.Row="1"
Margin="8 24 8 0">
<TextBlock FontWeight="Bold" Text="{Binding Device.DeviceInfo.Model}" />
<TextBlock TextWrapping="Wrap" VerticalAlignment="Center">
<Run Text="{Binding Device.DeviceInfo.Manufacturer, Mode=OneWay}" />
-
<Run Text="{Binding Device.DeviceInfo.DeviceType, Mode=OneWay}" />
</TextBlock>
</StackPanel>
<StackPanel
HorizontalAlignment="Right"
Grid.Row="2"
Orientation="Horizontal"
Margin="8">
<Button
Style="{StaticResource MaterialDesignToolButton}"
Width="30"
Padding="2 0 2 0"
materialDesign:RippleAssist.IsCentered="True">
<materialDesign:PackIcon
Kind="ShareVariant" />
</Button>
<Button
Style="{StaticResource MaterialDesignToolButton}"
Width="30"
Padding="2 0 2 0"
materialDesign:RippleAssist.IsCentered="True">
<materialDesign:PackIcon
Kind="Heart" />
</Button>
<materialDesign:PopupBox
Style="{StaticResource MaterialDesignToolPopupBox}"
Padding="2 0 2 0">
<StackPanel>
<Button
Content="More" />
<Button
Content="Options" />
</StackPanel>
</materialDesign:PopupBox>
</StackPanel>
</Grid>
</materialDesign:Card>
</UserControl>

View File

@ -22,6 +22,35 @@
<TextBlock Style="{StaticResource MaterialDesignHeadlineTextBlock}">General</TextBlock>
<StackPanel>
<TextBlock>General settings like start up with Windows etc.</TextBlock>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Bottom" Grid.Row="0" Grid.Column="0">Render scale</TextBlock>
<Slider Minimum="0.10"
Maximum="1"
TickFrequency="0.05"
Grid.Row="1"
Grid.Column="0"
Style="{StaticResource MaterialDesignDiscreteSlider}"
ToolTip="MaterialDesignDiscreteSlider"
Value="{Binding RenderScale}" />
<TextBlock VerticalAlignment="Bottom" Grid.Row="0" Grid.Column="1">Target framerate</TextBlock>
<Slider Minimum="5"
Maximum="60"
Grid.Row="1"
Grid.Column="1"
Style="{StaticResource MaterialDesignDiscreteSlider}"
ToolTip="MaterialDesignDiscreteSlider"
Value="{Binding TargetFrameRate}" />
</Grid>
<Button Command="{s:Action ShowDebugger}" Style="{StaticResource MaterialDesignRaisedButton}" HorizontalAlignment="Left" Margin="0, 10, 0, 0">
Show debugger
@ -35,7 +64,7 @@
<ItemsControl ItemsSource="{Binding DeviceSettingsViewModels}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>