void Awake()
        {
            editPresenter = EditNotesPresenter.Instance;


            // Select by dragging
            this.UpdateAsObservable()
            .Where(_ => KeyInput.CtrlKey())
            .Where(_ => Input.GetMouseButtonDown(0))
            .Select(_ => Input.mousePosition)
            .SelectMany(startPos => this.UpdateAsObservable()
                        .TakeWhile(_ => !Input.GetMouseButtonUp(0))
                        .Where(_ => NoteCanvas.IsMouseOverNotesRegion.Value)
                        .Select(_ => Input.mousePosition)
                        .Select(currentPos => new Rect(startPos, currentPos - startPos)))
            .Do(rect => GLLineDrawer.Draw(ToLines(rect, selectionRectColor)))
            .Do(_ => { if (!Audio.IsPlaying.Value)
                       {
                           Deselect();
                       }
                })
            .SelectMany(rect => GetNotesWithin(rect))
            .Do(kv => selectedNoteObjects[kv.Key] = kv.Value)
            .Subscribe(kv =>
            {
                if (kv.Value != null)
                {
                    kv.Value.isSelected.Value = true;
                }
            });


            // All select by Ctrl-A
            this.UpdateAsObservable()
            .Where(_ => KeyInput.CtrlPlus(KeyCode.A))
            .SelectMany(_ => EditData.Notes.Values.ToList())
            .Do(noteObj => noteObj.isSelected.Value = true)
            .Subscribe(noteObj => selectedNoteObjects[noteObj.note.position] = noteObj);


            // Copy notes by Ctrl-C
            this.UpdateAsObservable()
            .Where(_ => KeyInput.CtrlPlus(KeyCode.C))
            .Subscribe(notes => CopyNotes(selectedNoteObjects.Values));


            // Cutting notes by Ctrl-X
            this.UpdateAsObservable()
            .Where(_ => KeyInput.CtrlPlus(KeyCode.X))
            .Select(_ => selectedNoteObjects.Values
                    .Where(noteObj => EditData.Notes.ContainsKey(noteObj.note.position)))
            .Do(notes => CopyNotes(notes))
            .Subscribe(notes => DeleteNotes(notes));


            // Deselect by mousedown
            this.UpdateAsObservable()
            .Where(_ => !NoteCanvas.IsMouseOverWaveformRegion.Value)
            .Where(_ => Input.GetMouseButtonDown(0))
            .Subscribe(_ => Deselect());


            // Delete selected notes by delete key
            this.UpdateAsObservable()
            .Where(_ => Input.GetKeyDown(KeyCode.Delete) || Input.GetKeyDown(KeyCode.Backspace))
            .Select(_ => selectedNoteObjects.Values
                    .Where(noteObj => EditData.Notes.ContainsKey(noteObj.note.position)).ToList())
            .Do(_ => selectedNoteObjects.Clear())
            .Subscribe(notes => DeleteNotes(notes));


            // Paste to next beat by Ctrl-V
            this.UpdateAsObservable()
            .Where(_ => KeyInput.CtrlPlus(KeyCode.V))
            .Where(_ => copiedNotes.Count > 0)
            .Select(_ => copiedNotes.OrderBy(note => note.position.ToSamples(Audio.Source.clip.frequency, EditData.BPM.Value)))
            .Subscribe(sortedCopiedNotes =>
            {
                var firstPos = sortedCopiedNotes.First().position;
                var lastPos  = sortedCopiedNotes.Last().position;
                var beatDiff = 1 + lastPos.num / lastPos.LPB - firstPos.num / firstPos.LPB;

                var validNotes = copiedNotes.Where(note => note.position.Add(0, note.position.LPB * beatDiff, 0).ToSamples(Audio.Source.clip.frequency, EditData.BPM.Value) < Audio.Source.clip.samples)
                                 .ToList();

                copiedNotes.Clear();

                validNotes.ToObservable()
                .Select(note =>
                        note.type == NoteTypes.Single
                                ? new Note()
                {
                    position   = note.position.Add(0, note.position.LPB * beatDiff, 0),
                    type       = NoteTypes.Single,
                    attributes = note.attributes,
                    direction  = note.direction,
                }
                                : new Note()
                {
                    position   = note.position.Add(0, note.position.LPB * beatDiff, 0),
                    type       = note.type,
                    next       = note.next.Add(0, note.next.LPB * beatDiff, 0),
                    prev       = note.prev.Add(0, note.prev.LPB * beatDiff, 0),
                    attributes = note.attributes,
                    direction  = note.direction
                })
                .Do(note => copiedNotes.Add(note))
                .Subscribe(note =>
                           (EditData.Notes.ContainsKey(note.position)
                                ? editPresenter.RequestForChangeNoteStatus
                                : editPresenter.RequestForAddNote)
                           .OnNext(note));

                Deselect();

                validNotes.Select(obj => obj.position.Add(0, obj.position.LPB * beatDiff, 0))
                .ToObservable()
                .DelayFrame(1)
                .Select(pastedPosition => EditData.Notes[pastedPosition])
                .Do(pastedObj => selectedNoteObjects[pastedObj.note.position] = pastedObj)
                .Subscribe(pastedObj => pastedObj.isSelected.Value            = true);
            });
        }
Пример #2
0
        public void Init()
        {
            disposable = new CompositeDisposable(
                isSelected,
                LateUpdateObservable,
                OnClickObservable,
                noteColor_,
                noteType);

            var editPresenter = EditNotesPresenter.Instance;

            noteType = this.ObserveEveryValueChanged(_ => note.type).ToReactiveProperty();

            disposable.Add(noteType.Where(_ => !isSelected.Value)
                           .Merge(isSelected.Select(_ => noteType.Value))
                           .Select(type => type == NoteTypes.Long)
                           .Subscribe(isLongNote =>
            {
                noteColor_.Value = isLongNote ? longNoteColor : singleNoteColor;
            }));

            disposable.Add(isSelected.Where(selected => selected)
                           .Subscribe(_ => noteColor_.Value = selectedStateColor));

            var mouseDownObservable = OnClickObservable
                                      .Select(_ => EditState.NoteType.Value)
                                      .Where(_ => NoteCanvas.ClosestNotePosition.Value.Equals(note.position));

            disposable.Add(mouseDownObservable.Where(editType => editType == NoteTypes.Single)
                           .Where(editType => editType == noteType.Value)
                           .Subscribe(_ => editPresenter.RequestForRemoveNote.OnNext(note)));

            disposable.Add(mouseDownObservable.Subscribe(_ =>
            {
                EditState.DirectionVector.Value = (int)(note.direction);
                EditState.AttributeType.Value   = (int)(note.attributes);
            }));

            disposable.Add(mouseDownObservable.Where(editType => editType == NoteTypes.Long)
                           .Where(editType => editType == noteType.Value)
                           .Subscribe(_ =>
            {
                if (EditData.Notes.ContainsKey(EditState.LongNoteTailPosition.Value) && note.prev.Equals(NotePosition.None))
                {
                    var currentTailNote  = new Note(EditData.Notes[EditState.LongNoteTailPosition.Value].note);
                    currentTailNote.next = note.position;
                    editPresenter.RequestForChangeNoteStatus.OnNext(currentTailNote);

                    var selfNote  = new Note(note);
                    selfNote.prev = currentTailNote.position;
                    editPresenter.RequestForChangeNoteStatus.OnNext(selfNote);
                }
                else
                {
                    if (EditData.Notes.ContainsKey(note.prev) && !EditData.Notes.ContainsKey(note.next))
                    {
                        EditState.LongNoteTailPosition.Value = note.prev;
                    }

                    editPresenter
                    .RequestForRemoveNote
                    .OnNext(new Note()
                    {
                        position   = note.position,
                        type       = EditState.NoteType.Value,
                        next       = note.next,
                        prev       = note.prev,
                        attributes = (NoteAttributes)EditState.AttributeType.Value,
                        direction  = (NoteDirection)EditState.DirectionVector.Value
                    });
                    RemoveLink();
                }
            }));

            var longNoteUpdateObservable = LateUpdateObservable
                                           .Where(_ => noteType.Value == NoteTypes.Long);

            disposable.Add(longNoteUpdateObservable
                           .Where(_ => EditData.Notes.ContainsKey(note.next))
                           .Select(_ => ConvertUtils.NoteToCanvasPosition(note.next))
                           .Merge(longNoteUpdateObservable
                                  .Where(_ => EditState.NoteType.Value == NoteTypes.Long)
                                  .Where(_ => EditState.LongNoteTailPosition.Value.Equals(note.position))
                                  .Select(_ => ConvertUtils.ScreenToCanvasPosition(Input.mousePosition)))
                           .Select(nextPosition => new Line(
                                       ConvertUtils.CanvasToScreenPosition(ConvertUtils.NoteToCanvasPosition(note.position)),
                                       ConvertUtils.CanvasToScreenPosition(nextPosition),
                                       isSelected.Value || EditData.Notes.ContainsKey(note.next) && EditData.Notes[note.next].isSelected.Value ? selectedStateColor
                        : 0 < nextPosition.x - ConvertUtils.NoteToCanvasPosition(note.position).x ? longNoteColor : invalidStateColor))
                           .Subscribe(line => GLLineDrawer.Draw(line)));
        }