[feat] remove format string & preview from GUI
Personal opinion: being able to change the format in the GUI, but not the fingering, felt misleading. I think the user should either be directed to the Fingering.js file or we should have a complete editor of fingerings in the GUI. Since adding more elements to the GUI would be a lot of work, I opted for the first option. - Removed all references to the format string and preview window - Also fixed some wordings/indentation
This commit is contained in:
@ -102,20 +102,11 @@ MuseScore {
|
||||
return profiles.length > 0 ? profiles[currentProfileIndex].format : ""
|
||||
}
|
||||
|
||||
function setCurrentFormatString(newFormat) {
|
||||
if (profiles.length > 0) {
|
||||
profiles[currentProfileIndex].format = newFormat
|
||||
userFormatString = newFormat
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Settings {
|
||||
id: pluginSettings
|
||||
category: "whistleTab"
|
||||
|
||||
// Declare each setting as a property (with defaults)
|
||||
property string storedProfiles: ""
|
||||
property int storedCurrentProfile: 0
|
||||
property int storedFontSize: 8
|
||||
property int storedJustification: 1
|
||||
@ -143,11 +134,9 @@ MuseScore {
|
||||
offsetField.text = userOffsetY.toFixed(1)
|
||||
spacingField.text = userLineSpacing.toFixed(1)
|
||||
justCombo.currentIndex = userJustification
|
||||
formatInput.text = userFormatString
|
||||
transposedCheck.checked = userTransposed
|
||||
|
||||
profileCombo.currentIndex = currentProfileIndex
|
||||
updatePreview()
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
@ -166,13 +155,6 @@ MuseScore {
|
||||
//---------------------------------------------------------
|
||||
|
||||
function saveSettings() {
|
||||
// Save profiles as JSON string
|
||||
var profilesForStorage = profiles.map(p => ({
|
||||
name: p.name,
|
||||
fingering: p.fingering,
|
||||
format: p.format
|
||||
}))
|
||||
pluginSettings.storedProfiles = JSON.stringify(profilesForStorage)
|
||||
pluginSettings.storedCurrentProfile = currentProfileIndex
|
||||
pluginSettings.storedFontSize = userFontSize
|
||||
pluginSettings.storedJustification = userJustification
|
||||
@ -186,32 +168,11 @@ MuseScore {
|
||||
|
||||
function loadSettings() {
|
||||
// Load profiles
|
||||
var profilesStr = pluginSettings.storedProfiles
|
||||
if (profilesStr && profilesStr !== "") {
|
||||
try {
|
||||
var loaded = JSON.parse(profilesStr)
|
||||
profiles = loaded.map(p => ({
|
||||
name: p.name,
|
||||
fingering: p.fingering,
|
||||
format: p.format
|
||||
}))
|
||||
} catch (e) {
|
||||
console.log("Failed to parse saved profiles, using defaults")
|
||||
error("Failed to parse saved profiles, using defaults")
|
||||
|
||||
profiles = Fingering.woodwinds.map(p => ({
|
||||
name: p.name,
|
||||
fingering: JSON.parse(JSON.stringify(p.fingering)),
|
||||
format: p.format
|
||||
}))
|
||||
}
|
||||
} else {
|
||||
profiles = Fingering.woodwinds.map(p => ({
|
||||
name: p.name,
|
||||
fingering: JSON.parse(JSON.stringify(p.fingering)),
|
||||
format: p.format
|
||||
}))
|
||||
}
|
||||
|
||||
// Load current profile index
|
||||
currentProfileIndex = pluginSettings.storedCurrentProfile
|
||||
@ -240,11 +201,6 @@ MuseScore {
|
||||
getHistory().begin() // if you have undo/redo
|
||||
|
||||
// 1. Restore profiles from woodwinds
|
||||
profiles = Fingering.woodwinds.map(p => ({
|
||||
name: p.name,
|
||||
fingering: JSON.parse(JSON.stringify(p.fingering)),
|
||||
format: p.format
|
||||
}))
|
||||
currentProfileIndex = 0
|
||||
|
||||
// 2. Reset global settings to defaults
|
||||
@ -257,7 +213,6 @@ MuseScore {
|
||||
|
||||
// 3. Update UI to reflect the new profile and settings
|
||||
userFormatString = getCurrentFormatString()
|
||||
formatInput.text = userFormatString
|
||||
profileCombo.currentIndex = 0
|
||||
fontSizeField.text = userFontSize
|
||||
fontFamilyField.text = userFontFamily
|
||||
@ -268,11 +223,6 @@ MuseScore {
|
||||
|
||||
|
||||
// 4. Persist all changes to Settings
|
||||
pluginSettings.storedProfiles = JSON.stringify(profiles.map(p => ({
|
||||
name: p.name,
|
||||
fingering: p.fingering,
|
||||
format: p.format
|
||||
})))
|
||||
pluginSettings.storedCurrentProfile = currentProfileIndex
|
||||
pluginSettings.storedFontSize = userFontSize
|
||||
pluginSettings.storedJustification = userJustification
|
||||
@ -283,7 +233,6 @@ MuseScore {
|
||||
pluginSettings.sync() // optional: force immediate write
|
||||
|
||||
getHistory().end()
|
||||
updatePreview()
|
||||
console.log("Reset to defaults")
|
||||
}
|
||||
|
||||
@ -429,7 +378,7 @@ MuseScore {
|
||||
const half_hor = "-"
|
||||
const open_split = "o"
|
||||
if (!binaryString || binaryString.length < 1)
|
||||
return "Invalid fingering pattern. Length is wrong"
|
||||
return "Invalid fingering pattern. Length is wrong. Check Fingering.js"
|
||||
|
||||
if (!format || typeof format !== "string")
|
||||
return "ERR"
|
||||
@ -446,7 +395,7 @@ MuseScore {
|
||||
binaryString[i] !== half_ver &&
|
||||
binaryString[i] !== half_hor &&
|
||||
binaryString[i] !== open_split)
|
||||
return "Invalid Fingering Pattern Value. Check the config in the .qml file!"
|
||||
return "Invalid Fingering Pattern Value. Check Fingering.js"
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -714,52 +663,12 @@ MuseScore {
|
||||
return notes[randomIndex]
|
||||
}
|
||||
|
||||
|
||||
function getPreviewText() {
|
||||
var dict = getCurrentFingeringDict()
|
||||
var firstNote = getRandomNoteName()
|
||||
if (dict[firstNote]) {
|
||||
return buildFingeringText(dict[firstNote], formatInput.text, firstNote)
|
||||
}
|
||||
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(){
|
||||
var baseFont = Qt.font({
|
||||
family: "WhistleSymbols",
|
||||
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
|
||||
var fallbacks = userFontFamily.split(',').map(f => f.trim())
|
||||
baseFont.families = ["WhistleSymbols"].concat(fallbacks)
|
||||
|
||||
|
||||
return baseFont
|
||||
}
|
||||
|
||||
|
||||
// Build the full font stack dynamically
|
||||
function getFontStack() {
|
||||
// return "WhistleSymbols" + ", " + userFontFamily;
|
||||
return userFontFamily
|
||||
}
|
||||
|
||||
|
||||
|
||||
function updatePreview() {
|
||||
//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")
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Setters with undo/redo
|
||||
//---------------------------------------------------------
|
||||
@ -770,12 +679,10 @@ MuseScore {
|
||||
function() {
|
||||
userFontSize = oldSize
|
||||
fontSizeField.text = oldSize
|
||||
previewLabel.font.pointSize = Math.max(1, oldSize + computePreviewOffset())
|
||||
},
|
||||
function() {
|
||||
userFontSize = size
|
||||
fontSizeField.text = size
|
||||
previewLabel.font.pointSize = Math.max(1, size + computePreviewOffset())
|
||||
},
|
||||
"font size"
|
||||
)
|
||||
@ -786,12 +693,10 @@ MuseScore {
|
||||
function() {
|
||||
userFontFamily = oldFamily
|
||||
fontFamilyField.text = oldFamily
|
||||
previewLabel.font = getPreviewFont()
|
||||
},
|
||||
function() {
|
||||
userFontFamily = family
|
||||
fontFamilyField.text = family
|
||||
previewLabel.font = getPreviewFont()
|
||||
},
|
||||
"font family"
|
||||
)
|
||||
@ -836,30 +741,6 @@ MuseScore {
|
||||
)
|
||||
}
|
||||
|
||||
function setUserFormatString(format) {
|
||||
var oldFormat = userFormatString
|
||||
var oldProfileFormat = getCurrentFormatString()
|
||||
getHistory().add(
|
||||
function() {
|
||||
// Undo: restore both userFormatString and the profile's format
|
||||
userFormatString = oldFormat
|
||||
formatInput.text = oldFormat
|
||||
if (profiles.length > 0) {
|
||||
profiles[currentProfileIndex].format = oldProfileFormat
|
||||
}
|
||||
},
|
||||
function() {
|
||||
// Redo: apply new format to both
|
||||
userFormatString = format
|
||||
formatInput.text = format
|
||||
if (profiles.length > 0) {
|
||||
profiles[currentProfileIndex].format = format
|
||||
}
|
||||
},
|
||||
"format string"
|
||||
)
|
||||
}
|
||||
|
||||
function setModified(state) {
|
||||
var oldModified = modified
|
||||
getHistory().add(
|
||||
@ -873,19 +754,10 @@ MuseScore {
|
||||
// Event handlers (call setters and save)
|
||||
//---------------------------------------------------------
|
||||
|
||||
function formatChanged(format) {
|
||||
getHistory().begin()
|
||||
setModified(true)
|
||||
setUserFormatString(format)
|
||||
getHistory().end()
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
function fontSizeChanged(size) {
|
||||
getHistory().begin()
|
||||
setModified(true)
|
||||
setUserFontSize(size)
|
||||
updatePreview()
|
||||
getHistory().end()
|
||||
saveSettings()
|
||||
}
|
||||
@ -894,7 +766,6 @@ MuseScore {
|
||||
getHistory().begin()
|
||||
setModified(true)
|
||||
setUserFontFamily(family)
|
||||
updatePreview()
|
||||
getHistory().end()
|
||||
saveSettings()
|
||||
}
|
||||
@ -904,7 +775,6 @@ MuseScore {
|
||||
getHistory().begin()
|
||||
setModified(true)
|
||||
setUserJustification(justification)
|
||||
updatePreview()
|
||||
getHistory().end()
|
||||
saveSettings()
|
||||
}
|
||||
@ -913,7 +783,6 @@ MuseScore {
|
||||
getHistory().begin()
|
||||
setModified(true)
|
||||
setUserOffsetY(offset)
|
||||
updatePreview()
|
||||
getHistory().end()
|
||||
saveSettings()
|
||||
}
|
||||
@ -922,7 +791,6 @@ MuseScore {
|
||||
getHistory().begin()
|
||||
setModified(true)
|
||||
setUserLineSpacing(spacing)
|
||||
updatePreview()
|
||||
getHistory().end()
|
||||
saveSettings()
|
||||
}
|
||||
@ -931,8 +799,6 @@ MuseScore {
|
||||
if (index < 0 || index >= profiles.length) return
|
||||
currentProfileIndex = index
|
||||
userFormatString = profiles[index].format
|
||||
formatInput.text = userFormatString
|
||||
updatePreview()
|
||||
saveSettings() // immediately save profile change
|
||||
}
|
||||
|
||||
@ -1074,13 +940,6 @@ MuseScore {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onTextChanged: {
|
||||
var newValue = parseInt(text)
|
||||
if (!isNaN(newValue) && newValue >= 1 && newValue <= 999) {
|
||||
previewLabel.font.pointSize = Math.max(1, newValue + computePreviewOffset())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
@ -1095,7 +954,6 @@ MuseScore {
|
||||
currentIndex: userJustification
|
||||
onActivated: {
|
||||
justificationChanged(index)
|
||||
updatePreview()
|
||||
}
|
||||
contentItem: Text {
|
||||
text: justCombo.displayText
|
||||
@ -1134,7 +992,6 @@ MuseScore {
|
||||
if (!isNaN(newValue) && newValue >= -999.0 && newValue <= 999.0) {
|
||||
if (newValue !== userOffsetY) {
|
||||
offsetYChanged(newValue)
|
||||
updatePreview()
|
||||
}
|
||||
} else {
|
||||
text = userOffsetY.toFixed(1)
|
||||
@ -1147,7 +1004,6 @@ MuseScore {
|
||||
if (!isNaN(newValue) && newValue >= -999.0 && newValue <= 999.0) {
|
||||
if (newValue !== userOffsetY) {
|
||||
offsetYChanged(newValue)
|
||||
updatePreview()
|
||||
}
|
||||
} else {
|
||||
text = userOffsetY.toFixed(1)
|
||||
@ -1209,7 +1065,6 @@ MuseScore {
|
||||
if (!isNaN(newValue) && newValue >= 0 && newValue <= 6) {
|
||||
if (newValue !== userLineSpacing) {
|
||||
lineSpacingChanged(newValue)
|
||||
updatePreview()
|
||||
}
|
||||
} else {
|
||||
text = userLineSpacing.toFixed(1)
|
||||
@ -1222,7 +1077,6 @@ MuseScore {
|
||||
if (!isNaN(newValue) && newValue >= 0 && newValue <= 999) {
|
||||
if (newValue !== userLineSpacing) {
|
||||
lineSpacingChanged(newValue)
|
||||
updatePreview()
|
||||
}
|
||||
} else {
|
||||
text = userLineSpacing.toFixed(1)
|
||||
@ -1303,130 +1157,6 @@ MuseScore {
|
||||
}
|
||||
}
|
||||
|
||||
// BOTTOM ROW - Format String and Preview
|
||||
GroupBox {
|
||||
title: "Format String & Preview"
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
background: Rectangle {
|
||||
color: backgroundColor
|
||||
border.color: textColor
|
||||
}
|
||||
label: Label {
|
||||
text: parent.title
|
||||
color: textColor
|
||||
background: Rectangle { color: backgroundColor }
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
width: parent.width
|
||||
spacing: 20
|
||||
anchors.margins: 10
|
||||
|
||||
// Format String Area (left side)
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
spacing: 5
|
||||
|
||||
Label {
|
||||
text: "Format String:"
|
||||
color: textColor
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredHeight: 200
|
||||
clip: true
|
||||
background: Rectangle {
|
||||
color: backgroundColor
|
||||
border.color: textColor
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: formatInput
|
||||
width: parent.width
|
||||
height: contentHeight
|
||||
wrapMode: TextEdit.Wrap
|
||||
text: userFormatString
|
||||
color: sysPal.text
|
||||
selectionColor: sysPal.highlight
|
||||
selectedTextColor: sysPal.highlightedText
|
||||
background: Rectangle {
|
||||
color: backgroundColor
|
||||
border.color: textColor
|
||||
}
|
||||
property var previousText: userFormatString
|
||||
onEditingFinished: {
|
||||
formatChanged(formatInput.text)
|
||||
updatePreview()
|
||||
}
|
||||
onTextChanged: {
|
||||
updatePreview()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "Use placeholders like $1, $2, ..., for the holes and $note for the note (e.g. G#5)"
|
||||
font.pixelSize: 10
|
||||
color: textColor
|
||||
}
|
||||
}
|
||||
|
||||
// Preview Area (right side)
|
||||
GroupBox {
|
||||
title: "Preview (@100%)"
|
||||
Layout.preferredWidth: 120
|
||||
Layout.fillHeight: true
|
||||
background: Rectangle {
|
||||
color: backgroundColor
|
||||
border.color: textColor
|
||||
}
|
||||
label: Label {
|
||||
text: parent.title
|
||||
color: textColor
|
||||
background: Rectangle { color: backgroundColor }
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 5
|
||||
clip: true
|
||||
background: Rectangle {
|
||||
color: backgroundColor
|
||||
border.color: textColor
|
||||
}
|
||||
|
||||
Label {
|
||||
id: previewLabel
|
||||
text: getPreviewText()
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.delay: 1000
|
||||
ToolTip.text: "Due to a limitation, the preview font does not reflect the selected font"
|
||||
//font.family: getFontStack()
|
||||
//font.pointSize: userFontSize
|
||||
color: textColor
|
||||
wrapMode: Text.NoWrap
|
||||
width: parent.width
|
||||
lineHeight: userLineSpacing
|
||||
lineHeightMode: Text.ProportionalHeight
|
||||
font: getPreviewFont()
|
||||
|
||||
// Dynamic alignment based on userJustification
|
||||
horizontalAlignment: {
|
||||
if (userJustification === 0) return Text.AlignLeft
|
||||
if (userJustification === 1) return Text.AlignHCenter
|
||||
return Text.AlignRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BOTTOM BUTTONS - Apply and Cancel
|
||||
RowLayout {
|
||||
Layout.columnSpan: 2
|
||||
@ -1519,7 +1249,7 @@ MuseScore {
|
||||
MessageDialog {
|
||||
id: resetDialog
|
||||
title: "Confirm"
|
||||
text: "This will refresh and reset all text configurations, woodwind dictionaries and format strings. Continue?"
|
||||
text: "This will refresh and reset all text configurations. Continue?"
|
||||
standardButtons: [StandardButton.Ok, StandardButton.Cancel]
|
||||
onAccepted: {
|
||||
resetToDefaults()
|
||||
|
||||
Reference in New Issue
Block a user