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); }); }
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))); }