Example #1
0
        public LinkViewModel(PadViewModel src, PadViewModel sink)
        {
            this.Src  = src;
            this.Sink = sink;

            var srcX  = src.WhenAnyValue(src => src.X);
            var srcY  = src.WhenAnyValue(src => src.Y);
            var sinkX = sink.WhenAnyValue(sink => sink.X);
            var sinkY = sink.WhenAnyValue(sink => sink.Y);

            var x = srcX.CombineLatest(sinkX, Math.Min).Select(x => x - Settings.LinkBezierPadding);
            var y = srcY.CombineLatest(sinkY, Math.Min).Select(y => y - Settings.LinkBezierPadding);

            this.x = x.ToProperty(this, x => x.X);
            this.y = y.ToProperty(this, x => x.Y);

            var width  = srcX.CombineLatest(sinkX, (srcX, sinkX) => Math.Max(1, Math.Abs(sinkX - srcX)) + (2 * Settings.LinkBezierPadding));
            var height = srcY.CombineLatest(sinkY, (srcY, sinkY) => Math.Max(1, Math.Abs(sinkY - srcY)) + (2 * Settings.LinkBezierPadding));

            this.width  = width.ToProperty(this, pad => pad.Width);
            this.height = height.ToProperty(this, pad => pad.Height);

            var srcXOffset  = x.CombineLatest(srcX, (x, srcX) => srcX + Settings.PadRadius - x).Where(offset => offset >= 0);
            var srcYOffset  = y.CombineLatest(srcY, (y, srcY) => srcY + Settings.PadRadius - y).Where(offset => offset >= 0);
            var sinkXOffset = x.CombineLatest(sinkX, (x, sinkX) => sinkX + Settings.PadRadius - x).Where(offset => offset >= 0);
            var sinkYOffset = y.CombineLatest(sinkY, (y, sinkY) => sinkY + Settings.PadRadius - y).Where(offset => offset >= 0);

            var start = srcXOffset.CombineLatest(srcYOffset, (x, y) => new Point(x, y));
            var end   = sinkXOffset.CombineLatest(sinkYOffset, (x, y) => new Point(x, y));

            this.start = start.ToProperty(this, pad => pad.Start);
            this.end   = end.ToProperty(this, pad => pad.End);

            var control1 = start.CombineLatest(width, (start, width) =>
            {
                return(start + new Vector(Math.Max(width / 2, 25), 0));
            });
            var control2 = end.CombineLatest(width, (end, width) =>
            {
                return(end + new Vector(-Math.Max(width / 2, 25), 0));
            });

            this.control1 = control1.ToProperty(this, pad => pad.Control1);
            this.control2 = control2.ToProperty(this, pad => pad.Control2);

            this.WhenActivated((disposables) =>
            {
                this.x.DisposeWith(disposables);
                this.y.DisposeWith(disposables);
                this.width.DisposeWith(disposables);
                this.height.DisposeWith(disposables);
                this.start.DisposeWith(disposables);
                this.control1.DisposeWith(disposables);
                this.control2.DisposeWith(disposables);
                this.end.DisposeWith(disposables);
            });
        }