From c7e057b7273679537454b7405fe8a828fbe3fe61 Mon Sep 17 00:00:00 2001 From: Amras Date: Sat, 16 May 2026 15:47:23 +0200 Subject: [PATCH] [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 --- .../woodwind_tab_generator.qml | 344 ++---------------- 1 file changed, 37 insertions(+), 307 deletions(-) diff --git a/woodwind_tab_generator/woodwind_tab_generator.qml b/woodwind_tab_generator/woodwind_tab_generator.qml index ca7f680..c8b7742 100644 --- a/woodwind_tab_generator/woodwind_tab_generator.qml +++ b/woodwind_tab_generator/woodwind_tab_generator.qml @@ -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,51 +168,30 @@ 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 - })) - } + 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 if (currentProfileIndex < 0 || currentProfileIndex >= profiles.length) currentProfileIndex = 0 - // Load global settings (fall back to defaults if stored value is undefined) - userFontSize = pluginSettings.storedFontSize ?? defaultFontSize - userJustification = pluginSettings.storedJustification ?? defaultJustification - userOffsetY = pluginSettings.storedOffsetY ?? defaultOffsetY - userLineSpacing = pluginSettings.storedLineSpacing ?? defaultLineSpacing - userFontFamily = pluginSettings.storedFontFamily ?? defaultFontFamily - userTransposed = pluginSettings.storedTransposed ?? defaultTransposed + // Load global settings (fall back to defaults if stored value is undefined) + userFontSize = pluginSettings.storedFontSize ?? defaultFontSize + userJustification = pluginSettings.storedJustification ?? defaultJustification + userOffsetY = pluginSettings.storedOffsetY ?? defaultOffsetY + userLineSpacing = pluginSettings.storedLineSpacing ?? defaultLineSpacing + userFontFamily = pluginSettings.storedFontFamily ?? defaultFontFamily + userTransposed = pluginSettings.storedTransposed ?? defaultTransposed - if (typeof fontFamilyField !== 'undefined') { - fontFamilyField.text = userFontFamily - } + if (typeof fontFamilyField !== 'undefined') { + fontFamilyField.text = userFontFamily + } - console.log("Settings loaded") + console.log("Settings loaded") } //--------------------------------------------------------- // Reset to defaults @@ -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,34 +213,27 @@ 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 - offsetField.text = userOffsetY.toFixed(1) - spacingField.text = userLineSpacing.toFixed(1) - justCombo.currentIndex = userJustification - transposedCheck.checked = userTransposed + profileCombo.currentIndex = 0 + fontSizeField.text = userFontSize + fontFamilyField.text = userFontFamily + offsetField.text = userOffsetY.toFixed(1) + spacingField.text = userLineSpacing.toFixed(1) + justCombo.currentIndex = userJustification + transposedCheck.checked = userTransposed - // 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 - pluginSettings.storedOffsetY = userOffsetY - pluginSettings.storedLineSpacing = userLineSpacing - pluginSettings.storedFontFamily = userFontFamily - pluginSettings.storedTransposed = userTransposed - pluginSettings.sync() // optional: force immediate write + // 4. Persist all changes to Settings + pluginSettings.storedCurrentProfile = currentProfileIndex + pluginSettings.storedFontSize = userFontSize + pluginSettings.storedJustification = userJustification + pluginSettings.storedOffsetY = userOffsetY + pluginSettings.storedLineSpacing = userLineSpacing + pluginSettings.storedFontFamily = userFontFamily + pluginSettings.storedTransposed = userTransposed + pluginSettings.sync() // optional: force immediate write - getHistory().end() - updatePreview() - console.log("Reset to defaults") + getHistory().end() + 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()