diff --git a/README.md b/README.md index 5a9f7ad..3ef75b4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -This is a plugin for MuseScore 3 to add harmonica tablature notation below the notes. It currently supports +This is a plugin for MuseScore 4.6 to add harmonica tablature notation with options for color of tabs, tab font size, and placement of tabs above or below the notes. It currently supports * the Hohner Highlander only, for both side, A highlander and D - [Reference](http://musescore.org/sites/musescore.org/files/Hohner%20Highlander%20scale.jpg) * Diatonic A - [Reference](http://harmopoint.com/harmonica-virtuel/) [and for overblows and overdraws](http://www.overblow.com/?menuid=26) @@ -7,8 +7,10 @@ This is a plugin for MuseScore 3 to add harmonica tablature notation below the n * Diatonic D - [Reference](http://musescore.org/sites/musescore.org/files/Lee%20Oskar%20Diatonic%20D.jpg) [and for overblows and overdraws](http://www.overblow.com/?menuid=26) * Diatonic F - [Reference](http://harmopoint.com/harmonica-virtuel/) [and for overblows and overdraws](http://www.overblow.com/?menuid=26) * Diatonic G - [Reference](http://musescore.org/sites/musescore.org/files/Lee%20Oskar%20%20Diatonic%20G.jpg) [and for overblows and overdraws](http://www.overblow.com/?menuid=26) + * Chromatic C, 10 holes - * Chromatic C, 12 holes - [Reference](http://musescore.org/sites/musescore.org/files/12%20Hole%20Chromatic%20slide%20Harmonica.txt) * Chromatic C, 16 holes - [Reference](https://coast2coastmusic.com/chromatic/tuning_charts.shtml) + * Tremolo C, 24 holes - If you want to have your harmonica added to the it, please contact me, or better, do a pull request. @@ -22,10 +24,11 @@ If you want to have your harmonica added to the it, please contact me, or better * "' = 3 halfsteps bend * +X? = overblow * -X? = overdraw -* "<" = slide +* "s" = slide Bends, over blow, over draw may be supported if it's the only way to play the note. If there are two holes for one note, a choice has been made (draw) ##More info See the official [project page](http://musescore.org/en/project/harmonicatablature) + diff --git a/harmonica_tablature.qml b/harmonica_tablature.qml index a35d294..c4a3c43 100644 --- a/harmonica_tablature.qml +++ b/harmonica_tablature.qml @@ -11,16 +11,18 @@ // the file LICENCE.GPL //============================================================================= -import QtQuick 2.9 -import QtQuick.Controls 1.5 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts import MuseScore 3.0 MuseScore { - version: "3.0" - description: "Harmonica Tab plugin" - menuPath: "Plugins.Harmonica Tablature" + + version: "4.6" + description: "Harmonica Tab plugin, cleaned up code, stylized selection box, added text color and size options, added tremolo 24-hole harmonica, added chromatic 10-hole harmonica, updated default selections. Updated by Joshua Buys" pluginType: "dialog" + title: "Harmonica Tablature Setup" + thumbnailName: "harmonica_tabs.png" // ------ OPTIONS ------- property string sep : "\n" // change to "," if you want tabs horizontally @@ -28,118 +30,531 @@ MuseScore { // ------ OPTIONS ------- id: window - width:280 - height: 180 - ColumnLayout { - id: column - anchors.margins : 10 - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - height: 90 - - ComboBox { - currentIndex: 17 - model: ListModel { - id: keylist - property var key - ListElement { text: "Low G"; harpkey: 43 } - ListElement { text: "Low Ab"; harpkey: 44 } - ListElement { text: "Low A"; harpkey: 45 } - ListElement { text: "Low Bb"; harpkey: 46 } - ListElement { text: "Low B"; harpkey: 47 } - ListElement { text: "Low C"; harpkey: 48 } - ListElement { text: "Low C#"; harpkey: 49 } - ListElement { text: "Low D"; harpkey: 50 } - ListElement { text: "Low Eb"; harpkey: 51 } - ListElement { text: "Low E"; harpkey: 52 } - ListElement { text: "Low F"; harpkey: 53 } - ListElement { text: "Low F#"; harpkey: 52 } - ListElement { text: "G"; harpkey: 55 } - ListElement { text: "Ab"; harpkey: 56 } - ListElement { text: "A"; harpkey: 57 } - ListElement { text: "Bb"; harpkey: 58 } - ListElement { text: "B"; harpkey: 59 } - ListElement { text: "C"; harpkey: 60 } - ListElement { text: "Db"; harpkey: 61 } - ListElement { text: "D"; harpkey: 62 } - ListElement { text: "Eb"; harpkey: 63 } - ListElement { text: "E"; harpkey: 64 } - ListElement { text: "F"; harpkey: 65 } - ListElement { text: "F#"; harpkey: 66 } - ListElement { text: "High G"; harpkey: 67 } - } - width: 100 - onCurrentIndexChanged: { - console.debug(keylist.get(currentIndex).text + ", " + keylist.get(currentIndex).harpkey) - keylist.key = keylist.get(currentIndex).harpkey - } + width: 550 + height: 300 + + property var itemTextX1 : 20 + property var itemTextY1 : 20 + property var itemTextY2 : 20 + property var xPositionInit : 0.0 + property var yPositionInit : 0.0 + property color dropdownBase: "lightsteelblue" + property color dropdownText: "#001B2E" + + Rectangle { + id: mainInput + anchors.fill: parent + color: "#000A57" + + function comboStyle() { } - ComboBox { - currentIndex: 0 - model: ListModel { - id: harp - property var tuning - ListElement { text: "Blues Harp (Richter)"; tuning: 1 } - ListElement { text: "Richter valved"; tuning: 2 } - ListElement { text: "Paddy Richter (Brendan Power), valved"; tuning: 10 } - ListElement { text: "Natural Minor"; tuning: 7 } - ListElement { text: "Melody Maker"; tuning: 8 } - ListElement { text: "Country"; tuning: 3 } - ListElement { text: "Circular (Seydel), valved"; tuning: 5 } - ListElement { text: "Circular (Inversed for blow 1), valved "; tuning: 9 } - ListElement { text: "TrueChromatic Diatonic, valved"; tuning: 6 } - ListElement { text: "Power Bender (Brendan Power), valved"; tuning: 11 } - ListElement { text: "Power Draw (Brendan Power), valved"; tuning: 12 } - ListElement { text: "Standard Chromatic"; tuning: 4 } + + Column { + id: column + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.margins: 10 + spacing: 17 + //z: 5 + anchors.topMargin: 25 + height: parent.height - 70 + + Row { + id:keyRow + spacing: 20 + width: parent.width + x: 20 + + Label { + font.pointSize: 14 + font.family: "Inter" + //font.weight: Font.ExtraBold + font.bold: true + color: "#00C8D7" + anchors.verticalCenter: parent.verticalCenter + width: parent.width / 4 + horizontalAlignment: Text.AlignRight + text: "Harmonica key:" + } + + ComboBox { + id: keyBox + anchors.verticalCenter: parent.verticalCenter + textRole: "text" + implicitWidth: 50 + implicitHeight: 25 + + background: Rectangle { + color: dropdownBase + radius: 12 + clip: true + } + + contentItem: Text { + text: keyBox.displayText + color: dropdownText + font.pointSize: 12 + font.bold: true + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + leftPadding: 15 + } + + currentIndex: 17 + model: ListModel { + id: keylist + property var key: undefined // Initialize property with default value (updated F# to 54) + ListElement { text: "Low G"; harpkey: 43 } + ListElement { text: "Low Ab"; harpkey: 44 } + ListElement { text: "Low A"; harpkey: 45 } + ListElement { text: "Low Bb"; harpkey: 46 } + ListElement { text: "Low B"; harpkey: 47 } + ListElement { text: "Low C"; harpkey: 48 } + ListElement { text: "Low C#"; harpkey: 49 } + ListElement { text: "Low D"; harpkey: 50 } + ListElement { text: "Low Eb"; harpkey: 51 } + ListElement { text: "Low E"; harpkey: 52 } + ListElement { text: "Low F"; harpkey: 53 } + ListElement { text: "Low F#"; harpkey: 54 } + ListElement { text: "G"; harpkey: 55 } + ListElement { text: "Ab"; harpkey: 56 } + ListElement { text: "A"; harpkey: 57 } + ListElement { text: "Bb"; harpkey: 58 } + ListElement { text: "B"; harpkey: 59 } + ListElement { text: "C"; harpkey: 60 } + ListElement { text: "Db"; harpkey: 61 } + ListElement { text: "D"; harpkey: 62 } + ListElement { text: "Eb"; harpkey: 63 } + ListElement { text: "E"; harpkey: 64 } + ListElement { text: "F"; harpkey: 65 } + ListElement { text: "F#"; harpkey: 66 } + ListElement { text: "High G"; harpkey: 67 } + } + + onCurrentIndexChanged: { + // Validate currentIndex + if (currentIndex >= 0 && currentIndex < keylist.count) { + // Retrieve the current item + var currentItem = keylist.get(currentIndex); + // Debugging output + console.debug("Selected item:", currentItem.text, ", Harpkey:", currentItem.harpkey); + // Set the key property + keylist.key = currentItem.harpkey; + } else { + console.error("Invalid currentIndex:", currentIndex); + } + } + + Component.onCompleted: { + // Set initial harpkey value + if (currentIndex >= 0 && currentIndex < keylist.count) { + var initialItem = keylist.get(currentIndex); + keylist.key = initialItem.harpkey; + console.debug("Initial item:", initialItem.text, ", Harpkey:", initialItem.harpkey); + } else { + console.error("Invalid initial currentIndex:", currentIndex); + } + } + } } - width: 100 - onCurrentIndexChanged: { - console.debug(harp.get(currentIndex).text + ", " + harp.get(currentIndex).tuning) - harp.tuning = harp.get(currentIndex).tuning + + + Row { + id:typeRow + spacing: 20 + width: parent.width + x: 20 + + Label { + font.pointSize: 14 + font.family: "Inter" + //font.weight: Font.ExtraBold + font.bold: true + color: "#00C8D7" + anchors.verticalCenter: parent.verticalCenter + width: parent.width / 4 + horizontalAlignment: Text.AlignRight + text: "Harmonica type:" + } + + ComboBox { + id: typeBox + anchors.verticalCenter: parent.verticalCenter + textRole: "text" + implicitWidth: 300 + implicitHeight: 25 + + background: Rectangle { + color: dropdownBase + radius: 12 + clip: true + } + + contentItem: Text { + text: typeBox.displayText + color: dropdownText + font.pointSize: 12 + font.bold: true + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + leftPadding: 15 + } + + currentIndex: 0 + model: ListModel { + id: harp + property var tuning: undefined // Initialize property with default value, updated list order for consistency through code + ListElement { text: "Blues Harp (Richter)"; tuning: 1 } + ListElement { text: "Richter valved"; tuning: 2 } + ListElement { text: "Country"; tuning: 3 } + ListElement { text: "Chromatic 10 Hole"; tuning: 4 } + ListElement { text: "Chromatic 12 Hole"; tuning: 5 } + ListElement { text: "Chromatic 16 Hole"; tuning: 6 } + ListElement { text: "Circular (Seydel), valved"; tuning: 7 } + ListElement { text: "TrueChromatic Diatonic, valved"; tuning: 8 } + ListElement { text: "Natural Minor"; tuning: 9 } + ListElement { text: "Melody Maker"; tuning: 10 } + ListElement { text: "Circular (Inversed for blow 1), valved "; tuning: 11 } + ListElement { text: "Paddy Richter (Brendan Power), valved"; tuning: 12 } + ListElement { text: "Power Bender (Brendan Power), valved"; tuning: 13 } + ListElement { text: "Power Draw (Brendan Power), valved"; tuning: 14 } + ListElement { text: "Tremolo 24-hole"; tuning: 15 } // (added tremolo 24-hole option) + } + + onCurrentIndexChanged: { + // Validate currentIndex + if (currentIndex >= 0 && currentIndex < harp.count) { + // Retrieve the current item + var currentItem = harp.get(currentIndex); + // Debugging output + console.debug("Selected item:", currentItem.text, ", Tuning:", currentItem.tuning); + // Set the tuning property + harp.tuning = currentItem.tuning; + } else { + console.error("Invalid currentIndex:", currentIndex); + } + } + + Component.onCompleted: { + // Set initial tuning value + if (currentIndex >= 0 && currentIndex < harp.count) { + var initialItem = harp.get(currentIndex); + harp.tuning = initialItem.tuning; + console.debug("Initial item:", initialItem.text, ", Tuning:", initialItem.tuning); + } else { + console.error("Invalid initial currentIndex:", currentIndex); + } + } + } } - } - ComboBox { - currentIndex: 1 - model: ListModel { - id: placetext - property var position - ListElement { text: "Above staff"; position: "above" } - ListElement { text: "Below staff"; position: "below" } + + Row { + id:positionRow + spacing: 20 + width: parent.width + x: 20 + + Label { + font.pointSize: 14 + font.family: "Inter" + //font.weight: Font.ExtraBold + font.bold: true + color: "#00C8D7" + anchors.verticalCenter: parent.verticalCenter + width: parent.width / 4 + horizontalAlignment: Text.AlignRight + text: "Position:" + } + + ComboBox { + id: positionBox + anchors.verticalCenter: parent.verticalCenter + textRole: "text" + implicitWidth: 125 + implicitHeight: 25 + + background: Rectangle { + color: dropdownBase + radius: 12 + clip: true + } + + contentItem: Text { + text: positionBox.displayText + color: dropdownText + font.pointSize: 12 + font.bold: true + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + leftPadding: 15 + } + + currentIndex: 0 + model: ListModel { + id: placetext + property var position: undefined // Initialize property with default value + ListElement { text: "Above staff"; position: "above" } + ListElement { text: "Below staff"; position: "below" } + } + + onCurrentIndexChanged: { + // Validate currentIndex + if (currentIndex >= 0 && currentIndex < placetext.count) { + // Retrieve the current item + var currentItem = placetext.get(currentIndex); + // Debugging output + console.debug("Selected item:", currentItem.text, ", Position:", currentItem.position); + // Set the position property + placetext.position = currentItem.position; + } else { + console.error("Invalid currentIndex:", currentIndex); + } + } + + Component.onCompleted: { + // Set initial position value + if (currentIndex >= 0 && currentIndex < placetext.count) { + var initialItem = placetext.get(currentIndex); + placetext.position = initialItem.position; + console.debug("Initial item:", initialItem.text, ", Position:", initialItem.position); + } else { + console.error("Invalid initial currentIndex:", currentIndex); + } + } + } } - width: 100 - onCurrentIndexChanged: { - console.debug(placetext.get(currentIndex).text + ", " + placetext.get(currentIndex).position) - placetext.position = placetext.get(currentIndex).position + + Row { + id:colorRow + spacing: 20 + width: parent.width + x: 20 + + Label { + font.pointSize: 14 + font.family: "Inter" + //font.weight: Font.ExtraBold + font.bold: true + color: "#00C8D7" + anchors.verticalCenter: parent.verticalCenter + width: parent.width / 4 + horizontalAlignment: Text.AlignRight + text: "Color:" + } + + ComboBox { + id: colorBox + anchors.verticalCenter: parent.verticalCenter + textRole: "text" + implicitWidth: 100 + implicitHeight: 25 + + background: Rectangle { + color: dropdownBase + radius: 12 + clip: true + } + + contentItem: Text { + text: colorBox.displayText + color: dropdownText + font.pointSize: 12 + font.bold: true + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + leftPadding: 15 + } + + currentIndex: 2 + model: ListModel { + id: colorlist + property var textColor: undefined // Initialize property with default value (added color option) + ListElement { text: "Black"; colorkey: "black" } + ListElement { text: "Brown"; colorkey: "brown" } + ListElement { text: "Red"; colorkey: "red" } + ListElement { text: "Pink"; colorkey: "deeppink" } + ListElement { text: "Orange"; colorkey: "orange" } + ListElement { text: "Green"; colorkey: "green" } + ListElement { text: "Blue"; colorkey: "blue" } + ListElement { text: "Purple"; colorkey: "purple" } + } + + onCurrentIndexChanged: { + // Validate currentIndex + if (currentIndex >= 0 && currentIndex < colorlist.count) { + // Retrieve the current item + var currentItem = colorlist.get(currentIndex); + // Debugging output + console.debug("Selected item:", currentItem.text, ", Color:", currentItem.colorkey); + // Set the color property + colorlist.textColor = currentItem.colorkey; + } else { + console.error("Invalid currentIndex:", currentIndex); + } + } + + Component.onCompleted: { + // Set initial color value + if (currentIndex >= 0 && currentIndex < colorlist.count) { + var initialItem = colorlist.get(currentIndex); + colorlist.textColor = initialItem.colorkey; + console.debug("Initial item:", initialItem.text, ", Color:", initialItem.colorkey); + } else { + console.error("Invalid initial currentIndex:", currentIndex); + } + } + } + } + + Row { + id: sizeRow + spacing: 20 + width: parent.width + x: 20 + + Label { + font.pointSize: 14 + font.family: "Inter" + //font.weight: Font.ExtraBold + font.bold: true + color: "#00C8D7" + anchors.verticalCenter: parent.verticalCenter + width: parent.width / 4 + horizontalAlignment: Text.AlignRight + text: "Font Size:" + } + + ComboBox { + id: sizeBox + anchors.verticalCenter: parent.verticalCenter + textRole: "text" + implicitWidth: 50 + implicitHeight: 25 + + background: Rectangle { + color: dropdownBase + radius: 12 + clip: true + } + + contentItem: Text { + text: sizeBox.displayText + color: dropdownText + font.pointSize: 12 + font.bold: true + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + leftPadding: 15 + } + + currentIndex: 1 + model: ListModel { + id: sizelist + property var textSize: undefined // Initialize property with default value (added font size option) + ListElement { text: "10"; sizekey: 10 } + ListElement { text: "12"; sizekey: 12 } + ListElement { text: "14"; sizekey: 14 } + ListElement { text: "16"; sizekey: 16 } + ListElement { text: "18"; sizekey: 18 } + } + + onCurrentIndexChanged: { + // Validate currentIndex + if (currentIndex >= 0 && currentIndex < sizelist.count) { + // Retrieve the current item + var currentItem = sizelist.get(currentIndex); + // Debugging output + console.debug("Selected item:", currentItem.text, ", Color:", currentItem.sizekey); + // Set the color property + sizelist.textSize = currentItem.sizekey; + } else { + console.error("Invalid currentIndex:", currentIndex); + } + } + + Component.onCompleted: { + // Set initial font size value + if (currentIndex >= 0 && currentIndex < sizelist.count) { + var initialItem = sizelist.get(currentIndex); + sizelist.textSize = initialItem.sizekey; + console.debug("Initial item:", initialItem.text, ", Color:", initialItem.sizekey); + } else { + console.error("Invalid initial currentIndex:", currentIndex); + } + } + } } } } - RowLayout { + + Row { + id: buttonRow + height: 40 + anchors.bottomMargin: 20 + anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter - anchors.top: column.bottom - height: 70 + spacing: 20 + Button { - id: okButton - text: "Ok" + id: applyButton + width: 110 + height: 40 + text: "Apply" + background: Rectangle { + color: "#49A26E" + anchors.fill: parent + radius: 18 + } + + contentItem: Text { + text: applyButton.text + color: "#003D12" + font.pointSize: 18 + font.bold: true + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + onClicked: { apply() - Qt.quit() + quit() } } + Button { - id: closeButton - text: "Close" - onClicked: { Qt.quit() } - } + id: cancelButton + width: 110 + height: 40 + text: "Cancel" + background: Rectangle { + color: "#E56579" + anchors.fill: parent + radius: 18 + } + + contentItem: Text { + text: cancelButton.text + color: "#680000" + //color: "#315611" + font.pointSize: 18 + font.bold: true + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + onClicked: { + quit() + } + } } - function tabNotes(notes, text) { + function tabNotes(notes, text) { // updated order for consistency throughout code - var richter = ["+1", "-1b", "-1", "+1o", "+2", "-2bb", "-2b", "-2", "-3bbb", "-3bb", "-3b", "-3", + var richter = ["+1", "-1b", "-1", "+1o", "+2", "-2bb", "-2b", "+3", "-3bbb", "-3bb", "-3b", "-3", "+4", "-4b", "-4", "+4o", "+5", "-5", "+5o", "+6", "-6b", "-6", "+6o", "-7", "+7", "-7o", "-8", "+8b", "+8", "-9", "+9b", "+9", "-9o", "-10", "+10bb", "+10b", - "+10", "-10o" ]; //Standard Richter tuning with overbends + "+10", "-10o" ]; //Standard Richter tuning with overbends (updated -2 to +3 (same note) as it's used more often) var richterValved = ["+1", "-1b", "-1", "+2b", "+2", "-2bb", "-2b", "-2", "-3bbb", "-3bb", "-3b", "-3", "+4", "-4b", "-4", "+5b", "+5", "-5", "+6b", "+6", "-6b", "-6", "-7b", "-7", @@ -147,20 +562,23 @@ MuseScore { "+10" ]; richterValved[-2] = "+1bb"; richterValved[-1] = "+1b"; //Two notes below the key at blow 1 - var paddyRichter = ["+1", "-1b", "-1", "+2b", "+2", "-2bb", "-2b", "-2", "+3b", "+3", "-3b", "-3", - "+4", "-4b", "-4", "+5b", "+5", "-5", "+6b", "+6", "-6b", "-6", "-7b", "-7", - "+7", "-8b", "-8", "+8b", "+8", "-9", "+9b", "+9", "-10b", "-10", "+10bb", "+10b", - "+10" ]; - paddyRichter[-2] = "+1bb"; paddyRichter[-1] = "+1b"; //Two notes below the key at blow 1 - // Brendan Power's tuning, half valved - var country = ["+1", "-1b", "-1", "+1o", "+2", "-2bb", "-2b", "-2", "-3bbb", "-3bb", "-3b", "-3", "+4", "-4b", "-4", "+4o", "+5", "-5b", "-5", "+6", "-6b", "-6", "+6o", "-7", "+7", "-7o", "-8", "+8b", "+8", "-9", "+9b", "+9", "-9o", "-10", "+10bb", "+10b", "+10", "-10o" ]; + var chromatic10hole = ["+1", '+1s', "-1", "-1s", "+2", "-2", "-2s", "+3", "+3s", "-3", "-3s","-4", + "+5", "+5s", "-5", "-5s", "+6", "-6", "-6s", "+7", "+7s", "-7", "-7s", "-8", + "+8", "+8s", "-9", "-9s", "+9", "-10", "-10s", "+10", "+10s" ]; + var standardChromatic = ["+1", '+1s', "-1", "-1s", "+2", "-2", "-2s", "+3", "+3s", "-3", "-3s","-4", - "+4", "+4s", "-5", "-5s", "+6", "-6", "-6s", "+7", "+7s", "-7", "-7s", "-8", + "+5", "+5s", "-5", "-5s", "+6", "-6", "-6s", "+7", "+7s", "-7", "-7s", "-8", + "+8", "+8s", "-9", "-9s", "+10", "-10", "-10s", "+11", "+11s", "-11", "-11s", "-12", + "+12", "+12s", "-12", "-12s" ]; // updated +4 to +5 (same note) as it's used more often + + var chromatic16H = ["+1.", "+1.s", "-1.", "-1.s", "+2.", "-2.", "-2.s", "+3.", "+3.s", "-3.", "-3.s","-4.", + "+1", "+1<", "-1", "-1s", "+2", "-2", "-2s", "+3", "+3s", "-3", "-3s","-4", + "+4", "+5s", "-5", "-5s", "+6", "-6", "-6s", "+7", "+7s", "-7", "-7s", "-8", "+8", "+8s", "-9", "-9s", "+10", "-10", "-10s", "+11", "+11s", "-11", "-11s", "-12", "+12", "+12s", "-12", "-12s" ]; @@ -192,6 +610,13 @@ MuseScore { "+8", "-8b", "-8", "+9b", "+9", "-9", "+10b", "+10", "-10b", "-10" ]; // Circular/Spiral tuned diatonic // Inversed for Blow 1. Key of C major scale starts at blow 1 + var paddyRichter = ["+1", "-1b", "-1", "+2b", "+2", "-2bb", "-2b", "-2", "+3b", "+3", "-3b", "-3", + "+4", "-4b", "-4", "+5b", "+5", "-5", "+6b", "+6", "-6b", "-6", "-7b", "-7", + "+7", "-8b", "-8", "+8b", "+8", "-9", "+9b", "+9", "-10b", "-10", "+10bb", "+10b", + "+10" ]; + paddyRichter[-2] = "+1bb"; paddyRichter[-1] = "+1b"; //Two notes below the key at blow 1 + // Brendan Power's tuning, half valved + var powerBender = ["+1", "-1b", "-1", "+2b", "+2", "-2bb", "-2b", "-2", "-3bbb", "-3bb", "-3b", "-3", "+4", "-4b", "-4", "-5b", "-5", "+6", "-6b", "-6", "+7b", "+7", "-7b", "-7", "+8", "-8b", "-8", "+9b", "+9", "-9bb", "-9b", "-9", "+10b", "+10", "-10bb", "-10b", @@ -205,21 +630,29 @@ MuseScore { "-10" ]; powerDraw[-2] = "+1bb"; powerDraw[-1] = "+1b"; //Two notes below the key at blow 1 // Brendan Power's tuning, half valved + + var tremolo24 = ["+3", "-2b", "-2", "+3o", "+5", "-4", "+7o", "+7", "-6b", "-6", "-8b", "-8", + "+9", "-10b", "-10", "+11o", "+11", "-12", "+13o", "+13", "-14b", "-14", "-16b", "-16", + "+15", "-16o", "-18", "+17b", "+17", "-20", "+19b", "+19", "-20o", "-22", "+24b", "+24", + "+21", "-22o" ]; //Standard Richter tuning with overbends (added tremolo24 notes) var tuning = richter - switch (harp.tuning) { + switch (harp.tuning) { // updated order for consistency throughout code case 1: tuning = richter; break; case 2: tuning = richterValved; break; case 3: tuning = country; break; - case 4: tuning = standardChromatic; break; - case 5: tuning = zirkValved; break; - case 6: tuning = trueChrom; break; - case 7: tuning = naturalMinor; break; - case 8: tuning = melodyMaker; break; - case 9: tuning = spiral_b1; break; - case 10: tuning = paddyRichter; break; - case 11: tuning = powerBender; break; - case 12: tuning = powerDraw; break; + case 4: tuning = chromatic10hole; break; + case 5: tuning = standardChromatic; break; + case 6: tuning = chromatic16H; break; + case 7: tuning = zirkValved; break; + case 8: tuning = trueChrom; break; + case 9: tuning = naturalMinor; break; + case 10: tuning = melodyMaker; break; + case 11: tuning = spiral_b1; break; + case 12: tuning = paddyRichter; break; + case 13: tuning = powerBender; break; + case 14: tuning = powerDraw; break; + case 15: tuning = tremolo24; break; // (added tremolo24 option) default: tuning = richter; break; } @@ -240,21 +673,22 @@ MuseScore { if (bendChar !== "b") tab = tab.replace(/b/g, bendChar); text.text = tab + text.text; - } + } } } function applyToSelection(func) { if (typeof curScore === 'undefined') - Qt.quit(); + quit(); var cursor = curScore.newCursor(); var startStaff; var endStaff; var endTick; var fullScore = false; - var textposition = (placetext.position === "above" ? Placement.ABOVE : Placement.BELOW); - + var textcolor = colorlist.textColor // added color option + var textsize = sizelist.textSize // added font size option + cursor.rewind(1); if (!cursor.segment) { // no selection fullScore = true; @@ -287,7 +721,7 @@ MuseScore { while (cursor.segment && (fullScore || cursor.tick < endTick)) { if (cursor.element && cursor.element.type == Element.CHORD) { - var text = newElement(Element.STAFF_TEXT); + var text = newElement(Element.LYRICS); var graceChords = cursor.element.graceNotes; for (var i = 0; i < graceChords.length; i++) { @@ -296,15 +730,19 @@ MuseScore { tabNotes(notes, text); // TODO: deal with placement of grace note on the x axis text.placement = textposition - text.offset = Qt.point(-40 * (graceChords.length - i), 0) + text.color = textcolor // added color option + text.offset = Qt.point(-2 * (graceChords.length - i), 0) + text.fontSize = textsize // added font size option cursor.add(text); // new text for next element - text = newElement(Element.STAFF_TEXT); + text = newElement(Element.LYRICS); } var notes = cursor.element.notes; tabNotes(notes, text); text.placement = textposition + text.fontSize = textsize // added font size option + text.color = textcolor // added color option cursor.add(text); } // end if CHORD @@ -312,7 +750,7 @@ MuseScore { } // end while segment } // end for voice } // end for staff - Qt.quit(); + quit(); } // end applyToSelection() function apply() { @@ -323,6 +761,6 @@ MuseScore { onRun: { if (typeof curScore === 'undefined') - Qt.quit(); + quit(); } } diff --git a/harmonica_tabs.png b/harmonica_tabs.png new file mode 100644 index 0000000..efb91df Binary files /dev/null and b/harmonica_tabs.png differ