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

Undid UI freeze fix since it broker other things :c, implemented dynamic property extra options

This commit is contained in:
SpoinkyNL 2016-05-19 22:31:24 +02:00
parent 028d22bc7b
commit a9373012a8
8 changed files with 191 additions and 124 deletions

View File

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing;
using System.Threading;
using System.Windows;
using Artemis.Properties;
@ -9,7 +8,6 @@ using CUE.NET.Brushes;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Devices.Keyboard;
using CUE.NET.Exceptions;
using Point = System.Drawing.Point;
namespace Artemis.KeyboardProviders.Corsair
{

View File

@ -1,12 +1,16 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing;
using System.Windows;
using Size = System.Windows.Size;
namespace Artemis.KeyboardProviders
{
public abstract class KeyboardProvider
public abstract class KeyboardProvider : DeviceProvider
{
protected KeyboardProvider()
{
Type = DeviceType.Keyboard;
}
public string Name { get; set; }
public int Height { get; set; }
public int Width { get; set; }
@ -15,7 +19,8 @@ namespace Artemis.KeyboardProviders
public PreviewSettings PreviewSettings { get; set; }
public abstract bool CanEnable();
public abstract void Enable(); // TODO: This should be done in a background thread with a callback mechanism as it causes UI lag
public abstract void Enable();
// TODO: This should be done in a background thread with a callback mechanism as it causes UI lag
public abstract void Disable();
public abstract void DrawBitmap(Bitmap bitmap);
@ -34,6 +39,18 @@ namespace Artemis.KeyboardProviders
public Rect KeyboardRectangle(int scale) => new Rect(new Size(Width*scale, Height*scale));
}
public class DeviceProvider
{
public DeviceType Type { get; set; }
}
public enum DeviceType
{
Keyboard,
Mouse,
Headset
}
public struct PreviewSettings
{
public int Width { get; set; }

View File

@ -1,11 +1,9 @@
using System;
using System.Drawing;
using System.Threading;
using System.Timers;
using Artemis.Events;
using Caliburn.Micro;
using Ninject.Extensions.Logging;
using Timer = System.Timers.Timer;
namespace Artemis.Managers
{
@ -110,52 +108,49 @@ namespace Artemis.Managers
return;
}
if (!Monitor.TryEnter(_keyboardManager.ActiveKeyboard))
return;
// Skip frame if effect is still initializing
if (renderEffect.Initialized == false)
return;
// ApplyProperties the current effect
if (renderEffect.Initialized)
renderEffect.Update();
// Get ActiveEffect's bitmap
var bitmap = renderEffect.Initialized
? renderEffect.GenerateBitmap()
: null;
// Draw enabled overlays on top
foreach (var overlayModel in _effectManager.EnabledOverlays)
lock (_keyboardManager.ActiveKeyboard)
{
overlayModel.Update();
bitmap = bitmap != null
? overlayModel.GenerateBitmap(bitmap)
: overlayModel.GenerateBitmap();
// Skip frame if effect is still initializing
if (renderEffect.Initialized == false)
return;
// ApplyProperties the current effect
if (renderEffect.Initialized)
renderEffect.Update();
// Get ActiveEffect's bitmap
var bitmap = renderEffect.Initialized
? renderEffect.GenerateBitmap()
: null;
// Draw enabled overlays on top
foreach (var overlayModel in _effectManager.EnabledOverlays)
{
overlayModel.Update();
bitmap = bitmap != null
? overlayModel.GenerateBitmap(bitmap)
: overlayModel.GenerateBitmap();
}
if (bitmap == null)
return;
// Fill the bitmap's background with black to avoid trailing colors on some keyboards
var fixedBmp = new Bitmap(bitmap.Width, bitmap.Height);
using (var g = Graphics.FromImage(fixedBmp))
{
g.Clear(Color.Black);
g.DrawImage(bitmap, 0, 0);
}
bitmap = fixedBmp;
// If it exists, send bitmap to the device
_keyboardManager.ActiveKeyboard?.DrawBitmap(bitmap);
// debugging TODO: Disable when window isn't shown (in Debug VM, or get rid of it, w/e)
_events.PublishOnUIThread(new ChangeBitmap(bitmap));
}
if (bitmap == null)
return;
// Fill the bitmap's background with black to avoid trailing colors on some keyboards
var fixedBmp = new Bitmap(bitmap.Width, bitmap.Height);
using (var g = Graphics.FromImage(fixedBmp))
{
g.Clear(Color.Black);
g.DrawImage(bitmap, 0, 0);
}
bitmap = fixedBmp;
// If it exists, send bitmap to the device
_keyboardManager.ActiveKeyboard?.DrawBitmap(bitmap);
// debugging TODO: Disable when window isn't shown (in Debug VM, or get rid of it, w/e)
_events.PublishOnUIThread(new ChangeBitmap(bitmap));
if (_keyboardManager.ActiveKeyboard != null)
Monitor.Exit(_keyboardManager.ActiveKeyboard);
}
}
}

View File

@ -45,31 +45,49 @@ namespace Artemis.Models.Profiles.Properties
ApplyPercentageOfProperty(dataModel, properties);
}
private void ApplyPercentageOf(IGameDataModel dataModel, KeyboardPropertiesModel properties,
double percentageSource)
private void ApplyPercentageOf(IGameDataModel dataModel, KeyboardPropertiesModel properties, double src)
{
// Property to apply on
var layerProp = properties.GetType().GetProperty(LayerProperty);
// Property to base the percentage upon
var gameProperty = dataModel.GetPropValue<int>(GameProperty);
if (layerProp == null)
if (GameProperty == null)
return;
var percentage = ToDouble(gameProperty)/percentageSource;
var appliedValue = percentage*(double) layerProp.GetValue(properties);
var gameProperty = dataModel.GetPropValue<int>(GameProperty);
var percentage = ToDouble(gameProperty)/src;
// Opacity requires some special treatment as it causes an exception if it's < 0.0 or > 1.0
if (LayerProperty == "Opacity")
{
appliedValue = percentage;
if (appliedValue < 0.0)
appliedValue = 0.0;
if (appliedValue > 1.0)
appliedValue = 1.0;
}
if (LayerProperty == "Width")
ApplyWidth(properties, percentage);
else if (LayerProperty == "Height")
ApplyHeight(properties, percentage);
else if (LayerProperty == "Opacity")
ApplyOpacity(properties, percentage);
}
layerProp.SetValue(properties, appliedValue);
private void ApplyWidth(KeyboardPropertiesModel properties, double percentage)
{
var newWidth = percentage * properties.Width;
var difference = properties.Width - newWidth;
properties.Width = newWidth;
// Apply the right to left option
if (LayerPropertyOptions == LayerPropertyOptions.RightToLeft)
properties.X = properties.X + difference;
}
private void ApplyHeight(KeyboardPropertiesModel properties, double percentage)
{
properties.Height = percentage*properties.Height;
}
private void ApplyOpacity(KeyboardPropertiesModel properties, double percentage)
{
properties.Opacity = percentage*properties.Opacity;
if (properties.Opacity < 0.0)
properties.Opacity = 0.0;
if (properties.Opacity > 1.0)
properties.Opacity = 1.0;
// Apply the inverse/decrease option
if (LayerPropertyOptions == LayerPropertyOptions.Decrease)
properties.Opacity = 1.0 - properties.Opacity;
}
private void ApplyPercentageOfProperty(IGameDataModel dataModel, KeyboardPropertiesModel properties)

View File

@ -61,6 +61,9 @@ namespace Artemis.Utilities
/// <returns></returns>
public static T GetPropValue<T>(this object obj, string name)
{
if (name == null)
return default(T);
var retVal = GetPropValue(obj, name);
if (retVal == null)
return default(T);

View File

@ -9,11 +9,10 @@ namespace Artemis.ViewModels.LayerEditor
public sealed class LayerDynamicPropertiesViewModel : PropertyChangedBase
{
private readonly string _property;
private BindableCollection<string> _layerPropertyOptions;
private BindableCollection<LayerPropertyOptions> _layerPropertyOptions;
private LayerPropertyType _layerPropertyType;
private string _name;
private DynamicPropertiesModel _proposed;
private string _selectedLayerPropertyOption;
private GeneralHelpers.PropertyCollection _selectedSource;
private GeneralHelpers.PropertyCollection _selectedTarget;
private bool _sourcesIsVisible;
@ -36,32 +35,8 @@ namespace Artemis.ViewModels.LayerEditor
else
GeneralHelpers.CopyProperties(Proposed, original);
Name = property + ":";
var nullTarget = new GeneralHelpers.PropertyCollection {Display = "None"};
Targets = new BindableCollection<GeneralHelpers.PropertyCollection> {nullTarget};
Targets.AddRange(dataModelProps.Where(p => p.Type == "Int32"));
Sources = new BindableCollection<GeneralHelpers.PropertyCollection>();
Sources.AddRange(dataModelProps.Where(p => p.Type == "Int32"));
UserSourceIsVisible = LayerPropertyType == LayerPropertyType.PercentageOf;
SourcesIsVisible = LayerPropertyType == LayerPropertyType.PercentageOfProperty;
PropertyChanged += OnPropertyChanged;
// Preselect according to the model
SelectedTarget = dataModelProps.FirstOrDefault(p => p.Path == Proposed.GameProperty);
SelectedSource = dataModelProps.FirstOrDefault(p => p.Path == Proposed.PercentageProperty);
LayerPropertyType = Proposed.LayerPropertyType;
// Set up a default for SelectedTarget if it was null
if (SelectedTarget.Display == null)
SelectedTarget = nullTarget;
if (property == "Width")
LayerPropertyOptions = new BindableCollection<string> { "Left to right", "Right to left" };
else if (property == "Height")
LayerPropertyOptions = new BindableCollection<string> { "Downwards", "Upwards" };
else if (property == "Opacity")
LayerPropertyOptions = new BindableCollection<string> { "Increase", "Decrease" };
SetupControls(dataModelProps);
}
public LayerPropertyType LayerPropertyType
@ -120,7 +95,7 @@ namespace Artemis.ViewModels.LayerEditor
}
}
public BindableCollection<string> LayerPropertyOptions
public BindableCollection<LayerPropertyOptions> LayerPropertyOptions
{
get { return _layerPropertyOptions; }
set
@ -131,17 +106,6 @@ namespace Artemis.ViewModels.LayerEditor
}
}
public string SelectedLayerPropertyOption
{
get { return _selectedLayerPropertyOption; }
set
{
if (value == _selectedLayerPropertyOption) return;
_selectedLayerPropertyOption = value;
NotifyOfPropertyChange(() => SelectedLayerPropertyOption);
}
}
public bool SourcesIsVisible
{
get { return _sourcesIsVisible; }
@ -170,13 +134,70 @@ namespace Artemis.ViewModels.LayerEditor
public BindableCollection<GeneralHelpers.PropertyCollection> Sources { get; set; }
private void SetupControls(BindableCollection<GeneralHelpers.PropertyCollection> dataModelProps)
{
Name = _property + ":";
// Populate target combobox
Targets = new BindableCollection<GeneralHelpers.PropertyCollection>
{
new GeneralHelpers.PropertyCollection {Display = "None"}
};
Targets.AddRange(dataModelProps.Where(p => p.Type == "Int32"));
// Populate sources combobox
Sources = new BindableCollection<GeneralHelpers.PropertyCollection>();
Sources.AddRange(dataModelProps.Where(p => p.Type == "Int32"));
// Preselect according to the model
SelectedTarget = dataModelProps.FirstOrDefault(p => p.Path == Proposed.GameProperty);
SelectedSource = dataModelProps.FirstOrDefault(p => p.Path == Proposed.PercentageProperty);
LayerPropertyType = Proposed.LayerPropertyType;
// Populate the extra options combobox
switch (_property)
{
case "Width":
LayerPropertyOptions = new BindableCollection<LayerPropertyOptions>
{
Models.Profiles.Properties.LayerPropertyOptions.LeftToRight,
Models.Profiles.Properties.LayerPropertyOptions.RightToLeft
};
break;
case "Height":
LayerPropertyOptions = new BindableCollection<LayerPropertyOptions>
{
Models.Profiles.Properties.LayerPropertyOptions.Downwards,
Models.Profiles.Properties.LayerPropertyOptions.Upwards
};
break;
case "Opacity":
LayerPropertyOptions = new BindableCollection<LayerPropertyOptions>
{
Models.Profiles.Properties.LayerPropertyOptions.Increase,
Models.Profiles.Properties.LayerPropertyOptions.Decrease
};
break;
}
UserSourceIsVisible = LayerPropertyType == LayerPropertyType.PercentageOf;
SourcesIsVisible = LayerPropertyType == LayerPropertyType.PercentageOfProperty;
// Set up a default for SelectedTarget if it was null
if (SelectedTarget.Display == null)
SelectedTarget = Targets.FirstOrDefault();
// Set up a default for the extra option if it fell outside the range
if (!LayerPropertyOptions.Contains(Proposed.LayerPropertyOptions))
Proposed.LayerPropertyOptions = LayerPropertyOptions.FirstOrDefault();
}
private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "SelectedTarget")
Proposed.GameProperty = SelectedTarget.Path;
if (e.PropertyName == "SelectedSource")
else if (e.PropertyName == "SelectedSource")
Proposed.PercentageProperty = SelectedSource.Path;
if (e.PropertyName == "LayerPropertyType")
else if (e.PropertyName == "LayerPropertyType")
{
Proposed.LayerPropertyType = LayerPropertyType;
UserSourceIsVisible = LayerPropertyType == LayerPropertyType.PercentageOf;

View File

@ -248,7 +248,7 @@ namespace Artemis.ViewModels
/// </summary>
public void AddLayer()
{
if (_selectedProfile == null)
if (SelectedProfile == null)
return;
var layer = SelectedProfile.AddLayer();
@ -262,7 +262,7 @@ namespace Artemis.ViewModels
/// </summary>
public void RemoveLayer()
{
if (_selectedProfile == null || _selectedLayer == null)
if (SelectedProfile == null || _selectedLayer == null)
return;
SelectedProfile.Layers.Remove(_selectedLayer);
@ -352,6 +352,9 @@ namespace Artemis.ViewModels
/// <param name="e"></param>
public void MouseUpKeyboardPreview(MouseButtonEventArgs e)
{
if (SelectedProfile == null)
return;
var timeSinceDown = DateTime.Now - _downTime;
if (!(timeSinceDown.TotalMilliseconds < 500))
return;
@ -376,6 +379,9 @@ namespace Artemis.ViewModels
/// <param name="e"></param>
public void MouseMoveKeyboardPreview(MouseEventArgs e)
{
if (SelectedProfile == null)
return;
var pos = e.GetPosition((Image) e.OriginalSource);
var x = pos.X/((double) ActiveKeyboard.PreviewSettings.Width/ActiveKeyboard.Width);
var y = pos.Y/((double) ActiveKeyboard.PreviewSettings.Height/ActiveKeyboard.Height);
@ -406,7 +412,7 @@ namespace Artemis.ViewModels
private void InvokeUpdateKeyboardPreview(object sender, ElapsedEventArgs e)
{
Application.Current.Dispatcher.Invoke(UpdateKeyboardPreview, DispatcherPriority.ContextIdle);
Application.Current.Dispatcher.Invoke(UpdateKeyboardPreview, DispatcherPriority.ContextIdle);
}
/// <summary>
@ -414,9 +420,12 @@ namespace Artemis.ViewModels
/// </summary>
public void UpdateKeyboardPreview()
{
if (_selectedProfile == null || ActiveKeyboard == null)
if (SelectedProfile == null || ActiveKeyboard == null)
{
KeyboardPreview = new DrawingImage();
return;
}
var keyboardRect = ActiveKeyboard.KeyboardRectangle(4);
var visual = new DrawingVisual();
using (var drawingContext = visual.RenderOpen())

View File

@ -12,9 +12,7 @@
<UserControl.Resources>
<utilities:EnumDescriptionConverter x:Key="HEnumDescriptionConverter" />
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="DynamicPropertyValues">
<ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="DynamicPropertyValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="properties:LayerPropertyType" />
</ObjectDataProvider.MethodParameters>
@ -89,7 +87,15 @@
</StackPanel>
<!-- Extra option -->
<ComboBox Grid.Column="4" x:Name="LayerPropertyOptions" VerticalAlignment="Center" Margin="10,0"
IsEnabled="{Binding Path=ControlsEnabled}" />
<ComboBox SelectedItem="{Binding Path=Proposed.LayerPropertyOptions}" Grid.Column="4"
ItemsSource="{Binding Path=LayerPropertyOptions}"
Margin="10,0" VerticalAlignment="Center" Height="22"
IsEnabled="{Binding Path=ControlsEnabled}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource HEnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</UserControl>