mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
feat(view): implement smooth wheel scrolling for NGridView
This commit is contained in:
+53
-2
@@ -85,6 +85,32 @@ Item {
|
||||
|
||||
// Scroll speed multiplier for mouse wheel (1.0 = default, higher = faster)
|
||||
property real wheelScrollMultiplier: 2.0
|
||||
property int smoothWheelAnimationDuration: Style.animationNormal
|
||||
property real _wheelTargetY: 0
|
||||
|
||||
function clampScrollY(value) {
|
||||
return Math.max(0, Math.min(value, gridView.contentHeight - gridView.height));
|
||||
}
|
||||
|
||||
function applyWheelScroll(delta) {
|
||||
if (!root.contentOverflows)
|
||||
return;
|
||||
|
||||
const step = delta * root.wheelScrollMultiplier;
|
||||
|
||||
if (!Settings.data.general.smoothScrollEnabled || Settings.data.general.animationDisabled) {
|
||||
gridView.contentY = root.clampScrollY(gridView.contentY - step);
|
||||
root._wheelTargetY = gridView.contentY;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wheelScrollAnimation.running)
|
||||
root._wheelTargetY = gridView.contentY;
|
||||
|
||||
root._wheelTargetY = root.clampScrollY(root._wheelTargetY - step);
|
||||
wheelScrollAnimation.to = root._wheelTargetY;
|
||||
wheelScrollAnimation.restart();
|
||||
}
|
||||
|
||||
// Track selection index for gradient visibility (set externally)
|
||||
property int trackedSelectionIndex: -1
|
||||
@@ -197,6 +223,7 @@ Item {
|
||||
implicitHeight: 200
|
||||
|
||||
Component.onCompleted: {
|
||||
_wheelTargetY = gridView.contentY;
|
||||
createGradients();
|
||||
}
|
||||
|
||||
@@ -280,6 +307,31 @@ Item {
|
||||
// Enable flickable for smooth scrolling
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
|
||||
NumberAnimation {
|
||||
id: wheelScrollAnimation
|
||||
target: gridView
|
||||
property: "contentY"
|
||||
duration: root.smoothWheelAnimationDuration
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
|
||||
onDraggingChanged: {
|
||||
if (dragging) {
|
||||
wheelScrollAnimation.stop();
|
||||
root._wheelTargetY = contentY;
|
||||
}
|
||||
}
|
||||
|
||||
onFlickingChanged: {
|
||||
if (flicking) {
|
||||
wheelScrollAnimation.stop();
|
||||
root._wheelTargetY = contentY;
|
||||
}
|
||||
}
|
||||
|
||||
onContentHeightChanged: root._wheelTargetY = root.clampScrollY(root._wheelTargetY)
|
||||
onHeightChanged: root._wheelTargetY = root.clampScrollY(root._wheelTargetY)
|
||||
|
||||
// Focus handling depends on keyNavigationEnabled
|
||||
focus: keyNavigationEnabled
|
||||
activeFocusOnTab: keyNavigationEnabled
|
||||
@@ -296,8 +348,7 @@ Item {
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
onWheel: event => {
|
||||
const delta = event.pixelDelta.y !== 0 ? event.pixelDelta.y : event.angleDelta.y / 2;
|
||||
const newY = gridView.contentY - (delta * root.wheelScrollMultiplier);
|
||||
gridView.contentY = Math.max(0, Math.min(newY, gridView.contentHeight - gridView.height));
|
||||
root.applyWheelScroll(delta);
|
||||
event.accepted = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user