Widgets Drag&Drop: fix for panel closing when clicking rapidly in the background of a widget.

This commit is contained in:
LemmyCook 2025-09-10 09:33:08 -04:00
parent 0a4317f712
commit 3f388bdb4b
2 changed files with 26 additions and 17 deletions

View file

@ -18,9 +18,11 @@ NBox {
signal removeWidget(string section, int index) signal removeWidget(string section, int index)
signal reorderWidget(string section, int fromIndex, int toIndex) signal reorderWidget(string section, int fromIndex, int toIndex)
signal updateWidgetSettings(string section, int index, var settings) signal updateWidgetSettings(string section, int index, var settings)
signal dragStarted signal dragPotentialStarted
signal dragEnded // Emitted when a widget is pressed (potential drag start)
signal dragPotentialEnded
// Emitted when interaction ends (drag or click)
color: Color.mSurface color: Color.mSurface
Layout.fillWidth: true Layout.fillWidth: true
Layout.minimumHeight: { Layout.minimumHeight: {
@ -308,6 +310,7 @@ NBox {
property point startPos: Qt.point(0, 0) property point startPos: Qt.point(0, 0)
property bool dragStarted: false property bool dragStarted: false
property bool potentialDrag: false // Track if we're in a potential drag interaction
property int draggedIndex: -1 property int draggedIndex: -1
property real dragThreshold: 15 * scaling property real dragThreshold: 15 * scaling
property Item draggedWidget: null property Item draggedWidget: null
@ -406,6 +409,7 @@ NBox {
onPressed: mouse => { onPressed: mouse => {
startPos = Qt.point(mouse.x, mouse.y) startPos = Qt.point(mouse.x, mouse.y)
dragStarted = false dragStarted = false
potentialDrag = false
draggedIndex = -1 draggedIndex = -1
draggedWidget = null draggedWidget = null
dropTargetIndex = -1 dropTargetIndex = -1
@ -422,12 +426,18 @@ NBox {
const buttonsStartX = widget.width - (widget.buttonsCount * widget.buttonsWidth) const buttonsStartX = widget.width - (widget.buttonsCount * widget.buttonsWidth)
if (localX < buttonsStartX) { if (localX < buttonsStartX) {
// This is a draggable area - prevent panel close immediately
draggedIndex = widget.widgetIndex draggedIndex = widget.widgetIndex
draggedWidget = widget draggedWidget = widget
draggedModelData = widget.modelData draggedModelData = widget.modelData
potentialDrag = true
preventStealing = true preventStealing = true
// Signal that interaction started (prevents panel close)
root.dragPotentialStarted()
break break
} else { } else {
// This is a button area - let the click through
mouse.accepted = false mouse.accepted = false
return return
} }
@ -437,7 +447,7 @@ NBox {
} }
onPositionChanged: mouse => { onPositionChanged: mouse => {
if (draggedIndex !== -1) { if (draggedIndex !== -1 && potentialDrag) {
const deltaX = mouse.x - startPos.x const deltaX = mouse.x - startPos.x
const deltaY = mouse.y - startPos.y const deltaY = mouse.y - startPos.y
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY) const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY)
@ -445,9 +455,6 @@ NBox {
if (!dragStarted && distance > dragThreshold) { if (!dragStarted && distance > dragThreshold) {
dragStarted = true dragStarted = true
// Emit signal when drag starts
root.dragStarted()
// Setup ghost widget // Setup ghost widget
if (draggedWidget) { if (draggedWidget) {
dragGhost.width = draggedWidget.width dragGhost.width = draggedWidget.width
@ -473,13 +480,14 @@ NBox {
reorderWidget(sectionId, draggedIndex, dropTargetIndex) reorderWidget(sectionId, draggedIndex, dropTargetIndex)
} }
// Emit signal when drag ends (only if it was actually started) // Always signal end of interaction if we started one
if (dragStarted) { if (potentialDrag) {
root.dragEnded() root.dragPotentialEnded()
} }
// Reset everything // Reset everything
dragStarted = false dragStarted = false
potentialDrag = false
draggedIndex = -1 draggedIndex = -1
draggedWidget = null draggedWidget = null
dropTargetIndex = -1 dropTargetIndex = -1
@ -500,12 +508,13 @@ NBox {
onCanceled: { onCanceled: {
// Handle cancel (e.g., ESC key pressed during drag) // Handle cancel (e.g., ESC key pressed during drag)
if (dragStarted) { if (potentialDrag) {
root.dragEnded() root.dragPotentialEnded()
} }
// Reset everything // Reset everything
dragStarted = false dragStarted = false
potentialDrag = false
draggedIndex = -1 draggedIndex = -1
draggedWidget = null draggedWidget = null
dropTargetIndex = -1 dropTargetIndex = -1

View file

@ -132,8 +132,8 @@ ColumnLayout {
onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index) onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index)
onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex) onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex)
onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings) onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings)
onDragStarted: root.handleDragStart() onDragPotentialStarted: root.handleDragStart()
onDragEnded: root.handleDragEnd() onDragPotentialEnded: root.handleDragEnd()
} }
// Center Section // Center Section
@ -146,8 +146,8 @@ ColumnLayout {
onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index) onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index)
onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex) onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex)
onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings) onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings)
onDragStarted: root.handleDragStart() onDragPotentialStarted: root.handleDragStart()
onDragEnded: root.handleDragEnd() onDragPotentialEnded: root.handleDragEnd()
} }
// Right Section // Right Section
@ -160,8 +160,8 @@ ColumnLayout {
onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index) onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index)
onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex) onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex)
onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings) onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings)
onDragStarted: root.handleDragStart() onDragPotentialStarted: root.handleDragStart()
onDragEnded: root.handleDragEnd() onDragPotentialEnded: root.handleDragEnd()
} }
} }
} }