Added an toggle for sheet transposition (+8Va scenario)

This commit is contained in:
Stephan Roos
2026-03-01 13:35:59 +02:00
parent 9e9d58b28a
commit d946ec55fb

View File

@ -2,16 +2,20 @@
// MuseScore // MuseScore
// Music Composition & Notation // Music Composition & Notation
// //
// Generalized whistle tab plugin // Highly flexible whistle tab plugin for MuseScore using ASCII symbols.
// Requires the tin whistle font downloaded from Blayne Chastain: // Can be configured to generate tablature for an unlimited number of holes, with customized fingerings and tab layouts
// https://www.blaynechastain.com/tin-whistle-tab-sibelius-plugin/
// //
// Based on the Note Names Plugin which is: // Inspired by the tin-whistle-tablature project:
// Copyright (C) 2018 Jon Gadsden
//
// Which was inspired by the projects of
//
// The Note Names Plugin:
// Copyright (C) 2012 Werner Schweer // Copyright (C) 2012 Werner Schweer
// Copyright (C) 2013 - 2016 Joachim Schmitz // Copyright (C) 2013 - 2016 Joachim Schmitz
// Copyright (C) 2014 Jörn Eichler // Copyright (C) 2014 Jörn Eichler
// //
// and also based on the Recorder Woodwind Tablature plugin: // and the Recorder Woodwind Tablature plugin:
// Copyright (C)2011 Dario Escobedo, Werner Schweer, Jens Iwanenko and others // Copyright (C)2011 Dario Escobedo, Werner Schweer, Jens Iwanenko and others
// //
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
@ -29,7 +33,7 @@ MuseScore {
id: mscore id: mscore
version: "4.2" version: "4.2"
title: "ASCII Whistle Fingering" title: "ASCII Whistle Fingering"
description: "Inserts ASCII fingering diagrams using binary dictionary" description: "Inserts ASCII fingering diagrams using numerical dictionary"
pluginType: "dialog" pluginType: "dialog"
categoryCode: "composing-arranging-tools" categoryCode: "composing-arranging-tools"
thumbnailName: "whistle_tab_generator.png" thumbnailName: "whistle_tab_generator.png"
@ -66,14 +70,14 @@ MuseScore {
property real userLineSpacing: 0.7 property real userLineSpacing: 0.7
property string userFormatString: "" // mirrors current profile's formatString property string userFormatString: "" // mirrors current profile's formatString
property string userFontFamily: "Menlo, Consolas, Liberation Mono, Courier New, monospace" property string userFontFamily: "Menlo, Consolas, Liberation Mono, Courier New, monospace"
property bool userTransposed: false
property int defaultFontSize: 6 property int defaultFontSize: 6
property int defaultJustification: 1 property int defaultJustification: 1
property real defaultOffsetY: 1.2 property real defaultOffsetY: 1.2
property real defaultLineSpacing: 0.7 property real defaultLineSpacing: 0.7
property string defaultFontFamily: "Menlo, Consolas, Liberation Mono, Courier New, monospace" property string defaultFontFamily: "Menlo, Consolas, Liberation Mono, Courier New, monospace"
property bool defaultTransposed: false
// For undo/redo // For undo/redo
property var history: 0 property var history: 0
@ -88,6 +92,7 @@ MuseScore {
//NOTE: Note specification convention here uses sharps, so e.g. a Bb whistle needs to be defined as A# //NOTE: Note specification convention here uses sharps, so e.g. a Bb whistle needs to be defined as A#
//2 indicates a closed hole, 1 indicates a half hole, 0 indicates open hole. The last digit is a reserved section indicating how many plusses (+) should be drawn to signal overblowing. //2 indicates a closed hole, 1 indicates a half hole, 0 indicates open hole. The last digit is a reserved section indicating how many plusses (+) should be drawn to signal overblowing.
// ○ = 0 // ○ = 0
// ◐ = 1 // ◐ = 1
// ● = 2 // ● = 2
@ -106,9 +111,13 @@ MuseScore {
// "G#5": " 2 2 1 0 0 0 0 " <- overblow bit set to zero to indicate first octave // "G#5": " 2 2 1 0 0 0 0 " <- overblow bit set to zero to indicate first octave
// | | | | | | | // | | | | | | |
// variables in format string: $1 $2 $3 $4 $5 $6 $+ and then $note would be replaced with 'G#5' // variables in format string: $1 $2 $3 $4 $5 $6 $+ and then $note would be replaced with 'G#5'
// These variables are replaced by the corresponding symbol or text when run.
//Can have any number of holes in the specification, but the formatting string must consume all hole variables //Can have any number of holes in the specification
//NOTE: This plugin was generated from a maker's perspective, and thus the note names correspond with the sounding pitch, and not the
// typical octave shift down presented in notations. The dictionary can easily be edited to reflect the transposition, however, if desired.
//TODO: Add transposition checkmark which corrects notations to octave down pitch commonly used.
//Whistle definitions //Whistle definitions
property var defaultProfiles: [ property var defaultProfiles: [
@ -426,6 +435,7 @@ MuseScore {
property real storedOffsetY: 1.2 property real storedOffsetY: 1.2
property real storedLineSpacing: 0.6 property real storedLineSpacing: 0.6
property string storedFontFamily: defaultFontFamily property string storedFontFamily: defaultFontFamily
property bool storedTransposed: false
} }
//--------------------------------------------------------- //---------------------------------------------------------
@ -447,6 +457,8 @@ MuseScore {
spacingField.text = userLineSpacing.toFixed(1) spacingField.text = userLineSpacing.toFixed(1)
justCombo.currentIndex = userJustification justCombo.currentIndex = userJustification
formatInput.text = userFormatString formatInput.text = userFormatString
transposedCheck.checked = userTransposed
profileCombo.currentIndex = currentProfileIndex profileCombo.currentIndex = currentProfileIndex
updatePreview() updatePreview()
} }
@ -480,6 +492,7 @@ MuseScore {
pluginSettings.storedOffsetY = userOffsetY pluginSettings.storedOffsetY = userOffsetY
pluginSettings.storedLineSpacing = userLineSpacing pluginSettings.storedLineSpacing = userLineSpacing
pluginSettings.storedFontFamily = userFontFamily pluginSettings.storedFontFamily = userFontFamily
pluginSettings.storedTransposed = userTransposed
console.log("Settings saved") console.log("Settings saved")
} }
@ -524,7 +537,7 @@ MuseScore {
userOffsetY = pluginSettings.storedOffsetY ?? defaultOffsetY userOffsetY = pluginSettings.storedOffsetY ?? defaultOffsetY
userLineSpacing = pluginSettings.storedLineSpacing ?? defaultLineSpacing userLineSpacing = pluginSettings.storedLineSpacing ?? defaultLineSpacing
userFontFamily = pluginSettings.storedFontFamily ?? defaultFontFamily userFontFamily = pluginSettings.storedFontFamily ?? defaultFontFamily
userTransposed = pluginSettings.storedTransposed ?? defaultTransposed
if (typeof fontFamilyField !== 'undefined') { if (typeof fontFamilyField !== 'undefined') {
fontFamilyField.text = userFontFamily fontFamilyField.text = userFontFamily
@ -553,7 +566,7 @@ MuseScore {
setUserOffsetY(defaultOffsetY) setUserOffsetY(defaultOffsetY)
setUserLineSpacing(defaultLineSpacing) setUserLineSpacing(defaultLineSpacing)
setUserFontFamily(defaultFontFamily) setUserFontFamily(defaultFontFamily)
userTransposed = defaultTransposed
// 3. Update UI to reflect the new profile and settings // 3. Update UI to reflect the new profile and settings
userFormatString = getCurrentFormatString() userFormatString = getCurrentFormatString()
@ -564,6 +577,8 @@ MuseScore {
offsetField.text = userOffsetY.toFixed(1) offsetField.text = userOffsetY.toFixed(1)
spacingField.text = userLineSpacing.toFixed(1) spacingField.text = userLineSpacing.toFixed(1)
justCombo.currentIndex = userJustification justCombo.currentIndex = userJustification
transposedCheck.checked = userTransposed
// 4. Persist all changes to Settings // 4. Persist all changes to Settings
pluginSettings.storedProfiles = JSON.stringify(profiles.map(p => ({ pluginSettings.storedProfiles = JSON.stringify(profiles.map(p => ({
@ -577,6 +592,7 @@ MuseScore {
pluginSettings.storedOffsetY = userOffsetY pluginSettings.storedOffsetY = userOffsetY
pluginSettings.storedLineSpacing = userLineSpacing pluginSettings.storedLineSpacing = userLineSpacing
pluginSettings.storedFontFamily = userFontFamily pluginSettings.storedFontFamily = userFontFamily
pluginSettings.storedTransposed = userTransposed
pluginSettings.sync() // optional: force immediate write pluginSettings.sync() // optional: force immediate write
getHistory().end() getHistory().end()
@ -705,7 +721,7 @@ MuseScore {
} }
//------------------------------------------------- //-------------------------------------------------
// Replace plus placeholder ($+) with number of plusses based on plusBit // Replace plus placeholder ($+) with number of plusses based on plus bit
//------------------------------------------------- //-------------------------------------------------
while (output.indexOf("$+") !== -1) { while (output.indexOf("$+") !== -1) {
@ -871,6 +887,9 @@ MuseScore {
if (cursor.element && cursor.element.type === Element.CHORD) { if (cursor.element && cursor.element.type === Element.CHORD) {
var chord = cursor.element var chord = cursor.element
var midi = chord.notes[0].pitch var midi = chord.notes[0].pitch
if (userTransposed) midi += 12
var noteName = pitchToName(midi) var noteName = pitchToName(midi)
var text = newElement(Element.STAFF_TEXT) var text = newElement(Element.STAFF_TEXT)
@ -1437,9 +1456,20 @@ MuseScore {
} }
} }
} }
Item {
height: 50 // Spacer CheckBox {
width: parent.width id: transposedCheck
Layout.columnSpan: 4
checked: userTransposed
text: "Transposed?"
ToolTip.visible: hovered
ToolTip.delay: 500
ToolTip.text: "When checked, notes are assumed to be written an octave lower than they sound (e.g. High D whistle: written D4 = sounding D5). Displayed note will be the sounding note"
palette.windowText: textColor
onToggled: {
userTransposed = checked
saveSettings()
}
} }
} }
} }