V4.2: Changed font to use the same symbol addresses to fix display issues if font isn't loaded at start. Fixed theme switching colors. Note preview now scales to realistic size at 100% zoom. Fixed preview justification ignoring whitespace

This commit is contained in:
Stephan Roos
2026-03-01 11:02:33 +02:00
parent 3163be8c59
commit 98089b6ee0
2 changed files with 77 additions and 66 deletions

View File

@ -27,7 +27,7 @@ import MuseScore 3.0
MuseScore { MuseScore {
id: mscore id: mscore
version: "4.1" 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 binary dictionary"
pluginType: "dialog" pluginType: "dialog"
@ -74,6 +74,7 @@ MuseScore {
property real defaultLineSpacing: 0.8 property real defaultLineSpacing: 0.8
property string defaultFontFamily: "Menlo, Consolas, Liberation Mono, Courier New, monospace" property string defaultFontFamily: "Menlo, Consolas, Liberation Mono, Courier New, monospace"
// For undo/redo // For undo/redo
property var history: 0 property var history: 0
property var modified: false property var modified: false
@ -467,7 +468,7 @@ MuseScore {
} }
//--------------------------------------------------------- //---------------------------------------------------------
// MIDI → NOTE NAME // MIDI -> Note Name
//--------------------------------------------------------- //---------------------------------------------------------
function pitchToName(midiPitch) { function pitchToName(midiPitch) {
@ -534,11 +535,11 @@ MuseScore {
for (var i = 0; i < holeCount; i++) { for (var i = 0; i < holeCount; i++) {
var symbol var symbol
if (binaryString[i] === "2") if (binaryString[i] === "2")
symbol = String.fromCharCode(0xE001) // Closed hole - custom font symbol = String.fromCharCode(0x25CF) // Closed hole - custom font
else if (binaryString[i] === "1") else if (binaryString[i] === "1")
symbol = String.fromCharCode(0xE002) // Half hole - custom font symbol = String.fromCharCode(0x25D0) // Half hole - custom font
else else
symbol = String.fromCharCode(0xE000) // Open Hole - custom font symbol = String.fromCharCode(0x25CB) // Open Hole - custom font
var token = "$" + (i+1) var token = "$" + (i+1)
while (output.indexOf(token) !== -1) { while (output.indexOf(token) !== -1) {
@ -625,9 +626,9 @@ MuseScore {
// Check if this annotation belongs to the same track // Check if this annotation belongs to the same track
if (annotation.track === track && annotation.type === Element.STAFF_TEXT) { if (annotation.track === track && annotation.type === Element.STAFF_TEXT) {
var text = annotation.text var text = annotation.text
if (text && (text.indexOf(String.fromCharCode(0xE001)) !== -1 || // Closed hole - custom font if (text && (text.indexOf(String.fromCharCode(0x25CF)) !== -1 || // Closed hole - custom font
text.indexOf(String.fromCharCode(0xE002)) !== -1 || // Half hole - custom font text.indexOf(String.fromCharCode(0x25D0)) !== -1 || // Half hole - custom font
text.indexOf(String.fromCharCode(0xE000)) !== -1 || // Open hole - custom font text.indexOf(String.fromCharCode(0x25CB)) !== -1 || // Open hole - custom font
text.indexOf("☒") !== -1)) { text.indexOf("☒") !== -1)) {
return true return true
} }
@ -671,9 +672,9 @@ MuseScore {
// Check if this annotation belongs to the same track // Check if this annotation belongs to the same track
if (annotation.track === track && annotation.type === Element.STAFF_TEXT) { if (annotation.track === track && annotation.type === Element.STAFF_TEXT) {
var text = annotation.text var text = annotation.text
if (text && (text.indexOf(String.fromCharCode(0xE001)) !== -1 || //Closed hole symbol if (text && (text.indexOf(String.fromCharCode(0x25CF)) !== -1 || //Closed hole symbol
text.indexOf(String.fromCharCode(0xE002)) !== -1 || // Half hole - custom font text.indexOf(String.fromCharCode(0x25D0)) !== -1 || // Half hole - custom font
text.indexOf(String.fromCharCode(0xE000)) !== -1 || // Open Hole text.indexOf(String.fromCharCode(0x25CB)) !== -1 || // Open Hole
text.indexOf("☒") !== -1)) { text.indexOf("☒") !== -1)) {
removeElement(annotation) removeElement(annotation)
removed++ removed++
@ -786,10 +787,17 @@ MuseScore {
return "No preview available" return "No preview available"
} }
//Estimate offset for preview font size to match what will appear on staff at 100% zoom
function computePreviewOffset() {
var dpiScale = 96 / 72 // MuseScore vs Qt DPI convention
return Math.round(userFontSize * Screen.devicePixelRatio * dpiScale) - userFontSize
}
//Font definition for preview symbols. Does not support multiple fonts, so only use the whistle font
function getPreviewFont(){ function getPreviewFont(){
var baseFont = Qt.font({ var baseFont = Qt.font({
family: "WhistleSymbols", family: "WhistleSymbols",
pointSize: userFontSize pointSize: Math.max(1, userFontSize + computePreviewOffset()) //offset font size to match visual size on staff
}) })
// Split userFontFamily string into array and flatten with whistle font // Split userFontFamily string into array and flatten with whistle font
@ -807,8 +815,11 @@ MuseScore {
} }
function updatePreview() { function updatePreview() {
previewLabel.text = getPreviewText() //Replace whitespaces with non-breaking whitespace, as the label field ignores
//whitespaces when justifying, making the preview inaccurate otherwise.
previewLabel.text = getPreviewText().replace(/ /g, "\u00A0")
} }
//--------------------------------------------------------- //---------------------------------------------------------
@ -821,12 +832,12 @@ MuseScore {
function() { function() {
userFontSize = oldSize userFontSize = oldSize
fontSizeField.text = oldSize fontSizeField.text = oldSize
previewLabel.font.pointSize = oldSize previewLabel.font.pointSize = Math.max(1, oldSize + computePreviewOffset())
}, },
function() { function() {
userFontSize = size userFontSize = size
fontSizeField.text = size fontSizeField.text = size
previewLabel.font.pointSize = size previewLabel.font.pointSize = Math.max(1, size + computePreviewOffset())
}, },
"font size" "font size"
) )
@ -1012,13 +1023,13 @@ MuseScore {
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 2 Layout.columnSpan: 2
background: Rectangle { background: Rectangle {
color: sysPal.window color: backgroundColor
border.color: sysPal.mid border.color: textColor
} }
label: Label { label: Label {
text: parent.title text: parent.title
color: sysPal.windowText color: textColor
background: Rectangle { color: sysPal.window } background: Rectangle { color: backgroundColor }
} }
RowLayout { RowLayout {
@ -1028,7 +1039,7 @@ MuseScore {
Label { Label {
text: "Select whistle:" text: "Select whistle:"
color: sysPal.windowText color: textColor
} }
ComboBox { ComboBox {
id: profileCombo id: profileCombo
@ -1040,15 +1051,15 @@ MuseScore {
} }
contentItem: Text { contentItem: Text {
text: profileCombo.displayText text: profileCombo.displayText
color: sysPal.windowText color: textColor
font: profileCombo.font font: profileCombo.font
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight elide: Text.ElideRight
} }
background: Rectangle { background: Rectangle {
color: sysPal.window color: backgroundColor
border.color: sysPal.mid border.color: textColor
} }
} }
Item { Item {
@ -1065,13 +1076,13 @@ MuseScore {
Layout.preferredWidth: 600 Layout.preferredWidth: 600
Layout.columnSpan: 2 Layout.columnSpan: 2
background: Rectangle { background: Rectangle {
color: sysPal.window color: backgroundColor
border.color: sysPal.mid border.color: textColor
} }
label: Label { label: Label {
text: parent.title text: parent.title
color: sysPal.windowText color: textColor
background: Rectangle { color: sysPal.window } background: Rectangle { color: backgroundColor }
} }
GridLayout { GridLayout {
@ -1083,7 +1094,7 @@ MuseScore {
Label { Label {
text: "Font Size:" text: "Font Size:"
color: sysPal.windowText color: textColor
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
} }
TextField { TextField {
@ -1095,8 +1106,8 @@ MuseScore {
selectedTextColor: sysPal.highlightedText selectedTextColor: sysPal.highlightedText
validator: IntValidator { bottom: 1; top: 999 } validator: IntValidator { bottom: 1; top: 999 }
background: Rectangle { background: Rectangle {
color: sysPal.window color: backgroundColor
border.color: sysPal.mid border.color: textColor
} }
onAccepted: { onAccepted: {
@ -1126,14 +1137,14 @@ MuseScore {
onTextChanged: { onTextChanged: {
var newValue = parseInt(text) var newValue = parseInt(text)
if (!isNaN(newValue) && newValue >= 1 && newValue <= 999) { if (!isNaN(newValue) && newValue >= 1 && newValue <= 999) {
previewLabel.font.pointSize = newValue previewLabel.font.pointSize = Math.max(1, newValue + computePreviewOffset())
} }
} }
} }
Label { Label {
text: "Justification:" text: "Justification:"
color: sysPal.windowText color: textColor
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
} }
ComboBox { ComboBox {
@ -1147,21 +1158,21 @@ MuseScore {
} }
contentItem: Text { contentItem: Text {
text: justCombo.displayText text: justCombo.displayText
color: sysPal.windowText color: textColor
font: justCombo.font font: justCombo.font
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight elide: Text.ElideRight
} }
background: Rectangle { background: Rectangle {
color: sysPal.window color: backgroundColor
border.color: sysPal.mid border.color: textColor
} }
} }
Label { Label {
text: "Vertical Offset:" text: "Vertical Offset:"
color: sysPal.windowText color: textColor
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
} }
TextField { TextField {
@ -1173,8 +1184,8 @@ MuseScore {
selectedTextColor: sysPal.highlightedText selectedTextColor: sysPal.highlightedText
validator: DoubleValidator { bottom: -999.0; top: 999.0; decimals: 1 } validator: DoubleValidator { bottom: -999.0; top: 999.0; decimals: 1 }
background: Rectangle { background: Rectangle {
color: sysPal.window color: backgroundColor
border.color: sysPal.mid border.color: textColor
} }
onAccepted: { onAccepted: {
@ -1205,7 +1216,7 @@ MuseScore {
} }
Label { Label {
text: "Font Family:" text: "Font Family:"
color: sysPal.windowText color: textColor
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
} }
TextField { TextField {
@ -1217,8 +1228,8 @@ MuseScore {
selectionColor: sysPal.highlight selectionColor: sysPal.highlight
selectedTextColor: sysPal.highlightedText selectedTextColor: sysPal.highlightedText
background: Rectangle { background: Rectangle {
color: sysPal.window color: backgroundColor
border.color: sysPal.mid border.color: textColor
} }
onAccepted: { onAccepted: {
if (text !== userFontFamily) { if (text !== userFontFamily) {
@ -1233,7 +1244,7 @@ MuseScore {
Label { Label {
text: "Line Spacing:" text: "Line Spacing:"
color: sysPal.windowText color: textColor
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
} }
TextField { TextField {
@ -1245,8 +1256,8 @@ MuseScore {
selectedTextColor: sysPal.highlightedText selectedTextColor: sysPal.highlightedText
validator: DoubleValidator { bottom: 0; top: 6; decimals: 1 } validator: DoubleValidator { bottom: 0; top: 6; decimals: 1 }
background: Rectangle { background: Rectangle {
color: sysPal.window color: backgroundColor
border.color: sysPal.mid border.color: textColor
} }
onAccepted: { onAccepted: {
@ -1301,7 +1312,7 @@ MuseScore {
} }
background: Rectangle { background: Rectangle {
color: sysPal.button color: sysPal.button
border.color: sysPal.mid border.color: textColor
} }
onClicked: { onClicked: {
resetToDefaults() resetToDefaults()
@ -1315,13 +1326,13 @@ MuseScore {
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 2 Layout.columnSpan: 2
background: Rectangle { background: Rectangle {
color: sysPal.window color: backgroundColor
border.color: sysPal.mid border.color: textColor
} }
label: Label { label: Label {
text: parent.title text: parent.title
color: sysPal.windowText color: textColor
background: Rectangle { color: sysPal.window } background: Rectangle { color: backgroundColor }
} }
RowLayout { RowLayout {
@ -1337,7 +1348,7 @@ MuseScore {
Label { Label {
text: "Format String:" text: "Format String:"
color: sysPal.windowText color: textColor
font.bold: true font.bold: true
} }
@ -1347,8 +1358,8 @@ MuseScore {
Layout.preferredHeight: 200 Layout.preferredHeight: 200
clip: true clip: true
background: Rectangle { background: Rectangle {
color: sysPal.window color: backgroundColor
border.color: sysPal.mid border.color: textColor
} }
TextArea { TextArea {
@ -1361,8 +1372,8 @@ MuseScore {
selectionColor: sysPal.highlight selectionColor: sysPal.highlight
selectedTextColor: sysPal.highlightedText selectedTextColor: sysPal.highlightedText
background: Rectangle { background: Rectangle {
color: sysPal.window color: backgroundColor
border.color: sysPal.mid border.color: textColor
} }
property var previousText: userFormatString property var previousText: userFormatString
onEditingFinished: { onEditingFinished: {
@ -1378,23 +1389,23 @@ MuseScore {
Label { Label {
text: "Use placeholders like $1, $2, ..., for the holes, \n$+ for the plus indicator and $note for the note (e.g. G#5)" text: "Use placeholders like $1, $2, ..., for the holes, \n$+ for the plus indicator and $note for the note (e.g. G#5)"
font.pixelSize: 10 font.pixelSize: 10
color: sysPal.windowText color: textColor
} }
} }
// Preview Area (right side) // Preview Area (right side)
GroupBox { GroupBox {
title: "Preview" title: "Preview (@100%)"
Layout.preferredWidth: 120 Layout.preferredWidth: 120
Layout.fillHeight: true Layout.fillHeight: true
background: Rectangle { background: Rectangle {
color: sysPal.window color: backgroundColor
border.color: sysPal.mid border.color: textColor
} }
label: Label { label: Label {
text: parent.title text: parent.title
color: sysPal.windowText color: textColor
background: Rectangle { color: sysPal.window } background: Rectangle { color: backgroundColor }
} }
ScrollView { ScrollView {
@ -1402,8 +1413,8 @@ MuseScore {
anchors.margins: 5 anchors.margins: 5
clip: true clip: true
background: Rectangle { background: Rectangle {
color: sysPal.window color: backgroundColor
border.color: sysPal.mid border.color: textColor
} }
Label { Label {
@ -1411,8 +1422,8 @@ MuseScore {
text: getPreviewText() text: getPreviewText()
//font.family: getFontStack() //font.family: getFontStack()
//font.pointSize: userFontSize //font.pointSize: userFontSize
color: sysPal.windowText color: textColor
wrapMode: Text.WordWrap wrapMode: Text.NoWrap
width: parent.width width: parent.width
lineHeight: userLineSpacing lineHeight: userLineSpacing
lineHeightMode: Text.ProportionalHeight lineHeightMode: Text.ProportionalHeight
@ -1448,7 +1459,7 @@ MuseScore {
} }
background: Rectangle { background: Rectangle {
color: sysPal.button color: sysPal.button
border.color: sysPal.mid border.color: textColor
} }
onClicked: { onClicked: {
if (hasExistingAnnotations()) { if (hasExistingAnnotations()) {
@ -1471,7 +1482,7 @@ MuseScore {
} }
background: Rectangle { background: Rectangle {
color: sysPal.button color: sysPal.button
border.color: sysPal.mid border.color: textColor
} }
onClicked: { onClicked: {
quit() quit()