mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Node editor - Added VM structure
Debugger - Run updates on UI thread
This commit is contained in:
parent
4c274a1749
commit
c99224ab2d
@ -6,7 +6,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a view model for a plugin configuration window
|
/// Represents a view model for a plugin configuration window
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class PluginConfigurationViewModel : ViewModelBase, IPluginConfigurationViewModel
|
public abstract class PluginConfigurationViewModel : ViewModelValidationBase, IPluginConfigurationViewModel
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the <see cref="PluginConfigurationViewModel" /> class
|
/// Creates a new instance of the <see cref="PluginConfigurationViewModel" /> class
|
||||||
|
|||||||
@ -60,6 +60,33 @@ public abstract class ViewModelValidationBase : ReactiveValidationObject
|
|||||||
get => _displayName;
|
get => _displayName;
|
||||||
set => this.RaiseAndSetIfChanged(ref _displayName, value);
|
set => this.RaiseAndSetIfChanged(ref _displayName, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// RaiseAndSetIfChanged fully implements a Setter for a read-write property on a ReactiveObject, using
|
||||||
|
/// CallerMemberName to raise the notification and the ref to the backing field to set the property.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TRet">The type of the return value.</typeparam>
|
||||||
|
/// <param name="backingField">A Reference to the backing field for this property.</param>
|
||||||
|
/// <param name="newValue">The new value.</param>
|
||||||
|
/// <param name="propertyName">
|
||||||
|
/// The name of the property, usually automatically provided through the CallerMemberName
|
||||||
|
/// attribute.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>The newly set value, normally discarded.</returns>
|
||||||
|
[NotifyPropertyChangedInvocator]
|
||||||
|
public TRet RaiseAndSetIfChanged<TRet>(ref TRet backingField, TRet newValue, [CallerMemberName] string? propertyName = null)
|
||||||
|
{
|
||||||
|
if (propertyName is null)
|
||||||
|
throw new ArgumentNullException(nameof(propertyName));
|
||||||
|
|
||||||
|
if (EqualityComparer<TRet>.Default.Equals(backingField, newValue))
|
||||||
|
return newValue;
|
||||||
|
|
||||||
|
this.RaisePropertyChanging(propertyName);
|
||||||
|
backingField = newValue;
|
||||||
|
this.RaisePropertyChanged(propertyName);
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -90,6 +90,11 @@
|
|||||||
"Splat": "14.1.45"
|
"Splat": "14.1.45"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ArtemisRGB.Plugins.BuildTask": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "1.1.0",
|
||||||
|
"contentHash": "B8A5NkUEzTUgc5M/QACfyjIF5M23EUzSx8A8l/owJtB0bgmij6y/MQW1i/PcS3EDFQRothBOUuC3BCPY5UoRRQ=="
|
||||||
|
},
|
||||||
"Avalonia.Angle.Windows.Natives": {
|
"Avalonia.Angle.Windows.Natives": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "2.1.0.2020091801",
|
"resolved": "2.1.0.2020091801",
|
||||||
@ -560,6 +565,11 @@
|
|||||||
"Ninject": "3.3.3"
|
"Ninject": "3.3.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"OpenRGB.NET": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "1.7.0",
|
||||||
|
"contentHash": "12pMEUaeoG8mN707QRO9hdT529+UnqUpwMW1H/gDTMsJrerhJve6Yt5Dnheu1isQB4PWP1wu3IDVbHCchznkiw=="
|
||||||
|
},
|
||||||
"ReactiveUI.Validation": {
|
"ReactiveUI.Validation": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "2.2.1",
|
"resolved": "2.2.1",
|
||||||
@ -1762,6 +1772,21 @@
|
|||||||
"System.ValueTuple": "4.5.0"
|
"System.ValueTuple": "4.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"artemis.plugins.devices.openrgb": {
|
||||||
|
"type": "Project",
|
||||||
|
"dependencies": {
|
||||||
|
"ArtemisRGB.Plugins.BuildTask": "1.1.0",
|
||||||
|
"Avalonia": "0.10.11",
|
||||||
|
"Avalonia.Controls.DataGrid": "0.10.11",
|
||||||
|
"Avalonia.ReactiveUI": "0.10.11",
|
||||||
|
"Material.Icons.Avalonia": "1.0.2",
|
||||||
|
"OpenRGB.NET": "1.7.0",
|
||||||
|
"RGB.NET.Core": "1.0.0-prerelease7",
|
||||||
|
"ReactiveUI": "16.3.10",
|
||||||
|
"Serilog": "2.10.0",
|
||||||
|
"SkiaSharp": "2.88.0-preview.178"
|
||||||
|
}
|
||||||
|
},
|
||||||
"artemis.storage": {
|
"artemis.storage": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@ -14,6 +14,8 @@ using Artemis.UI.Screens.ProfileEditor.VisualEditor.Visualizers;
|
|||||||
using Artemis.UI.Screens.Settings;
|
using Artemis.UI.Screens.Settings;
|
||||||
using Artemis.UI.Screens.Sidebar;
|
using Artemis.UI.Screens.Sidebar;
|
||||||
using Artemis.UI.Screens.SurfaceEditor;
|
using Artemis.UI.Screens.SurfaceEditor;
|
||||||
|
using Artemis.UI.Screens.VisualScripting;
|
||||||
|
using Artemis.UI.Screens.VisualScripting.Pins;
|
||||||
using Artemis.UI.Services;
|
using Artemis.UI.Services;
|
||||||
using DynamicData.Binding;
|
using DynamicData.Binding;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
@ -87,4 +89,15 @@ namespace Artemis.UI.Ninject.Factories
|
|||||||
ITreePropertyViewModel TreePropertyViewModel(ILayerProperty layerProperty, PropertyViewModel propertyViewModel);
|
ITreePropertyViewModel TreePropertyViewModel(ILayerProperty layerProperty, PropertyViewModel propertyViewModel);
|
||||||
ITimelinePropertyViewModel TimelinePropertyViewModel(ILayerProperty layerProperty, PropertyViewModel propertyViewModel);
|
ITimelinePropertyViewModel TimelinePropertyViewModel(ILayerProperty layerProperty, PropertyViewModel propertyViewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface INodeVmFactory
|
||||||
|
{
|
||||||
|
NodeScriptViewModel NodeScriptViewModel(NodeScript nodeScript);
|
||||||
|
NodePickerViewModel NodePickerViewModel(NodeScript nodeScript);
|
||||||
|
NodeViewModel NodeViewModel(INode node);
|
||||||
|
InputPinCollectionViewModel<T> InputPinCollectionViewModel<T>(InputPinCollection<T> inputPinCollection);
|
||||||
|
InputPinViewModel<T> InputPinViewModel<T>(InputPin<T> inputPin);
|
||||||
|
OutputPinCollectionViewModel<T> OutputPinCollectionViewModel<T>(OutputPinCollection<T> outputPinCollection);
|
||||||
|
OutputPinViewModel<T> OutputPinViewModel<T>(OutputPin<T> outputPin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -4,144 +4,145 @@ using System.Collections.ObjectModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Timers;
|
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Modules;
|
using Artemis.Core.Modules;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.DataModelVisualization.Shared;
|
using Artemis.UI.Shared.DataModelVisualization.Shared;
|
||||||
using Artemis.UI.Shared.Services.Interfaces;
|
using Artemis.UI.Shared.Services.Interfaces;
|
||||||
|
using Avalonia.Threading;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Debugger.DataModel
|
namespace Artemis.UI.Screens.Debugger.DataModel;
|
||||||
|
|
||||||
|
public class DataModelDebugViewModel : ActivatableViewModelBase, IRoutableViewModel
|
||||||
{
|
{
|
||||||
public class DataModelDebugViewModel : ActivatableViewModelBase, IRoutableViewModel
|
private readonly IDataModelUIService _dataModelUIService;
|
||||||
|
private readonly IPluginManagementService _pluginManagementService;
|
||||||
|
private readonly DispatcherTimer _updateTimer;
|
||||||
|
|
||||||
|
private bool _isModuleFilterEnabled;
|
||||||
|
private DataModelPropertiesViewModel? _mainDataModel;
|
||||||
|
private string? _propertySearch;
|
||||||
|
private Module? _selectedModule;
|
||||||
|
private bool _slowUpdates;
|
||||||
|
|
||||||
|
public DataModelDebugViewModel(IScreen hostScreen, IDataModelUIService dataModelUIService, IPluginManagementService pluginManagementService)
|
||||||
{
|
{
|
||||||
private readonly IDataModelUIService _dataModelUIService;
|
_dataModelUIService = dataModelUIService;
|
||||||
private readonly IPluginManagementService _pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
private readonly Timer _updateTimer;
|
_updateTimer = new DispatcherTimer(TimeSpan.FromMilliseconds(25), DispatcherPriority.Normal, (_, _) => Update());
|
||||||
|
|
||||||
private bool _isModuleFilterEnabled;
|
HostScreen = hostScreen;
|
||||||
private DataModelPropertiesViewModel? _mainDataModel;
|
Modules = new ObservableCollection<Module>();
|
||||||
private string? _propertySearch;
|
|
||||||
private Module? _selectedModule;
|
this.WhenActivated(disposables =>
|
||||||
private bool _slowUpdates;
|
|
||||||
|
|
||||||
public DataModelDebugViewModel(IScreen hostScreen, IDataModelUIService dataModelUIService, IPluginManagementService pluginManagementService)
|
|
||||||
{
|
{
|
||||||
_dataModelUIService = dataModelUIService;
|
Observable.FromEventPattern<PluginFeatureEventArgs>(x => pluginManagementService.PluginFeatureEnabled += x, x => pluginManagementService.PluginFeatureEnabled -= x)
|
||||||
_pluginManagementService = pluginManagementService;
|
.Subscribe(d => PluginFeatureToggled(d.EventArgs.PluginFeature))
|
||||||
_updateTimer = new Timer(25);
|
.DisposeWith(disposables);
|
||||||
_updateTimer.Elapsed += UpdateTimerOnElapsed;
|
Observable.FromEventPattern<PluginFeatureEventArgs>(x => pluginManagementService.PluginFeatureDisabled += x, x => pluginManagementService.PluginFeatureDisabled -= x)
|
||||||
|
.Subscribe(d => PluginFeatureToggled(d.EventArgs.PluginFeature))
|
||||||
|
.DisposeWith(disposables);
|
||||||
|
|
||||||
HostScreen = hostScreen;
|
GetDataModel();
|
||||||
Modules = new ObservableCollection<Module>();
|
_updateTimer.Start();
|
||||||
|
Disposable.Create(() => _updateTimer.Stop()).DisposeWith(disposables);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.WhenActivated(disposables =>
|
public DataModelPropertiesViewModel? MainDataModel
|
||||||
{
|
{
|
||||||
Observable.FromEventPattern<PluginFeatureEventArgs>(x => pluginManagementService.PluginFeatureEnabled += x, x => pluginManagementService.PluginFeatureEnabled -= x)
|
get => _mainDataModel;
|
||||||
.Subscribe(d => PluginFeatureToggled(d.EventArgs.PluginFeature))
|
set => RaiseAndSetIfChanged(ref _mainDataModel, value);
|
||||||
.DisposeWith(disposables);
|
}
|
||||||
Observable.FromEventPattern<PluginFeatureEventArgs>(x => pluginManagementService.PluginFeatureDisabled += x, x => pluginManagementService.PluginFeatureDisabled -= x)
|
|
||||||
.Subscribe(d => PluginFeatureToggled(d.EventArgs.PluginFeature))
|
|
||||||
.DisposeWith(disposables);
|
|
||||||
|
|
||||||
GetDataModel();
|
public string? PropertySearch
|
||||||
_updateTimer.Start();
|
{
|
||||||
Disposable.Create(() => _updateTimer.Stop()).DisposeWith(disposables);
|
get => _propertySearch;
|
||||||
});
|
set => RaiseAndSetIfChanged(ref _propertySearch, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string UrlPathSegment => "data-model";
|
public bool SlowUpdates
|
||||||
public IScreen HostScreen { get; }
|
{
|
||||||
|
get => _slowUpdates;
|
||||||
public DataModelPropertiesViewModel? MainDataModel
|
set
|
||||||
{
|
{
|
||||||
get => _mainDataModel;
|
RaiseAndSetIfChanged(ref _slowUpdates, value);
|
||||||
set => RaiseAndSetIfChanged(ref _mainDataModel, value);
|
_updateTimer.Interval = TimeSpan.FromMilliseconds(_slowUpdates ? 500 : 25);
|
||||||
}
|
|
||||||
|
|
||||||
public string? PropertySearch
|
|
||||||
{
|
|
||||||
get => _propertySearch;
|
|
||||||
set => RaiseAndSetIfChanged(ref _propertySearch, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SlowUpdates
|
|
||||||
{
|
|
||||||
get => _slowUpdates;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
RaiseAndSetIfChanged(ref _slowUpdates, value);
|
|
||||||
_updateTimer.Interval = _slowUpdates ? 500 : 25;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableCollection<Module> Modules { get; }
|
|
||||||
|
|
||||||
public Module? SelectedModule
|
|
||||||
{
|
|
||||||
get => _selectedModule;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
RaiseAndSetIfChanged(ref _selectedModule, value);
|
|
||||||
GetDataModel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsModuleFilterEnabled
|
|
||||||
{
|
|
||||||
get => _isModuleFilterEnabled;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
RaiseAndSetIfChanged(ref _isModuleFilterEnabled, value);
|
|
||||||
|
|
||||||
if (!IsModuleFilterEnabled)
|
|
||||||
SelectedModule = null;
|
|
||||||
else
|
|
||||||
GetDataModel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void UpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
|
|
||||||
{
|
|
||||||
if (MainDataModel == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
lock (MainDataModel)
|
|
||||||
{
|
|
||||||
MainDataModel.Update(_dataModelUIService, new DataModelUpdateConfiguration(true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PluginFeatureToggled(PluginFeature pluginFeature)
|
|
||||||
{
|
|
||||||
if (pluginFeature is Module)
|
|
||||||
PopulateModules();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GetDataModel()
|
|
||||||
{
|
|
||||||
MainDataModel = SelectedModule != null
|
|
||||||
? _dataModelUIService.GetPluginDataModelVisualization(new List<Module>() { SelectedModule }, false)
|
|
||||||
: _dataModelUIService.GetMainDataModelVisualization();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PopulateModules()
|
|
||||||
{
|
|
||||||
Modules.Clear();
|
|
||||||
Modules.AddRange(_pluginManagementService.GetFeaturesOfType<Module>().Where(p => p.IsEnabled).OrderBy(m => m.Info.Name));
|
|
||||||
|
|
||||||
if (MainDataModel == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (SelectedModule == null)
|
|
||||||
{
|
|
||||||
if (MainDataModel != null)
|
|
||||||
_dataModelUIService.UpdateModules(MainDataModel);
|
|
||||||
}
|
|
||||||
else if (!SelectedModule.IsEnabled)
|
|
||||||
SelectedModule = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ObservableCollection<Module> Modules { get; }
|
||||||
|
|
||||||
|
public Module? SelectedModule
|
||||||
|
{
|
||||||
|
get => _selectedModule;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
RaiseAndSetIfChanged(ref _selectedModule, value);
|
||||||
|
GetDataModel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsModuleFilterEnabled
|
||||||
|
{
|
||||||
|
get => _isModuleFilterEnabled;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
RaiseAndSetIfChanged(ref _isModuleFilterEnabled, value);
|
||||||
|
|
||||||
|
if (!IsModuleFilterEnabled)
|
||||||
|
SelectedModule = null;
|
||||||
|
else
|
||||||
|
GetDataModel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (MainDataModel == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lock (MainDataModel)
|
||||||
|
{
|
||||||
|
MainDataModel.Update(_dataModelUIService, new DataModelUpdateConfiguration(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PluginFeatureToggled(PluginFeature pluginFeature)
|
||||||
|
{
|
||||||
|
if (pluginFeature is Module)
|
||||||
|
PopulateModules();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetDataModel()
|
||||||
|
{
|
||||||
|
MainDataModel = SelectedModule != null
|
||||||
|
? _dataModelUIService.GetPluginDataModelVisualization(new List<Module> {SelectedModule}, false)
|
||||||
|
: _dataModelUIService.GetMainDataModelVisualization();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopulateModules()
|
||||||
|
{
|
||||||
|
Modules.Clear();
|
||||||
|
Modules.AddRange(_pluginManagementService.GetFeaturesOfType<Module>().Where(p => p.IsEnabled).OrderBy(m => m.Info.Name));
|
||||||
|
|
||||||
|
if (MainDataModel == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (SelectedModule == null)
|
||||||
|
{
|
||||||
|
if (MainDataModel != null)
|
||||||
|
_dataModelUIService.UpdateModules(MainDataModel);
|
||||||
|
}
|
||||||
|
else if (!SelectedModule.IsEnabled)
|
||||||
|
{
|
||||||
|
SelectedModule = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string UrlPathSegment => "data-model";
|
||||||
|
public IScreen HostScreen { get; }
|
||||||
}
|
}
|
||||||
@ -3,129 +3,128 @@ using System.Collections.ObjectModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Timers;
|
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
|
using Avalonia.Threading;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Debugger.Performance
|
namespace Artemis.UI.Screens.Debugger.Performance;
|
||||||
|
|
||||||
|
public class PerformanceDebugViewModel : ActivatableViewModelBase, IRoutableViewModel
|
||||||
{
|
{
|
||||||
public class PerformanceDebugViewModel : ActivatableViewModelBase, IRoutableViewModel
|
private readonly ICoreService _coreService;
|
||||||
|
private readonly IPluginManagementService _pluginManagementService;
|
||||||
|
private readonly DispatcherTimer _updateTimer;
|
||||||
|
private double _currentFps;
|
||||||
|
private string? _renderer;
|
||||||
|
private int _renderHeight;
|
||||||
|
private int _renderWidth;
|
||||||
|
|
||||||
|
public PerformanceDebugViewModel(IScreen hostScreen, ICoreService coreService, IPluginManagementService pluginManagementService)
|
||||||
{
|
{
|
||||||
private readonly ICoreService _coreService;
|
HostScreen = hostScreen;
|
||||||
private readonly IPluginManagementService _pluginManagementService;
|
_coreService = coreService;
|
||||||
private double _currentFps;
|
_pluginManagementService = pluginManagementService;
|
||||||
private string? _renderer;
|
_updateTimer = new DispatcherTimer(TimeSpan.FromMilliseconds(500), DispatcherPriority.Normal, (_, _) => Update());
|
||||||
private int _renderHeight;
|
|
||||||
private int _renderWidth;
|
|
||||||
|
|
||||||
public PerformanceDebugViewModel(IScreen hostScreen, ICoreService coreService, IPluginManagementService pluginManagementService)
|
this.WhenActivated(disposables =>
|
||||||
{
|
{
|
||||||
HostScreen = hostScreen;
|
Observable.FromEventPattern<PluginFeatureEventArgs>(x => pluginManagementService.PluginFeatureEnabled += x, x => pluginManagementService.PluginFeatureEnabled -= x)
|
||||||
_coreService = coreService;
|
.Subscribe(_ => Repopulate())
|
||||||
_pluginManagementService = pluginManagementService;
|
.DisposeWith(disposables);
|
||||||
|
Observable.FromEventPattern<PluginFeatureEventArgs>(x => pluginManagementService.PluginFeatureDisabled += x, x => pluginManagementService.PluginFeatureDisabled -= x)
|
||||||
|
.Subscribe(_ => Repopulate())
|
||||||
|
.DisposeWith(disposables);
|
||||||
|
Observable.FromEventPattern<PluginEventArgs>(x => pluginManagementService.PluginEnabled += x, x => pluginManagementService.PluginEnabled -= x)
|
||||||
|
.Subscribe(_ => Repopulate())
|
||||||
|
.DisposeWith(disposables);
|
||||||
|
Observable.FromEventPattern<PluginEventArgs>(x => pluginManagementService.PluginDisabled += x, x => pluginManagementService.PluginDisabled -= x)
|
||||||
|
.Subscribe(_ => Repopulate())
|
||||||
|
.DisposeWith(disposables);
|
||||||
|
|
||||||
Timer updateTimer = new(500);
|
HandleActivation();
|
||||||
updateTimer.Elapsed += UpdateTimerOnElapsed;
|
|
||||||
|
|
||||||
this.WhenActivated(disposables =>
|
|
||||||
{
|
|
||||||
Observable.FromEventPattern<PluginFeatureEventArgs>(x => pluginManagementService.PluginFeatureEnabled += x, x => pluginManagementService.PluginFeatureEnabled -= x)
|
|
||||||
.Subscribe(_ => Repopulate())
|
|
||||||
.DisposeWith(disposables);
|
|
||||||
Observable.FromEventPattern<PluginFeatureEventArgs>(x => pluginManagementService.PluginFeatureDisabled += x, x => pluginManagementService.PluginFeatureDisabled -= x)
|
|
||||||
.Subscribe(_ => Repopulate())
|
|
||||||
.DisposeWith(disposables);
|
|
||||||
Observable.FromEventPattern<PluginEventArgs>(x => pluginManagementService.PluginEnabled += x, x => pluginManagementService.PluginEnabled -= x)
|
|
||||||
.Subscribe(_ => Repopulate())
|
|
||||||
.DisposeWith(disposables);
|
|
||||||
Observable.FromEventPattern<PluginEventArgs>(x => pluginManagementService.PluginDisabled += x, x => pluginManagementService.PluginDisabled -= x)
|
|
||||||
.Subscribe(_ => Repopulate())
|
|
||||||
.DisposeWith(disposables);
|
|
||||||
|
|
||||||
HandleActivation();
|
|
||||||
PopulateItems();
|
|
||||||
updateTimer.Start();
|
|
||||||
|
|
||||||
Disposable.Create(() =>
|
|
||||||
{
|
|
||||||
updateTimer.Stop();
|
|
||||||
Items.Clear();
|
|
||||||
HandleDeactivation();
|
|
||||||
}).DisposeWith(disposables);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public string UrlPathSegment => "performance";
|
|
||||||
public IScreen HostScreen { get; }
|
|
||||||
public ObservableCollection<PerformanceDebugPluginViewModel> Items { get; } = new();
|
|
||||||
|
|
||||||
public double CurrentFps
|
|
||||||
{
|
|
||||||
get => _currentFps;
|
|
||||||
set => RaiseAndSetIfChanged(ref _currentFps, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int RenderWidth
|
|
||||||
{
|
|
||||||
get => _renderWidth;
|
|
||||||
set => RaiseAndSetIfChanged(ref _renderWidth, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int RenderHeight
|
|
||||||
{
|
|
||||||
get => _renderHeight;
|
|
||||||
set => RaiseAndSetIfChanged(ref _renderHeight, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string? Renderer
|
|
||||||
{
|
|
||||||
get => _renderer;
|
|
||||||
set => RaiseAndSetIfChanged(ref _renderer, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleActivation()
|
|
||||||
{
|
|
||||||
Renderer = Constants.ManagedGraphicsContext != null ? Constants.ManagedGraphicsContext.GetType().Name : "Software";
|
|
||||||
_coreService.FrameRendered += CoreServiceOnFrameRendered;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleDeactivation()
|
|
||||||
{
|
|
||||||
_coreService.FrameRendered -= CoreServiceOnFrameRendered;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PopulateItems()
|
|
||||||
{
|
|
||||||
foreach (PerformanceDebugPluginViewModel performanceDebugPluginViewModel in _pluginManagementService.GetAllPlugins()
|
|
||||||
.Where(p => p.IsEnabled && p.Profilers.Any(pr => pr.Measurements.Any()))
|
|
||||||
.OrderBy(p => p.Info.Name)
|
|
||||||
.Select(p => new PerformanceDebugPluginViewModel(p)))
|
|
||||||
Items.Add(performanceDebugPluginViewModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Repopulate()
|
|
||||||
{
|
|
||||||
Items.Clear();
|
|
||||||
PopulateItems();
|
PopulateItems();
|
||||||
}
|
_updateTimer.Start();
|
||||||
|
|
||||||
private void UpdateTimerOnElapsed(object? sender, ElapsedEventArgs e)
|
Disposable.Create(() =>
|
||||||
{
|
{
|
||||||
foreach (PerformanceDebugPluginViewModel viewModel in Items)
|
_updateTimer.Stop();
|
||||||
viewModel.Update();
|
Items.Clear();
|
||||||
}
|
HandleDeactivation();
|
||||||
|
}).DisposeWith(disposables);
|
||||||
private void CoreServiceOnFrameRendered(object? sender, FrameRenderedEventArgs e)
|
});
|
||||||
{
|
|
||||||
CurrentFps = _coreService.FrameRate;
|
|
||||||
SKImageInfo bitmapInfo = e.Texture.ImageInfo;
|
|
||||||
|
|
||||||
RenderHeight = bitmapInfo.Height;
|
|
||||||
RenderWidth = bitmapInfo.Width;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ObservableCollection<PerformanceDebugPluginViewModel> Items { get; } = new();
|
||||||
|
|
||||||
|
public double CurrentFps
|
||||||
|
{
|
||||||
|
get => _currentFps;
|
||||||
|
set => RaiseAndSetIfChanged(ref _currentFps, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int RenderWidth
|
||||||
|
{
|
||||||
|
get => _renderWidth;
|
||||||
|
set => RaiseAndSetIfChanged(ref _renderWidth, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int RenderHeight
|
||||||
|
{
|
||||||
|
get => _renderHeight;
|
||||||
|
set => RaiseAndSetIfChanged(ref _renderHeight, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string? Renderer
|
||||||
|
{
|
||||||
|
get => _renderer;
|
||||||
|
set => RaiseAndSetIfChanged(ref _renderer, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleActivation()
|
||||||
|
{
|
||||||
|
Renderer = Constants.ManagedGraphicsContext != null ? Constants.ManagedGraphicsContext.GetType().Name : "Software";
|
||||||
|
_coreService.FrameRendered += CoreServiceOnFrameRendered;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleDeactivation()
|
||||||
|
{
|
||||||
|
_coreService.FrameRendered -= CoreServiceOnFrameRendered;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopulateItems()
|
||||||
|
{
|
||||||
|
foreach (PerformanceDebugPluginViewModel performanceDebugPluginViewModel in _pluginManagementService.GetAllPlugins()
|
||||||
|
.Where(p => p.IsEnabled && p.Profilers.Any(pr => pr.Measurements.Any()))
|
||||||
|
.OrderBy(p => p.Info.Name)
|
||||||
|
.Select(p => new PerformanceDebugPluginViewModel(p)))
|
||||||
|
Items.Add(performanceDebugPluginViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Repopulate()
|
||||||
|
{
|
||||||
|
Items.Clear();
|
||||||
|
PopulateItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
foreach (PerformanceDebugPluginViewModel viewModel in Items)
|
||||||
|
viewModel.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CoreServiceOnFrameRendered(object? sender, FrameRenderedEventArgs e)
|
||||||
|
{
|
||||||
|
CurrentFps = _coreService.FrameRate;
|
||||||
|
SKImageInfo bitmapInfo = e.Texture.ImageInfo;
|
||||||
|
|
||||||
|
RenderHeight = bitmapInfo.Height;
|
||||||
|
RenderWidth = bitmapInfo.Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public string UrlPathSegment => "performance";
|
||||||
|
public IScreen HostScreen { get; }
|
||||||
}
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Artemis.UI.Screens.VisualScripting.CableView">
|
||||||
|
Welcome to Avalonia!
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting
|
||||||
|
{
|
||||||
|
public partial class CableView : ReactiveUserControl<CableViewModel>
|
||||||
|
{
|
||||||
|
public CableView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
using Artemis.UI.Screens.VisualScripting.Pins;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting;
|
||||||
|
|
||||||
|
public class CableViewModel : ActivatableViewModelBase
|
||||||
|
{
|
||||||
|
private PinViewModel _from;
|
||||||
|
private PinViewModel _to;
|
||||||
|
|
||||||
|
public CableViewModel(PinViewModel from, PinViewModel to)
|
||||||
|
{
|
||||||
|
_from = from;
|
||||||
|
_to = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PinViewModel From
|
||||||
|
{
|
||||||
|
get => _from;
|
||||||
|
set => RaiseAndSetIfChanged(ref _from, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PinViewModel To
|
||||||
|
{
|
||||||
|
get => _to;
|
||||||
|
set => RaiseAndSetIfChanged(ref _to, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:visualScripting="clr-namespace:Artemis.UI.Screens.VisualScripting"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Artemis.UI.Screens.VisualScripting.NodePickerView"
|
||||||
|
x:DataType="visualScripting:NodePickerViewModel">
|
||||||
|
<UserControl.Styles>
|
||||||
|
<Style Selector="Border.picker-container">
|
||||||
|
|
||||||
|
</Style>
|
||||||
|
<Style Selector="Border.picker-container-hidden">
|
||||||
|
<Style.Animations>
|
||||||
|
<Animation Duration="0:0:1">
|
||||||
|
<KeyFrame Cue="0%">
|
||||||
|
<Setter Property="Opacity" Value="1.0" />
|
||||||
|
</KeyFrame>
|
||||||
|
<KeyFrame Cue="100%">
|
||||||
|
<Setter Property="Opacity" Value="0.0" />
|
||||||
|
<Setter Property="IsVisible" Value="False" />
|
||||||
|
</KeyFrame>
|
||||||
|
</Animation>
|
||||||
|
</Style.Animations>
|
||||||
|
</Style>
|
||||||
|
<Style Selector="Border.picker-container-visible">
|
||||||
|
<Style.Animations>
|
||||||
|
<Animation Duration="0:0:1">
|
||||||
|
<KeyFrame Cue="0%">
|
||||||
|
<Setter Property="Opacity" Value="0.0" />
|
||||||
|
<Setter Property="IsVisible" Value="True" />
|
||||||
|
</KeyFrame>
|
||||||
|
<KeyFrame Cue="100%">
|
||||||
|
<Setter Property="Opacity" Value="1.0" />
|
||||||
|
</KeyFrame>
|
||||||
|
</Animation>
|
||||||
|
</Style.Animations>
|
||||||
|
</Style>
|
||||||
|
</UserControl.Styles>
|
||||||
|
<Border Classes="grid picker-container"
|
||||||
|
Classes.picker-container-hidden="{CompiledBinding !IsVisible}"
|
||||||
|
Classes.picker-container-visible="{CompiledBinding !IsVisible}">
|
||||||
|
<TextBlock>Test</TextBlock>
|
||||||
|
</Border>
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting
|
||||||
|
{
|
||||||
|
public partial class NodePickerView : ReactiveUserControl<NodePickerViewModel>
|
||||||
|
{
|
||||||
|
public NodePickerView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
using Avalonia;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting;
|
||||||
|
|
||||||
|
public class NodePickerViewModel : ActivatableViewModelBase
|
||||||
|
{
|
||||||
|
private readonly INodeService _nodeService;
|
||||||
|
|
||||||
|
private bool _isVisible;
|
||||||
|
private Point _position;
|
||||||
|
|
||||||
|
public bool IsVisible
|
||||||
|
{
|
||||||
|
get => _isVisible;
|
||||||
|
set => RaiseAndSetIfChanged(ref _isVisible, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point Position
|
||||||
|
{
|
||||||
|
get => _position;
|
||||||
|
set => RaiseAndSetIfChanged(ref _position, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NodePickerViewModel(INodeService nodeService)
|
||||||
|
{
|
||||||
|
_nodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Show(Point position)
|
||||||
|
{
|
||||||
|
IsVisible = true;
|
||||||
|
Position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Hide()
|
||||||
|
{
|
||||||
|
IsVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:visualScripting="clr-namespace:Artemis.UI.Screens.VisualScripting"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Artemis.UI.Screens.VisualScripting.NodeScriptView"
|
||||||
|
x:DataType="visualScripting:NodeScriptViewModel">
|
||||||
|
<Canvas PointerReleased="InputElement_OnPointerReleased">
|
||||||
|
<!-- Cables -->
|
||||||
|
|
||||||
|
<!-- Nodes -->
|
||||||
|
|
||||||
|
<!-- Flyout -->
|
||||||
|
<ContentControl Content="{CompiledBinding NodePickerViewModel}"
|
||||||
|
Canvas.Left="{CompiledBinding NodePickerViewModel.Position.X}"
|
||||||
|
Canvas.Top="{CompiledBinding NodePickerViewModel.Position.Y}"/>
|
||||||
|
</Canvas>
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Input;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting
|
||||||
|
{
|
||||||
|
public partial class NodeScriptView : ReactiveUserControl<NodeScriptViewModel>
|
||||||
|
{
|
||||||
|
public NodeScriptView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InputElement_OnPointerReleased(object? sender, PointerReleasedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.InitialPressMouseButton == MouseButton.Right)
|
||||||
|
ViewModel?.ShowNodePicker(e.GetCurrentPoint(this).Position);
|
||||||
|
if (e.InitialPressMouseButton == MouseButton.Left)
|
||||||
|
ViewModel?.HideNodePicker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.Core.Events;
|
||||||
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.UI.Ninject.Factories;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls.Mixins;
|
||||||
|
using ReactiveUI;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting;
|
||||||
|
|
||||||
|
public class NodeScriptViewModel : ActivatableViewModelBase
|
||||||
|
{
|
||||||
|
private readonly INodeService _nodeService;
|
||||||
|
private readonly INodeVmFactory _nodeVmFactory;
|
||||||
|
|
||||||
|
public NodeScriptViewModel(NodeScript nodeScript, INodeVmFactory nodeVmFactory, INodeService nodeService)
|
||||||
|
{
|
||||||
|
_nodeVmFactory = nodeVmFactory;
|
||||||
|
_nodeService = nodeService;
|
||||||
|
|
||||||
|
NodeScript = nodeScript;
|
||||||
|
NodePickerViewModel = _nodeVmFactory.NodePickerViewModel(nodeScript);
|
||||||
|
|
||||||
|
this.WhenActivated(d =>
|
||||||
|
{
|
||||||
|
Observable.FromEventPattern<SingleValueEventArgs<INode>>(x => NodeScript.NodeAdded += x, x => NodeScript.NodeAdded -= x)
|
||||||
|
.Subscribe(e => HandleNodeAdded(e.EventArgs))
|
||||||
|
.DisposeWith(d);
|
||||||
|
Observable.FromEventPattern<SingleValueEventArgs<INode>>(x => NodeScript.NodeRemoved += x, x => NodeScript.NodeRemoved -= x)
|
||||||
|
.Subscribe(e => HandleNodeRemoved(e.EventArgs))
|
||||||
|
.DisposeWith(d);
|
||||||
|
});
|
||||||
|
|
||||||
|
NodeViewModels = new ObservableCollection<NodeViewModel>();
|
||||||
|
foreach (INode nodeScriptNode in NodeScript.Nodes)
|
||||||
|
NodeViewModels.Add(_nodeVmFactory.NodeViewModel(nodeScriptNode));
|
||||||
|
}
|
||||||
|
|
||||||
|
public NodeScript NodeScript { get; }
|
||||||
|
public ObservableCollection<NodeViewModel> NodeViewModels { get; }
|
||||||
|
public NodePickerViewModel NodePickerViewModel { get; }
|
||||||
|
|
||||||
|
|
||||||
|
private void HandleNodeAdded(SingleValueEventArgs<INode> eventArgs)
|
||||||
|
{
|
||||||
|
NodeViewModels.Add(_nodeVmFactory.NodeViewModel(eventArgs.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleNodeRemoved(SingleValueEventArgs<INode> eventArgs)
|
||||||
|
{
|
||||||
|
NodeViewModel? toRemove = NodeViewModels.FirstOrDefault(vm => vm.Node == eventArgs.Value);
|
||||||
|
if (toRemove != null)
|
||||||
|
NodeViewModels.Remove(toRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowNodePicker(Point position)
|
||||||
|
{
|
||||||
|
NodePickerViewModel.Show(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HideNodePicker()
|
||||||
|
{
|
||||||
|
NodePickerViewModel.Hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Artemis.UI.Screens.VisualScripting.NodeView">
|
||||||
|
Welcome to Avalonia!
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting
|
||||||
|
{
|
||||||
|
public partial class NodeView : ReactiveUserControl<NodeViewModel>
|
||||||
|
{
|
||||||
|
public NodeView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
using Avalonia;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting;
|
||||||
|
|
||||||
|
public class NodeViewModel : ActivatableViewModelBase
|
||||||
|
{
|
||||||
|
private Point _position;
|
||||||
|
|
||||||
|
public NodeViewModel(INode node)
|
||||||
|
{
|
||||||
|
Node = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public INode Node { get; }
|
||||||
|
|
||||||
|
public Point Position
|
||||||
|
{
|
||||||
|
get => _position;
|
||||||
|
set => RaiseAndSetIfChanged(ref _position, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Artemis.UI.Screens.VisualScripting.Pins.InputPinCollectionView">
|
||||||
|
Welcome to Avalonia!
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting.Pins
|
||||||
|
{
|
||||||
|
public partial class InputPinCollectionView : ReactiveUserControl<PinCollectionViewModel>
|
||||||
|
{
|
||||||
|
public InputPinCollectionView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting.Pins;
|
||||||
|
|
||||||
|
public class InputPinCollectionViewModel<T> : PinCollectionViewModel
|
||||||
|
{
|
||||||
|
public InputPinCollection<T> InputPinCollection { get; }
|
||||||
|
|
||||||
|
public InputPinCollectionViewModel(InputPinCollection<T> inputPinCollection) : base(inputPinCollection)
|
||||||
|
{
|
||||||
|
InputPinCollection = inputPinCollection;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Artemis.UI.Screens.VisualScripting.Pins.InputPinView">
|
||||||
|
Welcome to Avalonia!
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting.Pins
|
||||||
|
{
|
||||||
|
public partial class InputPinView : ReactiveUserControl<PinViewModel>
|
||||||
|
{
|
||||||
|
public InputPinView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting.Pins;
|
||||||
|
|
||||||
|
public class InputPinViewModel<T> : PinViewModel
|
||||||
|
{
|
||||||
|
public InputPin<T> InputPin { get; }
|
||||||
|
|
||||||
|
public InputPinViewModel(InputPin<T> inputPin) : base(inputPin)
|
||||||
|
{
|
||||||
|
InputPin = inputPin;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Artemis.UI.Screens.VisualScripting.Pins.OutputPinCollectionView">
|
||||||
|
Welcome to Avalonia!
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting.Pins
|
||||||
|
{
|
||||||
|
public partial class OutputPinCollectionView : ReactiveUserControl<PinCollectionViewModel>
|
||||||
|
{
|
||||||
|
public OutputPinCollectionView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting.Pins;
|
||||||
|
|
||||||
|
public class OutputPinCollectionViewModel<T> : PinCollectionViewModel
|
||||||
|
{
|
||||||
|
public OutputPinCollection<T> OutputPinCollection { get; }
|
||||||
|
|
||||||
|
public OutputPinCollectionViewModel(OutputPinCollection<T> outputPinCollection) : base(outputPinCollection)
|
||||||
|
{
|
||||||
|
OutputPinCollection = outputPinCollection;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Artemis.UI.Screens.VisualScripting.Pins.OutputPinView">
|
||||||
|
Welcome to Avalonia!
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting.Pins
|
||||||
|
{
|
||||||
|
public partial class OutputPinView : ReactiveUserControl<PinViewModel>
|
||||||
|
{
|
||||||
|
public OutputPinView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting.Pins;
|
||||||
|
|
||||||
|
public class OutputPinViewModel<T> : PinViewModel
|
||||||
|
{
|
||||||
|
public OutputPin<T> OutputPin { get; }
|
||||||
|
|
||||||
|
public OutputPinViewModel(OutputPin<T> outputPin) : base(outputPin)
|
||||||
|
{
|
||||||
|
OutputPin = outputPin;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting.Pins;
|
||||||
|
|
||||||
|
public abstract class PinCollectionViewModel : ActivatableViewModelBase
|
||||||
|
{
|
||||||
|
public PinCollection PinCollection { get; }
|
||||||
|
|
||||||
|
protected PinCollectionViewModel(PinCollection pinCollection)
|
||||||
|
{
|
||||||
|
PinCollection = pinCollection;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.VisualScripting.Pins;
|
||||||
|
|
||||||
|
public abstract class PinViewModel : ActivatableViewModelBase
|
||||||
|
{
|
||||||
|
protected PinViewModel(IPin pin)
|
||||||
|
{
|
||||||
|
Pin = pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPin Pin { get; }
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user