Example #1
0
    void setTestPanelParameters()
    {
        string max       = MaxPitch.ToString();
        string min       = MinPitch.ToString();
        string pitch     = Pitch.ToString();
        string pitchRate = smoothing.ToString();

        if (TestingTypeDropdown)
        {
            TestingTypeDropdown.value = (int)MyType;
        }
        if (inputMaxPitch)
        {
            inputMaxPitch.text = max;
        }
        if (inputMinPitch)
        {
            inputMinPitch.text = min;
        }
        if (inputPitch)
        {
            inputPitch.text = pitch;
        }
        if (inputPitchRate)
        {
            inputPitchRate.text = pitchRate;
        }
        if (VolumeSlider)
        {
            VolumeSlider.value = 0.5f;
        }
    }
Example #2
0
        internal MotorViewModel(Motor motor)
        {
            CultureInfo culture = CultureInfo.InvariantCulture;

            MessageBox = motor
                         .ObserveProperty(x => x.MessageBox)
                         .Do(_ => MessageBox?.Value.Dispose())
                         .Select(x => new MessageBoxViewModel(x))
                         .ToReadOnlyReactivePropertySlim()
                         .AddTo(disposable);

            ToolTipVertexPitch = motor
                                 .ObserveProperty(x => x.ToolTipVertexPitch)
                                 .Do(_ => ToolTipVertexPitch?.Value.Dispose())
                                 .Select(x => new ToolTipViewModel(x))
                                 .ToReadOnlyReactivePropertySlim()
                                 .AddTo(disposable);

            ToolTipVertexVolume = motor
                                  .ObserveProperty(x => x.ToolTipVertexVolume)
                                  .Do(_ => ToolTipVertexVolume?.Value.Dispose())
                                  .Select(x => new ToolTipViewModel(x))
                                  .ToReadOnlyReactivePropertySlim()
                                  .AddTo(disposable);

            CurrentModifierKeys = motor
                                  .ToReactivePropertyAsSynchronized(x => x.CurrentModifierKeys)
                                  .AddTo(disposable);

            CurrentCursorType = motor
                                .ObserveProperty(x => x.CurrentCursorType)
                                .ToReadOnlyReactivePropertySlim()
                                .AddTo(disposable);

            MinVelocity = motor
                          .ToReactivePropertyAsSynchronized(
                x => x.MinVelocity,
                x => x.ToString(culture),
                x => double.Parse(x, NumberStyles.Float, culture),
                ignoreValidationErrorValue: true
                )
                          .AddTo(disposable);

            MinVelocity.Subscribe(_ => motor.IsRefreshGlControl = true).AddTo(disposable);

            MaxVelocity = motor
                          .ToReactivePropertyAsSynchronized(
                x => x.MaxVelocity,
                x => x.ToString(culture),
                x => double.Parse(x, NumberStyles.Float, culture),
                ignoreValidationErrorValue: true
                )
                          .AddTo(disposable);

            MaxVelocity.Subscribe(_ => motor.IsRefreshGlControl = true).AddTo(disposable);

            MinPitch = motor
                       .ToReactivePropertyAsSynchronized(
                x => x.MinPitch,
                x => x.ToString(culture),
                x => double.Parse(x, NumberStyles.Float, culture),
                ignoreValidationErrorValue: true
                )
                       .AddTo(disposable);

            MinPitch.Subscribe(_ => motor.IsRefreshGlControl = true).AddTo(disposable);

            MaxPitch = motor
                       .ToReactivePropertyAsSynchronized(
                x => x.MaxPitch,
                x => x.ToString(culture),
                x => double.Parse(x, NumberStyles.Float, culture),
                ignoreValidationErrorValue: true
                )
                       .AddTo(disposable);

            MaxPitch.Subscribe(_ => motor.IsRefreshGlControl = true).AddTo(disposable);

            MinVolume = motor
                        .ToReactivePropertyAsSynchronized(
                x => x.MinVolume,
                x => x.ToString(culture),
                x => double.Parse(x, NumberStyles.Float, culture),
                ignoreValidationErrorValue: true
                )
                        .AddTo(disposable);

            MinVolume.Subscribe(_ => motor.IsRefreshGlControl = true).AddTo(disposable);

            MaxVolume = motor
                        .ToReactivePropertyAsSynchronized(
                x => x.MaxVolume,
                x => x.ToString(culture),
                x => double.Parse(x, NumberStyles.Float, culture),
                ignoreValidationErrorValue: true
                )
                        .AddTo(disposable);

            MaxVolume.Subscribe(_ => motor.IsRefreshGlControl = true).AddTo(disposable);

            NowVelocity = motor
                          .ObserveProperty(x => x.NowVelocity)
                          .ToReadOnlyReactivePropertySlim()
                          .AddTo(disposable);

            NowPitch = motor
                       .ObserveProperty(x => x.NowPitch)
                       .ToReadOnlyReactivePropertySlim()
                       .AddTo(disposable);

            NowVolume = motor
                        .ObserveProperty(x => x.NowVolume)
                        .ToReadOnlyReactivePropertySlim()
                        .AddTo(disposable);

            CurrentSelectedTrack = motor
                                   .ObserveProperty(x => x.SelectedTrackInfo)
                                   .ToReadOnlyReactivePropertySlim()
                                   .AddTo(disposable);

            CurrentSelectedTrack
            .Subscribe(_ =>
            {
                motor.ResetSelect();
                motor.IsRefreshGlControl = true;
            })
            .AddTo(disposable);

            CurrentInputMode = motor
                               .ObserveProperty(x => x.CurrentInputMode)
                               .ToReadOnlyReactivePropertySlim()
                               .AddTo(disposable);

            CurrentInputMode
            .Subscribe(_ =>
            {
                motor.ResetSelect();
                motor.IsRefreshGlControl = true;
            })
            .AddTo(disposable);

            SelectedSoundIndex = motor
                                 .ToReactivePropertyAsSynchronized(x => x.SelectedSoundIndex)
                                 .AddTo(disposable);

            CurrentToolMode = motor
                              .ObserveProperty(x => x.CurrentToolMode)
                              .ToReadOnlyReactivePropertySlim()
                              .AddTo(disposable);

            CurrentToolMode
            .Subscribe(_ =>
            {
                motor.ResetSelect();
                motor.IsRefreshGlControl = true;
            })
            .AddTo(disposable);

            StoppedSim = motor
                         .ObserveProperty(x => x.CurrentSimState)
                         .Select(x => x == Motor.SimulationState.Disable || x == Motor.SimulationState.Stopped)
                         .ToReadOnlyReactivePropertySlim()
                         .AddTo(disposable);

            RunIndex = motor
                       .ToReactivePropertyAsSynchronized(x => x.RunIndex)
                       .AddTo(disposable);

            IsPlayTrack1 = motor
                           .ToReactivePropertyAsSynchronized(x => x.IsPlayTrack1)
                           .AddTo(disposable);

            IsPlayTrack2 = motor
                           .ToReactivePropertyAsSynchronized(x => x.IsPlayTrack2)
                           .AddTo(disposable);

            IsLoop = motor
                     .ToReactivePropertyAsSynchronized(x => x.IsLoop)
                     .AddTo(disposable);

            IsConstant = motor
                         .ToReactivePropertyAsSynchronized(x => x.IsConstant)
                         .AddTo(disposable);

            Acceleration = motor
                           .ToReactivePropertyAsSynchronized(
                x => x.Acceleration,
                x => x.ToString(culture),
                x => double.Parse(x, NumberStyles.Float, culture),
                ignoreValidationErrorValue: true
                )
                           .SetValidateNotifyError(x =>
            {
                double result;
                string message;

                Utilities.TryParse(x, NumberRange.NonNegative, out result, out message);

                return(message);
            })
                           .AddTo(disposable);

            StartSpeed = motor
                         .ToReactivePropertyAsSynchronized(
                x => x.StartSpeed,
                x => x.ToString(culture),
                x => double.Parse(x, NumberStyles.Float, culture),
                ignoreValidationErrorValue: true
                )
                         .SetValidateNotifyError(x =>
            {
                double result;
                string message;

                Utilities.TryParse(x, NumberRange.NonNegative, out result, out message);

                return(message);
            })
                         .AddTo(disposable);

            EndSpeed = motor
                       .ToReactivePropertyAsSynchronized(
                x => x.EndSpeed,
                x => x.ToString(culture),
                x => double.Parse(x, NumberStyles.Float, culture),
                ignoreValidationErrorValue: true
                )
                       .SetValidateNotifyError(x =>
            {
                double result;
                string message;

                Utilities.TryParse(x, NumberRange.NonNegative, out result, out message);

                return(message);
            })
                       .AddTo(disposable);

            EnabledDirect = new[]
            {
                CurrentInputMode.Select(x => x != Motor.InputMode.SoundIndex),
                StoppedSim
            }
            .CombineLatestValuesAreAllTrue()
            .ToReadOnlyReactivePropertySlim()
            .AddTo(disposable);

            DirectX = new ReactiveProperty <string>(0.0.ToString(culture))
                      .SetValidateNotifyError(x =>
            {
                double result;
                string message;

                switch (CurrentToolMode.Value)
                {
                case Motor.ToolMode.Move:
                    Utilities.TryParse(x, NumberRange.Any, out result, out message);
                    break;

                case Motor.ToolMode.Dot:
                    Utilities.TryParse(x, NumberRange.NonNegative, out result, out message);
                    break;

                default:
                    message = null;
                    break;
                }

                return(message);
            })
                      .AddTo(disposable);

            DirectY = new ReactiveProperty <string>(0.0.ToString(culture))
                      .SetValidateNotifyError(x =>
            {
                double result;
                string message;

                switch (CurrentToolMode.Value)
                {
                case Motor.ToolMode.Move:
                    Utilities.TryParse(x, NumberRange.Any, out result, out message);
                    break;

                case Motor.ToolMode.Dot:
                    Utilities.TryParse(x, NumberRange.NonNegative, out result, out message);
                    break;

                default:
                    message = null;
                    break;
                }

                return(message);
            })
                      .AddTo(disposable);

            CurrentToolMode
            .Subscribe(_ =>
            {
                DirectX.ForceValidate();
                DirectY.ForceValidate();
            })
            .AddTo(disposable);

            GlControlWidth = motor
                             .ToReactivePropertyAsSynchronized(
                x => x.GlControlWidth,
                ignoreValidationErrorValue: true
                )
                             .SetValidateNotifyError(x => x <= 0 ? string.Empty : null)
                             .AddTo(disposable);

            GlControlWidth.Subscribe(_ => motor.IsRefreshGlControl = true).AddTo(disposable);

            GlControlHeight = motor
                              .ToReactivePropertyAsSynchronized(
                x => x.GlControlHeight,
                ignoreValidationErrorValue: true
                )
                              .SetValidateNotifyError(x => x <= 0 ? string.Empty : null)
                              .AddTo(disposable);

            GlControlHeight.Subscribe(_ => motor.IsRefreshGlControl = true).AddTo(disposable);

            IsRefreshGlControl = motor
                                 .ToReactivePropertyAsSynchronized(x => x.IsRefreshGlControl)
                                 .AddTo(disposable);

            ChangeSelectedTrack = new ReactiveCommand <Motor.TrackInfo>().WithSubscribe(x => motor.SelectedTrackInfo = x).AddTo(disposable);

            ChangeInputMode = new ReactiveCommand <Motor.InputMode>().WithSubscribe(x => motor.CurrentInputMode = x).AddTo(disposable);

            ChangeToolMode = new[]
            {
                CurrentInputMode.Select(x => x != Motor.InputMode.SoundIndex),
                StoppedSim
            }
            .CombineLatestValuesAreAllTrue()
            .ToReactiveCommand <Motor.ToolMode>()
            .WithSubscribe(x => motor.CurrentToolMode = x)
            .AddTo(disposable);

            ZoomIn = new ReactiveCommand().WithSubscribe(motor.ZoomIn).AddTo(disposable);

            ZoomOut = new ReactiveCommand().WithSubscribe(motor.ZoomOut).AddTo(disposable);

            Reset = new ReactiveCommand().WithSubscribe(motor.Reset).AddTo(disposable);

            MoveLeft = new ReactiveCommand().WithSubscribe(motor.MoveLeft).AddTo(disposable);

            MoveRight = new ReactiveCommand().WithSubscribe(motor.MoveRight).AddTo(disposable);

            MoveBottom = new ReactiveCommand().WithSubscribe(motor.MoveBottom).AddTo(disposable);

            MoveTop = new ReactiveCommand().WithSubscribe(motor.MoveTop).AddTo(disposable);

            Undo = new[]
            {
                new[]
                {
                    motor.PropertyChangedAsObservable().Where(x => x.PropertyName == nameof(motor.SelectedTrackInfo)).OfType <object>(),
                    motor.PrevTrackStates.CollectionChangedAsObservable().OfType <object>()
                }
                .Merge()
                .Select(_ => motor.PrevTrackStates.Any(x => x.Info == motor.SelectedTrackInfo)),
                StoppedSim
            }
            .CombineLatestValuesAreAllTrue()
            .ToReactiveCommand(false)
            .WithSubscribe(motor.Undo)
            .AddTo(disposable);

            Redo = new[]
            {
                new[]
                {
                    motor.PropertyChangedAsObservable().Where(x => x.PropertyName == nameof(motor.SelectedTrackInfo)).OfType <object>(),
                    motor.NextTrackStates.CollectionChangedAsObservable().OfType <object>()
                }
                .Merge()
                .Select(_ => motor.NextTrackStates.Any(x => x.Info == motor.SelectedTrackInfo)),
                StoppedSim
            }
            .CombineLatestValuesAreAllTrue()
            .ToReactiveCommand(false)
            .WithSubscribe(motor.Redo)
            .AddTo(disposable);

            TearingOff = StoppedSim
                         .ToReactiveCommand()
                         .WithSubscribe(motor.TearingOff)
                         .AddTo(disposable);

            Copy = StoppedSim
                   .ToReactiveCommand()
                   .WithSubscribe(motor.Copy)
                   .AddTo(disposable);

            Paste = new[]
            {
                motor.ObserveProperty(x => x.CopyTrack).Select(x => x != null),
                StoppedSim
            }
            .CombineLatestValuesAreAllTrue()
            .ToReactiveCommand()
            .WithSubscribe(motor.Paste)
            .AddTo(disposable);

            Cleanup = StoppedSim
                      .ToReactiveCommand()
                      .WithSubscribe(motor.Cleanup)
                      .AddTo(disposable);

            Delete = StoppedSim
                     .ToReactiveCommand()
                     .WithSubscribe(motor.Delete)
                     .AddTo(disposable);

            MouseDown = new ReactiveCommand <InputEventModel.EventArgs>().WithSubscribe(motor.MouseDown).AddTo(disposable);

            MouseMove = new ReactiveCommand <InputEventModel.EventArgs>().WithSubscribe(motor.MouseMove).AddTo(disposable);

            MouseUp = new ReactiveCommand().WithSubscribe(motor.MouseUp).AddTo(disposable);

            DirectDot = new[]
            {
                StoppedSim,
                CurrentToolMode.Select(x => x == Motor.ToolMode.Dot),
                DirectX.ObserveHasErrors.Select(x => !x),
                DirectY.ObserveHasErrors.Select(x => !x)
            }
            .CombineLatestValuesAreAllTrue()
            .ToReactiveCommand()
            .WithSubscribe(() => motor.DirectDot(double.Parse(DirectX.Value), double.Parse(DirectY.Value)))
            .AddTo(disposable);

            DirectMove = new[]
            {
                StoppedSim,
                CurrentToolMode.Select(x => x == Motor.ToolMode.Move),
                DirectX.ObserveHasErrors.Select(x => !x),
                DirectY.ObserveHasErrors.Select(x => !x)
            }
            .CombineLatestValuesAreAllTrue()
            .ToReactiveCommand()
            .WithSubscribe(() => motor.DirectMove(double.Parse(DirectX.Value), double.Parse(DirectY.Value)))
            .AddTo(disposable);

            SwapSpeed = StoppedSim
                        .ToReactiveCommand()
                        .WithSubscribe(() =>
            {
                string tmp       = StartSpeed.Value;
                StartSpeed.Value = EndSpeed.Value;
                EndSpeed.Value   = tmp;
            })
                        .AddTo(disposable);

            SimulationTimer = new ReactiveTimer(TimeSpan.FromMilliseconds(1000.0 / 30.0));

            SimulationTimer
            .Subscribe(_ =>
            {
                SimulationTimer.Stop();
                Observable.Start(motor.RunSimulation, UIDispatcherScheduler.Default).Wait();
                SimulationTimer.Start(TimeSpan.FromMilliseconds(1000.0 / 30.0));
            })
            .AddTo(disposable);

            motor.ObserveProperty(x => x.CurrentSimState)
            .ToReadOnlyReactivePropertySlim()
            .Subscribe(x =>
            {
                switch (x)
                {
                case Motor.SimulationState.Started:
                    SimulationTimer.Start();
                    break;

                default:
                    SimulationTimer.Stop();
                    break;
                }
            })
            .AddTo(disposable);

            StartSimulation = motor
                              .ObserveProperty(x => x.CurrentSimState)
                              .Select(x => x == Motor.SimulationState.Paused || x == Motor.SimulationState.Stopped)
                              .ToReactiveCommand()
                              .WithSubscribe(motor.StartSimulation)
                              .AddTo(disposable);

            PauseSimulation = motor
                              .ObserveProperty(x => x.CurrentSimState)
                              .Select(x => x == Motor.SimulationState.Started)
                              .ToReactiveCommand()
                              .WithSubscribe(motor.PauseSimulation)
                              .AddTo(disposable);

            StopSimulation = motor
                             .ObserveProperty(x => x.CurrentSimState)
                             .Select(x => x == Motor.SimulationState.Paused || x == Motor.SimulationState.Started)
                             .ToReactiveCommand()
                             .WithSubscribe(motor.StopSimulation)
                             .AddTo(disposable);

            DrawGlControl = new ReactiveCommand()
                            .WithSubscribe(motor.DrawGlControl)
                            .AddTo(disposable);

            MinVelocity
            .SetValidateNotifyError(x =>
            {
                double min;
                string message;

                if (Utilities.TryParse(x, NumberRange.NonNegative, out min, out message))
                {
                    double max;

                    if (Utilities.TryParse(MaxVelocity.Value, NumberRange.NonNegative, out max) && min >= max)
                    {
                        message = "MinはMax未満でなければなりません。";
                    }
                }

                return(message);
            })
            .Subscribe(_ => MaxVelocity.ForceValidate())
            .AddTo(disposable);

            MinVelocity.ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => MinVelocity.ForceNotify())
            .AddTo(disposable);

            MaxVelocity
            .SetValidateNotifyError(x =>
            {
                double max;
                string message;

                if (Utilities.TryParse(x, NumberRange.NonNegative, out max, out message))
                {
                    double min;

                    if (Utilities.TryParse(MinVelocity.Value, NumberRange.NonNegative, out min) && max <= min)
                    {
                        message = "MinはMax未満でなければなりません。";
                    }
                }

                return(message);
            })
            .Subscribe(_ => MinVelocity.ForceValidate())
            .AddTo(disposable);

            MaxVelocity.ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => MaxVelocity.ForceNotify())
            .AddTo(disposable);

            MinPitch
            .SetValidateNotifyError(x =>
            {
                double min;
                string message;

                if (Utilities.TryParse(x, NumberRange.NonNegative, out min, out message))
                {
                    double max;

                    if (Utilities.TryParse(MaxPitch.Value, NumberRange.NonNegative, out max) && min >= max)
                    {
                        message = "MinはMax未満でなければなりません。";
                    }
                }

                return(message);
            })
            .Subscribe(_ => MaxPitch.ForceValidate())
            .AddTo(disposable);

            MinPitch.ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => MinPitch.ForceNotify())
            .AddTo(disposable);

            MaxPitch
            .SetValidateNotifyError(x =>
            {
                double max;
                string message;

                if (Utilities.TryParse(x, NumberRange.NonNegative, out max, out message))
                {
                    double min;

                    if (Utilities.TryParse(MinPitch.Value, NumberRange.NonNegative, out min) && max <= min)
                    {
                        message = "MinはMax未満でなければなりません。";
                    }
                }

                return(message);
            })
            .Subscribe(_ => MinPitch.ForceValidate())
            .AddTo(disposable);

            MaxPitch.ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => MaxPitch.ForceNotify())
            .AddTo(disposable);

            MinVolume
            .SetValidateNotifyError(x =>
            {
                double min;
                string message;

                if (Utilities.TryParse(x, NumberRange.NonNegative, out min, out message))
                {
                    double max;

                    if (Utilities.TryParse(MaxVolume.Value, NumberRange.NonNegative, out max) && min >= max)
                    {
                        message = "MinはMax未満でなければなりません。";
                    }
                }

                return(message);
            })
            .Subscribe(_ => MaxVolume.ForceValidate())
            .AddTo(disposable);

            MinVolume.ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => MinVolume.ForceNotify())
            .AddTo(disposable);

            MaxVolume
            .SetValidateNotifyError(x =>
            {
                double max;
                string message;

                if (Utilities.TryParse(x, NumberRange.NonNegative, out max, out message))
                {
                    double min;

                    if (Utilities.TryParse(MinVolume.Value, NumberRange.NonNegative, out min) && max <= min)
                    {
                        message = "MinはMax未満でなければなりません。";
                    }
                }

                return(message);
            })
            .Subscribe(_ => MinVolume.ForceValidate())
            .AddTo(disposable);

            MaxVolume.ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => MaxVolume.ForceNotify())
            .AddTo(disposable);
        }