//==============================================
// MuseScore
//
// Shakuhachi Notation plugin for MuseScore Ver. 3.1
//
// Copyright (C)2010-2018 Hiroshi Tachibana
//
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//==============================================
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import MuseScore 1.0
import FileIO 1.0
import Qt.labs.settings 1.0
MuseScore {
menuPath: "Plugins.Shakuhachi Notation 311" //
version: "3.1.10"
description: qsTr("Shakuhachi note names, fingering etc.")
pluginType: "dialog"
id: window
width:285 // menu window size
height:285
ExclusiveGroup { id: exclusiveGroupKey }
property var fileExist :true
property var seplines
property var shakuhachiLengthInit : 18
property var fontListInitNumber : 0
property var fontListInitName : "ShakuhachiTozan1"
property var fontSizeInit : 13
property var yPositionInit : 0
property var xPositionInit : 0
property var partListInit : 0
property var colorListInit : 0
property var fontName: [ "ShakuhachiTozan1","Shakuhachi18","ShakuhachiO","ShakuhachiKinko","ShakuhachiFingeringTozan","ShakuhachiFingeringNotationTozan","Doremi","Helvetica" ,"SenshuTK","SenshuTK" ]
property var fontNameSel
// Item positions in menu window
property var itemX1 : 10
property var itemX2 : 150
property var itemY1 : 10
property var itemDY : 25
Settings {
id : settings
category : "pluginSettings"
property int shakuhachiLength: 18
property int fontList: 0
property int fontSize: 14
property int xPosition: 0
property int yPosition: 0
property int partList: 0
property int colorList: 1
}
RowLayout { //====================== LENGTH
id: row0
x :itemX1
y :itemY1
Label {
font.pointSize: 14
text: "Shakuhachi Length" // effect , no effect
}
}
RowLayout {
id: row0R
x : itemX2
y : itemY1
SpinBox {
id: valShakuhachiLength
implicitWidth: 55
decimals: 0
minimumValue: 6
maximumValue: 36
value: shakuhachiLengthInit
font.pointSize: 14
}
}
RowLayout { //====================== FONT
id: row1
x :itemX1
y :itemY1+itemDY*1
Label {
font.pointSize: 14
text: "Font"
}
}
RowLayout {
id: row1R
x :itemX2
y :itemY1+itemDY*1
ComboBox {
currentIndex: fontListInitNumber
model: ListModel {
id: fontList
property var key
ListElement { text: "Tozan"; fName: 0 }
ListElement { text: "Tozan2"; fName: 1 }
ListElement { text: "Tozan2 ( )"; fName: 2 }
ListElement { text: "Kinko"; fName: 3 }
ListElement { text: "Fingering"; fName: 4 }
ListElement { text: "Tozan+Fingering"; fName: 5 }
ListElement { text: "DoReMi (Katakana)"; fName:6 }
ListElement { text: "CDEFG"; fName: 7 }
ListElement { text: "SenshuTozan"; fName: 8 }
ListElement { text: "SenshuKinko"; fName: 9 }
}
width: 100
onCurrentIndexChanged: {
console.debug(fontList.get(currentIndex).text + ", " + fontList.get(currentIndex).fName)
fontList.key = fontList.get(currentIndex).fName
}
} // end ComboBox
}
RowLayout { //====================== FONT SIZE
id: row2
x :itemX1
y :itemY1+itemDY*2+5
Label {
font.pointSize: 14
text: "Font Size"
}
}
RowLayout {
id: row2R
x :itemX2
y :itemY1+itemDY*2+5
SpinBox {
id: valFontSize
implicitWidth: 55
decimals: 0
minimumValue: 4
maximumValue: 36
value: fontSizeInit
font.pointSize: 14
}
}
RowLayout { //====================== Y POSITION
id: row3
x :itemX1
y :itemY1+itemDY*3+5
Label {
font.pointSize: 14
text: "Y (Tate) Position"
}
}
RowLayout {
id: row3R
x :itemX2
y :itemY1+itemDY*3+5
SpinBox {
id: valYPosition
implicitWidth: 55
decimals: 0
minimumValue: -20
maximumValue: 30
value: yPositionInit
font.pointSize: 14
}
}
RowLayout { //====================== X POSITION
id: row4
x :itemX1
y :itemY1+itemDY*4+40
Label {
font.pointSize: 14
text: "X (Yoko) Position"
}
}
RowLayout {
id: row4R
x :itemX2
y :itemY1+itemDY*4+40
SpinBox {
id: valXPosition
implicitWidth: 55
decimals: 1
minimumValue: -5
maximumValue: 5
value: xPositionInit
stepSize: 0.1
font.pointSize: 14
}
}
RowLayout { //====================== PART
id: row5
x :itemX1
y :itemY1+itemDY*5+40
Label {
font.pointSize: 14
text: "Part"
}
}
RowLayout {
id: row5R
x :itemX2
y :itemY1+itemDY*5+40
ComboBox {
currentIndex: partListInit
model: ListModel {
id: partList
property var key
ListElement { text: "Part 1"; pName: 0 }
ListElement { text: "Part 2"; pName: 1 }
ListElement { text: "Part 3"; pName: 2 }
ListElement { text: "Part 4"; pName: 3 }
}
width: 60
onCurrentIndexChanged: {
//console.debug(partList.get(currentIndex).text + ", " + partList.get(currentIndex).pName)
partList.key = partList.get(currentIndex).pName
}
} // end ComboBox
}
RowLayout { //====================== COLOR
id: row6
x :itemX1
y :itemY1+itemDY*6+40
Label {
font.pointSize: 14
text: "Color"
}
}
RowLayout {
id: row6R
x :itemX2
y :itemY1+itemDY*6+40
ComboBox {
currentIndex: colorListInit
model: ListModel {
id: colorList
property var key
ListElement { text: "Black"; cName: 0 }
ListElement { text: "Red"; cName: 1 }
ListElement { text: "Blue"; cName: 2 }
ListElement { text: "Green"; cName: 3 }
ListElement { text: "Purple"; cName: 4 }
ListElement { text: "Gray"; cName: 5 }
}
width: 60
onCurrentIndexChanged: {
//console.debug(colorList.get(currentIndex).text + ", " + colorList.get(currentIndex).cName)
colorList.key = colorList.get(currentIndex).cName
}
} // end ComboBox
}
RowLayout { //====================== CANCEL / OK
id: row7
x : 150
y : 250
Button {
id: closeButton
text: "Cancel"
onClicked: { Qt.quit() }
}
Button {
id: okButton
text: "Ok"
onClicked: {
apply()
Qt.quit()
}
}
}
function apply() {
curScore.startCmd()
applyToSelection()
settings.shakuhachiLength = (settings.shakuhachiLength == 0) ? shakuhachiLengthInit : valShakuhachiLength.value
settings.fontList = fontList.key
settings.fontSize = valFontSize.value
settings.yPosition = valYPosition.value
settings.xPosition = valXPosition.value
settings.partList = partList.key
settings.colorList = colorList.key
my_file1.write(valShakuhachiLength.value+"\n"+fontList.key+"\n"+valFontSize.value+"\n"+valYPosition.value+"\n"+valXPosition.value+"\n"+partList.key+"\n"+colorList.key)
curScore.endCmd()
}
onRun: {
valShakuhachiLength.value = settings.shakuhachiLength
fontList.key = settings.fontList
valFontSize.value = settings.fontSize
valYPosition.value = settings.yPosition
valXPosition.value = settings.xPosition
partList.key = settings.partList
colorList.key = settings.colorList
if( fileExist ) var fileContents = my_file1.read();
if( !fileExist ) var fileContents="18\n0\n13\n0\n0\n0\n0\n0";
//console.log("fileExist="+fileExist);
//console.log("fileContents="+fileContents);
seplines=fileContents.split("\n");
//console.log("seplines="+seplines);
shakuhachiLengthInit=Number(seplines[0] );
fontListInitNumber=Number(seplines[1]);
fontListInitName=fontName[Number(seplines[1])];
fontSizeInit=Number(seplines[2]);
yPositionInit=Number(seplines[3]);
xPositionInit=Number(seplines[4]);
partListInit=Number(seplines[5]);
colorListInit=Number(seplines[6]);
//console.log("on Run : fontListInitName="+fontListInitName);
if (typeof curScore === 'undefined')
Qt.quit();
} // end onRun
function applyToSelection() {
var cursor = curScore.newCursor();
var startStaff;
var endStaff;
var endTick;
var fullScore = false;
var shakuhachiLength = valShakuhachiLength.value;
// console.log(shakuhachiLength);
// Initial vertical offset
var yPos = valYPosition.value+10 ; // Y offset= +10
// Initial horizontal offsets
if(fontList.key==0) var xPos = valXPosition.value-2.0; // Tozan ?????
if(fontList.key==1) var xPos = valXPosition.value-0.4; // Tozan2
if(fontList.key==2) var xPos = valXPosition.value-0.4; // Tozan ( )
if(fontList.key==3) var xPos = valXPosition.value-0.4; // Kinko
if(fontList.key==4) var xPos = valXPosition.value; // Fingering
if(fontList.key==5) var xPos = valXPosition.value; // Tozan + Fingering
if(fontList.key==6) var xPos = valXPosition.value-0.8; // Do Re Mi (Katakana)
if(fontList.key==7) var xPos = valXPosition.value-0.4; // CDEFG
if(fontList.key==8) var xPos = valXPosition.value-1.0; // SenshuTozan
if(fontList.key==9) var xPos = valXPosition.value-1.0; // SenshuKinko
fontNameSel =fontName[ Number(fontList.key)];
//console.log("in apply fontNameSel="+fontNameSel);
var fontSize = valFontSize.value;
// console.log("Read from file="+fileContents);
// if(fontNameSel=="ShakuhachiTozan0") xPos=xPos-0.5;
if(fontNameSel=="ShakuhachiFingeringTozan") {
fontSize=fontSize*3;
}
if(fontNameSel=="ShakuhachiFingeringNotationTozan") {
fontSize=fontSize*3;
}
if(fontNameSel=="SenshuTK") fontSize=fontSize+7;
var fontSizeTag="";
var fontFaceTag="";
var selPart=0;
// RGB color Black , Red , Blue , Green , Purple , Gray
var colorData= [ "#000000" ,"#FF0000" ,"#0000FF" ,"#00FF00" ,"#C007C0" ,"#888888" ];
var fontColor=colorData[colorList.key];
//console.log(fontName);
cursor.rewind(1); // rewind to start of selection
if (!cursor.segment) { // no selection
fullScore = true;
startStaff = 0; // start with 1st staff
endStaff = curScore.nstaves - 1; // and end with last
} else {
startStaff = cursor.staffIdx;
cursor.rewind(2); // rewind to end of selection
if (cursor.tick == 0) {
endTick = curScore.lastSegment.tick + 1;
} else {
endTick = cursor.tick;
}
endStaff = cursor.staffIdx;
}
//console.log("Part: "+partList.key);
//console.log(startStaff + " - " + endStaff + " - " + endTick);
for (var staff = startStaff; staff <= endStaff; staff++) {
// for (var voice = 0; voice < 4; voice++) {
var voice=partList.key;
cursor.rewind(1); // beginning of selection
cursor.voice = voice;
cursor.staffIdx = staff;
if (fullScore) // no selection
cursor.rewind(0); // beginning of score
while (cursor.segment && (fullScore || cursor.tick < endTick)) {
if (cursor.element && cursor.element.type == Element.CHORD) {
var text = newElement(Element.STAFF_TEXT);
// ######################## GRACE #####################################
var graceChords = cursor.element.graceNotes;
for (var i = 0; i < graceChords.length; i++) {
var notes = graceChords[i].notes;
nameChord(notes, text, shakuhachiLength, fontName,fontList.key);
text.pos.x =xPos -2.3 * (graceChords.length - i); // X position of Grace note
switch (voice) {
case 0: text.pos.y = yPos; break;
case 1: text.pos.y = yPos+2; break;
case 2: text.pos.y = yPos+4; break;
case 3: text.pos.y = yPos+6; break;
}
text.color= fontColor;
if(fontList.key==6) text.text= fontSizeTag + text.text;
else text.text= fontSizeTag + fontFaceTag + text.text;
//console.log(text.text + " ===Grace===");
cursor.add(text);
text = newElement(Element.STAFF_TEXT);
} // end graceChorde
//####################################################################
var notes = cursor.element.notes;
nameChord(notes, text,shakuhachiLength, fontName,fontList.key);
switch (voice) {
case 0: text.pos.y = yPos; break;
case 1: text.pos.y = yPos+2; break;
case 2: text.pos.y = yPos+4; break;
case 3: text.pos.y = yPos+6; break;
}
text.color= fontColor;
text.pos.x= xPos;
if(fontList.key==6) text.text= fontSizeTag + text.text;
else text.text= fontSizeTag + fontFaceTag + text.text;
//console.log(text.text);
cursor.add(text);
} // end if CHORD
cursor.next();
} // end while segment
// } // end for voice
} // end for staff
Qt.quit();
} // end onRun
function nameChord (notes, text, shakuhachiLength, fontName, fontListKey) {
var fingerings = [ "A", "B", // Otsu RO Omeri(A), Otsu RO meri(B)
"C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", // Otsu RO(C) - HiMeri(N)
"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", // Kan RO(O) - HiMeri(N)
"a", "b", "c", // Pi(a),Ta(b),Shi(c)
"d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "P","Q", "R", "S", "T",// daikan TSU(d)- C(k) ,D(m)
"n", "o", "p", "q", "r"] // I(n), Fra(o), Koro(p), Kara(q), U(r)
var noteNameS = [ "C","C#","D","D#","E","F","F#","G","G#","A","A#","B" ]
var noteNameF = [ "C","Db","D","Eb","E","F","Gb","G","Ab","A","Bb","B" ]
// 泉州フォント用
var fingeringsSenshuT = [ "a", "b", // Otsu RO Omeri, Otsu RO meri
"c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", // Otsu RO(D4) - HiMeri(C#5)
"c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", // Kan RO- Shi
"f", "g", "h", "i", "j", "k", "l", "m", "n", "o", // Daikan Tsu- D
"d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o"] //
// 琴古フォントを2018.9.17に修正(アンケートでの、乙の指使いの間違いの指摘による。フォントファイルも変更)
var fingeringsSenshuK = [ "A", "B", // Otsu RO Omeri, Otsu RO meri
"C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "B", // Otsu RO(D4) - HiMeri(C#5)
"C", "D", "E", "F", "G", "H", "U", "J", "V", "W", "X", "N", "O", "P", "Q", // Kan RO- Shi
"F", "G", "H", "U", "J", "V", "W", "X", "N", "C", // Daikan Tsu- D
"D", "E", "F", "G", "H", "U", "J", "V", "W", "X", "N", "C"] //
/*
var fingeringsSenshu = [ "a", "a", // Otsu RO Omeri, Otsu RO meri
"A", "s", "S", "D", "f", "F", "g", "G", "h", "H", "J", "k", // Otsu RO-
"A", "s", "S", "D", "f", "F", "g", "G", "h", "H", "J", "k", "Q", "w", "W", // Kan RO- Shi
"D", "f", "F", "g", "G", "h", "H", "j", "k", "Q"] // Daikan Tsu-
*/
// space chracter is needed. "s"
var pitchFing;
// text.text="";
//console.log( fingerings.length) // 49
//console.log( fingeringsSenshu.length) // 39
for (var i = 0; i < notes.length; i++) {
var sep = "\n"; // ","; // change to "\n" if you want them vertically
if ( i > 0 ) text.text = sep + text.text;
//console.log(notes[i].pitch % 12+ " "+notes[i].tpc);
// var pitchFing=notes[i].pitch-78+18;
if(fontNameSel=="Doremi"){
pitchFing=(notes[i].pitch -6 +shakuhachiLength) % 12 ;
} else if ( fontNameSel=="Helvetica" ) {
if(notes[i].tpc>=6 && notes[i].tpc<=12 ) { // b Flat
text.text=noteNameF[(notes[i].pitch % 12)] +text.text ;
} else if ( notes[i].tpc>=20 && notes[i].tpc<=26 ){ // # Sharp
text.text=qsTr(noteNameS[(notes[i].pitch % 12)]) +text.text ;
} else{
text.text=qsTr(noteNameF[(notes[i].pitch % 12)]) +text.text ;
}
} else pitchFing=notes[i].pitch-78+shakuhachiLength;
if(pitchFing<0 || pitchFing>fingerings.length-6) // out of range
text.text=" "+text.text;
else{ // range
if(notes[i].tieBack == null){
if(fontNameSel !="Helvetica")
if(fontListKey==8) text.text=fingeringsSenshuT[pitchFing]+text.text;
else if(fontListKey==9) text.text=fingeringsSenshuK[pitchFing]+text.text;
// if(fontNameSel=="SenshuTK") text.text=fingeringsSenshu[pitchFing]+text.text;
else text.text=fingerings[pitchFing]+text.text ; // 0 == OtsuRO
// if(notes[i].tieBack == null &&) text.text=fingeringsSenshu[pitchFing]+text.text;
}
//console.log(pitchFing,fingeringsSenshu[pitchFing]);
if(fontNameSel=="Doremi"){
if(notes[i].tpc>=6 && notes[i].tpc<=12 ) { // b Flat
text.text=""+text.text;
} else if ( notes[i].tpc>=20 && notes[i].tpc<=26 ){ // # Sharp
text.text=""+text.text;
} else {
text.text=""+text.text;
}
pitchFing=(notes[i].pitch -78+shakuhachiLength) % 12 ;
}
}
} // end for note
} // end function
FileIO {
id: my_file1
source: tempPath() + "/temp9999s.txt"
// source: "/Users/tac/Documents/temp9999SS.txt"
onError: fileExist=false // console.log(msg)
}
} // end MuseScore