Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Percussion panel - implement keyboard swapping #25565

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ FocusScope {
property real backgroundRadius: 3

property bool drawFocusBorderInsideRect: false
property bool disableFocusBorder: false

property int orientation: Qt.Vertical
readonly property bool isVertical: root.orientation === Qt.Vertical
Expand Down Expand Up @@ -149,7 +150,7 @@ FocusScope {
border.color: ui.theme.strokeColor

NavigationFocusBorder {
navigationCtrl: navCtrl
navigationCtrl: disableFocusBorder ? null : navCtrl
drawOutsideParent: !root.drawFocusBorderInsideRect
}

Expand Down
160 changes: 135 additions & 25 deletions src/notation/qml/MuseScore/NotationScene/PercussionPanel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ Item {
Component.onCompleted: {
percModel.init()
}

onCurrentPanelModeChanged: {
// TODO: This is a placeholder, changing the panel mode shouldn't cancel a keyboard swap
if (padGrid.isKeyboardSwapActive) {
padGrid.swapOriginPad = null
padGrid.isKeyboardSwapActive = false
padGrid.model.endPadSwap(-1)
}
}
}

// TODO: Will live inside percussion panel until #22050 is implemented
Expand All @@ -69,8 +78,8 @@ Item {
width: parent.width
height: 36

navigation.section: root.navigationSection
navigation.order: root.contentNavigationPanelOrderStart
navigationSection: root.navigationSection
navigationOrderStart: root.contentNavigationPanelOrderStart

model: percModel

Expand Down Expand Up @@ -103,6 +112,16 @@ Item {
height: padGrid.cellHeight * padGrid.numRows
spacing: padGrid.spacing / 2

NavigationPanel {
id: deleteButtonsPanel

name: "PercussionPanelDeleteRowButtons"
section: root.navigationSection
order: toolbar.navigationOrderEnd + 3

enabled: deleteButtonsColumn.visible
}

Column {
id: deleteButtonsColumn

Expand All @@ -112,6 +131,7 @@ Item {
width: rowLayout.sideColumnsWidth

visible: percModel.currentPanelMode === PanelMode.EDIT_LAYOUT
enabled: !padGrid.isKeyboardSwapActive

Repeater {
id: deleteRepeater
Expand All @@ -135,6 +155,9 @@ Item {
icon: IconCode.DELETE_TANK
backgroundRadius: deleteButton.width / 2

navigation.panel: deleteButtonsPanel
navigation.row: model.index

onClicked: {
padGrid.model.deleteRow(model.index)
}
Expand All @@ -161,7 +184,16 @@ Item {
readonly property int numColumns: model.numColumns
readonly property int spacing: 12

property Item draggedPad: null
property Item swapOriginPad: null
property bool isKeyboardSwapActive: false

QtObject {
id: gridPrv

// This variable ensures we stay within a given pad when tabbing back-and-forth between
// "main" and "footer" controls
property var currentPadNavigationIndex: [0, 0]
}

Layout.alignment: Qt.AlignTop
Layout.fillHeight: true
Expand All @@ -175,6 +207,36 @@ Item {

model: percModel.padListModel

NavigationPanel {
id: padsNavPanel

name: "PercussionPanelPads"
section: root.navigationSection
order: toolbar.navigationOrderEnd + 1

onNavigationEvent: function(event) {
if (event.type === NavigationEvent.AboutActive) {
event.setData("controlIndex", gridPrv.currentPadNavigationIndex)
}
}
}

NavigationPanel {
id: padFootersNavPanel

name: "PercussionPanelFooters"
section: root.navigationSection
order: toolbar.navigationOrderEnd + 2

enabled: percModel.currentPanelMode !== PanelMode.EDIT_LAYOUT

onNavigationEvent: function(event) {
if (event.type === NavigationEvent.AboutActive) {
event.setData("controlIndex", gridPrv.currentPadNavigationIndex)
}
}
}

delegate: Item {
id: padArea

Expand All @@ -193,54 +255,98 @@ Item {
panelMode: percModel.currentPanelMode
useNotationPreview: percModel.useNotationPreview

// When dragging, only show the outline for the dragged pad and the drag target...
// When swapping, only show the outline for the swap origin and the swap target...
showEditOutline: percModel.currentPanelMode === PanelMode.EDIT_LAYOUT
&& (!Boolean(padGrid.draggedPad) || padGrid.draggedPad === pad || pad.containsDrag)
showOriginBackground: pad.containsDrag || pad === padGrid.draggedPad
&& (!Boolean(padGrid.swapOriginPad) || padGrid.swapOriginPad === pad)
showOriginBackground: pad.containsDrag || (pad === padGrid.swapOriginPad && !padGrid.isKeyboardSwapActive)

panelHasActiveKeyboardSwap: padGrid.isKeyboardSwapActive
dragParent: root

onDragStarted: {
padGrid.draggedPad = pad
padGrid.model.startDrag(index)
navigationRow: index / padGrid.numColumns
navigationColumn: index % padGrid.numColumns
padNavigationCtrl.panel: padsNavPanel
footerNavigationCtrl.panel: padFootersNavPanel

onStartPadSwapRequested: function(isKeyboardSwap) {
padGrid.swapOriginPad = pad
padGrid.isKeyboardSwapActive = isKeyboardSwap
padGrid.model.startPadSwap(index)
}

onDropped: function(dropEvent) {
padGrid.draggedPad = null
padGrid.model.endDrag(index)
dropEvent.accepted = true
onEndPadSwapRequested: {
padGrid.swapOriginPad = null
padGrid.isKeyboardSwapActive = false
padGrid.model.endPadSwap(index)
}

onDragCancelled: {
padGrid.draggedPad = null
padGrid.model.endDrag(-1)
onCancelPadSwapRequested: {
padGrid.swapOriginPad = null
padGrid.isKeyboardSwapActive = false
padGrid.model.endPadSwap(-1)
}

onHasActiveControlChanged: {
if (!pad.hasActiveControl) {
return;
}
gridPrv.currentPadNavigationIndex = [pad.navigationRow, pad.navigationColumn]
}
}

states: [
// If this is the drop target - move the draggable area to the origin of the dragged pad (preview the drop)
// If this is the swap target - move the swappable area to the swap origin (preview the swap)
State {
name: "DROP_TARGET"
when: Boolean(padGrid.draggedPad) && pad.containsDrag && padGrid.draggedPad !== pad
name: "SWAP_TARGET"
when: Boolean(padGrid.swapOriginPad) && (pad.containsDrag || pad.padNavigationCtrl.active) && padGrid.swapOriginPad !== pad

ParentChange {
target: pad.draggableArea
parent: padGrid.draggedPad
target: pad.swappableArea
parent: padGrid.swapOriginPad
}
AnchorChanges {
target: pad.draggableArea
anchors.verticalCenter: padGrid.draggedPad.verticalCenter
anchors.horizontalCenter: padGrid.draggedPad.horizontalCenter
target: pad.swappableArea
anchors.verticalCenter: padGrid.swapOriginPad.verticalCenter
anchors.horizontalCenter: padGrid.swapOriginPad.horizontalCenter
}
PropertyChanges {
target: pad
showEditOutline: true
}

// Origin background not needed for the dragged pad when a preview is taking place...
PropertyChanges {
target: padGrid.draggedPad
target: padGrid.swapOriginPad
showOriginBackground: false
}

// In the case of a keyboard swap, we also need to move the origin pad
ParentChange {
// TODO: not a nice solution to use null here (works, but throws an error)
target: padGrid.isKeyboardSwapActive ? padGrid.swapOriginPad.swappableArea : null
parent: pad
}
AnchorChanges {
// TODO: not a nice solution to use null here (works, but throws an error)
target: padGrid.isKeyboardSwapActive ? padGrid.swapOriginPad.swappableArea : null
anchors.verticalCenter: pad.verticalCenter
anchors.horizontalCenter: pad.horizontalCenter
}
}
]
}
}

NavigationPanel {
id: addRowButtonPanel

name: "PercussionPanelAddRowButton"
section: root.navigationSection
order: toolbar.navigationOrderEnd + 4

enabled: addRowButton.visible
}

FlatButton {
id: addRowButton

Expand All @@ -249,10 +355,14 @@ Item {
Layout.bottomMargin: (padGrid.cellHeight / 2) - (height / 2)

visible: percModel.currentPanelMode === PanelMode.EDIT_LAYOUT
enabled: !padGrid.isKeyboardSwapActive

icon: IconCode.PLUS
text: qsTrc("notation", "Add row")
orientation: Qt.Horizontal

navigation.panel: addRowButtonPanel

onClicked: {
padGrid.model.addRow()
flickable.goToBottom()
Expand Down
Loading