diff --git a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
index 0772ade79..5984e5432 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
@@ -6,12 +6,12 @@ namespace Artemis.Core
///
public class DataBinding : IDataBinding
{
+ private TProperty _currentValue = default!;
private bool _disposed;
private TimeSpan _easingProgress;
- private bool _reapplyValue;
- private TProperty _currentValue = default!;
- private TProperty _previousValue = default!;
private TProperty _lastAppliedValue = default!;
+ private TProperty _previousValue = default!;
+ private bool _reapplyValue;
internal DataBinding(DataBindingRegistration dataBindingRegistration)
{
@@ -100,27 +100,6 @@ namespace Artemis.Core
return Registration?.PropertyExpression.ReturnType;
}
- ///
- /// Updates the smoothing progress of the data binding
- ///
- /// The delta to apply during update
- public void UpdateWithDelta(TimeSpan delta)
- {
- if (_disposed)
- throw new ObjectDisposedException("DataBinding");
-
- // Data bindings cannot go back in time like brushes
- if (delta < TimeSpan.Zero)
- delta = TimeSpan.Zero;
-
- _easingProgress = _easingProgress.Add(delta);
- if (_easingProgress > EasingTime)
- _easingProgress = EasingTime;
-
- // Tell Apply() to apply a new value next call
- _reapplyValue = false;
- }
-
private void ResetEasing(TProperty value)
{
_previousValue = GetInterpolatedValue();
@@ -165,12 +144,30 @@ namespace Artemis.Core
{
// Don't update data bindings if there is no delta, otherwise this creates an inconsistency between
// data bindings with easing and data bindings without easing (the ones with easing will seemingly not update)
- if (timeline.Delta == TimeSpan.Zero)
+ if (timeline.Delta == TimeSpan.Zero)
return;
-
+
UpdateWithDelta(timeline.Delta);
}
+ ///
+ public void UpdateWithDelta(TimeSpan delta)
+ {
+ if (_disposed)
+ throw new ObjectDisposedException("DataBinding");
+
+ // Data bindings cannot go back in time like brushes
+ if (delta < TimeSpan.Zero)
+ delta = TimeSpan.Zero;
+
+ _easingProgress = _easingProgress.Add(delta);
+ if (_easingProgress > EasingTime)
+ _easingProgress = EasingTime;
+
+ // Tell Apply() to apply a new value next call
+ _reapplyValue = false;
+ }
+
///
public void Apply()
{
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/IDataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/IDataBinding.cs
index a609b1b3a..c2913c85f 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/IDataBinding.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/IDataBinding.cs
@@ -9,6 +9,12 @@ namespace Artemis.Core
///
public interface IDataBinding : IStorageModel, IUpdateModel, IDisposable
{
+ ///
+ /// Updates the smoothing progress of the data binding and recalculates the value next call
+ ///
+ /// The delta to apply during update
+ void UpdateWithDelta(TimeSpan delta);
+
///
/// Applies the data binding to the layer property
///
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs
index 3f8b67c94..7adf0622e 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs
@@ -2,6 +2,7 @@
using System.Linq;
using System.Timers;
using Artemis.Core;
+using Artemis.Core.Services;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline;
using Artemis.UI.Shared;
@@ -13,8 +14,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
public sealed class DataBindingViewModel : Conductor, IDataBindingViewModel
{
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
+ private readonly ICoreService _coreService;
private readonly IProfileEditorService _profileEditorService;
- private readonly Timer _updateTimer;
private int _easingTime;
private bool _isDataBindingEnabled;
private bool _isEasingTimeEnabled;
@@ -23,22 +24,26 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
private bool _updating;
private bool _updatingTestResult;
+ private DateTime _lastUpdate;
public DataBindingViewModel(DataBindingRegistration registration,
+ ICoreService coreService,
+ ISettingsService settingsService,
IProfileEditorService profileEditorService,
IDataModelUIService dataModelUIService,
IDataBindingsVmFactory dataBindingsVmFactory)
{
Registration = registration;
+ _coreService = coreService;
_profileEditorService = profileEditorService;
_dataBindingsVmFactory = dataBindingsVmFactory;
- _updateTimer = new Timer(40);
if (Registration.Member != null)
DisplayName = Registration.Member.Name.ToUpper();
else
DisplayName = Registration.LayerProperty.PropertyDescription.Name.ToUpper();
+ AlwaysApplyDataBindings = settingsService.GetSetting("ProfileEditor.AlwaysApplyDataBindings", true);
DataBindingModes = new BindableCollection(EnumUtilities.GetAllValuesAndDescriptions(typeof(DataBindingModeType)));
EasingViewModels = new BindableCollection();
TestInputValue = dataModelUIService.GetDataModelDisplayViewModel(typeof(TProperty), null, true);
@@ -46,7 +51,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
}
public DataBindingRegistration Registration { get; }
-
+ public PluginSetting AlwaysApplyDataBindings { get; }
public BindableCollection DataBindingModes { get; }
public BindableCollection EasingViewModels { get; }
public DataModelDisplayViewModel TestInputValue { get; }
@@ -67,7 +72,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
get => _isDataBindingEnabled;
set => SetAndNotify(ref _isDataBindingEnabled, value);
}
-
+
public TimelineEasingViewModel SelectedEasingViewModel
{
get => _selectedEasingViewModel;
@@ -108,9 +113,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
{
EasingViewModels.AddRange(Enum.GetValues(typeof(Easings.Functions)).Cast().Select(v => new TimelineEasingViewModel(v, false)));
- _updateTimer.Start();
- _updateTimer.Elapsed += OnUpdateTimerOnElapsed;
-
+ _lastUpdate = DateTime.Now;
+ _coreService.FrameRendered += OnFrameRendered;
CreateDataBindingModeModeViewModel();
Update();
}
@@ -205,7 +209,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
return;
_updatingTestResult = true;
-
if (Registration.DataBinding == null || ActiveItem == null)
{
TestInputValue.UpdateValue(default);
@@ -214,8 +217,13 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
return;
}
- // While playing in preview data bindings aren't updated
- Registration.DataBinding.UpdateWithDelta(TimeSpan.FromMilliseconds(40));
+ // If always update is disabled, do constantly update the data binding as long as the view model is open
+ // If always update is enabled, this is done for all data bindings in ProfileViewModel
+ if (!AlwaysApplyDataBindings.Value)
+ {
+ Registration.DataBinding.UpdateWithDelta(DateTime.Now - _lastUpdate);
+ _profileEditorService.UpdateProfilePreview();
+ }
if (ActiveItem.SupportsTestValue)
{
@@ -227,8 +235,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
{
TestResultValue.UpdateValue(Registration.DataBinding != null ? Registration.DataBinding.GetValue(default) : default);
}
-
- _profileEditorService.UpdateProfilePreview();
+
_updatingTestResult = false;
}
@@ -252,6 +259,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
_profileEditorService.UpdateSelectedProfileElement();
}
+ private void OnFrameRendered(object sender, FrameRenderedEventArgs e)
+ {
+ UpdateTestResult();
+ _lastUpdate = DateTime.Now;
+ }
+
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
{
UpdateTestResult();
@@ -262,8 +275,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
///
public void Dispose()
{
- _updateTimer.Dispose();
- _updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
+ _coreService.FrameRendered -= OnFrameRendered;
}
#endregion
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileView.xaml
index 52c232a23..aea990eaf 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileView.xaml
@@ -126,15 +126,20 @@
-
+
-
- Only show shape of selected layer (NYI)
-
-
+
Highlight LEDs of selected layer
+
+ Constantly apply data bindings in editor
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileViewModel.cs
index ccd778935..c2f4f935c 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileViewModel.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
@@ -18,6 +18,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
public class ProfileViewModel : Screen, IProfileEditorPanelViewModel, IHandle, IHandle
{
private readonly IProfileEditorService _profileEditorService;
+ private readonly ICoreService _coreService;
private readonly IProfileLayerVmFactory _profileLayerVmFactory;
private readonly ISettingsService _settingsService;
private readonly ISurfaceService _surfaceService;
@@ -31,13 +32,15 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
private BindableCollection _devices;
private BindableCollection _highlightedLeds;
private PluginSetting _highlightSelectedLayer;
- private PluginSetting _onlyShowSelectedShape;
+ private PluginSetting _alwaysApplyDataBindings;
private PanZoomViewModel _panZoomViewModel;
private Layer _previousSelectedLayer;
private int _previousTool;
private BindableCollection _selectedLeds;
+ private DateTime _lastUpdate;
public ProfileViewModel(IProfileEditorService profileEditorService,
+ ICoreService coreService,
ISurfaceService surfaceService,
ISettingsService settingsService,
IEventAggregator eventAggregator,
@@ -45,6 +48,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
IProfileLayerVmFactory profileLayerVmFactory)
{
_profileEditorService = profileEditorService;
+ _coreService = coreService;
_surfaceService = surfaceService;
_settingsService = settingsService;
_visualizationToolVmFactory = visualizationToolVmFactory;
@@ -102,10 +106,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
set => SetAndNotify(ref _selectedLeds, value);
}
- public PluginSetting OnlyShowSelectedShape
+ public PluginSetting AlwaysApplyDataBindings
{
- get => _onlyShowSelectedShape;
- set => SetAndNotify(ref _onlyShowSelectedShape, value);
+ get => _alwaysApplyDataBindings;
+ set => SetAndNotify(ref _alwaysApplyDataBindings, value);
}
public PluginSetting HighlightSelectedLayer
@@ -170,9 +174,12 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
{
ApplyActiveProfile();
- OnlyShowSelectedShape = _settingsService.GetSetting("ProfileEditor.OnlyShowSelectedShape", true);
+ AlwaysApplyDataBindings = _settingsService.GetSetting("ProfileEditor.AlwaysApplyDataBindings", true);
HighlightSelectedLayer = _settingsService.GetSetting("ProfileEditor.HighlightSelectedLayer", true);
+ _lastUpdate = DateTime.Now;
+ _coreService.FrameRendered += OnFrameRendered;
+
HighlightSelectedLayer.SettingChanged += HighlightSelectedLayerOnSettingChanged;
_surfaceService.ActiveSurfaceConfigurationSelected += OnActiveSurfaceConfigurationSelected;
_profileEditorService.ProfileSelected += OnProfileSelected;
@@ -181,9 +188,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
base.OnInitialActivate();
}
-
+
protected override void OnClose()
{
+ _coreService.FrameRendered -= OnFrameRendered;
HighlightSelectedLayer.SettingChanged -= HighlightSelectedLayerOnSettingChanged;
_surfaceService.ActiveSurfaceConfigurationSelected -= OnActiveSurfaceConfigurationSelected;
_profileEditorService.ProfileSelected -= OnProfileSelected;
@@ -192,7 +200,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
if (_previousSelectedLayer != null)
_previousSelectedLayer.LayerBrushUpdated -= SelectedLayerOnLayerBrushUpdated;
- OnlyShowSelectedShape.Save();
+ AlwaysApplyDataBindings.Save();
HighlightSelectedLayer.Save();
foreach (CanvasViewModel canvasViewModel in CanvasViewModels)
@@ -355,6 +363,27 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
#region Event handlers
+ private void OnFrameRendered(object sender, FrameRenderedEventArgs e)
+ {
+ TimeSpan delta = DateTime.Now - _lastUpdate;
+ _lastUpdate = DateTime.Now;
+
+ if (!AlwaysApplyDataBindings.Value || _profileEditorService.SelectedProfile == null)
+ return;
+
+ foreach (IDataBindingRegistration dataBindingRegistration in _profileEditorService.SelectedProfile.GetAllFolders()
+ .SelectMany(f => f.GetAllLayerProperties(), (f, p) => p)
+ .SelectMany(p => p.GetAllDataBindingRegistrations()))
+ dataBindingRegistration.GetDataBinding()?.UpdateWithDelta(delta);
+ foreach (IDataBindingRegistration dataBindingRegistration in _profileEditorService.SelectedProfile.GetAllLayers()
+ .SelectMany(f => f.GetAllLayerProperties(), (f, p) => p)
+ .SelectMany(p => p.GetAllDataBindingRegistrations()))
+ dataBindingRegistration.GetDataBinding()?.UpdateWithDelta(delta);
+
+ // TODO: Only update when there are data bindings
+ _profileEditorService.UpdateProfilePreview();
+ }
+
private void HighlightSelectedLayerOnSettingChanged(object sender, EventArgs e)
{
UpdateLedsDimStatus();
diff --git a/src/Artemis.UI/Services/LayerEditorService.cs b/src/Artemis.UI/Services/LayerEditorService.cs
index 52b12adde..7fad79c3d 100644
--- a/src/Artemis.UI/Services/LayerEditorService.cs
+++ b/src/Artemis.UI/Services/LayerEditorService.cs
@@ -103,16 +103,15 @@ namespace Artemis.UI.Services
///
public SKPoint GetScaledPoint(Layer layer, SKPoint point, bool absolute)
{
- double renderScale = _settingsService.GetSetting("Core.RenderScale", 0.5).Value;
if (absolute)
return new SKPoint(
- 100f / layer.Bounds.Width * ((float) (point.X * renderScale) - layer.Bounds.Left) / 100f,
- 100f / layer.Bounds.Height * ((float) (point.Y * renderScale) - layer.Bounds.Top) / 100f
+ 100f / layer.Bounds.Width * (point.X - layer.Bounds.Left) / 100f,
+ 100f / layer.Bounds.Height * (point.Y - layer.Bounds.Top) / 100f
);
return new SKPoint(
- 100f / layer.Bounds.Width * (float) (point.X * renderScale) / 100f,
- 100f / layer.Bounds.Height * (float) (point.Y * renderScale) / 100f
+ 100f / layer.Bounds.Width * point.X / 100f,
+ 100f / layer.Bounds.Height * point.Y / 100f
);
}