Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b395d31
added input by duration mode + cleanup
RomanPudashkin Jan 9, 2025
3df6991
got rid of note input mode menu
RomanPudashkin Jan 10, 2025
df1462a
fix #20891
RomanPudashkin Jan 10, 2025
be8704d
renamed "step-time" mode to "input by note name"
RomanPudashkin Jan 10, 2025
4fe2361
removed redundant / unused methods
RomanPudashkin Jan 14, 2025
9335769
optimization
RomanPudashkin Jan 15, 2025
8c66759
input by duration: draw input preview
RomanPudashkin Jan 10, 2025
874a04b
input by duration: store active pitches to input them later
RomanPudashkin Jan 14, 2025
12528f3
changes to MIDI sound preview
RomanPudashkin Jan 16, 2025
f82c38e
change default note input mode via Preferences
RomanPudashkin Jan 16, 2025
8d90561
move pitch up/down using arrow keys
RomanPudashkin Jan 17, 2025
3e4407d
input by duration: implemented sound preview
RomanPudashkin Jan 21, 2025
7975185
updated icons font
RomanPudashkin Jan 22, 2025
ca90dbb
added NotationRuler
RomanPudashkin Jan 20, 2025
2642a20
Preferences / Note input rework
RomanPudashkin Jan 21, 2025
ffe65fb
added the ability to override the note input preview color
RomanPudashkin Jan 22, 2025
43ea474
input by duration: fixed accidentals input
RomanPudashkin Jan 24, 2025
19e18f4
input by duration: don't play preview notes by default
RomanPudashkin Jan 27, 2025
ce1c21f
option to add accidental, dots, artculations to previous note entered
RomanPudashkin Jan 27, 2025
93dd923
input by duration: fixed input on transposing instruments
RomanPudashkin Jan 29, 2025
901be37
input by duration: added option to enable note input cursor
RomanPudashkin Jan 29, 2025
b9ee01b
input by duration: always add notes to current chord
RomanPudashkin Jan 30, 2025
2a17312
input by duration: update input note when switching to another staff
RomanPudashkin Jan 30, 2025
7972242
fixed crash when starting input at MM Rest
RomanPudashkin Jan 30, 2025
f88a7c2
input by duration: percussions support + reduced code duplication
RomanPudashkin Jan 30, 2025
fdfcdf8
input by duration: added to tours
RomanPudashkin Jan 31, 2025
f3dde11
input by duration: fallback to input by note name on TAB staves
RomanPudashkin Feb 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/app/configs/data/shortcuts.xml
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,15 @@
<seq>I</seq>
</SC>
<SC>
<key>note-input</key>
<key>note-input-by-note-name</key>
<seq>N</seq>
<autorepeat>0</autorepeat>
</SC>
<SC>
<key>note-input-by-duration</key>
<seq>M</seq>
<autorepeat>0</autorepeat>
</SC>
<SC>
<key>note-input-repitch</key>
<seq>Ctrl+Shift+I</seq>
Expand Down
7 changes: 6 additions & 1 deletion src/app/configs/data/shortcuts_azerty.xml
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,15 @@
<seq>I</seq>
</SC>
<SC>
<key>note-input</key>
<key>note-input-by-note-name</key>
<seq>N</seq>
<autorepeat>0</autorepeat>
</SC>
<SC>
<key>note-input-by-duration</key>
<seq>M</seq>
<autorepeat>0</autorepeat>
</SC>
<SC>
<key>note-input-repitch</key>
<seq>Ctrl+Shift+I</seq>
Expand Down
7 changes: 6 additions & 1 deletion src/app/configs/data/shortcuts_mac.xml
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,15 @@
<seq>I</seq>
</SC>
<SC>
<key>note-input</key>
<key>note-input-by-note-name</key>
<seq>N</seq>
<autorepeat>0</autorepeat>
</SC>
<SC>
<key>note-input-by-duration</key>
<seq>M</seq>
<autorepeat>0</autorepeat>
</SC>
<SC>
<key>note-input-repitch</key>
<seq>Ctrl+Shift+I</seq>
Expand Down
8 changes: 6 additions & 2 deletions src/appshell/appshell.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
<file>qml/platform/mac/Main.qml</file>
<file>qml/platform/win/Main.qml</file>
<file>resources/win_opengl_buglist.json</file>
<file>resources/tours.json</file>
<file>qml/Preferences/internal/BaseSection.qml</file>
<file>qml/Preferences/internal/LanguagesSection.qml</file>
<file>qml/Preferences/internal/AutoSaveSection.qml</file>
Expand All @@ -83,8 +84,11 @@
<file>qml/Preferences/internal/AdvancedTopSection.qml</file>
<file>qml/Preferences/internal/ZoomSection.qml</file>
<file>qml/Preferences/internal/ScrollPagesSection.qml</file>
<file>qml/Preferences/internal/NoteInputSection.qml</file>
<file>qml/Preferences/internal/NoteInputPlaySection.qml</file>
<file>qml/Preferences/internal/NoteInput/NoteInputSection.qml</file>
<file>qml/Preferences/internal/NoteInput/MidiInputSection.qml</file>
<file>qml/Preferences/internal/NoteInput/NotePreviewSection.qml</file>
<file>qml/Preferences/internal/NoteInput/VoiceAssignmentSection.qml</file>
<file>qml/Preferences/internal/NoteInput/NoteColorsSection.qml</file>
<file>qml/Preferences/internal/DefaultFilesSection.qml</file>
<file>qml/Preferences/internal/AutomaticUpdateSection.qml</file>
<file>qml/platform/win/AppTitleBar.qml</file>
Expand Down
97 changes: 62 additions & 35 deletions src/appshell/qml/Preferences/NoteInputPreferencesPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import Muse.Ui 1.0
import Muse.UiComponents 1.0
import MuseScore.Preferences 1.0

import "internal"
import "internal/NoteInput"

PreferencesPage {
id: root
Expand All @@ -43,24 +43,48 @@ PreferencesPage {
spacing: root.sectionsSpacing

NoteInputSection {
noteInputMethods: noteInputModel.noteInputMethods()
defaultNoteInputMethod: noteInputModel.defaultNoteInputMethod
addAccidentalDotsArticulationsToNextNoteEntered: noteInputModel.addAccidentalDotsArticulationsToNextNoteEntered
useNoteInputCursorInInputByDuration: noteInputModel.useNoteInputCursorInInputByDuration

navigation.section: root.navigationSection
navigation.order: root.navigationOrderStart + 1

onDefaultNoteInputMethodChangeRequested: function(method) {
noteInputModel.defaultNoteInputMethod = method
}

onAddAccidentalDotsArticulationsToNextNoteEnteredChangeRequested: function(add) {
noteInputModel.addAccidentalDotsArticulationsToNextNoteEntered = add
}

onUseNoteInputCursorInInputByDurationChangeRequested: function(use) {
noteInputModel.useNoteInputCursorInInputByDuration = use
}
}

SeparatorLine {}

MidiInputSection {
midiInputEnabled: noteInputModel.midiInputEnabled
startNoteInputWhenPressingKey: noteInputModel.startNoteInputAtSelectionWhenPressingMidiKey
advanceToNextNote: noteInputModel.advanceToNextNoteOnKeyRelease
colorNotes: noteInputModel.colorNotesOutsideOfUsablePitchRange
warnGuitarBends: noteInputModel.warnGuitarBends
delayBetweenNotes: noteInputModel.delayBetweenNotesInRealTimeModeMilliseconds

navigation.section: root.navigationSection
navigation.order: root.navigationOrderStart + 1
navigation.order: root.navigationOrderStart + 2

onAdvanceToNextNoteChangeRequested: function(advance) {
noteInputModel.advanceToNextNoteOnKeyRelease = advance
onMidiInputEnabledChangeRequested: function(enabled) {
noteInputModel.midiInputEnabled = enabled
}

onColorNotesChangeRequested: function(color) {
noteInputModel.colorNotesOutsideOfUsablePitchRange = color
onStartNoteInputWhenPressingKeyChangeRequested: function(start) {
noteInputModel.startNoteInputAtSelectionWhenPressingMidiKey = start
}

onWarnGuitarBendsChangeRequested: function(warn) {
noteInputModel.warnGuitarBends = warn
onAdvanceToNextNoteChangeRequested: function(advance) {
noteInputModel.advanceToNextNoteOnKeyRelease = advance
}

onDelayBetweenNotesChangeRequested: function(delay) {
Expand All @@ -70,19 +94,24 @@ PreferencesPage {

SeparatorLine {}

NoteInputPlaySection {
NotePreviewSection {
playNotesWhenEditing: noteInputModel.playNotesWhenEditing
playChordWhenEditing: noteInputModel.playChordWhenEditing
playPreviewNotesInInputByDuration: noteInputModel.playPreviewNotesInInputByDuration
playChordSymbolWhenEditing: noteInputModel.playChordSymbolWhenEditing
notePlayDurationMilliseconds: noteInputModel.notePlayDurationMilliseconds

navigation.section: root.navigationSection
navigation.order: root.navigationOrderStart + 2
navigation.order: root.navigationOrderStart + 3

onPlayNotesWhenEditingChangeRequested: function(play) {
noteInputModel.playNotesWhenEditing = play
}

onPlayPreviewNotesInInputByDurationChangeRequested: function(play) {
noteInputModel.playPreviewNotesInInputByDuration = play
}

onPlayChordWhenEditingChangeRequested: function(play) {
noteInputModel.playChordWhenEditing = play
}
Expand All @@ -98,40 +127,38 @@ PreferencesPage {

SeparatorLine {}

BaseSection {
id: dynamicsAllVoicesSection

VoiceAssignmentSection {
width: parent.width

title: qsTrc("appshell/preferences", "Voice assignment")
navigation.section: root.navigationSection
navigation.order: root.navigationOrderStart + 4

dynamicsApplyToAllVoices: noteInputModel.dynamicsApplyToAllVoices

StyledTextLabel {
width: parent.width
text: qsTrc("appshell/preferences", "When entered, dynamics and hairpins should affect:")
horizontalAlignment: Text.AlignLeft
onDynamicsApplyToAllVoicesChangeRequested: function(value) {
noteInputModel.dynamicsApplyToAllVoices = value
}
}

RoundedRadioButton {
width: parent.width
SeparatorLine {}

text: qsTrc("appshell/preferences", "All voices on the instrument")
NoteColorsSection {
width: parent.width

checked: noteInputModel.dynamicsApplyToAllVoices
onToggled: {
noteInputModel.dynamicsApplyToAllVoices = checked
}
}
colorNotes: noteInputModel.colorNotesOutsideOfUsablePitchRange
warnGuitarBends: noteInputModel.warnGuitarBends

RoundedRadioButton {
width: parent.width
navigation.section: root.navigationSection
navigation.order: root.navigationOrderStart + 5

text: qsTrc("appshell/preferences", "Only the voice they are applied to")
onColorNotesChangeRequested: function(color) {
noteInputModel.colorNotesOutsideOfUsablePitchRange = color
}

checked: !noteInputModel.dynamicsApplyToAllVoices
onToggled: {
noteInputModel.dynamicsApplyToAllVoices = !checked
}
onWarnGuitarBendsChangeRequested: function(warn) {
noteInputModel.warnGuitarBends = warn
}

}
}
}
142 changes: 142 additions & 0 deletions src/appshell/qml/Preferences/internal/NoteInput/MidiInputSection.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-Studio-CLA-applies
*
* MuseScore Studio
* Music Composition & Notation
*
* Copyright (C) 2025 MuseScore Limited
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* 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 <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15

import Muse.Ui 1.0
import Muse.UiComponents 1.0

import "../../internal"

BaseSection {
id: root

title: qsTrc("appshell/preferences", "MIDI devices")

property alias midiInputEnabled: enableMidiInputToggle.checked
property alias startNoteInputWhenPressingKey: startNoteInputWhenPressingKeyBox.checked
property bool advanceToNextNote: false
property int delayBetweenNotes: 0

signal midiInputEnabledChangeRequested(bool enabled)
signal startNoteInputWhenPressingKeyChangeRequested(bool start)
signal advanceToNextNoteChangeRequested(bool advance)
signal delayBetweenNotesChangeRequested(int delay)

Row {
width: parent.width
height: enableMidiInputToggle.height

spacing: 6

ToggleButton {
id: enableMidiInputToggle

navigation.name: "EnableMidiInputToggle"
navigation.panel: root.navigation
navigation.row: 0

onToggled: {
root.midiInputEnabledChangeRequested(!checked)
}
}

StyledTextLabel {
height: parent.height

horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter

text: qsTrc("appshell/preferences", "Enable MIDI input")
}
}

CheckBox {
id: startNoteInputWhenPressingKeyBox
width: parent.width

enabled: root.midiInputEnabled
text: qsTrc("appshell/preferences", "When pressing a key, begin note input at the selected measure, note, or rest")

navigation.name: "StartNoteInputWhenPressingKeyBox"
navigation.panel: root.navigation
navigation.row: 1

onClicked: {
root.startNoteInputWhenPressingKeyChangeRequested(!checked)
}
}

ExpandableBlank {
width: parent.width

enabled: root.midiInputEnabled
title: qsTrc("appshell/preferences", "Real-time input modes")
isExpanded: false

contentItemComponent: Column {
width: parent.width

spacing: root.spacing

CheckBox {
id: advanceToNextNoteBox
width: parent.width

enabled: root.midiInputEnabled
text: qsTrc("appshell/preferences", "Advance to next note on key release")

checked: root.advanceToNextNote

navigation.name: "AdvanceToNextNoteBox"
navigation.panel: root.navigation
navigation.row: 2

onClicked: {
root.advanceToNextNoteChangeRequested(!checked)
}
}

IncrementalPropertyControlWithTitle {
id: delayBetweenNotesControl

enabled: root.midiInputEnabled
title: qsTrc("appshell/preferences", "Delay between notes")

currentValue: root.delayBetweenNotes

columnWidth: root.columnWidth
spacing: root.columnSpacing

measureUnitsSymbol: qsTrc("global", "ms")

navigation.name: "DelayBetweenNotesControl"
navigation.panel: root.navigation
navigation.row: 3

onValueEdited: function(newValue) {
root.delayBetweenNotesChangeRequested(newValue)
}
}
}
}
}
Loading