Meta - Replace WPF projects with Avalonia projects

This commit is contained in:
Robert committed 2022-03-27 11:55:26 +02:00
1 parent fcf0376a9a
commit d7f3ee1190
1110 files changed
+10872 -52240

No files matched your search

@@ -0,0 +1,32 @@
<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:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:pins="clr-namespace:Artemis.UI.Screens.VisualScripting.Pins"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.VisualScripting.Pins.InputPinCollectionView"
x:DataType="pins:PinCollectionViewModel">
<StackPanel>
<Button Classes="icon-button icon-button-small pin-collection-button"
ToolTip.Tip="Add new pin"
Command="{CompiledBinding AddPin}">
<avalonia:MaterialIcon Kind="Add"></avalonia:MaterialIcon>
</Button>
<ItemsControl Items="{CompiledBinding PinViewModels}" Margin="4 0">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="pins:PinViewModel">
<StackPanel Orientation="Horizontal">
<ContentControl Content="{CompiledBinding}"></ContentControl>
<Button Classes="icon-button icon-button-small"
ToolTip.Tip="Remove pin"
Command="{CompiledBinding RemovePin}"
CommandParameter="{CompiledBinding Pin}">
<avalonia:MaterialIcon Kind="Close"></avalonia:MaterialIcon>
</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</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,25 @@
using Artemis.Core;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Shared.Services.NodeEditor;
namespace Artemis.UI.Screens.VisualScripting.Pins;
public class InputPinCollectionViewModel : PinCollectionViewModel
{
private readonly INodeVmFactory _nodeVmFactory;
public IPinCollection InputPinCollection { get; }
public InputPinCollectionViewModel(IPinCollection inputPinCollection, NodeScriptViewModel nodeScriptViewModel, INodeVmFactory nodeVmFactory, INodeEditorService nodeEditorService)
: base(inputPinCollection, nodeScriptViewModel, nodeEditorService)
{
_nodeVmFactory = nodeVmFactory;
InputPinCollection = inputPinCollection;
}
protected override PinViewModel CreatePinViewModel(IPin pin)
{
PinViewModel vm = _nodeVmFactory.InputPinViewModel(pin);
vm.RemovePin = RemovePin;
return vm;
}
}
@@ -0,0 +1,31 @@
<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:pins="clr-namespace:Artemis.UI.Screens.VisualScripting.Pins"
mc:Ignorable="d"
d:DesignWidth="200"
x:Class="Artemis.UI.Screens.VisualScripting.Pins.InputPinView"
x:DataType="pins:PinViewModel">
<UserControl.Styles>
<StyleInclude Source="/Screens/VisualScripting/VisualScripting.axaml" />
<Style Selector="StackPanel#PinContainer Border#VisualPinPoint">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="{CompiledBinding DarkenedPinColor}"></SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="{CompiledBinding PinColor}"></SolidColorBrush>
</Setter.Value>
</Setter>
</Style>
</UserControl.Styles>
<StackPanel Name="PinContainer" Orientation="Horizontal" Spacing="6">
<Border Name="PinPoint">
<Border Name="VisualPinPoint" />
</Border>
<TextBlock Name="PinName" VerticalAlignment="Center" Text="{CompiledBinding Pin.Name}" />
</StackPanel>
</UserControl>
@@ -0,0 +1,18 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.VisualScripting.Pins;
public class InputPinView : PinView
{
public InputPinView()
{
InitializeComponent();
InitializePin(this.Get<Border>("PinPoint"));
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
@@ -0,0 +1,11 @@
using Artemis.Core;
using Artemis.Core.Services;
namespace Artemis.UI.Screens.VisualScripting.Pins;
public class InputPinViewModel : PinViewModel
{
public InputPinViewModel(IPin inputPin, INodeService nodeService) : base(inputPin, nodeService)
{
}
}
@@ -0,0 +1,33 @@
<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:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:pins="clr-namespace:Artemis.UI.Screens.VisualScripting.Pins"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.VisualScripting.Pins.OutputPinCollectionView"
x:DataType="pins:PinCollectionViewModel">
<StackPanel>
<Button Classes="icon-button icon-button-small pin-collection-button"
ToolTip.Tip="Add new pin"
HorizontalAlignment="Right"
Command="{CompiledBinding AddPin}">
<avalonia:MaterialIcon Kind="Add"></avalonia:MaterialIcon>
</Button>
<ItemsControl Items="{CompiledBinding PinViewModels}" Margin="4 0" HorizontalAlignment="Right">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="pins:PinViewModel">
<StackPanel Orientation="Horizontal">
<Button Classes="icon-button icon-button-small"
ToolTip.Tip="Remove pin"
Command="{CompiledBinding RemovePin}"
CommandParameter="{CompiledBinding Pin}">
<avalonia:MaterialIcon Kind="Close"></avalonia:MaterialIcon>
</Button>
<ContentControl Content="{CompiledBinding}"></ContentControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</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,25 @@
using Artemis.Core;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Shared.Services.NodeEditor;
namespace Artemis.UI.Screens.VisualScripting.Pins;
public class OutputPinCollectionViewModel : PinCollectionViewModel
{
private readonly INodeVmFactory _nodeVmFactory;
public IPinCollection OutputPinCollection { get; }
public OutputPinCollectionViewModel(IPinCollection outputPinCollection, NodeScriptViewModel nodeScriptViewModel, INodeVmFactory nodeVmFactory, INodeEditorService nodeEditorService)
: base(outputPinCollection, nodeScriptViewModel, nodeEditorService)
{
_nodeVmFactory = nodeVmFactory;
OutputPinCollection = outputPinCollection;
}
protected override PinViewModel CreatePinViewModel(IPin pin)
{
PinViewModel vm = _nodeVmFactory.OutputPinViewModel(pin);
vm.RemovePin = RemovePin;
return vm;
}
}
@@ -0,0 +1,31 @@
<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:pins="clr-namespace:Artemis.UI.Screens.VisualScripting.Pins"
mc:Ignorable="d"
d:DesignWidth="200"
x:Class="Artemis.UI.Screens.VisualScripting.Pins.OutputPinView"
x:DataType="pins:PinViewModel">
<UserControl.Styles>
<StyleInclude Source="/Screens/VisualScripting/VisualScripting.axaml" />
<Style Selector="StackPanel#PinContainer Border#VisualPinPoint">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="{CompiledBinding DarkenedPinColor}" />
</Setter.Value>
</Setter>
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="{CompiledBinding PinColor}" />
</Setter.Value>
</Setter>
</Style>
</UserControl.Styles>
<StackPanel Name="PinContainer" Orientation="Horizontal" Spacing="6">
<TextBlock Name="PinName" VerticalAlignment="Center" Text="{CompiledBinding Pin.Name}" />
<Border Name="PinPoint">
<Border Name="VisualPinPoint" />
</Border>
</StackPanel>
</UserControl>
@@ -0,0 +1,18 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.VisualScripting.Pins;
public class OutputPinView : PinView
{
public OutputPinView()
{
InitializeComponent();
InitializePin(this.Get<Border>("PinPoint"));
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
@@ -0,0 +1,11 @@
using Artemis.Core;
using Artemis.Core.Services;
namespace Artemis.UI.Screens.VisualScripting.Pins;
public class OutputPinViewModel : PinViewModel
{
public OutputPinViewModel(IPin outputPin, INodeService nodeService) : base(outputPin, nodeService)
{
}
}
@@ -0,0 +1,49 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using Artemis.Core;
using Artemis.Core.Events;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services.NodeEditor;
using Artemis.UI.Shared.Services.NodeEditor.Commands;
using Avalonia.Controls.Mixins;
using DynamicData;
using ReactiveUI;
namespace Artemis.UI.Screens.VisualScripting.Pins;
public abstract class PinCollectionViewModel : ActivatableViewModelBase
{
protected PinCollectionViewModel(IPinCollection pinCollection, NodeScriptViewModel nodeScriptViewModel, INodeEditorService nodeEditorService)
{
PinCollection = pinCollection;
PinViewModels = new ObservableCollection<PinViewModel>();
this.WhenActivated(d =>
{
PinViewModels.Clear();
PinViewModels.AddRange(PinCollection.Select(CreatePinViewModel));
Observable.FromEventPattern<SingleValueEventArgs<IPin>>(x => PinCollection.PinAdded += x, x => PinCollection.PinAdded -= x)
.Subscribe(e => PinViewModels.Add(CreatePinViewModel(e.EventArgs.Value)))
.DisposeWith(d);
Observable.FromEventPattern<SingleValueEventArgs<IPin>>(x => PinCollection.PinRemoved += x, x => PinCollection.PinRemoved -= x)
.Subscribe(e => PinViewModels.RemoveMany(PinViewModels.Where(p => p.Pin == e.EventArgs.Value).ToList()))
.DisposeWith(d);
});
AddPin = ReactiveCommand.Create(() => nodeEditorService.ExecuteCommand(nodeScriptViewModel.NodeScript, new AddPin(pinCollection)));
RemovePin = ReactiveCommand.Create((IPin pin) => nodeEditorService.ExecuteCommand(nodeScriptViewModel.NodeScript, new RemovePin(pinCollection, pin)));
}
public IPinCollection PinCollection { get; }
public ReactiveCommand<Unit, Unit> AddPin { get; }
public ReactiveCommand<IPin, Unit> RemovePin { get; }
public ObservableCollection<PinViewModel> PinViewModels { get; }
protected abstract PinViewModel CreatePinViewModel(IPin pin);
}
@@ -0,0 +1,90 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Media;
using Avalonia.ReactiveUI;
using Avalonia.VisualTree;
namespace Artemis.UI.Screens.VisualScripting.Pins;
public class PinView : ReactiveUserControl<PinViewModel>
{
private bool _dragging;
private Canvas? _container;
private Border? _pinPoint;
protected void InitializePin(Border pinPoint)
{
_pinPoint = pinPoint;
_pinPoint.PointerMoved += PinPointOnPointerMoved;
_pinPoint.PointerReleased += PinPointOnPointerReleased;
}
private void PinPointOnPointerMoved(object? sender, PointerEventArgs e)
{
if (ViewModel == null || _container == null || _pinPoint == null)
return;
NodeScriptViewModel? nodeScriptViewModel = this.FindAncestorOfType<NodeScriptView>()?.ViewModel;
PointerPoint point = e.GetCurrentPoint(_container);
if (nodeScriptViewModel == null || !point.Properties.IsLeftButtonPressed)
return;
if (!_dragging)
e.Pointer.Capture(_pinPoint);
PinViewModel? targetPin = (_container.InputHitTest(point.Position) as Border)?.DataContext as PinViewModel;
if (targetPin == ViewModel)
targetPin = null;
_pinPoint.Cursor = new Cursor(nodeScriptViewModel.UpdatePinDrag(ViewModel, targetPin, point.Position) ? StandardCursorType.Hand : StandardCursorType.No);
_dragging = true;
e.Handled = true;
}
private void PinPointOnPointerReleased(object? sender, PointerReleasedEventArgs e)
{
if (!_dragging || ViewModel == null || _container == null || _pinPoint == null)
return;
_dragging = false;
e.Pointer.Capture(null);
PointerPoint point = e.GetCurrentPoint(_container);
PinViewModel? targetPin = (_container.InputHitTest(point.Position) as Border)?.DataContext as PinViewModel;
if (targetPin == ViewModel)
targetPin = null;
this.FindAncestorOfType<NodeScriptView>()?.ViewModel?.FinishPinDrag(ViewModel, targetPin, point.Position);
_pinPoint.Cursor = new Cursor(StandardCursorType.Hand);
e.Handled = true;
}
#region Overrides of Visual
/// <inheritdoc />
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
_container = this.FindAncestorOfType<Canvas>();
}
/// <inheritdoc />
public override void Render(DrawingContext context)
{
base.Render(context);
UpdatePosition();
}
private void UpdatePosition()
{
if (_container == null || _pinPoint == null || ViewModel == null)
return;
Matrix? transform = _pinPoint.TransformToVisual(_container);
if (transform != null)
ViewModel.Position = new Point(_pinPoint.Bounds.Width / 2, _pinPoint.Bounds.Height / 2).Transform(transform.Value);
}
#endregion
}
@@ -0,0 +1,88 @@
using System;
using System.Reactive;
using System.Reactive.Linq;
using Artemis.Core;
using Artemis.Core.Events;
using Artemis.Core.Services;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Extensions;
using Avalonia;
using Avalonia.Controls.Mixins;
using Avalonia.Media;
using DynamicData;
using ReactiveUI;
namespace Artemis.UI.Screens.VisualScripting.Pins;
public abstract class PinViewModel : ActivatableViewModelBase
{
private readonly INodeService _nodeService;
private ReactiveCommand<IPin, Unit>? _removePin;
private Point _position;
private Color _pinColor;
private Color _darkenedPinColor;
protected PinViewModel(IPin pin, INodeService nodeService)
{
_nodeService = nodeService;
Pin = pin;
SourceList<IPin> connectedPins = new();
this.WhenActivated(d =>
{
Observable.FromEventPattern<SingleValueEventArgs<IPin>>(x => Pin.PinConnected += x, x => Pin.PinConnected -= x)
.Subscribe(e => connectedPins.Add(e.EventArgs.Value))
.DisposeWith(d);
Observable.FromEventPattern<SingleValueEventArgs<IPin>>(x => Pin.PinDisconnected += x, x => Pin.PinDisconnected -= x)
.Subscribe(e => connectedPins.Remove(e.EventArgs.Value))
.DisposeWith(d);
Pin.WhenAnyValue(p => p.Type).Subscribe(_ => UpdatePinColor()).DisposeWith(d);
});
Connections = connectedPins.Connect().AsObservableList();
connectedPins.AddRange(Pin.ConnectedTo);
}
private void UpdatePinColor()
{
TypeColorRegistration registration = _nodeService.GetTypeColorRegistration(Pin.Type);
PinColor = registration.Color.ToColor();
DarkenedPinColor = registration.DarkenedColor.ToColor();
}
public IObservableList<IPin> Connections { get; }
public IPin Pin { get; }
public Color PinColor
{
get => _pinColor;
set => RaiseAndSetIfChanged(ref _pinColor, value);
}
public Color DarkenedPinColor
{
get => _darkenedPinColor;
set => RaiseAndSetIfChanged(ref _darkenedPinColor, value);
}
public Point Position
{
get => _position;
set => RaiseAndSetIfChanged(ref _position, value);
}
public ReactiveCommand<IPin, Unit>? RemovePin
{
get => _removePin;
set => RaiseAndSetIfChanged(ref _removePin, value);
}
public bool IsCompatibleWith(PinViewModel pinViewModel)
{
if (pinViewModel.Pin.Direction == Pin.Direction || pinViewModel.Pin.Node == Pin.Node)
return false;
return Pin.IsTypeCompatible(pinViewModel.Pin.Type);
}
}