Skip to content

Commit 32e1f38

Browse files
Add midi note mouse cursor change
1 parent 1bb1ecb commit 32e1f38

File tree

3 files changed

+130
-2
lines changed

3 files changed

+130
-2
lines changed

src/ui/component/editor/MIDIContentViewer.cpp

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "MIDIContentViewer.h"
2+
#include "../../misc/Tools.h"
23
#include "../../lookAndFeel/LookAndFeelFactory.h"
34
#include "../../Utils.h"
45
#include "../../../audioCore/AC_API.h"
@@ -296,6 +297,9 @@ void MIDIContentViewer::mouseUp(const juce::MouseEvent& event) {
296297
void MIDIContentViewer::mouseMove(const juce::MouseEvent& event) {
297298
/** Send Y Pos */
298299
this->mouseYPosFunc(event.position.getY());
300+
301+
/** Update Mouse Cursor */
302+
this->updateMouseCursor(event.position);
299303
}
300304

301305
void MIDIContentViewer::mouseDrag(const juce::MouseEvent& event) {
@@ -528,9 +532,13 @@ void MIDIContentViewer::updateNoteImageTemp() {
528532
juce::Font noteLabelFont(juce::FontOptions{ noteFontHeight });
529533
juce::Font noteLyricsFont(juce::FontOptions{ noteLyricsFontHeight });
530534

535+
/** Temp */
536+
this->noteRectTempList.clear();
537+
531538
/** Notes */
532539
int minNoteNum = std::floor(this->keyBottom), maxNoteNum = std::floor(this->keyTop);
533-
for (auto& note : this->midiDataTemp) {
540+
for (int i = 0; i < this->midiDataTemp.size(); i++) {
541+
auto& note = this->midiDataTemp.getReference(i);
534542
if (note.startSec <= this->secEnd &&
535543
this->secStart <= note.endSec) {
536544
if (note.num >= (minNoteNum - 1) &&
@@ -570,11 +578,119 @@ void MIDIContentViewer::updateNoteImageTemp() {
570578
g.drawFittedText(note.lyrics, noteLyricsRect.toNearestInt(),
571579
juce::Justification::left, 1, 1.0f);
572580
}
581+
582+
/** Add Temp */
583+
this->noteRectTempList.add({ i, noteRect });
573584
}
574585
}
575586
}
576587
}
577588

589+
void MIDIContentViewer::updateMouseCursor(const juce::Point<float>& pos) {
590+
std::tuple<MIDIContentViewer::NoteControllerType, int> noteController;
591+
switch (Tools::getInstance()->getType()) {
592+
case Tools::Type::Arrow:
593+
noteController = this->getNoteControllerWithoutEdge(pos);
594+
break;
595+
case Tools::Type::Pencil:
596+
noteController = this->getNoteController(pos);
597+
break;
598+
}
599+
600+
switch (std::get<0>(noteController)) {
601+
case NoteControllerType::Left:
602+
this->setMouseCursor(juce::MouseCursor::LeftEdgeResizeCursor);
603+
break;
604+
case NoteControllerType::Right:
605+
this->setMouseCursor(juce::MouseCursor::RightEdgeResizeCursor);
606+
break;
607+
case NoteControllerType::Inside:
608+
this->setMouseCursor(juce::MouseCursor::PointingHandCursor);
609+
break;
610+
default:
611+
this->setMouseCursor(juce::MouseCursor::NormalCursor);
612+
break;
613+
}
614+
}
615+
616+
std::tuple<MIDIContentViewer::NoteControllerType, int>
617+
MIDIContentViewer::getNoteController(const juce::Point<float>& pos) const {
618+
/** Size */
619+
auto screenSize = utils::getScreenSize(this);
620+
int noteJudgeWidth = screenSize.getWidth() * 0.005;
621+
622+
int width = this->noteTemp->getWidth(), height = this->noteTemp->getHeight();
623+
624+
/** Check Pos Inside Note */
625+
auto [type, index] = this->getNoteControllerWithoutEdge(pos);
626+
if (index >= 0) {
627+
auto& note = this->midiDataTemp.getReference(index);
628+
float startXPos = (note.startSec - this->secStart) / (this->secEnd - this->secStart) * width;
629+
float endXPos = (note.endSec - this->secStart) / (this->secEnd - this->secStart) * width;
630+
631+
/** Judge Area */
632+
float judgeSSX = startXPos - noteJudgeWidth, judgeSEX = startXPos + noteJudgeWidth;
633+
float judgeESX = endXPos - noteJudgeWidth, judgeEEX = endXPos + noteJudgeWidth;
634+
if (endXPos - startXPos < noteJudgeWidth * 2) {
635+
judgeSEX = startXPos + (endXPos - startXPos) / 2;
636+
judgeESX = endXPos - (endXPos - startXPos) / 2;
637+
}
638+
639+
/** Get Controller */
640+
if (pos.getX() >= judgeSSX && pos.getX() < judgeSEX) {
641+
return { NoteControllerType::Left, index };
642+
}
643+
else if (pos.getX() >= judgeESX && pos.getX() < judgeEEX) {
644+
return { NoteControllerType::Right, index };
645+
}
646+
else if (pos.getX() >= judgeSEX && pos.getX() < judgeESX) {
647+
return { NoteControllerType::Inside, index };
648+
}
649+
}
650+
651+
/** Get Each Block */
652+
for (auto& [index, rect] : this->noteRectTempList) {
653+
if (pos.getY() >= rect.getY() && pos.getY() < rect.getBottom()) {
654+
/** Judge Area */
655+
float judgeSSX = rect.getX() - noteJudgeWidth, judgeSEX = rect.getX() + noteJudgeWidth;
656+
float judgeESX = rect.getRight() - noteJudgeWidth, judgeEEX = rect.getRight() + noteJudgeWidth;
657+
if (rect.getRight() - rect.getX() < noteJudgeWidth * 2) {
658+
judgeSEX = rect.getX() + (rect.getRight() - rect.getX()) / 2;
659+
judgeESX = rect.getRight() - (rect.getRight() - rect.getX()) / 2;
660+
}
661+
662+
/** Get Controller */
663+
if (pos.getX() >= judgeSSX && pos.getX() < judgeSEX) {
664+
return { NoteControllerType::Left, index };
665+
}
666+
else if (pos.getX() >= judgeESX && pos.getX() < judgeEEX) {
667+
return { NoteControllerType::Right, index };
668+
}
669+
else if (pos.getX() >= judgeSEX && pos.getX() < judgeESX) {
670+
return { NoteControllerType::Inside, index };
671+
}
672+
}
673+
}
674+
675+
/** None */
676+
return { NoteControllerType::None, -1 };
677+
}
678+
679+
std::tuple<MIDIContentViewer::NoteControllerType, int>
680+
MIDIContentViewer::getNoteControllerWithoutEdge(const juce::Point<float>& pos) const {
681+
/** Get Each Note */
682+
for (auto& [index, rect] : this->noteRectTempList) {
683+
/** Inside Note */
684+
if (pos.getX() >= rect.getX() && pos.getX() < rect.getRight()
685+
&& pos.getY() >= rect.getY() && pos.getY() < rect.getBottom()) {
686+
return { NoteControllerType::Inside, index };
687+
}
688+
}
689+
690+
/** None */
691+
return { NoteControllerType::None, -1 };
692+
}
693+
578694
std::tuple<double, double> MIDIContentViewer::getHViewArea(double pos, double itemSize) const {
579695
double secStart = pos / itemSize;
580696
double secLength = this->getWidth() / itemSize;

src/ui/component/editor/MIDIContentViewer.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,23 @@ class MIDIContentViewer final
109109
juce::Array<juce::Colour> noteColorGradient;
110110
juce::Array<juce::Colour> noteLabelColorGradient;
111111

112+
/** Index, Rect */
113+
using NoteRectTemp = std::tuple<int, juce::Rectangle<float>>;
114+
juce::Array<NoteRectTemp> noteRectTempList;
115+
112116
void updateKeyImageTemp();
113117
void updateRulerImageTemp();
114118
void updateBlockImageTemp();
115119
void updateNoteImageTemp();
116120

121+
void updateMouseCursor(const juce::Point<float>& pos);
122+
123+
enum class NoteControllerType {
124+
None, Left, Right, Inside
125+
};
126+
std::tuple<NoteControllerType, int> getNoteController(const juce::Point<float>& pos) const;
127+
std::tuple<NoteControllerType, int> getNoteControllerWithoutEdge(const juce::Point<float>& pos) const;
128+
117129
std::tuple<double, double> getHViewArea(double pos, double itemSize) const;
118130
std::tuple<double, double> getVViewArea(double pos, double itemSize) const;
119131

src/ui/component/sequencer/SeqTrackContentViewer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,7 @@ SeqTrackContentViewer::getBlockControllerWithoutEdge(float posX) const {
885885
float startX = (block->startTime - this->secStart) / (this->secEnd - this->secStart) * this->getWidth();
886886
float endX = (block->endTime - this->secStart) / (this->secEnd - this->secStart) * this->getWidth();
887887

888-
/** Set Cursor */
888+
/** Inside Block */
889889
if (posX >= startX && posX < endX) {
890890
return { BlockControllerType::Inside, i };
891891
}

0 commit comments

Comments
 (0)