//============================================================================= // MuseScore // Music Composition & Notation // // Khromka Fingering PluginD (derived from the Note Names Plugin) // // Copyright (C) 2020 Joachim Schmitz // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 // as published by the Free Software Foundation and appearing in // the file LICENCE.GPL //============================================================================= import QtQuick 2.2 import MuseScore 3.0 MuseScore { version: "3.4" description: qsTr("This plugin adds fingreing for Khromka") menuPath: "Plugins." + qsTr("Khromka Fingering") // Small note name size is fraction of the full font size. property var fontSizeMini: 0.7; function nameChord (notes, text, fontSize, endStaff) { text.fontSize = fontSize if (endStaff) { switch (notes[notes.length-1].pitch) { case 36: text.text = "6" + text.text; break; // C2 case 38: text.text = "16" + text.text; break; // D2 case 40: text.text = "12" + text.text; break; // E2 case 41: text.text = "8" + text.text; break; // F2 case 42: text.text = "17" + text.text; break; // F♯2/G♭2 case 43: text.text = "4" + text.text; break; // G2 //case 43: text.text = "24" + text.text; break; // G2 case 45: text.text = "14" + text.text; break; // A2 //case 45: text.text = "18" + text.text; break; // A2 //case 45: text.text = "25" + text.text; break; // A2 case 47: text.text = "10" + text.text; break; // B2 //case 47: text.text = "19" + text.text; break; // B2 case 48: text.text = "6" + text.text; break; // C3 //case 48: text.text = "29" + text.text; break; // C3 //case 50: text.text = "2" + text.text; break; // D3 case 50: text.text = "16" + text.text; break; // D3 case 50: text.text = "21" + text.text; break; // D3 case 52: text.text = "12" + text.text; break; // E3 //case 52: text.text = "22" + text.text; break; // E3 case 53: text.text = "8" + text.text; break; // F3 case 55: text.text = "4" + text.text; break; // G3 case 57: if (notes.length === 1) text.text = "14" + text.text; // A3 else if (notes.length === 3 && notes[0].pitch === 50 && notes[1].pitch === 54) text.text = "1" + text.text; // D3, F♯3, A4 else text.text = qsTr("?") + text.text; break; case 59: text.text = "10" + text.text; break; // B3 case 60: text.text = "6" + text.text; break; // C3 case 62: if (notes.length === 3) { if (notes[0].pitch === 55 && notes[1].pitch === 59) text.text = "3" + text.text; // G3, B3, D4 else if (notes[0].pitch === 53 && notes[1].pitch === 57) text.text = "15" + text.text; // F3, A3, D4 else if (notes[0].pitch === 54 && notes[1].pitch === 57) text.text = "1" + text.text; // F♯3, A3, D4 else text.text = qsTr("?") + text.text; } else if (notes.length === 4) { if (notes[0].pitch === 54 && notes[1].pitch === 57 && notes[2].pitch === 60) text.text = "1" + text.text; // F♯3, A3, C4, D4 else text.text = qsTr("?") + text.text; } else text.text = qsTr("?") + text.text; break; case 63: text.text = "9" + text.text; break; // F♯3, A3, B3, D♯4 case 64: if (notes.length === 3) { if (notes[0].pitch === 55 && notes[1].pitch === 60) text.text = "5" + text.text; // G3, C4, E4 else if (notes[0].pitch === 57 && notes[1].pitch === 60) text.text = "13" + text.text; // A3, C4, E4 else text.text = qsTr("?") + text.text; } else if (notes.length === 4) { if (notes[0].pitch === 56 && notes[1].pitch === 59 && notes[2].pitch === 62) text.text = "11" + text.text; // G♯3, B3, D4, E4 else text.text = qsTr("?") + text.text; } else text.text = qsTr("?") + text.text; break; case 65: text.text = "7" + text.text; break; // Chord default: text.text = qsTr("?") + text.text; break; } // end switch pitch } else { switch (notes[notes.length-1].pitch) { case 60: text.text = "3" + text.text; break; // C3 case 62: text.text = "15" + text.text; break; // D4 case 63: text.text = "1" + text.text; break; // D♯4/E♭4 case 64: text.text = "4" + text.text; break; // E4 case 65: text.text = "16" + text.text; break; // F4 case 66: text.text = "14" + text.text; break; // F♯4/G♭4 case 67: text.text = "5" + text.text; break; // G4 case 68: text.text = "2" + text.text; break; // G♯4/A♭4 case 69: text.text = "17" + text.text; break; // A4 case 71: text.text = "6" + text.text; break; // B4 case 72: text.text = "18" + text.text; break; // C5 case 74: text.text = "7" + text.text; break; // D5 case 75: text.text = "1" + text.text; break; // D♯5/E♭5 case 76: text.text = "19" + text.text; break; // E5 case 77: text.text = "8" + text.text; break; // F5 case 78: text.text = "14" + text.text; break; // F♯5/G♭5 case 79: text.text = "20" + text.text; break; // G5 case 80: text.text = "2" + text.text; break; // G♯5/A♭5 case 81: text.text = "9" + text.text; break; // A5 case 83: text.text = "21" + text.text; break; // B5 case 84: text.text = "10" + text.text; break; // C6 case 86: text.text = "22" + text.text; break; // D6 case 87: text.text = "1" + text.text; break; // D♯6/E♭6 case 88: text.text = "11" + text.text; break; // E6 case 89: text.text = "23" + text.text; break; // F6 case 90: text.text = "14" + text.text; break; // F♯6/G♭5 case 91: text.text = "12" + text.text; break; // G6 case 92: text.text = "2" + text.text; break; // G♯6/A♭6 case 93: text.text = "24" + text.text; break; // A6 case 95: text.text = "13" + text.text; break; // B6 case 96: text.text = "25" + text.text; break; // C7 default: text.text = qsTr("?") + text.text; break; } // end switch pitch } // end else } function renderGraceNoteNames (cursor, list, text, fontSize) { if (list.length > 0) { // Check for existence. // Now render grace note's names... for (var chordNum = 0; chordNum < list.length; chordNum++) { // iterate through all grace chords var chord = list[chordNum]; // Set note test, grace notes are shown a bit smaller nameChord(chord.notes, text, fontSize) // Important: Set element's spatial attributes *after* adding it to the score. // otherwise they have no effect. cursor.add(text) // X position the note name over the grace chord //text.offsetX = chord.posX // Y position the note name with a small nudge upward. //text.offsetY = cursor.element.posY - 0.3 text.placement = Placement.BELOW; // If we consume a STAFF_TEXT we must manufacture a new one. text = newElement(Element.STAFF_TEXT); // Make another STAFF_TEXT } } return text } onRun: { var cursor = curScore.newCursor(); var startStaff= curScore.nstaves - 2; var endStaff = curScore.nstaves - 1; cursor.rewind(1); for (var staff = startStaff; staff <= endStaff; staff++) { //for (var voice = 0; voice < 4; voice++) { cursor.rewind(1); // beginning of selection cursor.voice = 0; cursor.staffIdx = staff; cursor.rewind(0); // beginning of score while (cursor.segment) { if (cursor.element && cursor.element.type === Element.CHORD) { var text = newElement(Element.STAFF_TEXT); // Make a STAFF_TEXT // First...we need to scan grace notes for existence and break them // into their appropriate lists with the correct ordering of notes. var leadingLifo = new Array(); // List for leading grace notes var trailingFifo = new Array(); // List for trailing grace notes var graceChords = cursor.element.graceNotes; // Build separate lists of leading and trailing grace note chords. if (graceChords.length > 0) { for (var chordNum = 0; chordNum < graceChords.length; chordNum++) { var noteType = graceChords[chordNum].notes[0].noteType if (noteType == NoteType.GRACE8_AFTER || noteType == NoteType.GRACE16_AFTER || noteType == NoteType.GRACE32_AFTER) { trailingFifo.unshift(graceChords[chordNum]) } else { leadingLifo.push(graceChords[chordNum]) } } } // Next process the leading grace notes, should they exist... text = renderGraceNoteNames(cursor, leadingLifo, text, text.fontSize * fontSizeMini) // Now handle the note names on the main chord... var notes = cursor.element.notes; nameChord(notes, text, text.fontSize, staff === endStaff); cursor.add(text); // X position the note name over the chord //text.offsetX = cursor.element.posX // Y position the note name over the chord //text.offsetY = cursor.element.posY text.placement = Placement.BELOW text = newElement(Element.STAFF_TEXT) // Make another STAFF_TEXT object // Finally process trailing grace notes if they exist... text = renderGraceNoteNames(cursor, trailingFifo, text, text.fontSize * fontSizeMini) } // end if CHORD cursor.next(); } // end while segment //} // end for voice } // end for staff Qt.quit(); } // end onRun }