@@ -100,7 +100,7 @@ void MIDIContentViewer::updateBlocks() {
100
100
auto list = quickAPI::getBlockList (
101
101
{ quickAPI::TrackType::Track, this ->index });
102
102
for (auto [startTime, endTime, offset] : list) {
103
- this ->blockItemTemp .add ({ startTime, endTime, startTime - offset });
103
+ this ->blockItemTemp .add ({ startTime, endTime, startTime + offset });
104
104
}
105
105
106
106
/* * Sort by Source Start Time to Optimize Note Drawing Time */
@@ -117,6 +117,7 @@ void MIDIContentViewer::updateBlocks() {
117
117
118
118
/* * Update UI */
119
119
this ->updateBlockImageTemp ();
120
+ this ->updateNoteImageTemp ();
120
121
this ->repaint ();
121
122
}
122
123
@@ -534,8 +535,18 @@ void MIDIContentViewer::midiChannelChanged() {
534
535
void MIDIContentViewer::insertNote (
535
536
double startTime, double length,
536
537
uint8_t pitch, uint8_t channel) {
537
- CoreActions::midiAddNote (this ->ref , this ->currentMIDITrack ,
538
- startTime, startTime + length, channel, pitch, NOTE_VELOCITY_INIT);
538
+ /* * Match Block */
539
+ double endTime = startTime + length;
540
+ for (int i = 0 ; i < this ->blockItemTemp .size (); i++) {
541
+ auto [blockStartTime, blockEndTime, sourceStartTime] = this ->blockItemTemp .getUnchecked (i);
542
+ if (blockStartTime <= startTime &&
543
+ blockEndTime >= endTime) {
544
+ double noteMappedStartTime = sourceStartTime + (startTime - blockStartTime);
545
+ CoreActions::midiAddNote (this ->ref , this ->currentMIDITrack ,
546
+ noteMappedStartTime, noteMappedStartTime + length, channel, pitch, NOTE_VELOCITY_INIT);
547
+ break ;
548
+ }
549
+ }
539
550
}
540
551
541
552
void MIDIContentViewer::updateKeyImageTemp () {
@@ -723,57 +734,71 @@ void MIDIContentViewer::updateNoteImageTemp() {
723
734
this ->noteRectTempList .clear ();
724
735
uint8_t midiChannel = Tools::getInstance ()->getMIDIChannel ();
725
736
726
- /* * Notes */
737
+ /* * Blocks */
727
738
int minNoteNum = std::floor (this ->keyBottom ), maxNoteNum = std::floor (this ->keyTop );
728
- for (int i = 0 ; i < this ->midiDataTemp .size (); i++) {
729
- auto & note = this ->midiDataTemp .getReference (i);
730
- if (note.startSec <= this ->secEnd &&
731
- this ->secStart <= note.endSec ) {
732
- if (note.num >= (minNoteNum - 1 ) &&
733
- note.num <= maxNoteNum) {
734
- /* * Opaque */
735
- float opaque = (note.channel == midiChannel) ? 1 .0f : 0 .4f ;
736
-
737
- /* * Note Rect */
738
- float startXPos = (note.startSec - this ->secStart ) / (this ->secEnd - this ->secStart ) * width;
739
- float endXPos = (note.endSec - this ->secStart ) / (this ->secEnd - this ->secStart ) * width;
740
- float noteYPos = ((note.num + 1 ) - this ->keyTop ) / (this ->keyBottom - this ->keyTop ) * height;
741
- juce::Rectangle<float > noteRect (
742
- startXPos, noteYPos,
743
- endXPos - startXPos, (float )this ->vItemSize );
744
- g.setColour (noteBaseColor);
745
- g.fillRoundedRectangle (noteRect, noteCornerSize);
746
- g.setColour (this ->noteColorGradient [note.channel - 1 ].withAlpha (opaque));
747
- g.fillRoundedRectangle (noteRect,noteCornerSize);
748
- g.setColour (noteOutlineColor.withAlpha (opaque));
749
- g.drawRoundedRectangle (noteRect, noteCornerSize, noteOutlineThickness);
750
-
751
- /* * Note Name */
752
- juce::String noteName = this ->keyNames [note.num % this ->keyMasks .size ()] + juce::String{ note.num / this ->keyMasks .size () };
753
- float noteNameWidth = juce::TextLayout::getStringWidth (noteLabelFont, noteName);
754
- if ((noteNameWidth + notePaddingWidth * 2 ) <= noteRect.getWidth ()
755
- && (noteFontHeight + notePaddingHeight * 2 ) <= noteRect.getHeight ()) {
756
- juce::Rectangle<float > noteLabelRect = noteRect.withWidth (noteNameWidth + notePaddingWidth * 2 );
757
- g.setFont (noteLabelFont);
758
- g.setColour (this ->noteLabelColorGradient [note.channel - 1 ].withAlpha (opaque));
759
- g.drawFittedText (noteName, noteLabelRect.toNearestInt (),
760
- juce::Justification::centred, 1 , 0 .75f );
761
- }
762
-
763
- /* * Lyrics */
764
- float noteLyricsWidth = juce::TextLayout::getStringWidth (noteLyricsFont, note.lyrics );
765
- if (notePaddingWidth * 2 <= noteRect.getWidth ()) {
766
- juce::Rectangle<float > noteLyricsRect (
767
- noteRect.getX () + notePaddingWidth, noteRect.getY () - (float )this ->vItemSize ,
768
- noteRect.getWidth () - notePaddingWidth * 2 , (float )this ->vItemSize );
769
- g.setFont (noteLyricsFont);
770
- g.setColour (noteLyricsColor.withAlpha (opaque));
771
- g.drawFittedText (note.lyrics , noteLyricsRect.toNearestInt (),
772
- juce::Justification::left, 1 , 1 .0f );
739
+ for (int i = 0 ; i < this ->blockItemTemp .size (); i++) {
740
+ auto [blockStartTime, blockEndTime, sourceStartTime] = this ->blockItemTemp .getUnchecked (i);
741
+ if ((blockStartTime <= this ->secEnd )
742
+ && (blockEndTime >= this ->secStart )) {
743
+ double sourceEndTime = sourceStartTime + (blockEndTime - blockStartTime);
744
+
745
+ /* * For Each Notes */
746
+ for (int j = 0 ; j < this ->midiDataTemp .size (); j++) {
747
+ auto & note = this ->midiDataTemp .getReference (j);
748
+ if (note.startSec <= sourceEndTime &&
749
+ sourceStartTime <= note.endSec ) {
750
+ double noteMappedStartSec = blockStartTime + (note.startSec - sourceStartTime);
751
+ double noteMappedEndSec = blockStartTime + (note.endSec - sourceStartTime);
752
+ if (noteMappedStartSec <= this ->secEnd &&
753
+ this ->secStart <= noteMappedEndSec) {
754
+ if (note.num >= (minNoteNum - 1 ) &&
755
+ note.num <= maxNoteNum) {
756
+ /* * Opaque */
757
+ float opaque = (note.channel == midiChannel) ? 1 .0f : 0 .4f ;
758
+
759
+ /* * Note Rect */
760
+ float startXPos = (noteMappedStartSec - this ->secStart ) / (this ->secEnd - this ->secStart ) * width;
761
+ float endXPos = (noteMappedEndSec - this ->secStart ) / (this ->secEnd - this ->secStart ) * width;
762
+ float noteYPos = ((note.num + 1 ) - this ->keyTop ) / (this ->keyBottom - this ->keyTop ) * height;
763
+ juce::Rectangle<float > noteRect (
764
+ startXPos, noteYPos,
765
+ endXPos - startXPos, (float )this ->vItemSize );
766
+ g.setColour (noteBaseColor);
767
+ g.fillRoundedRectangle (noteRect, noteCornerSize);
768
+ g.setColour (this ->noteColorGradient [note.channel - 1 ].withAlpha (opaque));
769
+ g.fillRoundedRectangle (noteRect, noteCornerSize);
770
+ g.setColour (noteOutlineColor.withAlpha (opaque));
771
+ g.drawRoundedRectangle (noteRect, noteCornerSize, noteOutlineThickness);
772
+
773
+ /* * Note Name */
774
+ juce::String noteName = this ->keyNames [note.num % this ->keyMasks .size ()] + juce::String{ note.num / this ->keyMasks .size () };
775
+ float noteNameWidth = juce::TextLayout::getStringWidth (noteLabelFont, noteName);
776
+ if ((noteNameWidth + notePaddingWidth * 2 ) <= noteRect.getWidth ()
777
+ && (noteFontHeight + notePaddingHeight * 2 ) <= noteRect.getHeight ()) {
778
+ juce::Rectangle<float > noteLabelRect = noteRect.withWidth (noteNameWidth + notePaddingWidth * 2 );
779
+ g.setFont (noteLabelFont);
780
+ g.setColour (this ->noteLabelColorGradient [note.channel - 1 ].withAlpha (opaque));
781
+ g.drawFittedText (noteName, noteLabelRect.toNearestInt (),
782
+ juce::Justification::centred, 1 , 0 .75f );
783
+ }
784
+
785
+ /* * Lyrics */
786
+ float noteLyricsWidth = juce::TextLayout::getStringWidth (noteLyricsFont, note.lyrics );
787
+ if (notePaddingWidth * 2 <= noteRect.getWidth ()) {
788
+ juce::Rectangle<float > noteLyricsRect (
789
+ noteRect.getX () + notePaddingWidth, noteRect.getY () - (float )this ->vItemSize ,
790
+ noteRect.getWidth () - notePaddingWidth * 2 , (float )this ->vItemSize );
791
+ g.setFont (noteLyricsFont);
792
+ g.setColour (noteLyricsColor.withAlpha (opaque));
793
+ g.drawFittedText (note.lyrics , noteLyricsRect.toNearestInt (),
794
+ juce::Justification::left, 1 , 1 .0f );
795
+ }
796
+
797
+ /* * Add Temp */
798
+ this ->noteRectTempList .add ({ j, noteRect, note.channel });
799
+ }
800
+ }
773
801
}
774
-
775
- /* * Add Temp */
776
- this ->noteRectTempList .add ({ i, noteRect, note.channel });
777
802
}
778
803
}
779
804
}
@@ -820,9 +845,9 @@ MIDIContentViewer::getNoteController(const juce::Point<float>& pos) const {
820
845
/* * Check Pos Inside Note */
821
846
auto [type, index ] = this ->getNoteControllerWithoutEdge (pos);
822
847
if (index >= 0 ) {
823
- auto & note = this ->midiDataTemp .getReference (index );
824
- float startXPos = (note. startSec - this -> secStart ) / ( this -> secEnd - this -> secStart ) * width ;
825
- float endXPos = (note. endSec - this -> secStart ) / ( this -> secEnd - this -> secStart ) * width ;
848
+ auto & note = this ->noteRectTempList .getReference (index );
849
+ float startXPos = std::get< 1 > (note). getX () ;
850
+ float endXPos = std::get< 1 > (note). getRight () ;
826
851
827
852
/* * Judge Area */
828
853
float judgeSSX = startXPos - noteJudgeWidth, judgeSEX = startXPos + noteJudgeWidth;
@@ -844,8 +869,9 @@ MIDIContentViewer::getNoteController(const juce::Point<float>& pos) const {
844
869
}
845
870
}
846
871
847
- /* * Get Each Block */
848
- for (auto & [index , rect, channel] : this ->noteRectTempList ) {
872
+ /* * Get Each Note */
873
+ for (int i = 0 ; i < this ->noteRectTempList .size (); i++) {
874
+ auto & [index , rect, channel] = this ->noteRectTempList .getReference (i);
849
875
if (channel == midiChannel) {
850
876
if (pos.getY () >= rect.getY () && pos.getY () < rect.getBottom ()) {
851
877
/* * Judge Area */
@@ -858,13 +884,13 @@ MIDIContentViewer::getNoteController(const juce::Point<float>& pos) const {
858
884
859
885
/* * Get Controller */
860
886
if (pos.getX () >= judgeSSX && pos.getX () < judgeSEX) {
861
- return { NoteControllerType::Left, index };
887
+ return { NoteControllerType::Left, i };
862
888
}
863
889
else if (pos.getX () >= judgeESX && pos.getX () < judgeEEX) {
864
- return { NoteControllerType::Right, index };
890
+ return { NoteControllerType::Right, i };
865
891
}
866
892
else if (pos.getX () >= judgeSEX && pos.getX () < judgeESX) {
867
- return { NoteControllerType::Inside, index };
893
+ return { NoteControllerType::Inside, i };
868
894
}
869
895
}
870
896
}
@@ -880,12 +906,13 @@ MIDIContentViewer::getNoteControllerWithoutEdge(const juce::Point<float>& pos) c
880
906
uint8_t midiChannel = Tools::getInstance ()->getMIDIChannel ();
881
907
882
908
/* * Get Each Note */
883
- for (auto & [index , rect, channel] : this ->noteRectTempList ) {
909
+ for (int i = 0 ; i < this ->noteRectTempList .size (); i++) {
910
+ auto & [index , rect, channel] = this ->noteRectTempList .getReference (i);
884
911
/* * Inside Note */
885
912
if (channel == midiChannel) {
886
913
if (pos.getX () >= rect.getX () && pos.getX () < rect.getRight ()
887
914
&& pos.getY () >= rect.getY () && pos.getY () < rect.getBottom ()) {
888
- return { NoteControllerType::Inside, index };
915
+ return { NoteControllerType::Inside, i };
889
916
}
890
917
}
891
918
}
0 commit comments