From e7b40eb125bf4b9062564a9ae012103b6a38988e Mon Sep 17 00:00:00 2001 From: pyonpyoco <60975353+pyonpyoco@users.noreply.github.com> Date: Thu, 11 Dec 2025 22:30:14 +0900 Subject: [PATCH 1/3] Add T/t and P/p fingerings for fretboard diagrams --- src/engraving/dom/fret.cpp | 36 +++++++++++++++++++ src/engraving/dom/fret.h | 14 ++++++++ src/engraving/rendering/score/tlayout.cpp | 2 +- .../fretdiagrams/FretDiagramSettings.qml | 26 +++++++++----- .../fretdiagrams/fretdiagramsettingsmodel.cpp | 31 ++++++++++++++-- .../fretdiagrams/fretdiagramsettingsmodel.h | 4 ++- .../fretdiagrams/internal/fretcanvas.cpp | 3 +- 7 files changed, 102 insertions(+), 14 deletions(-) diff --git a/src/engraving/dom/fret.cpp b/src/engraving/dom/fret.cpp index c92a881acddca..cecf39dd476a1 100644 --- a/src/engraving/dom/fret.cpp +++ b/src/engraving/dom/fret.cpp @@ -1320,6 +1320,42 @@ String FretDiagram::screenReaderInfo() const return res; } +int FretDiagram::fingeringFromChar(Char c) +{ + switch(c.unicode()){ + case '1': return int(FretDiagram::FingeringValue::ONE); + case '2': return int(FretDiagram::FingeringValue::TWO); + case '3': return int(FretDiagram::FingeringValue::THREE); + case '4': return int(FretDiagram::FingeringValue::FOUR); + case '5': return int(FretDiagram::FingeringValue::FIVE); + + case 'T': + case 't': + return int(FretDiagram::FingeringValue::THUMB); + + case 'P': + case 'p': + return int(FretDiagram::FingeringValue::PULGAR); + + default: + return int(FretDiagram::FingeringValue::NONE); + } +} + +String FretDiagram::fingeringToString(int v) +{ + if(v >= 1 && v <= 5) + return String::number(v); + + if(v == int(FretDiagram::FingeringValue::THUMB)) + return String("T"); + + if(v == int(FretDiagram::FingeringValue::PULGAR)) + return String("P"); + + return String(); +} + void FretDiagram::setFingering(std::vector v) { m_fingering = std::move(v); diff --git a/src/engraving/dom/fret.h b/src/engraving/dom/fret.h index d8a12b6674f90..f637be11a73bb 100644 --- a/src/engraving/dom/fret.h +++ b/src/engraving/dom/fret.h @@ -221,6 +221,20 @@ class FretDiagram final : public EngravingItem String accessibleInfo() const override; String screenReaderInfo() const override; + enum class FingeringValue : int { + NONE = 0, + ONE, + TWO, + THREE, + FOUR, + FIVE, + THUMB = 6, //T + PULGAR = 7 //P + }; + + static int fingeringFromChar(Char c); + static String fingeringToString(int v); + bool showFingering() const { return m_showFingering; } void setShowFingering(bool v) { m_showFingering = v; } const std::vector& fingering() const { return m_fingering; } diff --git a/src/engraving/rendering/score/tlayout.cpp b/src/engraving/rendering/score/tlayout.cpp index 6caf269145303..3c51b10b02682 100644 --- a/src/engraving/rendering/score/tlayout.cpp +++ b/src/engraving/rendering/score/tlayout.cpp @@ -2478,7 +2478,7 @@ void TLayout::layoutFretDiagram(const FretDiagram* item, FretDiagram::LayoutData if (finger == 0) { continue; } - String fingerS = String::number(finger); + String fingerS = FretDiagram::fingeringToString(finger); double width = fontMetrics.width(fingerS); double digitHeight = fontMetrics.tightBoundingRect(fingerS).height(); double xOff = -0.5 * width; diff --git a/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/FretDiagramSettings.qml b/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/FretDiagramSettings.qml index 7af3085369820..2a576f588a74d 100644 --- a/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/FretDiagramSettings.qml +++ b/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/FretDiagramSettings.qml @@ -123,7 +123,7 @@ Item { required property int index property int string: repeater.count - index - 1 - property string finger: root.model ? root.model.fingerings[string] : 0 + property string finger: root.model ? root.model.displayFingerings[string] : 0 Layout.preferredWidth: 40 spacing: 8 @@ -150,16 +150,27 @@ Item { textHorizontalAlignment: Qt.AlignHCenter indeterminateText: '-' + isIndeterminate: { - const fingerInt = parseInt(repeaterItem.finger) - return isNaN(fingerInt) || fingerInt < 1 || fingerInt > 5 + const f = repeaterItem.finger + + if(!f || f.length === 0) + return true + + if(f === "T" || f === "P") + return false + + const v = parseInt(f) + return isNaN(v) || v < 1 || v > 5 + } currentText: isIndeterminate ? '' : repeaterItem.finger - validator: IntInputValidator { - top: 5 - bottom: 0 + validator: RegularExpressionValidator { regularExpression: /^[1-5TtPp]?$/ } + + onTextEdited: { + text = text.toUpperCase() } navigation.name: `Finger ${repeaterItem.string + 1} text input` @@ -167,8 +178,7 @@ Item { navigation.row: repeater.navigationRowStart + repeaterItem.index navigation.accessible.name: qsTrc("inspector", "Finger for string %1").arg(repeaterItem.string + 1) - onTextEditingFinished: function (newTextValue) { - var newFinger = parseInt(newTextValue) + onTextEditingFinished: function (newFinger) { if (root.model) { root.model.setFingering(repeaterItem.string, newFinger) } diff --git a/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/fretdiagramsettingsmodel.cpp b/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/fretdiagramsettingsmodel.cpp index 803298555de9a..a7bde117d3d30 100644 --- a/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/fretdiagramsettingsmodel.cpp +++ b/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/fretdiagramsettingsmodel.cpp @@ -190,14 +190,39 @@ QStringList FretDiagramSettingsModel::fingerings() const return fingerings.split(','); } -void FretDiagramSettingsModel::setFingering(int string, int finger) +QStringList FretDiagramSettingsModel::displayFingerings() const { - finger = std::clamp(finger, 0, 5); + QStringList domList = fingerings(); + QStringList result; + + for (const QString& t : domList) { + bool ok = false; + int v = t.toInt(&ok); + if (!ok) { + v = int(mu::engraving::FretDiagram::FingeringValue::NONE); + } + + mu::engraving::String s = mu::engraving::FretDiagram::fingeringToString(v); + result << s.toQString(); + } + + return result; +} + +void FretDiagramSettingsModel::setFingering(int string, const QString& fingerText) +{ + + int fingerValue = int(mu::engraving::FretDiagram::FingeringValue::NONE); + + if(!fingerText.isEmpty()){ + mu::engraving::Char ch(fingerText[0].unicode()); + fingerValue = mu::engraving::FretDiagram::fingeringFromChar(ch); + } QStringList curFingerings = fingerings(); assert(string < curFingerings.size()); - QString newFinger = QString::number(finger); + QString newFinger = QString::number(fingerValue); curFingerings[string] = newFinger; QString newFingerings = curFingerings.join(","); diff --git a/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/fretdiagramsettingsmodel.h b/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/fretdiagramsettingsmodel.h index ab49c40e62bc9..a6369805bbcbd 100644 --- a/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/fretdiagramsettingsmodel.h +++ b/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/fretdiagramsettingsmodel.h @@ -57,6 +57,7 @@ class FretDiagramSettingsModel : public AbstractInspectorModel Q_PROPERTY(QVariant fretDiagram READ fretDiagram NOTIFY fretDiagramChanged) Q_PROPERTY(mu::inspector::PropertyItem * showFingerings READ showFingerings CONSTANT) Q_PROPERTY(QStringList fingerings READ fingerings NOTIFY fingeringsChanged) + Q_PROPERTY(QStringList displayFingerings READ displayFingerings NOTIFY fretDiagramChanged) public: explicit FretDiagramSettingsModel(QObject* parent, IElementRepositoryService* repository); @@ -76,8 +77,9 @@ class FretDiagramSettingsModel : public AbstractInspectorModel PropertyItem* verticalAlign() const; PropertyItem* showFingerings() const; QStringList fingerings() const; + QStringList displayFingerings() const; - Q_INVOKABLE void setFingering(int string, int finger); + Q_INVOKABLE void setFingering(int string, const QString& fingerText); Q_INVOKABLE void resetFingerings(); QVariant fretDiagram() const; diff --git a/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/internal/fretcanvas.cpp b/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/internal/fretcanvas.cpp index ce0953953b0c3..2a5ebc91c7a07 100644 --- a/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/internal/fretcanvas.cpp +++ b/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/internal/fretcanvas.cpp @@ -204,7 +204,8 @@ void FretCanvas::draw(QPainter* painter) if (finger == 0) { continue; } - QString fingerS = QString::number(finger); + String fs = mu::engraving::FretDiagram::fingeringToString(finger); + QString fingerS = fs.toQString(); double width = fontMetrics.width(fingerS); double xOff = -0.5 * width; double fingerX = (m_diagram->strings() - i - 1) * stringDist + xOff; From e7ab25f33ec4ce6c2aea755565f6558521221053 Mon Sep 17 00:00:00 2001 From: pyonpyoco <60975353+pyonpyoco@users.noreply.github.com> Date: Fri, 12 Dec 2025 22:10:43 +0900 Subject: [PATCH 2/3] Apply Uncrustify formatting --- src/engraving/dom/fret.cpp | 41 ++++++++++--------- src/engraving/dom/fret.h | 2 +- .../fretdiagrams/fretdiagramsettingsmodel.cpp | 3 +- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/engraving/dom/fret.cpp b/src/engraving/dom/fret.cpp index cecf39dd476a1..0b267a69decf6 100644 --- a/src/engraving/dom/fret.cpp +++ b/src/engraving/dom/fret.cpp @@ -1322,37 +1322,40 @@ String FretDiagram::screenReaderInfo() const int FretDiagram::fingeringFromChar(Char c) { - switch(c.unicode()){ - case '1': return int(FretDiagram::FingeringValue::ONE); - case '2': return int(FretDiagram::FingeringValue::TWO); - case '3': return int(FretDiagram::FingeringValue::THREE); - case '4': return int(FretDiagram::FingeringValue::FOUR); - case '5': return int(FretDiagram::FingeringValue::FIVE); + switch (c.unicode()) { + case '1': return int(FretDiagram::FingeringValue::ONE); + case '2': return int(FretDiagram::FingeringValue::TWO); + case '3': return int(FretDiagram::FingeringValue::THREE); + case '4': return int(FretDiagram::FingeringValue::FOUR); + case '5': return int(FretDiagram::FingeringValue::FIVE); - case 'T': - case 't': - return int(FretDiagram::FingeringValue::THUMB); + case 'T': + case 't': + return int(FretDiagram::FingeringValue::THUMB); - case 'P': - case 'p': - return int(FretDiagram::FingeringValue::PULGAR); + case 'P': + case 'p': + return int(FretDiagram::FingeringValue::PULGAR); - default: - return int(FretDiagram::FingeringValue::NONE); + default: + return int(FretDiagram::FingeringValue::NONE); } } String FretDiagram::fingeringToString(int v) { - if(v >= 1 && v <= 5) + if (v >= 1 && v <= 5) { return String::number(v); - - if(v == int(FretDiagram::FingeringValue::THUMB)) + } + + if (v == int(FretDiagram::FingeringValue::THUMB)) { return String("T"); + } - if(v == int(FretDiagram::FingeringValue::PULGAR)) + if (v == int(FretDiagram::FingeringValue::PULGAR)) { return String("P"); - + } + return String(); } diff --git a/src/engraving/dom/fret.h b/src/engraving/dom/fret.h index f637be11a73bb..14ee0163515db 100644 --- a/src/engraving/dom/fret.h +++ b/src/engraving/dom/fret.h @@ -234,7 +234,7 @@ class FretDiagram final : public EngravingItem static int fingeringFromChar(Char c); static String fingeringToString(int v); - + bool showFingering() const { return m_showFingering; } void setShowFingering(bool v) { m_showFingering = v; } const std::vector& fingering() const { return m_fingering; } diff --git a/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/fretdiagramsettingsmodel.cpp b/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/fretdiagramsettingsmodel.cpp index a7bde117d3d30..9a031079a86d2 100644 --- a/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/fretdiagramsettingsmodel.cpp +++ b/src/inspector/qml/MuseScore/Inspector/notation/fretdiagrams/fretdiagramsettingsmodel.cpp @@ -211,10 +211,9 @@ QStringList FretDiagramSettingsModel::displayFingerings() const void FretDiagramSettingsModel::setFingering(int string, const QString& fingerText) { - int fingerValue = int(mu::engraving::FretDiagram::FingeringValue::NONE); - if(!fingerText.isEmpty()){ + if (!fingerText.isEmpty()) { mu::engraving::Char ch(fingerText[0].unicode()); fingerValue = mu::engraving::FretDiagram::fingeringFromChar(ch); } From 025ee513615f1e948b97a16a80947533caf476c3 Mon Sep 17 00:00:00 2001 From: pyonpyoco <60975353+pyonpyoco@users.noreply.github.com> Date: Fri, 12 Dec 2025 22:13:40 +0900 Subject: [PATCH 3/3] Use UTF-16 string literals for thumb/pulgar fingering --- src/engraving/dom/fret.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engraving/dom/fret.cpp b/src/engraving/dom/fret.cpp index 0b267a69decf6..f6a5626fb3866 100644 --- a/src/engraving/dom/fret.cpp +++ b/src/engraving/dom/fret.cpp @@ -1349,11 +1349,11 @@ String FretDiagram::fingeringToString(int v) } if (v == int(FretDiagram::FingeringValue::THUMB)) { - return String("T"); + return String(u"T"); } if (v == int(FretDiagram::FingeringValue::PULGAR)) { - return String("P"); + return String(u"P"); } return String();