using System; using Intromat.Interfaces; using Intromat.Model.Compiler; using Intromat.Nodes.Code; using NodeNetwork.Toolkit.ValueNode; using ReactiveUI; namespace Intromat.ViewModels.Editors { public abstract class ExpressionEditorBaseViewModel : ValueEditorViewModel?>, IExpressionEditor where TValue : LiteralValueBase, new() where TModel : LiteralModelBase, new() { private T _customValue = default!; private ERelativeSource _relativeSource; private IObservable? _parentValueProvider; private IObservable? _inputValueProvider; private readonly ObservableAsPropertyHelper _parentValue; private readonly ObservableAsPropertyHelper _inputValue; protected ExpressionEditorBaseViewModel() { this.WhenAnyObservable(vm => vm.ParentValueProvider) .ToProperty(this, vm => vm.ParentValue, out _parentValue); this.WhenAnyObservable(vm => vm.InputValueProvider) .ToProperty(this, vm => vm.InputValue, out _inputValue); this.WhenAnyValue(vm => vm.ParentValue, vm => vm.InputValue, vm => vm.CustomValue, vm => vm.RelativeSource) .Subscribe(v => Value = CreateLiteralValue(v.Item1, v.Item2, v.Item3, v.Item4)); } protected LiteralValueBase CreateLiteralValue(T parentValue, T inputValue, T customValue, ERelativeSource relativeSource) { return new TValue { InputValue = inputValue, ParentValue = parentValue, Value = customValue, RelativeSource = relativeSource }; } public TModel CreateModel() { return new() { RelativeSource = RelativeSource, Value = CustomValue }; } public void LoadModel(TModel model) { RelativeSource = model.RelativeSource; CustomValue = model.Value; } public T CustomValue { get => _customValue; set => this.RaiseAndSetIfChanged(ref _customValue, value); } public ERelativeSource RelativeSource { get => _relativeSource; set => this.RaiseAndSetIfChanged(ref _relativeSource, value); } public IObservable? ParentValueProvider { get => _parentValueProvider; set => this.RaiseAndSetIfChanged(ref _parentValueProvider, value); } public T ParentValue => _parentValue.Value; public bool HasParentSource => ParentValueProvider != null; public IObservable? InputValueProvider { get => _inputValueProvider; set => this.RaiseAndSetIfChanged(ref _inputValueProvider, value); } public T InputValue => _inputValue.Value; public bool HasInputSource => InputValueProvider != null; public CodeGenPortViewModel CodeGenPort => (CodeGenPortViewModel)Parent.Port; } }