Fix gallery navigation: arrow keys, cursor stuck past ChoiceButton, scroll bounce
This commit is contained in:
@@ -20,15 +20,16 @@ import QtQuick
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// Keys.priority: Keys.AfterItem means a focused descendant (e.g. a
|
// Keys.priority: Keys.BeforeItem means this handler gets keys first,
|
||||||
// TextField inside an inline password prompt) gets the event first. Only
|
// even when a descendant has activeFocus. That's what lets Up/Down
|
||||||
// events the focused subtree ignores reach this handler — that's what
|
// arrows drive the cursor instead of being consumed by an inner
|
||||||
// lets j/k/Esc keep working in the panel while an input field consumes
|
// Flickable's built-in scroll handling. When a panel has an inline
|
||||||
// typing.
|
// editor (wifi passphrase, gallery TextField demo) the panel must
|
||||||
|
// set `blocked: editor.activeFocus` so this handler short-circuits
|
||||||
|
// and the editor receives keys normally.
|
||||||
//
|
//
|
||||||
// blocked: when true, ALL keys are forwarded to descendants without
|
// blocked: when true, ALL keys are forwarded to descendants without
|
||||||
// triggering signals. Useful when an inline editor is open and the
|
// triggering signals.
|
||||||
// caller wants the cursor model frozen.
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ Item {
|
|||||||
signal textKey(string text)
|
signal textKey(string text)
|
||||||
|
|
||||||
focus: true
|
focus: true
|
||||||
Keys.priority: Keys.AfterItem
|
Keys.priority: Keys.BeforeItem
|
||||||
Keys.onPressed: function(event) {
|
Keys.onPressed: function(event) {
|
||||||
if (blocked) return
|
if (blocked) return
|
||||||
|
|
||||||
|
|||||||
@@ -232,22 +232,17 @@ Item {
|
|||||||
// hasCursor change handler of every cursor target below.
|
// hasCursor change handler of every cursor target below.
|
||||||
function ensureCursorVisible(item) {
|
function ensureCursorVisible(item) {
|
||||||
if (!item || !scrollArea) return
|
if (!item || !scrollArea) return
|
||||||
var sb = scrollArea.ScrollBar.vertical
|
var flick = scrollArea.contentItem
|
||||||
if (!sb || scrollArea.contentHeight <= scrollArea.height) return
|
if (!flick || flick.contentY === undefined) return
|
||||||
var contentItem = scrollArea.contentItem
|
var pt = item.mapToItem(flick.contentItem || flick, 0, 0)
|
||||||
if (!contentItem) return
|
var top = pt.y
|
||||||
var p = item.mapToItem(contentItem, 0, 0)
|
var bottom = top + (item.height || 0)
|
||||||
var itemTop = p.y
|
var viewTop = flick.contentY
|
||||||
var itemBottom = p.y + item.height
|
var viewBottom = viewTop + flick.height
|
||||||
var viewTop = sb.position * scrollArea.contentHeight
|
var margin = 12
|
||||||
var viewBottom = viewTop + scrollArea.height
|
if (top < viewTop + margin) flick.contentY = Math.max(0, top - margin)
|
||||||
var pad = 20
|
else if (bottom > viewBottom - margin)
|
||||||
if (itemTop < viewTop + pad) {
|
flick.contentY = bottom + margin - flick.height
|
||||||
sb.position = Math.max(0, (itemTop - pad) / scrollArea.contentHeight)
|
|
||||||
} else if (itemBottom > viewBottom - pad) {
|
|
||||||
var newPos = (itemBottom + pad - scrollArea.height) / scrollArea.contentHeight
|
|
||||||
sb.position = Math.max(0, Math.min(1 - sb.size, newPos))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatingWindow {
|
FloatingWindow {
|
||||||
|
|||||||
Reference in New Issue
Block a user