import QtQuick 2.0 import MuseScore 3.0 import QtQuick.Controls 1.0 import QtQuick.Controls.Styles 1.3 import QtQuick.Dialogs 1.1 import "./" MuseScore { menuPath: "Plugins.QuarterTonePlayback" description: "This plugin applies quarter tone tuning while considering accidentals and custom key signatures. Please refer to the documentation file for more help on using the plugin." version: "1.0" pluginType: "dialog" width: 400 height: 350 property variant tunings : [ 0, // NONE 0, // SHARP 0, // FLAT 0, // SHARP2, 0, // FLAT2, 0, // NATURAL -50, // FLAT_SLASH 0, // FLAT_SLASH2 0, // MIRRPRED_FLAT2, -50, // MIRRPRED_FLAT 0, // MIRRPRED_FLAT_SLASH, 0, // FLAT_FLAT_SLASH 50, // SHARP_SLASH 0, // SHARP_SLASH2 0, // SHARP_SLASH3 0, // SHARP_SLASH4 0, // SHARP_ARROW_UP 0, // SHARP_ARROW_DOWN 0, // SHARP_ARROW_BOTH, 0, // FLAT_ARROW_UP 0, // FLAT_ARROW_DOWN 0, // FLAT_ARROW_BOTH 0, // NATURAL_ARROW_UP 0, // NATURAL_ARROW_DOWN 0, // NATURAL_ARROW_BOTH 0, // SORI 0, // KORON 0 //END ] property var keySigs : [] Rectangle { id: mWindow color: "#d0d0d0" anchors.fill: parent Text { id: title_text text: qsTr("Quarter Tone Playback") anchors.top : mWindow.top anchors.horizontalCenter : parent.horizontalCenter anchors.topMargin: 10 font.pointSize: 12; font.bold:true } Text { id: author_text text: qsTr("By Gilbert Yammine") anchors.top : title_text.bottom anchors.horizontalCenter : parent.horizontalCenter font.pointSize: 10 } Text { id: web_text text: 'www.gilbertyammine.com' anchors.top : author_text.bottom anchors.horizontalCenter : parent.horizontalCenter font.pointSize: 8 onLinkActivated: Qt.openUrlExternally(link) } GroupBox { id: gb_tuning title: "Tuning" anchors.horizontalCenter: parent.horizontalCenter anchors.top : web_text.bottom anchors.topMargin: 20 Row { spacing: 10 Image { id: i_flat_slash cache: false x: 28 y: 28 anchors.top : parent.top source: "flat_slash.png" } SpinBox { id: sp_flatTuning style: SpinBoxStyle { horizontalAlignment: Qt.AlignHCenter } minimumValue: -200 maximumValue: 200 value: -50 height: 28 width: 50 } Image { id: i_sharp_slash cache: false x: 28 y: 28 anchors.top : parent.top source: "sharp_slash.png" } SpinBox { id: sp_sharpTuning style: SpinBoxStyle { horizontalAlignment: Qt.AlignHCenter } minimumValue: -200 maximumValue: 200 value: 50 height: 28 width: 50 } } //Row } //GroupBox GroupBox { id: gb_keySigs title: "Key Signature" anchors.horizontalCenter: parent.horizontalCenter anchors.top : gb_tuning.bottom anchors.topMargin: 20 Grid { columns: 7 rows: 3 columnSpacing: 10 SlashFlatButton{ id: fb_c } SlashFlatButton{ id: fb_d } SlashFlatButton{ id: fb_e } SlashFlatButton{ id: fb_f } SlashFlatButton{ id: fb_g } SlashFlatButton{ id: fb_a } SlashFlatButton{ id: fb_b } Text { text: "C" width: 28 height: 28 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.pointSize: 12 } Text { text: "D" width: 28 height: 28 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.pointSize: 12 } Text { text: "E" width: 28 height: 28 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.pointSize: 12 } Text { text: "F" width: 28 height: 28 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.pointSize: 12 } Text { text: "G" width: 28 height: 28 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.pointSize: 12 } Text { text: "A" width: 28 height: 28 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.pointSize: 12 } Text { text: "B" width: 28 height: 28 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.pointSize: 12 } SlashSharpButton{ id: sb_c } SlashSharpButton{ id: sb_d } SlashSharpButton{ id: sb_e } SlashSharpButton{ id: sb_f } SlashSharpButton{ id: sb_g } SlashSharpButton{ id: sb_a } SlashSharpButton{ id: sb_b } } } Button { id: b_apply text: "Apply Tuning" anchors.horizontalCenter: parent.horizontalCenter anchors.top: gb_keySigs.bottom anchors.topMargin: 20 height: 30 onClicked: { keySigs = [] if (fb_c.isClicked) keySigs.push(Qt.vector2d(60%12, Accidental.FLAT_SLASH)); if (fb_d.isClicked) keySigs.push(Qt.vector2d(62%12, Accidental.FLAT_SLASH)); if (fb_e.isClicked) keySigs.push(Qt.vector2d(64%12, Accidental.FLAT_SLASH)); if (fb_f.isClicked) keySigs.push(Qt.vector2d(65%12, Accidental.FLAT_SLASH)); if (fb_g.isClicked) keySigs.push(Qt.vector2d(67%12, Accidental.FLAT_SLASH)); if (fb_a.isClicked) keySigs.push(Qt.vector2d(69%12, Accidental.FLAT_SLASH)); if (fb_b.isClicked) keySigs.push(Qt.vector2d(71%12, Accidental.FLAT_SLASH)); if (sb_c.isClicked) keySigs.push(Qt.vector2d(60%12, Accidental.SHARP_SLASH)); if (sb_d.isClicked) keySigs.push(Qt.vector2d(62%12, Accidental.SHARP_SLASH)); if (sb_e.isClicked) keySigs.push(Qt.vector2d(64%12, Accidental.SHARP_SLASH)); if (sb_f.isClicked) keySigs.push(Qt.vector2d(65%12, Accidental.SHARP_SLASH)); if (sb_g.isClicked) keySigs.push(Qt.vector2d(67%12, Accidental.SHARP_SLASH)); if (sb_a.isClicked) keySigs.push(Qt.vector2d(69%12, Accidental.SHARP_SLASH)); if (sb_b.isClicked) keySigs.push(Qt.vector2d(71%12, Accidental.SHARP_SLASH)); if (isFullScore()==true) msgDialog.open(); else processSelectedNotes(); } } } MessageDialog { id: msgDialog title: "Process Full Score" text: "Nothing is selected. Process full score?" standardButtons: StandardButton.Yes | StandardButton.Abort onYes: { processSelectedNotes(); } onRejected: { return; } } function isFullScore(){ var cursor = curScore.newCursor(); cursor.rewind(1); if (!cursor.segment) //nothing selected return true; else return false; } function processSelectedNotes(){ var acc = [] var cursor = curScore.newCursor(); cursor.rewind(1); var startStaff; var endStaff; var endTick; var fullScore = false; if (!cursor.segment) { //nothing selected fullScore = true; startStaff = 0; endStaff = curScore.nstaves - 1; } else { startStaff = cursor.staffIdx; cursor.rewind(2); //end of selection if (cursor.tick == 0){ endTick = curScore.lastSegment.tick+1; } else { endTick = cursor.tick; } endStaff = cursor.staffIdx; } for (var staff = startStaff; staff <= endStaff; staff++){ for (var voice = 0; voice < 4; voice++){ cursor.rewind(1); cursor.voice = voice; cursor.staffIdx = staff; if (fullScore) cursor.rewind(0); var measure = cursor.measure; while (cursor.segment && (fullScore || cursor.tick < endTick)){ if (cursor.measure != measure){ measure = cursor.measure; for (var i=0;i