public FpsCounterViewModel()
        {
            MouseDownUnit = new ReactivePropertySlim <Unit>(mode: ReactivePropertyMode.None).AddTo(CompositeDisposable);

            // http://reactivex.io/documentation/operators/buffer.html
            // Buffer(count, skip) : count個のデータが溜まったら、skip個ごとに count個をまとめた List<T> を流します
            // Buffer(count) : countの倍数で、count個をまとめた List<T> を流します。
            FpsCounter1 = MouseDownUnit
                          .Select(_ => DateTime.Now)
                          .Pairwise()
                          .Select(dateTime => dateTime.NewItem - dateTime.OldItem)
                          .Buffer(count: _bufferLength, skip: 1)
                          .Select(tss => 1000d / tss.Select(ts => ts.TotalMilliseconds).Average())
                          .ToReadOnlyReactivePropertySlim()
                          .AddTo(CompositeDisposable);

            FpsCounter2 = MouseDownUnit
                          .TimeInterval()
                          .Buffer(count: _bufferLength, skip: 1)
                          .Select(xs => 1000d / xs.Select(x => x.Interval.Milliseconds).Average())
                          .ToReadOnlyReactivePropertySlim()
                          .AddTo(CompositeDisposable);

            FpsCounter3 = MouseDownUnit
                          .Framerate(_bufferLength)
                          .ToReadOnlyReactivePropertySlim()
                          .AddTo(CompositeDisposable);
        }
Beispiel #2
0
        public SelectPointViewModel()
        {
            MouseLeftDownPoint = new ReactivePropertySlim <RoixBorderPoint>(mode: ReactivePropertyMode.None);
            MouseMovePoint     = new ReactivePropertySlim <RoixBorderPoint>();
            ViewBorderSize     = new ReactivePropertySlim <RoixSize>(mode: ReactivePropertyMode.DistinctUntilChanged);

            var imageSourceSize = MyImage.ToRoixIntSize();

            #region CursorPoint
            CursorBorderPoint = MouseMovePoint.ToReadOnlyReactivePropertySlim();

            CursorPointToModel = CursorBorderPoint
                                 .Where(borderPoint => borderPoint.IsNotZero)
                                 .Select(borderPoint => borderPoint.ConvertToNewBorderInt(imageSourceSize).Point)
                                 .ToReadOnlyReactivePropertySlim();
            #endregion

            #region DoubleClickPoint
            var eventAcceptedTime     = DateTime.Now;
            var mouseDoubleClickPoint = MouseLeftDownPoint
                                        .TimeInterval()
                                        .Skip(1)
                                        .Where(ti =>
            {
                // 前回の MouseDown から一定時間が経過していればダブクリと言わない
                if (ti.Interval > TimeSpan.FromMilliseconds(500))
                {
                    return(false);
                }

                var now = DateTime.Now;

                // 前回のダブクリ受付から一定時間が経過するまでは、次のダブクリを受け付けない
                if (now - eventAcceptedTime < TimeSpan.FromMilliseconds(500))
                {
                    return(false);
                }

                eventAcceptedTime = now;        // ダブクリ受付時間の更新
                return(true);
            })
                                        .Select(x => x.Value)
                                        .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.None);

            // 画像座標系の点(これを基準に管理する)
            var selectedPointOnImage = mouseDoubleClickPoint
                                       .Select(borderPoint =>
            {
                var borderInt = borderPoint.ConvertToNewBorderInt(imageSourceSize);
                return(borderInt.ClipToSize(borderInt.Border - 1));
            })
                                       .ToReadOnlyReactivePropertySlim();

            SinglePoint = selectedPointOnImage
                          .CombineLatest(ViewBorderSize, (intPoint, viewSize) =>
            {
                var leftTop       = intPoint.ConvertToNewBorder(viewSize).Point;
                var halfPixelSize = new RoixIntSize(1).ToRoixBorder(imageSourceSize).ConvertToNewBorder(viewSize).Size / 2d;
                return(leftTop + (RoixVector)halfPixelSize);        // 画素の中央部に点を打つためシフト
            })
                          .ToReadOnlyReactivePropertySlim();

            SinglePointToModel = selectedPointOnImage
                                 .Where(borderPoint => borderPoint.Border.IsNotZero)
                                 .Select(borderRectOnView => borderRectOnView.Point)
                                 .ToReadOnlyReactivePropertySlim();
            #endregion
        }