using System; using System.Collections.Generic; using System.Linq; using System.Reactive.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using DynamicData; using ReactiveUI; namespace NodeNetwork.ViewModels { /// /// Viewmodel for the view that is used to select nodes by dragging a rectangle around them. /// public class SelectionRectangleViewModel : ReactiveObject { #region StartPoint /// /// The coordinates of the first corner of the rectangle (where the user clicked down). /// public Point StartPoint { get => _startPoint; set => this.RaiseAndSetIfChanged(ref _startPoint, value); } private Point _startPoint; #endregion #region EndPoint /// /// The coordinates of the second corner of the rectangle. /// public Point EndPoint { get => _endPoint; set => this.RaiseAndSetIfChanged(ref _endPoint, value); } private Point _endPoint; #endregion #region Rectangle /// /// The Rect object formed by StartPoint and EndPoint. /// public Rect Rectangle => _rectangle.Value; private readonly ObservableAsPropertyHelper _rectangle; #endregion #region IsVisible /// /// If true, the selection rectangle view is visible. /// public bool IsVisible { get => _isVisible; set => this.RaiseAndSetIfChanged(ref _isVisible, value); } private bool _isVisible; #endregion #region IntersectingNodes /// /// List of nodes visually intersecting or contained in the rectangle. /// This list is driven by the view. /// public ISourceList IntersectingNodes { get; } = new SourceList(); #endregion public SelectionRectangleViewModel() { this.WhenAnyValue(vm => vm.StartPoint, vm => vm.EndPoint) .Select(_ => new Rect(StartPoint, EndPoint)) .ToProperty(this, vm => vm.Rectangle, out _rectangle); IntersectingNodes.Connect().ActOnEveryObject(node => node.IsSelected = true, node => node.IsSelected = false); } } }