private void PianoWindow_TrackMouseUp(object sender, VocalUtau.DirectUI.PianoMouseEventArgs e) { if (!_HandleEvents) { return; } bool NotMove = false; if (NoteDragingWork != NoteDragingType.None) { if (NoteDragingWork == NoteDragingType.NoteLength) { long NewSize = e.Tick - NoteList[CurrentNoteIndex].Tick; NewSize = (long)(NewSize / _TickStepTick) * _TickStepTick; if (NewSize >= 32) { NoteList[CurrentNoteIndex].Length = NewSize; int StartPX = Math.Max(0, CurrentNoteIndex); int EndPX = Math.Min(NoteList.Count - 1, CurrentNoteIndex + 1); PartsObject.PitchCompiler.SetupBasePitch_Aysnc(new Formats.Model.VocalObject.ParamTranslater.PitchCompiler.AsyncWorkCallbackHandler((F, L) => { this.PianoWindow.Invoke(new Action(() => { this.PianoWindow.RedrawPiano(); })); }), StartPX, EndPX); if (this.SingerDataFinder != null) { PartsObject po = PartsObject; this.SingerDataFinder.GetPhonemesDictionary(PartsObject).UpdateLyrics_Aysnc(new Formats.Model.Database.VocalDatabase.SplitDictionary.AsyncWorkCallbackHandler((P, F, L) => { }), ref po, CurrentNoteIndex, CurrentNoteIndex);; } } NoteDias.Clear(); } else if (NoteDragingWork == NoteDragingType.NoteMove) { long minTickChange = (long)PianoWindow.PianoProps.dertPixel2dertTick(AntiShakePixel); List <NoteObject> SelectingNoteCache = new List <NoteObject>(); for (int i = 0; i < NoteSelectIndexs.Count; i++) { SelectingNoteCache.Add(PartsObject.NoteList[NoteSelectIndexs[i]]); } bool TickChanged = false; if (NoteSelectIndexs.IndexOf(CurrentNoteIndex) == -1) { long NewTick = e.Tick - NoteTempTick; NewTick = (long)(NewTick / _TickStepTick) * _TickStepTick; long TickDert = NoteList[CurrentNoteIndex].Tick - NewTick; long NoteDert = NoteList[CurrentNoteIndex].PitchValue.NoteNumber - e.PitchValue.NoteNumber; if (NoteList[CurrentNoteIndex].PitchValue.NoteNumber != e.PitchValue.NoteNumber) { NoteList[CurrentNoteIndex].PitchValue = new PitchAtomObject(e.PitchValue.NoteNumber, NoteList[CurrentNoteIndex].PitchValue.PitchWheel); } TickChanged = Math.Abs(TickDert) >= minTickChange; NotMove = (NoteDert == 0 && Math.Abs(TickDert) < minTickChange); NoteObject OldNoteSt = NoteList[CurrentNoteIndex]; long oldStartTick = OldNoteSt.Tick; long oldEndTick = OldNoteSt.Tick + OldNoteSt.Length; if (Math.Abs(TickDert) > minTickChange) { NoteList[CurrentNoteIndex].Tick = NoteList[CurrentNoteIndex].Tick - TickDert; NoteList.Sort(); } long AStartTick = Math.Min(oldStartTick, OldNoteSt.Tick); long AEndTick = Math.Max(oldEndTick, OldNoteSt.Tick + OldNoteSt.Length); int ONI = NoteList.IndexOf(OldNoteSt); if (!NotMove) { int StartPX = ONI; int EndPX = ONI; List <NoteObject> PO = PartsObject.NoteList; int FSIdx = PartsObject.NoteCompiler.FindTickIndex(AStartTick, 0, PO.Count); int FEIdx = PartsObject.NoteCompiler.FindTickIndex(AEndTick, FSIdx, PO.Count); StartPX = Math.Min(StartPX, FSIdx); EndPX = Math.Max(EndPX, FEIdx); StartPX = Math.Max(0, StartPX); EndPX = Math.Min(NoteList.Count - 1, EndPX); PartsObject.PitchCompiler.SetupBasePitch_Aysnc(new Formats.Model.VocalObject.ParamTranslater.PitchCompiler.AsyncWorkCallbackHandler((F, L) => { this.PianoWindow.Invoke(new Action(() => { this.PianoWindow.RedrawPiano(); })); }), StartPX, EndPX); if (this.SingerDataFinder != null) { PartsObject po = PartsObject; this.SingerDataFinder.GetPhonemesDictionary(PartsObject).UpdateLyrics_Aysnc(new Formats.Model.Database.VocalDatabase.SplitDictionary.AsyncWorkCallbackHandler((P, F, L) => { }), ref po, ONI, ONI);; } } } else { long NewTick = e.Tick - NoteTempTick; NewTick = (long)(NewTick / _TickStepTick) * _TickStepTick; long TickDert = NoteList[CurrentNoteIndex].Tick - NewTick; long NoteDert = NoteList[CurrentNoteIndex].PitchValue.NoteNumber - e.PitchValue.NoteNumber; NotMove = (NoteDert == 0 && Math.Abs(TickDert) < minTickChange); TickChanged = Math.Abs(TickDert) >= minTickChange; NoteObject OldNoteSt = NoteList[NoteSelectIndexs[0]]; NoteObject LastNoteEd = NoteList[NoteSelectIndexs[NoteSelectIndexs.Count - 1]]; long oldStartTick = OldNoteSt.Tick; long oldEndTick = LastNoteEd.Tick + LastNoteEd.Length; for (int i = 0; i < SelectingNoteCache.Count; i++) { uint NewNoteNumber = (uint)(SelectingNoteCache[i].PitchValue.NoteNumber - NoteDert); if (SelectingNoteCache[i].PitchValue.NoteNumber != NewNoteNumber) { SelectingNoteCache[i].PitchValue = new PitchAtomObject(NewNoteNumber, SelectingNoteCache[i].PitchValue.PitchWheel); } if (Math.Abs(TickDert) > minTickChange) { SelectingNoteCache[i].Tick = SelectingNoteCache[i].Tick - TickDert; } } if (Math.Abs(TickDert) > minTickChange) { NoteList.Sort(); } long AStartTick = Math.Min(oldStartTick, OldNoteSt.Tick); long AEndTick = Math.Max(oldEndTick, LastNoteEd.Tick + LastNoteEd.Length); int First = Math.Min(NoteList.IndexOf(SelectingNoteCache[0]), NoteList.IndexOf(OldNoteSt)); int Last = Math.Max(NoteList.IndexOf(SelectingNoteCache[SelectingNoteCache.Count - 1]), NoteList.IndexOf(LastNoteEd)); if (First <= Last) { if (!NotMove) { int StartPX = First; int EndPX = Last; int FSIdx = PartsObject.NoteCompiler.FindTickIndex(AStartTick, 0, PartsObject.NoteList.Count); int FEIdx = PartsObject.NoteCompiler.FindTickIndex(AEndTick, FSIdx, PartsObject.NoteList.Count) + 1; StartPX = Math.Min(StartPX, FSIdx); EndPX = Math.Max(EndPX, FEIdx); StartPX = Math.Max(0, StartPX); EndPX = Math.Min(NoteList.Count - 1, EndPX); PartsObject.PitchCompiler.SetupBasePitch_Aysnc(new Formats.Model.VocalObject.ParamTranslater.PitchCompiler.AsyncWorkCallbackHandler((F, L) => { this.PianoWindow.Invoke(new Action(() => { this.PianoWindow.RedrawPiano(); })); }), StartPX, EndPX); if (this.SingerDataFinder != null) { PartsObject po = PartsObject; this.SingerDataFinder.GetPhonemesDictionary(PartsObject).UpdateOutboundsLyric_Aysnc(new Formats.Model.Database.VocalDatabase.SplitDictionary.AsyncWorkCallbackHandler((P, F, L) => { }), ref po, StartPX, EndPX);; } } } } if (TickChanged) { NoteSelectIndexs.Clear(); for (int i = 0; i < SelectingNoteCache.Count; i++) { NoteSelectIndexs.Add(PartsObject.NoteList.IndexOf(SelectingNoteCache[i])); } } NoteDias.Clear(); } else if (NoteDragingWork == NoteDragingType.NoteAdd) { NoteObject nPN = new NoteObject(NoteDias[0].TickStart, NoteDias[0].TickEnd - NoteDias[0].TickStart, NoteDias[0].TopNoteNum); if (nPN.Length >= 32) { nPN.InitNote(); NoteList.Add(nPN); NoteList.Sort(); NoteDias.Clear(); int NIndex = NoteList.IndexOf(nPN); PartsObject.PitchCompiler.SetupBasePitch_Aysnc(new Formats.Model.VocalObject.ParamTranslater.PitchCompiler.AsyncWorkCallbackHandler((F, L) => { this.PianoWindow.Invoke(new Action(() => { this.PianoWindow.RedrawPiano(); })); }), NIndex, NIndex); if (this.SingerDataFinder != null) { PartsObject po = PartsObject; this.SingerDataFinder.GetPhonemesDictionary(PartsObject).UpdateLyrics_Aysnc(new Formats.Model.Database.VocalDatabase.SplitDictionary.AsyncWorkCallbackHandler((P, F, L) => { }), ref po, NIndex, NIndex);; } } else { NoteDragingWork = NoteDragingType.AreaSelect; } } else if (NoteDragingWork == NoteDragingType.AreaSelect) { ClearSelect(); long mt = NoteDias[0].TickEnd; long nt = NoteDias[0].TickStart; if (e.Tick >= nt && e.Tick <= mt) { int Sfx = PartsObject.NoteCompiler.FindTickIndex(nt, 0, NoteList.Count); for (int i = Sfx; i < NoteList.Count; i++) { NoteObject PN = NoteList[i]; if (PN.Tick >= mt) { break; } if (PN.Tick + PN.Length < nt) { continue; } if (PN.PitchValue.NoteNumber >= NoteDias[0].BottomNoteNum && PN.PitchValue.NoteNumber <= NoteDias[0].TopNoteNum) { NoteSelectIndexs.Add(i); } } } if (NoteSelectListChange != null) { NoteSelectListChange(NoteSelectIndexs); } NoteDias.Clear(); } if (NoteDragingWork != NoteDragingType.AreaSelect && NoteActionEnd != null) { if (NotMove) { NoteActionEnd(NoteDragingWork, true); } else { NoteActionEnd(NoteDragingWork); } } } NoteDragingWork = NoteDragingType.None; }