diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj
index 4919162c0..22a877977 100644
--- a/src/Artemis.Core/Artemis.Core.csproj
+++ b/src/Artemis.Core/Artemis.Core.csproj
@@ -90,8 +90,11 @@
..\packages\Serilog.Enrichers.Demystify.1.0.0-dev-00019\lib\net45\Serilog.Enrichers.Demystify.dll
+
+ ..\packages\Serilog.Sinks.Debug.1.0.1\lib\net46\Serilog.Sinks.Debug.dll
+
- ..\packages\Serilog.Sinks.File.4.0.0\lib\net45\Serilog.Sinks.File.dll
+ ..\packages\Serilog.Sinks.File.4.1.0\lib\net45\Serilog.Sinks.File.dll
..\packages\SkiaSharp.1.68.2-preview.29\lib\net45\SkiaSharp.dll
diff --git a/src/Artemis.Core/Ninject/LoggerProvider.cs b/src/Artemis.Core/Ninject/LoggerProvider.cs
index f279ec5e3..4ba1c8295 100644
--- a/src/Artemis.Core/Ninject/LoggerProvider.cs
+++ b/src/Artemis.Core/Ninject/LoggerProvider.cs
@@ -1,24 +1,30 @@
using Ninject.Activation;
using Serilog;
+using Serilog.Core;
+using Serilog.Events;
namespace Artemis.Core.Ninject
{
internal class LoggerProvider : Provider
{
- private static readonly ILogger _logger = new LoggerConfiguration()
+ internal static readonly LoggingLevelSwitch LoggingLevelSwitch = new LoggingLevelSwitch(LogEventLevel.Verbose);
+
+ private static readonly ILogger Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithDemystifiedStackTraces()
.WriteTo.File("Logs/Artemis log-.txt",
rollingInterval: RollingInterval.Day,
- outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [{SourceContext:l}] {Message:lj}{NewLine}{Exception}")
+ outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}")
+ .WriteTo.Debug()
+ .MinimumLevel.ControlledBy(LoggingLevelSwitch)
.CreateLogger();
protected override ILogger CreateInstance(IContext context)
{
var requestingType = context.Request.ParentContext?.Plan?.Type;
if (requestingType != null)
- return _logger.ForContext(requestingType);
- return _logger;
+ return Logger.ForContext(requestingType);
+ return Logger;
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs
index af70048f2..4fbdecb35 100644
--- a/src/Artemis.Core/Services/CoreService.cs
+++ b/src/Artemis.Core/Services/CoreService.cs
@@ -4,12 +4,15 @@ using System.Threading.Tasks;
using Artemis.Core.Events;
using Artemis.Core.Exceptions;
using Artemis.Core.JsonConverters;
+using Artemis.Core.Ninject;
using Artemis.Core.Plugins.Abstract;
+using Artemis.Core.Plugins.Models;
using Artemis.Core.Services.Interfaces;
using Artemis.Core.Services.Storage.Interfaces;
using Newtonsoft.Json;
using RGB.NET.Core;
using Serilog;
+using Serilog.Events;
using SkiaSharp;
namespace Artemis.Core.Services
@@ -25,16 +28,21 @@ namespace Artemis.Core.Services
private readonly IRgbService _rgbService;
private readonly ISurfaceService _surfaceService;
private List _modules;
+ private PluginSetting _loggingLevel;
- internal CoreService(ILogger logger, IPluginService pluginService, IRgbService rgbService, ISurfaceService surfaceService, IProfileService profileService)
+ internal CoreService(ILogger logger, ISettingsService settingsService, IPluginService pluginService, IRgbService rgbService,
+ ISurfaceService surfaceService, IProfileService profileService)
{
_logger = logger;
_pluginService = pluginService;
_rgbService = rgbService;
_surfaceService = surfaceService;
_profileService = profileService;
+ _loggingLevel = settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information);
+
_rgbService.Surface.Updating += SurfaceOnUpdating;
_rgbService.Surface.Updated += SurfaceOnUpdated;
+ _loggingLevel.SettingChanged += (sender, args) => ApplyLoggingLevel();
_modules = _pluginService.GetPluginsOfType();
_pluginService.PluginEnabled += (sender, args) => _modules = _pluginService.GetPluginsOfType();
@@ -79,6 +87,7 @@ namespace Artemis.Core.Services
throw new ArtemisCoreException("Cannot initialize the core as it is already initialized.");
_logger.Information("Initializing Artemis Core version {version}", typeof(CoreService).Assembly.GetName().Version);
+ ApplyLoggingLevel();
// Initialize the services
await Task.Run(() => _pluginService.CopyBuiltInPlugins());
@@ -95,6 +104,12 @@ namespace Artemis.Core.Services
OnInitialized();
}
+ private void ApplyLoggingLevel()
+ {
+ _logger.Information("Setting logging level to {loggingLevel}", _loggingLevel.Value);
+ LoggerProvider.LoggingLevelSwitch.MinimumLevel = _loggingLevel.Value;
+ }
+
private void SurfaceOnUpdating(UpdatingEventArgs args)
{
try
diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs
index 15ba6c18e..b1a451cae 100644
--- a/src/Artemis.Core/Services/Storage/ProfileService.cs
+++ b/src/Artemis.Core/Services/Storage/ProfileService.cs
@@ -10,6 +10,7 @@ using Artemis.Core.Services.Storage.Interfaces;
using Artemis.Storage.Entities.Profile;
using Artemis.Storage.Repositories.Interfaces;
using Newtonsoft.Json;
+using Serilog;
namespace Artemis.Core.Services.Storage
{
@@ -19,12 +20,14 @@ namespace Artemis.Core.Services.Storage
public class ProfileService : IProfileService
{
private readonly ILayerService _layerService;
+ private readonly ILogger _logger;
private readonly IPluginService _pluginService;
private readonly IProfileRepository _profileRepository;
private readonly ISurfaceService _surfaceService;
- internal ProfileService(IPluginService pluginService, ISurfaceService surfaceService, ILayerService layerService, IProfileRepository profileRepository)
+ internal ProfileService(ILogger logger, IPluginService pluginService, ISurfaceService surfaceService, ILayerService layerService, IProfileRepository profileRepository)
{
+ _logger = logger;
_pluginService = pluginService;
_surfaceService = surfaceService;
_layerService = layerService;
@@ -121,7 +124,10 @@ namespace Artemis.Core.Services.Storage
public void UndoUpdateProfile(Profile profile, ProfileModule module)
{
if (!profile.UndoStack.Any())
+ {
+ _logger.Debug("Undo profile update - Failed, undo stack empty");
return;
+ }
ActivateProfile(module, null);
var top = profile.UndoStack.Pop();
@@ -130,12 +136,17 @@ namespace Artemis.Core.Services.Storage
profile.ProfileEntity = JsonConvert.DeserializeObject(top);
profile.ApplyToProfile();
ActivateProfile(module, profile);
+
+ _logger.Debug("Undo profile update - Success");
}
public void RedoUpdateProfile(Profile profile, ProfileModule module)
{
if (!profile.RedoStack.Any())
+ {
+ _logger.Debug("Redo profile update - Failed, redo empty");
return;
+ }
ActivateProfile(module, null);
var top = profile.RedoStack.Pop();
@@ -144,6 +155,8 @@ namespace Artemis.Core.Services.Storage
profile.ProfileEntity = JsonConvert.DeserializeObject(top);
profile.ApplyToProfile();
ActivateProfile(module, profile);
+
+ _logger.Debug("Redo profile update - Success");
}
private void InstantiateProfileLayerBrushes(Profile profile)
diff --git a/src/Artemis.Core/packages.config b/src/Artemis.Core/packages.config
index b37b39ea7..867b73146 100644
--- a/src/Artemis.Core/packages.config
+++ b/src/Artemis.Core/packages.config
@@ -1,5 +1,4 @@
-
@@ -14,11 +13,13 @@
-
+
+
+
diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj
index 17e92ea5a..aff7d6759 100644
--- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj
+++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj
@@ -91,20 +91,12 @@
Designer
MSBuild:Compile
-
- MSBuild:Compile
- Designer
-
ColorPicker.xaml
-
- UserControl1.xaml
- Code
-
diff --git a/src/Artemis.UI.Shared/DraggableFloat.xaml b/src/Artemis.UI.Shared/DraggableFloat.xaml
index c1be4cdc5..6f3c871f9 100644
--- a/src/Artemis.UI.Shared/DraggableFloat.xaml
+++ b/src/Artemis.UI.Shared/DraggableFloat.xaml
@@ -22,12 +22,13 @@
Height="17"
Padding="1 0"
Margin="0 4 0 0"
- Text="{Binding Value, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
+ Text="{Binding Value, StringFormat=N3, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
Cursor="/Resources/aero_drag_ew.cur"
Foreground="{DynamicResource SecondaryAccentBrush}"
MouseDown="InputMouseDown"
MouseUp="InputMouseUp"
- MouseMove="InputMouseMove" />
+ MouseMove="InputMouseMove"
+ RequestBringIntoView="Input_OnRequestBringIntoView"/>
@@ -36,7 +37,7 @@
Height="20"
materialDesign:ValidationAssist.UsePopup="True"
HorizontalAlignment="Left"
- Text="{Binding Value, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
+ Text="{Binding Value, StringFormat=N3, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
LostFocus="InputLostFocus"
KeyDown="InputKeyDown"
RequestBringIntoView="Input_OnRequestBringIntoView" />
diff --git a/src/Artemis.UI.Shared/DraggableFloat.xaml.cs b/src/Artemis.UI.Shared/DraggableFloat.xaml.cs
index 2a7b92050..c303a058b 100644
--- a/src/Artemis.UI.Shared/DraggableFloat.xaml.cs
+++ b/src/Artemis.UI.Shared/DraggableFloat.xaml.cs
@@ -24,9 +24,13 @@ namespace Artemis.UI.Shared
typeof(RoutedPropertyChangedEventHandler),
typeof(DraggableFloat));
+ public event EventHandler DragStarted;
+ public event EventHandler DragEnded;
+
private bool _inCallback;
private Point _mouseDragStartPoint;
private float _startValue;
+ private bool _calledDragStarted;
public DraggableFloat()
{
@@ -75,22 +79,33 @@ namespace Artemis.UI.Shared
var position = e.GetPosition((IInputElement) sender);
if (position == _mouseDragStartPoint)
DisplayInput();
+ else
+ {
+ OnDragEnded();
+ _calledDragStarted = false;
+ }
((IInputElement) sender).ReleaseMouseCapture();
}
private void InputMouseMove(object sender, MouseEventArgs e)
{
- if (e.LeftButton == MouseButtonState.Pressed)
+ if (e.LeftButton != MouseButtonState.Pressed)
+ return;
+
+ if (!_calledDragStarted)
{
- // Use decimals for everything to avoid floating point errors
- var startValue = new decimal(_startValue);
- var startX = new decimal(_mouseDragStartPoint.X);
- var x = new decimal(e.GetPosition((IInputElement) sender).X);
- var stepSize = new decimal(StepSize);
-
- Value = (float) (Math.Round(startValue + stepSize * (x - startX) / stepSize) * stepSize);
+ OnDragStarted();
+ _calledDragStarted = true;
}
+
+ // Use decimals for everything to avoid floating point errors
+ var startValue = new decimal(_startValue);
+ var startX = new decimal(_mouseDragStartPoint.X);
+ var x = new decimal(e.GetPosition((IInputElement) sender).X);
+ var stepSize = new decimal(StepSize);
+
+ Value = (float) UltimateRoundingFunction(startValue + stepSize * (x - startX), stepSize, 0.5m);
}
private void InputLostFocus(object sender, RoutedEventArgs e)
@@ -127,5 +142,20 @@ namespace Artemis.UI.Shared
{
e.Handled = true;
}
+
+ private static decimal UltimateRoundingFunction(decimal amountToRound, decimal nearstOf, decimal fairness)
+ {
+ return Math.Floor(amountToRound / nearstOf + fairness) * nearstOf;
+ }
+
+ protected virtual void OnDragStarted()
+ {
+ DragStarted?.Invoke(this, EventArgs.Empty);
+ }
+
+ protected virtual void OnDragEnded()
+ {
+ DragEnded?.Invoke(this, EventArgs.Empty);
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/UserControl1.xaml b/src/Artemis.UI.Shared/UserControl1.xaml
deleted file mode 100644
index 9a4ccd683..000000000
--- a/src/Artemis.UI.Shared/UserControl1.xaml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/UserControl1.xaml.cs b/src/Artemis.UI.Shared/UserControl1.xaml.cs
deleted file mode 100644
index 0e7afc80a..000000000
--- a/src/Artemis.UI.Shared/UserControl1.xaml.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Windows.Controls;
-
-namespace Artemis.UI.Shared
-{
- ///
- /// Interaction logic for UserControl1.xaml
- ///
- public partial class UserControl1 : UserControl
- {
- public UserControl1()
- {
- InitializeComponent();
- }
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj
index 9faed755c..4414933e6 100644
--- a/src/Artemis.UI/Artemis.UI.csproj
+++ b/src/Artemis.UI/Artemis.UI.csproj
@@ -227,6 +227,7 @@
+
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/BrushPropertyInputView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/BrushPropertyInputView.xaml
index 70bb43b15..143a229bf 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/BrushPropertyInputView.xaml
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/BrushPropertyInputView.xaml
@@ -3,9 +3,7 @@
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.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
- xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
@@ -19,8 +17,7 @@
ItemsSource="{Binding Path=EnumValues}"
SelectedValuePath="Value"
DisplayMemberPath="Description"
- SelectedValue="{Binding Path=BrushInputValue}"
- materialDesign:ComboBoxAssist.ClassicMode="True" />
+ SelectedValue="{Binding Path=BrushInputValue}" />
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/EnumPropertyInputView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/EnumPropertyInputView.xaml
index 489314187..7426a53d8 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/EnumPropertyInputView.xaml
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/EnumPropertyInputView.xaml
@@ -5,7 +5,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
- xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:EnumPropertyInputViewModel}">
@@ -20,8 +19,7 @@
ItemsSource="{Binding Path=EnumValues}"
SelectedValuePath="Value"
DisplayMemberPath="Description"
- SelectedValue="{Binding Path=EnumInputValue}"
- materialDesign:ComboBoxAssist.ClassicMode="True" />
+ SelectedValue="{Binding Path=EnumInputValue}" />
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/FloatPropertyInputView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/FloatPropertyInputView.xaml
index 815681cf1..bb8514f2e 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/FloatPropertyInputView.xaml
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/FloatPropertyInputView.xaml
@@ -11,7 +11,10 @@
d:DataContext="{d:DesignInstance local:FloatPropertyInputViewModel}">
-
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/IntPropertyInputView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/IntPropertyInputView.xaml
index 22df27bef..94b47cbb0 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/IntPropertyInputView.xaml
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/IntPropertyInputView.xaml
@@ -4,7 +4,6 @@
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.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput"
- xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
mc:Ignorable="d"
@@ -12,7 +11,10 @@
d:DataContext="{d:DesignInstance local:IntPropertyInputViewModel}">
-
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/PropertyInputViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/PropertyInputViewModel.cs
index eb9ab657a..7aef6f5f4 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/PropertyInputViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/PropertyInputViewModel.cs
@@ -13,10 +13,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P
ProfileEditorService = profileEditorService;
}
- protected IProfileEditorService ProfileEditorService { get; set; }
+ protected IProfileEditorService ProfileEditorService { get; }
public abstract List CompatibleTypes { get; }
public bool Initialized { get; private set; }
+ public bool InputDragging { get; private set; }
public LayerPropertyViewModel LayerPropertyViewModel { get; private set; }
protected object InputValue
@@ -56,7 +57,25 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P
// Force the keyframe engine to update, the edited keyframe might affect the current keyframe progress
LayerPropertyViewModel.LayerProperty.KeyframeEngine?.Update(0);
+ if (!InputDragging)
+ ProfileEditorService.UpdateSelectedProfileElement();
+ else
+ ProfileEditorService.UpdateProfilePreview();
+ }
+
+ #region Event handlers
+
+ public void InputDragStarted(object sender, EventArgs e)
+ {
+ InputDragging = true;
+ }
+
+ public void InputDragEnded(object sender, EventArgs e)
+ {
+ InputDragging = false;
ProfileEditorService.UpdateSelectedProfileElement();
}
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKColorPropertyInputView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKColorPropertyInputView.xaml
index 5884fc22f..1e26f6dfb 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKColorPropertyInputView.xaml
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKColorPropertyInputView.xaml
@@ -4,8 +4,6 @@
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.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput"
- xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
- xmlns:s="https://github.com/canton7/Stylet"
xmlns:artemis="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
xmlns:converters="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared"
mc:Ignorable="d"
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKPointPropertyInputView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKPointPropertyInputView.xaml
index 882bf4719..057d2e5a3 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKPointPropertyInputView.xaml
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKPointPropertyInputView.xaml
@@ -4,7 +4,6 @@
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.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput"
- xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
mc:Ignorable="d"
@@ -14,11 +13,15 @@
+ StepSize="{Binding LayerPropertyViewModel.LayerProperty.InputStepSize}"
+ DragStarted="{s:Action InputDragStarted}"
+ DragEnded="{s:Action InputDragEnded}" />
,
+ StepSize="{Binding LayerPropertyViewModel.LayerProperty.InputStepSize}"
+ DragStarted="{s:Action InputDragStarted}"
+ DragEnded="{s:Action InputDragEnded}" />
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKSizePropertyInputView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKSizePropertyInputView.xaml
index 210cf7da8..7e9ec1852 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKSizePropertyInputView.xaml
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKSizePropertyInputView.xaml
@@ -4,7 +4,6 @@
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.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput"
- xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
mc:Ignorable="d"
@@ -12,9 +11,17 @@
d:DataContext="{d:DesignInstance local:SKSizePropertyInputViewModel}">
-
+
,
-
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTimelineView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTimelineView.xaml
index a3afcc31c..239fafe15 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTimelineView.xaml
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTimelineView.xaml
@@ -9,11 +9,11 @@
d:DesignHeight="25"
d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:PropertyTimelineViewModel}">
-
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTimelineViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTimelineViewModel.cs
index 5cca8a591..ee0a8996d 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTimelineViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTimelineViewModel.cs
@@ -7,6 +7,7 @@ using System.Windows.Media;
using System.Windows.Shapes;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Services.Interfaces;
+using Artemis.UI.Utilities;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
@@ -95,26 +96,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
UpdateEndTime();
}
- #region Keyframe movement
-
- public void MoveSelectedKeyframes(TimeSpan offset)
- {
- var keyframeViewModels = PropertyTrackViewModels.SelectMany(t => t.KeyframeViewModels.OrderBy(k => k.Keyframe.Position)).ToList();
- foreach (var keyframeViewModel in keyframeViewModels.Where(k => k.IsSelected))
- {
- // TODO: Not ideal as this stacks them all if they get to 0, oh well
- if (keyframeViewModel.Keyframe.Position + offset > TimeSpan.Zero)
- {
- keyframeViewModel.Keyframe.Position += offset;
- keyframeViewModel.Update(LayerPropertiesViewModel.PixelsPerSecond);
- }
- }
-
- _profileEditorService.UpdateProfilePreview();
- }
-
- #endregion
-
private void CreateViewModels(LayerPropertyViewModel property)
{
PropertyTrackViewModels.Add(_propertyTrackVmFactory.Create(this, property));
@@ -122,6 +103,30 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
CreateViewModels(child);
}
+ #region Keyframe movement
+
+ public void MoveSelectedKeyframes(TimeSpan cursorTime)
+ {
+ // Ensure the selection rectangle doesn't show, the view isn't aware of different types of dragging
+ SelectionRectangle.Rect = new Rect();
+
+ var keyframeViewModels = PropertyTrackViewModels.SelectMany(t => t.KeyframeViewModels.OrderBy(k => k.Keyframe.Position)).ToList();
+ foreach (var keyframeViewModel in keyframeViewModels.Where(k => k.IsSelected))
+ keyframeViewModel.ApplyMovement(cursorTime);
+
+ _profileEditorService.UpdateProfilePreview();
+ }
+
+
+ public void ReleaseSelectedKeyframes()
+ {
+ var keyframeViewModels = PropertyTrackViewModels.SelectMany(t => t.KeyframeViewModels.OrderBy(k => k.Keyframe.Position)).ToList();
+ foreach (var keyframeViewModel in keyframeViewModels.Where(k => k.IsSelected))
+ keyframeViewModel.ReleaseMovement();
+ }
+
+ #endregion
+
#region Keyframe selection
private Point _mouseDragStartPoint;
@@ -130,6 +135,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
// ReSharper disable once UnusedMember.Global - Called from view
public void TimelineCanvasMouseDown(object sender, MouseButtonEventArgs e)
{
+ if (e.LeftButton == MouseButtonState.Released)
+ return;
+
((IInputElement) sender).CaptureMouse();
SelectionRectangle.Rect = new Rect();
@@ -148,18 +156,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
var selectedRect = new Rect(_mouseDragStartPoint, position);
SelectionRectangle.Rect = selectedRect;
- // Find all keyframes in the rectangle
- var selectedKeyframes = new List();
- var hitTestParams = new GeometryHitTestParameters(SelectionRectangle);
- var resultCallback = new HitTestResultCallback(result => HitTestResultBehavior.Continue);
- var filterCallback = new HitTestFilterCallback(element =>
- {
- if (element is Ellipse ellipse)
- selectedKeyframes.Add((PropertyTrackKeyframeViewModel) ellipse.DataContext);
- return HitTestFilterBehavior.Continue;
- });
- VisualTreeHelper.HitTest((Visual) sender, filterCallback, resultCallback, hitTestParams);
-
+ var selectedKeyframes = HitTestUtilities.GetHitViewModels((Visual) sender, SelectionRectangle);
var keyframeViewModels = PropertyTrackViewModels.SelectMany(t => t.KeyframeViewModels.OrderBy(k => k.Keyframe.Position)).ToList();
foreach (var keyframeViewModel in keyframeViewModels)
keyframeViewModel.IsSelected = selectedKeyframes.Contains(keyframeViewModel);
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackKeyframeViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackKeyframeViewModel.cs
index 4844a7978..141d34b71 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackKeyframeViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackKeyframeViewModel.cs
@@ -49,7 +49,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
if (e.LeftButton == MouseButtonState.Released)
return;
- ((IInputElement)sender).CaptureMouse();
+ ((IInputElement) sender).CaptureMouse();
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift) && !IsSelected)
PropertyTrackViewModel.PropertyTimelineViewModel.SelectKeyframe(this, true, false);
else if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
@@ -63,42 +63,45 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
public void KeyframeMouseUp(object sender, MouseButtonEventArgs e)
{
_profileEditorService.UpdateSelectedProfileElement();
+ PropertyTrackViewModel.PropertyTimelineViewModel.ReleaseSelectedKeyframes();
- ((IInputElement)sender).ReleaseMouseCapture();
- e.Handled = true;
+ ((IInputElement) sender).ReleaseMouseCapture();
}
public void KeyframeMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
- {
- // Get the parent grid, need that for our position
- var x = Math.Max(0, e.GetPosition(ParentView).X);
- var newTime = TimeSpan.FromSeconds(x / _pixelsPerSecond);
-
- // Round the time to something that fits the current zoom level
- if (_pixelsPerSecond < 200)
- newTime = TimeSpan.FromMilliseconds(Math.Round(newTime.TotalMilliseconds / 5.0) * 5.0);
- else if (_pixelsPerSecond < 500)
- newTime = TimeSpan.FromMilliseconds(Math.Round(newTime.TotalMilliseconds / 2.0) * 2.0);
- else
- newTime = TimeSpan.FromMilliseconds(Math.Round(newTime.TotalMilliseconds));
-
- // If shift is held, snap to the current time
- // Take a tolerance of 5 pixels (half a keyframe width)
- if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
- {
- var tolerance = 1000f / _pixelsPerSecond * 5;
- if (Math.Abs(_profileEditorService.CurrentTime.TotalMilliseconds - newTime.TotalMilliseconds) < tolerance)
- newTime = _profileEditorService.CurrentTime;
- }
-
- PropertyTrackViewModel.PropertyTimelineViewModel.MoveSelectedKeyframes(newTime - Keyframe.Position);
- }
+ PropertyTrackViewModel.PropertyTimelineViewModel.MoveSelectedKeyframes(GetCursorTime(e.GetPosition(ParentView)));
e.Handled = true;
}
+ private TimeSpan GetCursorTime(Point position)
+ {
+ // Get the parent grid, need that for our position
+ var x = Math.Max(0, position.X);
+ var time = TimeSpan.FromSeconds(x / _pixelsPerSecond);
+
+ // Round the time to something that fits the current zoom level
+ if (_pixelsPerSecond < 200)
+ time = TimeSpan.FromMilliseconds(Math.Round(time.TotalMilliseconds / 5.0) * 5.0);
+ else if (_pixelsPerSecond < 500)
+ time = TimeSpan.FromMilliseconds(Math.Round(time.TotalMilliseconds / 2.0) * 2.0);
+ else
+ time = TimeSpan.FromMilliseconds(Math.Round(time.TotalMilliseconds));
+
+ // If shift is held, snap to the current time
+ // Take a tolerance of 5 pixels (half a keyframe width)
+ if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
+ {
+ var tolerance = 1000f / _pixelsPerSecond * 5;
+ if (Math.Abs(_profileEditorService.CurrentTime.TotalMilliseconds - time.TotalMilliseconds) < tolerance)
+ time = _profileEditorService.CurrentTime;
+ }
+
+ return time;
+ }
+
#endregion
#region Context menu actions
@@ -137,5 +140,34 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
}
#endregion
+
+ #region Movement
+
+ private bool _movementReleased = true;
+ private TimeSpan _startOffset;
+
+ public void ApplyMovement(TimeSpan cursorTime)
+ {
+ if (_movementReleased)
+ {
+ _movementReleased = false;
+ _startOffset = cursorTime - Keyframe.Position;
+ }
+ else
+ {
+ Keyframe.Position = cursorTime - _startOffset;
+ if (Keyframe.Position < TimeSpan.Zero)
+ Keyframe.Position = TimeSpan.Zero;
+
+ Update(_pixelsPerSecond);
+ }
+ }
+
+ public void ReleaseMovement()
+ {
+ _movementReleased = true;
+ }
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs
index b95553d00..828bf59c2 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs
@@ -318,8 +318,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
// Scale down the resulting position and make it relative
var scaled = _layerEditorService.GetScaledPoint(layer, position, true);
- // Update the position property
- layer.PositionProperty.SetCurrentValue(scaled, ProfileEditorService.CurrentTime);
+ // Round and update the position property
+ layer.PositionProperty.SetCurrentValue(RoundPoint(scaled, 3), ProfileEditorService.CurrentTime);
ProfileEditorService.UpdateProfilePreview();
}
@@ -338,13 +338,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
var scaled = _layerEditorService.GetScaledPoint(layer, countered[1], false);
// Update the anchor point, this causes the shape to move
- layer.AnchorPointProperty.SetCurrentValue(RoundPoint(scaled, 5), ProfileEditorService.CurrentTime);
+ layer.AnchorPointProperty.SetCurrentValue(RoundPoint(scaled, 3), ProfileEditorService.CurrentTime);
// TopLeft is not updated yet and acts as a snapshot of the top-left before changing the anchor
var path = _layerEditorService.GetLayerPath(layer, true, true, true);
// Calculate the (scaled) difference between the old and now position
var difference = _layerEditorService.GetScaledPoint(layer, _topLeft - path.Points[0], false);
// Apply the difference so that the shape effectively stays in place
- layer.PositionProperty.SetCurrentValue(RoundPoint(layer.PositionProperty.CurrentValue + difference, 5), ProfileEditorService.CurrentTime);
+ layer.PositionProperty.SetCurrentValue(RoundPoint(layer.PositionProperty.CurrentValue + difference, 3), ProfileEditorService.CurrentTime);
ProfileEditorService.UpdateProfilePreview();
}
diff --git a/src/Artemis.UI/Screens/Settings/SettingsView.xaml b/src/Artemis.UI/Screens/Settings/SettingsView.xaml
index 45d1af187..449ba2f28 100644
--- a/src/Artemis.UI/Screens/Settings/SettingsView.xaml
+++ b/src/Artemis.UI/Screens/Settings/SettingsView.xaml
@@ -36,7 +36,7 @@
- Start up with Windows
+ Start up with Windows
@@ -54,7 +54,7 @@
- Start up with Windows minimized
+ Start up with Windows minimized
@@ -72,8 +72,8 @@
- Debugger
-
+ Debugger
+
Use the debugger to see the raw image Artemis is rendering on the surface.
@@ -95,18 +95,17 @@
- Logs
-
- Opens the directory where logs are stored.
+ Application files
+
+ Opens the directory where application files like plugins and settings are stored.
-
-
@@ -119,17 +118,39 @@
- Application files
-
- Opens the directory where application files like plugins and settings are stored.
+ Logs
+
+ Opens the directory where logs are stored.
-
- SHOW APP FILES
+
+ SHOW LOGS
+
+
+
+
+
+
+
+
+
+
+
+
+ Log level
+
+ Sets the logging level, a verbose logging level will result in more log files.
+
+
+
+
+
+
+
@@ -147,8 +168,8 @@
- Render scale
-
+ Render scale
+
Sets the resolution Artemis renders at, higher scale means more CPU-usage, especially on large surfaces.
@@ -168,8 +189,8 @@
- Target framerate
-
+ Target framerate
+
Sets the FPS Artemis tries to render at, higher FPS means more CPU-usage but smoother animations.
@@ -189,8 +210,8 @@
- LED sample size
-
+ LED sample size
+
Sets the amount of samples that is taken to determine each LEDs color. This means a LED can be semi off if it is not completely covered by a color.
diff --git a/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs b/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs
index f1324d1f7..06c247d1e 100644
--- a/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs
@@ -12,8 +12,10 @@ using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Settings.Debug;
using Artemis.UI.Screens.Settings.Tabs.Devices;
using Artemis.UI.Screens.Settings.Tabs.Plugins;
+using Artemis.UI.Shared.Utilities;
using MaterialDesignThemes.Wpf;
using Ninject;
+using Serilog.Events;
using Stylet;
namespace Artemis.UI.Screens.Settings
@@ -26,6 +28,7 @@ namespace Artemis.UI.Screens.Settings
private readonly ISettingsService _settingsService;
private readonly ISurfaceService _surfaceService;
private readonly IWindowManager _windowManager;
+ private object _test;
public SettingsViewModel(IKernel kernel,
ISurfaceService surfaceService,
@@ -47,6 +50,8 @@ namespace Artemis.UI.Screens.Settings
DeviceSettingsViewModels = new BindableCollection();
Plugins = new BindableCollection();
+
+ LogLevels = EnumUtilities.GetAllValuesAndDescriptions(typeof(LogEventLevel));
RenderScales = new List> {new Tuple("10%", 0.1)};
for (var i = 25; i <= 100; i += 25)
RenderScales.Add(new Tuple(i + "%", i / 100.0));
@@ -61,6 +66,8 @@ namespace Artemis.UI.Screens.Settings
public List> TargetFrameRates { get; set; }
public List> RenderScales { get; set; }
+ public IEnumerable LogLevels { get; private set; }
+
public List SampleSizes { get; set; }
public BindableCollection DeviceSettingsViewModels { get; set; }
public BindableCollection Plugins { get; set; }
@@ -77,6 +84,16 @@ namespace Artemis.UI.Screens.Settings
set => TargetFrameRate = value.Item2;
}
+ public LogEventLevel SelectedLogLevel
+ {
+ get => _settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information).Value;
+ set
+ {
+ _settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information).Value = value;
+ _settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information).Save();
+ }
+ }
+
public double RenderScale
{
get => _settingsService.GetSetting("Core.RenderScale", 1.0).Value;
@@ -87,7 +104,6 @@ namespace Artemis.UI.Screens.Settings
}
}
-
public int TargetFrameRate
{
get => _settingsService.GetSetting("Core.TargetFrameRate", 25).Value;
diff --git a/src/Artemis.UI/Utilities/HitTestUtilities.cs b/src/Artemis.UI/Utilities/HitTestUtilities.cs
new file mode 100644
index 000000000..92a2ce499
--- /dev/null
+++ b/src/Artemis.UI/Utilities/HitTestUtilities.cs
@@ -0,0 +1,32 @@
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Media;
+
+namespace Artemis.UI.Utilities
+{
+ public static class HitTestUtilities
+ {
+ ///
+ /// Runs a hit test on children of the container within the rectangle matching all elements that have a data context of .
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static List GetHitViewModels(Visual container, RectangleGeometry rectangleGeometry)
+ {
+ var result = new List();
+ var hitTestParams = new GeometryHitTestParameters(rectangleGeometry);
+ var resultCallback = new HitTestResultCallback(r => HitTestResultBehavior.Continue);
+ var filterCallback = new HitTestFilterCallback(e =>
+ {
+ if (e is FrameworkElement fe && fe.DataContext.GetType() == typeof(T) && !result.Contains((T) fe.DataContext))
+ result.Add((T) fe.DataContext);
+ return HitTestFilterBehavior.Continue;
+ });
+ VisualTreeHelper.HitTest(container, filterCallback, resultCallback, hitTestParams);
+
+ return result;
+ }
+ }
+}
\ No newline at end of file