Skip to content

Commit 83bc55b

Browse files
committed
transform notation actions to commands
1 parent f63b3d1 commit 83bc55b

10 files changed

Lines changed: 301 additions & 416 deletions

src/notationscene/inotationcommandscontroller.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ class INotationCommandsController : MODULE_CONTEXT_INTERFACE
5656
virtual NoteInputMethod noteInputMethod() const = 0;
5757
virtual DurationType currentDurationType() const = 0;
5858
virtual int currentDotCount() const = 0;
59+
virtual bool currentIsRest() const = 0;
5960
virtual AccidentalType currentAccidentalType() const = 0;
61+
virtual std::set<SymbolId> currentArticulations() const = 0;
62+
virtual voice_idx_t currentVoice() const = 0;
6063
};
6164
}

src/notationscene/internal/notationactioncontroller.cpp

Lines changed: 159 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,18 @@ void NotationActionController::init()
139139
registerCommand(ADD_TIE_COMMAND, &Controller::addTie);
140140
registerCommand(ADD_SLUR_COMMAND, &Controller::addSlur);
141141
registerCommand(ADD_LV_COMMAND, &Controller::addLaissezVib);
142+
registerCommand(ADD_MARCATO_COMMAND, [this]() { toggleArticulation(SymbolId::articMarcatoAbove); });
143+
registerCommand(ADD_SFORZATO_COMMAND, [this]() { toggleArticulation(SymbolId::articAccentAbove); });
144+
registerCommand(ADD_TENUTO_COMMAND, [this]() { toggleArticulation(SymbolId::articTenutoAbove); });
145+
registerCommand(ADD_STACCATO_COMMAND, [this]() { toggleArticulation(SymbolId::articStaccatoAbove); });
146+
147+
registerCommand(USE_VOICE_1_COMMAND, [this]() { changeVoice(0); });
148+
registerCommand(USE_VOICE_2_COMMAND, [this]() { changeVoice(1); });
149+
registerCommand(USE_VOICE_3_COMMAND, [this]() { changeVoice(2); });
150+
registerCommand(USE_VOICE_4_COMMAND, [this]() { changeVoice(3); });
151+
152+
registerCommand(FLIP_COMMAND, &Interaction::flipSelection);
153+
registerCommand(FLIP_HORIZONTALLY_COMMAND, &Interaction::flipSelectionHorizontally);
142154

143155
registerAction("note-action", &Controller::handleNoteAction);
144156

@@ -187,11 +199,6 @@ void NotationActionController::init()
187199

188200
registerAction("rest", &Interaction::putRestToSelection);
189201

190-
registerAction("add-marcato", [this]() { toggleArticulation(SymbolId::articMarcatoAbove); });
191-
registerAction("add-sforzato", [this]() { toggleArticulation(SymbolId::articAccentAbove); });
192-
registerAction("add-tenuto", [this]() { toggleArticulation(SymbolId::articTenutoAbove); });
193-
registerAction("add-staccato", [this]() { toggleArticulation(SymbolId::articStaccatoAbove); });
194-
195202
registerAction("duplet", [this]() { putTuplet(2); }, &Controller::noteOrRestSelected);
196203
registerAction("triplet", [this]() { putTuplet(3); }, &Controller::noteOrRestSelected);
197204
registerAction("quadruplet", [this]() { putTuplet(4); }, &Controller::noteOrRestSelected);
@@ -235,9 +242,6 @@ void NotationActionController::init()
235242
registerAction("notation-paste-special", [this]() { pasteSelection(PastingType::Special); });
236243
registerAction("notation-swap", &Interaction::swapSelection, &Controller::hasSelection);
237244

238-
registerAction("flip", &Interaction::flipSelection, &Controller::hasSelection);
239-
registerAction("flip-horizontally", &Interaction::flipSelectionHorizontally, &Controller::hasSelection);
240-
241245
registerAction("chord-tie", &Controller::chordTie);
242246

243247
registerAction("hammer-on-pull-off", &Controller::addHammerOnPullOff);
@@ -506,10 +510,6 @@ void NotationActionController::init()
506510
}
507511
}
508512

509-
for (voice_idx_t i = 0; i < mu::engraving::VOICES; ++i) {
510-
registerAction("voice-" + std::to_string(i + 1), [this, i]() { changeVoice(static_cast<int>(i)); });
511-
}
512-
513513
registerAction("voice-assignment-all-in-instrument", &Interaction::changeSelectedElementsVoiceAssignment,
514514
VoiceAssignment::ALL_VOICE_IN_INSTRUMENT);
515515
registerAction("voice-assignment-all-in-staff", &Interaction::changeSelectedElementsVoiceAssignment,
@@ -1015,6 +1015,40 @@ int NotationActionController::currentDotCount() const
10151015
return interaction->noteInput()->state().duration().dots();
10161016
}
10171017

1018+
bool NotationActionController::currentIsRest() const
1019+
{
1020+
INotationInteractionPtr interaction = currentNotationInteraction();
1021+
if (!interaction) {
1022+
return false;
1023+
}
1024+
1025+
INotationNoteInputPtr noteInput = interaction->noteInput();
1026+
if (!noteInput) {
1027+
return false;
1028+
}
1029+
1030+
if (noteInput->isNoteInputMode()) {
1031+
return noteInput->state().rest();
1032+
}
1033+
1034+
INotationSelectionPtr selection = interaction->selection();
1035+
if (!selection) {
1036+
return false;
1037+
}
1038+
1039+
if (selection->isNone() || selection->isRange()) {
1040+
return false;
1041+
}
1042+
1043+
for (const EngravingItem* element: selection->elements()) {
1044+
if (!element->isRest()) {
1045+
return false;
1046+
}
1047+
}
1048+
1049+
return true;
1050+
}
1051+
10181052
AccidentalType NotationActionController::currentAccidentalType() const
10191053
{
10201054
INotationInteractionPtr interaction = currentNotationInteraction();
@@ -1025,6 +1059,119 @@ AccidentalType NotationActionController::currentAccidentalType() const
10251059
return interaction->noteInput()->state().accidentalType();
10261060
}
10271061

1062+
std::set<SymbolId> NotationActionController::currentArticulations() const
1063+
{
1064+
INotationInteractionPtr interaction = currentNotationInteraction();
1065+
if (!interaction) {
1066+
return {};
1067+
}
1068+
1069+
INotationNoteInputPtr noteInput = interaction->noteInput();
1070+
if (!noteInput) {
1071+
return {};
1072+
}
1073+
1074+
if (noteInput->isNoteInputMode()) {
1075+
return mu::engraving::splitArticulations(noteInput->state().articulationIds());
1076+
}
1077+
1078+
INotationSelectionPtr selection = interaction->selection();
1079+
if (!selection) {
1080+
return {};
1081+
}
1082+
1083+
if (selection->isNone()) {
1084+
return {};
1085+
}
1086+
1087+
auto chordArticulations = [](const Chord* chord) {
1088+
std::set<SymbolId> result;
1089+
for (Articulation* articulation: chord->articulations()) {
1090+
result.insert(articulation->symId());
1091+
}
1092+
1093+
result = mu::engraving::flipArticulations(result, mu::engraving::PlacementV::ABOVE);
1094+
return mu::engraving::splitArticulations(result);
1095+
};
1096+
1097+
std::set<SymbolId> result;
1098+
bool isFirstNote = true;
1099+
for (const EngravingItem* element: selection->elements()) {
1100+
if (!element->isNote()) {
1101+
continue;
1102+
}
1103+
1104+
const Note* note = toNote(element);
1105+
if (isFirstNote) {
1106+
result = chordArticulations(note->chord());
1107+
isFirstNote = false;
1108+
} else {
1109+
std::set<SymbolId> currentNoteArticulations = chordArticulations(note->chord());
1110+
for (auto it = result.begin(); it != result.end();) {
1111+
if (std::find(currentNoteArticulations.begin(), currentNoteArticulations.end(),
1112+
*it) == currentNoteArticulations.end()) {
1113+
it = result.erase(it);
1114+
} else {
1115+
++it;
1116+
}
1117+
}
1118+
}
1119+
}
1120+
1121+
return result;
1122+
}
1123+
1124+
voice_idx_t NotationActionController::currentVoice() const
1125+
{
1126+
constexpr voice_idx_t INVALID_VOICE = muse::nidx;
1127+
1128+
INotationInteractionPtr interaction = currentNotationInteraction();
1129+
if (!interaction) {
1130+
return INVALID_VOICE;
1131+
}
1132+
1133+
INotationNoteInputPtr noteInput = interaction->noteInput();
1134+
if (!noteInput) {
1135+
return INVALID_VOICE;
1136+
}
1137+
1138+
if (noteInput->isNoteInputMode()) {
1139+
return noteInput->state().voice();
1140+
}
1141+
1142+
INotationSelectionPtr selection = interaction->selection();
1143+
if (!selection) {
1144+
return INVALID_VOICE;
1145+
}
1146+
1147+
if (selection->isNone()) {
1148+
return INVALID_VOICE;
1149+
}
1150+
1151+
const std::vector<EngravingItem*>& selectedElements = selection->elements();
1152+
if (selectedElements.empty()) {
1153+
return INVALID_VOICE;
1154+
}
1155+
1156+
voice_idx_t voice = INVALID_VOICE;
1157+
for (const EngravingItem* element : selectedElements) {
1158+
if (element->hasVoiceAssignmentProperties()) {
1159+
VoiceAssignment voiceAssignment = element->getProperty(Pid::VOICE_ASSIGNMENT).value<VoiceAssignment>();
1160+
if (voiceAssignment == VoiceAssignment::ALL_VOICE_IN_INSTRUMENT || voiceAssignment == VoiceAssignment::ALL_VOICE_IN_STAFF) {
1161+
return INVALID_VOICE;
1162+
}
1163+
}
1164+
voice_idx_t elementVoice = element->voice();
1165+
if (elementVoice != voice && voice != INVALID_VOICE) {
1166+
return INVALID_VOICE;
1167+
}
1168+
1169+
voice = elementVoice;
1170+
}
1171+
1172+
return voice;
1173+
}
1174+
10281175
muse::async::Notification NotationActionController::selectionChanged() const
10291176
{
10301177
return m_selectionChanged;

src/notationscene/internal/notationactioncontroller.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ class NotationActionController : public INotationCommandsController, public muse
8989
NoteInputMethod noteInputMethod() const override;
9090
DurationType currentDurationType() const override;
9191
int currentDotCount() const override;
92+
bool currentIsRest() const override;
9293
AccidentalType currentAccidentalType() const override;
94+
std::set<SymbolId> currentArticulations() const override;
95+
voice_idx_t currentVoice() const override;
9396

9497
muse::async::Notification currentNotationChanged() const;
9598

src/notationscene/internal/notationcommandsregister.cpp

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,77 @@ static const std::vector<CommandInfo> s_commandInfos = {
407407
TranslatableString("notation", "Add laissez vibrer"),
408408
InputSchema(),
409409
Decoration(IconCode::Code::NOTE_LV)
410-
}
410+
},
411+
CommandInfo{
412+
ADD_MARCATO_COMMAND,
413+
TranslatableString("notation", "Marcato"),
414+
TranslatableString("notation", "Add articulation: marcato"),
415+
InputSchema(),
416+
Decoration(IconCode::Code::MARCATO)
417+
},
418+
CommandInfo{
419+
ADD_SFORZATO_COMMAND,
420+
TranslatableString("notation", "Accent"),
421+
TranslatableString("notation", "Add articulation: accent"),
422+
InputSchema(),
423+
Decoration(IconCode::Code::ACCENT)
424+
},
425+
CommandInfo{
426+
ADD_TENUTO_COMMAND,
427+
TranslatableString("notation", "Tenuto"),
428+
TranslatableString("notation", "Add articulation: tenuto"),
429+
InputSchema(),
430+
Decoration(IconCode::Code::TENUTO)
431+
},
432+
CommandInfo{
433+
ADD_STACCATO_COMMAND,
434+
TranslatableString("notation", "Staccato"),
435+
TranslatableString("notation", "Add articulation: staccato"),
436+
InputSchema(),
437+
Decoration(IconCode::Code::STACCATO)
438+
},
439+
CommandInfo{
440+
USE_VOICE_1_COMMAND,
441+
TranslatableString("notation", "Voice 1"),
442+
TranslatableString("notation", "Use voice 1"),
443+
InputSchema(),
444+
Decoration(IconCode::Code::VOICE_1)
445+
},
446+
CommandInfo{
447+
USE_VOICE_2_COMMAND,
448+
TranslatableString("notation", "Voice 2"),
449+
TranslatableString("notation", "Use voice 2"),
450+
InputSchema(),
451+
Decoration(IconCode::Code::VOICE_2)
452+
},
453+
CommandInfo{
454+
USE_VOICE_3_COMMAND,
455+
TranslatableString("notation", "Voice 3"),
456+
TranslatableString("notation", "Use voice 3"),
457+
InputSchema(),
458+
Decoration(IconCode::Code::VOICE_3)
459+
},
460+
CommandInfo{
461+
USE_VOICE_4_COMMAND,
462+
TranslatableString("notation", "Voice 4"),
463+
TranslatableString("notation", "Use voice 4"),
464+
InputSchema(),
465+
Decoration(IconCode::Code::VOICE_4)
466+
},
467+
CommandInfo{
468+
FLIP_COMMAND,
469+
TranslatableString("notation", "Flip direction"),
470+
TranslatableString("notation", "Flip direction"),
471+
InputSchema(),
472+
Decoration(IconCode::Code::NOTE_FLIP)
473+
},
474+
CommandInfo{
475+
FLIP_HORIZONTALLY_COMMAND,
476+
TranslatableString("notation", "Flip horizontally"),
477+
TranslatableString("notation", "Flip horizontally"),
478+
InputSchema(),
479+
Decoration()
480+
},
411481
};
412482

413483
std::string NotationCommandsRegister::moduleName() const

0 commit comments

Comments
 (0)