diff --git a/src/Artemis.Core/Plugins/Modules/Module.cs b/src/Artemis.Core/Plugins/Modules/Module.cs
index 24a1fb3fd..31efee688 100644
--- a/src/Artemis.Core/Plugins/Modules/Module.cs
+++ b/src/Artemis.Core/Plugins/Modules/Module.cs
@@ -164,6 +164,16 @@ namespace Artemis.Core.Modules
///
public abstract void ModuleDeactivated(bool isOverride);
+ internal virtual void InternalUpdate(double deltaTime)
+ {
+ Update(deltaTime);
+ }
+
+ internal virtual void InternalRender(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo)
+ {
+ Render(deltaTime, surface, canvas, canvasInfo);
+ }
+
///
/// Evaluates the activation requirements following the and returns the result
///
diff --git a/src/Artemis.Core/Plugins/Modules/ProfileModule.cs b/src/Artemis.Core/Plugins/Modules/ProfileModule.cs
index 96647abd9..9b7c303ff 100644
--- a/src/Artemis.Core/Plugins/Modules/ProfileModule.cs
+++ b/src/Artemis.Core/Plugins/Modules/ProfileModule.cs
@@ -118,15 +118,7 @@ namespace Artemis.Core.Modules
/// Indicates whether or not a profile change is being animated
///
public bool AnimatingProfileChange { get; private set; }
-
- ///
- /// Called before the profile updates, this is the best place to perform data model updates
- ///
- /// Time in seconds since the last update
- public virtual void ProfileUpdate(double deltaTime)
- {
- }
-
+
///
/// Called after the profile has updated
///
@@ -135,17 +127,6 @@ namespace Artemis.Core.Modules
{
}
- ///
- /// Called before the profile renders
- ///
- /// Time since the last render
- /// The RGB Surface to render to
- ///
- ///
- public virtual void ProfileRender(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo)
- {
- }
-
///
/// Called after the profile has rendered
///
@@ -157,10 +138,9 @@ namespace Artemis.Core.Modules
{
}
- ///
- public sealed override void Update(double deltaTime)
+ internal override void InternalUpdate(double deltaTime)
{
- ProfileUpdate(deltaTime);
+ Update(deltaTime);
lock (this)
{
@@ -176,10 +156,9 @@ namespace Artemis.Core.Modules
ProfileUpdated(deltaTime);
}
- ///
- public sealed override void Render(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo)
+ internal override void InternalRender(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo)
{
- ProfileRender(deltaTime, surface, canvas, canvasInfo);
+ Render(deltaTime, surface, canvas, canvasInfo);
lock (this)
{
diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs
index 955a5f12f..1c739c425 100644
--- a/src/Artemis.Core/Services/CoreService.cs
+++ b/src/Artemis.Core/Services/CoreService.cs
@@ -174,7 +174,7 @@ namespace Artemis.Core.Services
// Update all active modules
foreach (var module in modules)
- module.Update(args.DeltaTime);
+ module.InternalUpdate(args.DeltaTime);
// If there is no ready bitmap brush, skip the frame
if (_rgbService.BitmapBrush == null)
@@ -192,7 +192,7 @@ namespace Artemis.Core.Services
{
// While non-activated modules may be updated above if they expand the main data model, they may never render
foreach (var module in modules.Where(m => m.IsActivated))
- module.Render(args.DeltaTime, _surfaceService.ActiveSurface, canvas, _rgbService.BitmapBrush.Bitmap.Info);
+ module.InternalRender(args.DeltaTime, _surfaceService.ActiveSurface, canvas, _rgbService.BitmapBrush.Bitmap.Info);
}
OnFrameRendering(new FrameRenderingEventArgs(modules, canvas, args.DeltaTime, _rgbService.Surface));
diff --git a/src/Artemis.Core/Utilities/IntroAnimation.cs b/src/Artemis.Core/Utilities/IntroAnimation.cs
index 6fd8fff60..745e3a063 100644
--- a/src/Artemis.Core/Utilities/IntroAnimation.cs
+++ b/src/Artemis.Core/Utilities/IntroAnimation.cs
@@ -77,6 +77,16 @@ namespace Artemis.Core
throw new NotImplementedException();
}
+ public override void Update(double deltaTime)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void Render(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo)
+ {
+ throw new NotImplementedException();
+ }
+
public override void ModuleActivated(bool isOverride)
{
throw new NotImplementedException();
diff --git a/src/Artemis.UI.Shared/Converters/NullToVisibilityConverter.cs b/src/Artemis.UI.Shared/Converters/NullToVisibilityConverter.cs
new file mode 100644
index 000000000..2d9f9200e
--- /dev/null
+++ b/src/Artemis.UI.Shared/Converters/NullToVisibilityConverter.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+
+namespace Artemis.UI.Shared
+{
+ public class NullToVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ Parameters direction;
+ if (parameter == null)
+ direction = Parameters.Normal;
+ else
+ direction = (Parameters) Enum.Parse(typeof(Parameters), (string) parameter);
+
+ if (direction == Parameters.Normal)
+ {
+ if (value == null)
+ return Visibility.Collapsed;
+ return Visibility.Visible;
+ }
+
+ if (value == null)
+ return Visibility.Visible;
+ return Visibility.Collapsed;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+
+ private enum Parameters
+ {
+ Normal,
+ Inverted
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml b/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml
new file mode 100644
index 000000000..f74af0f0b
--- /dev/null
+++ b/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml.cs b/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml.cs
new file mode 100644
index 000000000..fc0034294
--- /dev/null
+++ b/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml.cs
@@ -0,0 +1,26 @@
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Artemis.UI.Shared
+{
+ ///
+ /// Interaction logic for DataModelSelectionView.xaml
+ ///
+ public partial class DataModelSelectionView : UserControl
+ {
+ public DataModelSelectionView()
+ {
+ InitializeComponent();
+ }
+
+ private void PropertyButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ // DataContext is not set when using left button, I don't know why but there it is
+ if (sender is Button button && button.ContextMenu != null)
+ {
+ button.ContextMenu.DataContext = button.DataContext;
+ button.ContextMenu.IsOpen = true;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionViewModel.cs
new file mode 100644
index 000000000..029290827
--- /dev/null
+++ b/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionViewModel.cs
@@ -0,0 +1,134 @@
+using System;
+using System.Timers;
+using System.Windows.Media;
+using Artemis.Core;
+using Artemis.Core.DataModelExpansions;
+using Artemis.Core.Modules;
+using Artemis.Core.Services;
+using Artemis.UI.Shared.Services;
+using Stylet;
+
+// Remove, annoying while working on it
+#pragma warning disable 1591
+
+namespace Artemis.UI.Shared
+{
+ public class DataModelSelectionViewModel : PropertyChangedBase
+ {
+ private readonly IDataModelUIService _dataModelUIService;
+ private readonly Module _module;
+ private readonly Timer _updateTimer;
+ private Brush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188));
+
+ private DataModelPropertiesViewModel _dataModelViewModel;
+ private bool _isDataModelViewModelOpen;
+ private bool _isEnabled;
+ private string _placeholder = "Select a property";
+ private DataModelVisualizationViewModel _selectedPropertyViewModel;
+
+ public DataModelSelectionViewModel(Module module, ISettingsService settingsService, IDataModelUIService dataModelUIService)
+ {
+ _module = module;
+ _dataModelUIService = dataModelUIService;
+ _updateTimer = new Timer(500);
+
+ ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues");
+ SelectPropertyCommand = new DelegateCommand(ExecuteSelectPropertyCommand);
+
+ Initialize();
+ }
+
+ public string Placeholder
+ {
+ get => _placeholder;
+ set => SetAndNotify(ref _placeholder, value);
+ }
+
+ public Brush ButtonBrush
+ {
+ get => _buttonBrush;
+ set => SetAndNotify(ref _buttonBrush, value);
+ }
+
+ public DelegateCommand SelectPropertyCommand { get; }
+ public Type[] FilterTypes { get; set; }
+
+ public PluginSetting ShowDataModelValues { get; }
+
+ public bool IsEnabled
+ {
+ get => _isEnabled;
+ set => SetAndNotify(ref _isEnabled, value);
+ }
+
+ public DataModelPropertiesViewModel DataModelViewModel
+ {
+ get => _dataModelViewModel;
+ private set => SetAndNotify(ref _dataModelViewModel, value);
+ }
+
+ public bool IsDataModelViewModelOpen
+ {
+ get => _isDataModelViewModelOpen;
+ set => SetAndNotify(ref _isDataModelViewModelOpen, value);
+ }
+
+ public DataModelVisualizationViewModel SelectedPropertyViewModel
+ {
+ get => _selectedPropertyViewModel;
+ private set => SetAndNotify(ref _selectedPropertyViewModel, value);
+ }
+
+ public void PopulateSelectedPropertyViewModel(DataModel datamodel, string path)
+ {
+ if (datamodel == null)
+ SelectedPropertyViewModel = null;
+ else
+ SelectedPropertyViewModel = DataModelViewModel.GetChildByPath(datamodel.PluginInfo.Guid, path);
+ }
+
+ private void Initialize()
+ {
+ // Get the data models
+ DataModelViewModel = _dataModelUIService.GetMainDataModelVisualization();
+ if (!_dataModelUIService.GetPluginExtendsDataModel(_module))
+ DataModelViewModel.Children.Add(_dataModelUIService.GetPluginDataModelVisualization(_module));
+
+ DataModelViewModel.UpdateRequested += DataModelOnUpdateRequested;
+
+ _updateTimer.Start();
+ _updateTimer.Elapsed += OnUpdateTimerOnElapsed;
+ }
+
+ private void DataModelOnUpdateRequested(object sender, EventArgs e)
+ {
+ DataModelViewModel.ApplyTypeFilter(true, FilterTypes);
+ }
+
+ private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
+ {
+ if (IsDataModelViewModelOpen)
+ DataModelViewModel.Update(_dataModelUIService);
+ }
+
+ private void ExecuteSelectPropertyCommand(object context)
+ {
+ if (!(context is DataModelVisualizationViewModel selected))
+ return;
+
+ SelectedPropertyViewModel = selected;
+ OnPropertySelected(new DataModelPropertySelectedEventArgs(selected));
+ }
+
+ #region Events
+
+ public event EventHandler PropertySelected;
+
+ protected virtual void OnPropertySelected(DataModelPropertySelectedEventArgs e)
+ {
+ PropertySelected?.Invoke(this, e);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Events/DataModelPropertySelectedEventArgs.cs b/src/Artemis.UI.Shared/Events/DataModelPropertySelectedEventArgs.cs
new file mode 100644
index 000000000..81bb38629
--- /dev/null
+++ b/src/Artemis.UI.Shared/Events/DataModelPropertySelectedEventArgs.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace Artemis.UI.Shared
+{
+ public class DataModelPropertySelectedEventArgs : EventArgs
+ {
+ public DataModelVisualizationViewModel DataModelVisualizationViewModel { get; }
+
+ public DataModelPropertySelectedEventArgs(DataModelVisualizationViewModel dataModelVisualizationViewModel)
+ {
+ DataModelVisualizationViewModel = dataModelVisualizationViewModel;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/ResourceDictionaries/DisplayConditions.xaml b/src/Artemis.UI.Shared/ResourceDictionaries/DisplayConditions.xaml
new file mode 100644
index 000000000..d2834694b
--- /dev/null
+++ b/src/Artemis.UI.Shared/ResourceDictionaries/DisplayConditions.xaml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Services/DataModelUIService.cs b/src/Artemis.UI.Shared/Services/DataModelUIService.cs
index 3c64279b5..b8ead4820 100644
--- a/src/Artemis.UI.Shared/Services/DataModelUIService.cs
+++ b/src/Artemis.UI.Shared/Services/DataModelUIService.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using Artemis.Core;
using Artemis.Core.DataModelExpansions;
+using Artemis.Core.Modules;
using Artemis.Core.Services;
using Ninject;
using Ninject.Parameters;
@@ -178,6 +179,11 @@ namespace Artemis.UI.Shared.Services
}
}
+ public DataModelSelectionViewModel GetDataModelSelectionViewModel(Module module)
+ {
+ return _kernel.Get(new ConstructorArgument("module", module));
+ }
+
private DataModelInputViewModel InstantiateDataModelInputViewModel(DataModelVisualizationRegistration registration, DataModelPropertyAttribute description, object initialValue)
{
// The view models expecting value types shouldn't be given null, avoid that
diff --git a/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs b/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs
index be41d13e6..f4ee8cc13 100644
--- a/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs
+++ b/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using Artemis.Core;
using Artemis.Core.DataModelExpansions;
+using Artemis.Core.Modules;
namespace Artemis.UI.Shared.Services
{
@@ -26,5 +27,7 @@ namespace Artemis.UI.Shared.Services
DataModelDisplayViewModel GetDataModelDisplayViewModel(Type propertyType);
DataModelInputViewModel GetDataModelInputViewModel(Type propertyType, DataModelPropertyAttribute description, object initialValue, Action