diff --git a/src/engraving/dom/edit.cpp b/src/engraving/dom/edit.cpp index b7f47d0ec06e0..380f5a9e0c53b 100644 --- a/src/engraving/dom/edit.cpp +++ b/src/engraving/dom/edit.cpp @@ -24,6 +24,7 @@ #include #include "infrastructure/messagebox.h" +#include "notation/internal/notationconfiguration.h" #include "accidental.h" #include "articulation.h" @@ -1587,7 +1588,7 @@ NoteVal Score::noteVal(int pitch) const // if transposing, interpret MIDI pitch as representing desired written pitch // set pitch based on corresponding sounding pitch - if (!style().styleB(Sid::concertPitch)) { + if (!style().styleB(Sid::concertPitch) && notationConfiguration()->pianoKeyboardUseNotatedPitch().val) { nval.pitch += st->part()->instrument(inputState().tick())->transpose().chromatic; } // let addPitch calculate tpc values from pitch diff --git a/src/engraving/dom/score.h b/src/engraving/dom/score.h index 97861bba43a75..3f1fe2e012b43 100644 --- a/src/engraving/dom/score.h +++ b/src/engraving/dom/score.h @@ -90,6 +90,10 @@ namespace mu::engraving::compat { class WriteScoreHook; } +namespace mu::notation { +class INotationConfiguration; +} + namespace mu::engraving { class Articulation; class Audio; @@ -273,6 +277,7 @@ class Score : public EngravingObject, public muse::Injectable muse::Inject engravingFonts = { this }; muse::Inject application = { this }; muse::Inject elementsProvider = { this }; + muse::Inject notationConfiguration = { this }; // internal muse::Inject renderer = { this }; diff --git a/src/notation/inotationconfiguration.h b/src/notation/inotationconfiguration.h index ed4b51d9a2fa8..4ce05ee8748dc 100644 --- a/src/notation/inotationconfiguration.h +++ b/src/notation/inotationconfiguration.h @@ -193,6 +193,9 @@ class INotationConfiguration : MODULE_EXPORT_INTERFACE virtual muse::ValCh pianoKeyboardNumberOfKeys() const = 0; virtual void setPianoKeyboardNumberOfKeys(int number) = 0; + virtual muse::ValCh pianoKeyboardUseNotatedPitch() const = 0; + virtual void setPianoKeyboardUseNotatedPitch(bool useNotatedPitch) = 0; + // TODO: Delete when the new percussion panel is finished virtual bool useNewPercussionPanel() const = 0; virtual void setUseNewPercussionPanel(bool use) = 0; diff --git a/src/notation/internal/notationconfiguration.cpp b/src/notation/internal/notationconfiguration.cpp index 80331f0cbfab6..fe1dae7914a9a 100644 --- a/src/notation/internal/notationconfiguration.cpp +++ b/src/notation/internal/notationconfiguration.cpp @@ -89,6 +89,7 @@ static const Settings::Key NEED_TO_SHOW_ADD_FIGURED_BASS_ERROR_MESSAGE_KEY(modul static const Settings::Key NEED_TO_SHOW_ADD_GUITAR_BEND_ERROR_MESSAGE_KEY(module_name, "ui/dialogs/needToShowAddGuitarBendErrorMessage"); static const Settings::Key PIANO_KEYBOARD_NUMBER_OF_KEYS(module_name, "pianoKeyboard/numberOfKeys"); +static const Settings::Key PIANO_KEYBOARD_PITCH_STATE(module_name, "pianoKeyboard/useNotatedPitch"); static const Settings::Key USE_NEW_PERCUSSION_PANEL_KEY(module_name, "ui/useNewPercussionPanel"); static const Settings::Key AUTO_SHOW_PERCUSSION_PANEL_KEY(module_name, "ui/autoShowPercussionPanel"); @@ -220,6 +221,12 @@ void NotationConfiguration::init() m_pianoKeyboardNumberOfKeys.set(val.toInt()); }); + settings()->setDefaultValue(PIANO_KEYBOARD_PITCH_STATE, Val(true)); + m_pianoKeyboardUseNotatedPitch.val = settings()->value(PIANO_KEYBOARD_PITCH_STATE).toBool(); + settings()->valueChanged(PIANO_KEYBOARD_PITCH_STATE).onReceive(this, [this](const Val& val) { + m_pianoKeyboardUseNotatedPitch.set(val.toBool()); + }); + settings()->setDefaultValue(USE_NEW_PERCUSSION_PANEL_KEY, Val(false)); settings()->setDefaultValue(AUTO_SHOW_PERCUSSION_PANEL_KEY, Val(true)); @@ -919,6 +926,16 @@ void NotationConfiguration::setPianoKeyboardNumberOfKeys(int number) settings()->setSharedValue(PIANO_KEYBOARD_NUMBER_OF_KEYS, Val(number)); } +ValCh NotationConfiguration::pianoKeyboardUseNotatedPitch() const +{ + return m_pianoKeyboardUseNotatedPitch; +} + +void NotationConfiguration::setPianoKeyboardUseNotatedPitch(bool useNotatedPitch) +{ + settings()->setSharedValue(PIANO_KEYBOARD_PITCH_STATE, Val(useNotatedPitch)); +} + muse::io::path_t NotationConfiguration::firstScoreOrderListPath() const { return settings()->value(FIRST_SCORE_ORDER_LIST_KEY).toString(); diff --git a/src/notation/internal/notationconfiguration.h b/src/notation/internal/notationconfiguration.h index 78e929d23a389..78a998ae2d089 100644 --- a/src/notation/internal/notationconfiguration.h +++ b/src/notation/internal/notationconfiguration.h @@ -198,6 +198,9 @@ class NotationConfiguration : public INotationConfiguration, public muse::async: muse::ValCh pianoKeyboardNumberOfKeys() const override; void setPianoKeyboardNumberOfKeys(int number) override; + muse::ValCh pianoKeyboardUseNotatedPitch() const override; + void setPianoKeyboardUseNotatedPitch(bool useNotatedPitch) override; + bool useNewPercussionPanel() const override; void setUseNewPercussionPanel(bool use) override; @@ -231,6 +234,7 @@ class NotationConfiguration : public INotationConfiguration, public muse::async: muse::async::Notification m_isPlayRepeatsChanged; muse::async::Notification m_isPlayChordSymbolsChanged; muse::ValCh m_pianoKeyboardNumberOfKeys; + muse::ValCh m_pianoKeyboardUseNotatedPitch; muse::async::Channel m_anchorColorChanged; int m_styleDialogLastPageIndex = 0; diff --git a/src/notation/tests/mocks/notationconfigurationmock.h b/src/notation/tests/mocks/notationconfigurationmock.h index ce45c0fff2fdc..b0bf76334c631 100644 --- a/src/notation/tests/mocks/notationconfigurationmock.h +++ b/src/notation/tests/mocks/notationconfigurationmock.h @@ -183,6 +183,9 @@ class NotationConfigurationMock : public INotationConfiguration MOCK_METHOD(muse::ValCh, pianoKeyboardNumberOfKeys, (), (const, override)); MOCK_METHOD(void, setPianoKeyboardNumberOfKeys, (int), (override)); + MOCK_METHOD(muse::ValCh, pianoKeyboardUseNotatedPitch, (), (const, override)); + MOCK_METHOD(void, setPianoKeyboardUseNotatedPitch, (bool), (override)); + MOCK_METHOD(bool, useNewPercussionPanel, (), (const, override)); MOCK_METHOD(void, setUseNewPercussionPanel, (bool), (override)); diff --git a/src/notation/view/pianokeyboard/pianokeyboardcontroller.cpp b/src/notation/view/pianokeyboard/pianokeyboardcontroller.cpp index 66c8901d75508..124f6a57e342b 100644 --- a/src/notation/view/pianokeyboard/pianokeyboardcontroller.cpp +++ b/src/notation/view/pianokeyboard/pianokeyboardcontroller.cpp @@ -133,9 +133,9 @@ void PianoKeyboardController::updateNotesKeys(const std::vector& re }; for (const mu::engraving::Note* note : receivedNotes) { - newKeys.insert(static_cast(note->epitch())); + newKeys.insert(static_cast(useNotatedPitch() ? note->epitch() : note->ppitch())); for (const mu::engraving::Note* otherNote : note->chord()->notes()) { - newOtherNotesInChord.insert(static_cast(otherNote->epitch())); + newOtherNotesInChord.insert(static_cast(useNotatedPitch() ? otherNote->epitch() : otherNote->ppitch())); } } } @@ -175,3 +175,8 @@ INotationPtr PianoKeyboardController::currentNotation() const { return context()->currentNotation(); } + +bool PianoKeyboardController::useNotatedPitch() const +{ + return configuration()->pianoKeyboardUseNotatedPitch().val; +} diff --git a/src/notation/view/pianokeyboard/pianokeyboardcontroller.h b/src/notation/view/pianokeyboard/pianokeyboardcontroller.h index 140ead36b72b2..0170c5ac630fc 100644 --- a/src/notation/view/pianokeyboard/pianokeyboardcontroller.h +++ b/src/notation/view/pianokeyboard/pianokeyboardcontroller.h @@ -32,6 +32,7 @@ namespace mu::notation { class PianoKeyboardController : public muse::Injectable, public muse::async::Asyncable { + muse::Inject configuration = { this }; muse::Inject context = { this }; public: @@ -45,6 +46,8 @@ class PianoKeyboardController : public muse::Injectable, public muse::async::Asy bool isFromMidi() const; + bool useNotatedPitch() const; + private: INotationPtr currentNotation() const; diff --git a/src/notation/view/pianokeyboard/pianokeyboardpanelcontextmenumodel.cpp b/src/notation/view/pianokeyboard/pianokeyboardpanelcontextmenumodel.cpp index 4bb49b241ae35..ae19e847accae 100644 --- a/src/notation/view/pianokeyboard/pianokeyboardpanelcontextmenumodel.cpp +++ b/src/notation/view/pianokeyboard/pianokeyboardpanelcontextmenumodel.cpp @@ -35,6 +35,7 @@ using namespace muse::uicomponents; static const ActionCode SET_KEY_WIDTH_SCALING_CODE("piano-keyboard-set-key-width-scaling"); static const ActionCode SET_NUMBER_OF_KEYS_CODE("piano-keyboard-set-number-of-keys"); +static const ActionCode SET_NOTATED_PITCH_CODE("piano-keyboard-toggle-notated-pitch"); PianoKeyboardPanelContextMenuModel::PianoKeyboardPanelContextMenuModel(QObject* parent) : AbstractMenuModel(parent) @@ -44,7 +45,8 @@ PianoKeyboardPanelContextMenuModel::PianoKeyboardPanelContextMenuModel(QObject* void PianoKeyboardPanelContextMenuModel::load() { MenuItemList items { - makeViewMenu() + makeViewMenu(), + makePitchMenu(), }; setItems(items); @@ -71,6 +73,35 @@ int PianoKeyboardPanelContextMenuModel::numberOfKeys() const return configuration()->pianoKeyboardNumberOfKeys().val; } +MenuItem* PianoKeyboardPanelContextMenuModel::makePitchMenu() +{ + MenuItemList items; + + std::vector > possibleNotationStates { + { muse::TranslatableString("notation", "Use notated pitch"), true }, + { muse::TranslatableString("notation", "Use playback pitch"), false }, + }; + + for (auto [title, notationState] : possibleNotationStates) { + items << makeToggleNotatedPitchItem(title, notationState); + } + + configuration()->pianoKeyboardUseNotatedPitch().ch.onReceive(this, [this](bool) { + emit pianoKeyboardUseNotatedPitchChanged(); + }); + + dispatcher()->reg(this, SET_NOTATED_PITCH_CODE, [this](const ActionData& args) { + IF_ASSERT_FAILED(args.count() > 0) { + return; + } + + configuration()->setPianoKeyboardUseNotatedPitch(args.arg(0)); + emit pianoKeyboardUseNotatedPitchChanged(); + }); + + return makeMenu(muse::TranslatableString("notation", "Pitch mode for transposing instruments"), items); +} + MenuItem* PianoKeyboardPanelContextMenuModel::makeViewMenu() { MenuItemList items; @@ -167,6 +198,31 @@ MenuItem* PianoKeyboardPanelContextMenuModel::makeNumberOfKeysItem(const muse::T return item; } +MenuItem* PianoKeyboardPanelContextMenuModel::makeToggleNotatedPitchItem(const muse::TranslatableString& title, bool isNotatedPitch) +{ + UiAction action; + action.title = title; + action.code = SET_NOTATED_PITCH_CODE; + action.checkable = Checkable::Yes; + + MenuItem* item = new MenuItem(action, this); + item->setId(QString::fromStdString(SET_NOTATED_PITCH_CODE) + (isNotatedPitch ? "-notated" : "-playback")); + + ValCh currentState = configuration()->pianoKeyboardUseNotatedPitch(); + + bool checked = !(isNotatedPitch ^ currentState.val); + item->setState(UiActionState::make_enabled(checked)); + + currentState.ch.onReceive(item, [item, isNotatedPitch](bool s) { + bool checked = !(isNotatedPitch ^ s); + item->setState(UiActionState::make_enabled(checked)); + }); + + item->setArgs(ActionData::make_arg1(isNotatedPitch)); + + return item; +} + void PianoKeyboardPanelContextMenuModel::updateKeyWidthScalingItems() { qreal roundedCurrentScaling = NORMAL_KEY_WIDTH_SCALING; diff --git a/src/notation/view/pianokeyboard/pianokeyboardpanelcontextmenumodel.h b/src/notation/view/pianokeyboard/pianokeyboardpanelcontextmenumodel.h index a2fbb28537703..3ef6838fc37f9 100644 --- a/src/notation/view/pianokeyboard/pianokeyboardpanelcontextmenumodel.h +++ b/src/notation/view/pianokeyboard/pianokeyboardpanelcontextmenumodel.h @@ -58,13 +58,17 @@ class PianoKeyboardPanelContextMenuModel : public muse::uicomponents::AbstractMe void keyWidthScalingChanged(); void setKeyWidthScalingRequested(qreal scaling); void numberOfKeysChanged(); + void pianoKeyboardUseNotatedPitchChanged(); private: muse::uicomponents::MenuItem* makeViewMenu(); + muse::uicomponents::MenuItem* makePitchMenu(); muse::uicomponents::MenuItem* makeKeyWidthScalingItem(const muse::TranslatableString& title, qreal scaling); muse::uicomponents::MenuItem* makeNumberOfKeysItem(const muse::TranslatableString& title, int numberOfKeys); + muse::uicomponents::MenuItem* makeToggleNotatedPitchItem(const muse::TranslatableString& title, bool isNotatedPitch); + void updateKeyWidthScalingItems(); muse::uicomponents::MenuItemList m_keyWidthScalingItems; diff --git a/src/stubs/notation/notationconfigurationstub.cpp b/src/stubs/notation/notationconfigurationstub.cpp index 1327ddb1b579a..66d6a51c71053 100644 --- a/src/stubs/notation/notationconfigurationstub.cpp +++ b/src/stubs/notation/notationconfigurationstub.cpp @@ -465,6 +465,16 @@ void NotationConfigurationStub::setPianoKeyboardNumberOfKeys(int) { } +ValCh NotationConfigurationStub::pianoKeyboardUseNotatedPitch() const +{ + static ValCh vch; + return vch; +} + +void NotationConfigurationStub::setPianoKeyboardUseNotatedPitch(bool) +{ +} + bool NotationConfigurationStub::useNewPercussionPanel() const { return false diff --git a/src/stubs/notation/notationconfigurationstub.h b/src/stubs/notation/notationconfigurationstub.h index 6b1b8e811d2c5..c368d74a489a1 100644 --- a/src/stubs/notation/notationconfigurationstub.h +++ b/src/stubs/notation/notationconfigurationstub.h @@ -171,6 +171,9 @@ class NotationConfigurationStub : public INotationConfiguration ValCh pianoKeyboardNumberOfKeys() const override; void setPianoKeyboardNumberOfKeys(int number) override; + ValCh pianoKeyboardUseNotatedPitch() const override; + void setPianoKeyboardUseNotatedPitch(bool value) override; + bool useNewPercussionPanel() const override; void setUseNewPercussionPanel(bool use) override;