forked from Shinonome/dots-hyprland
Merge branch 'main' into all-tooltips
This commit is contained in:
@@ -15,9 +15,26 @@ Singleton {
|
||||
property QtObject sizes
|
||||
property string syntaxHighlightingTheme
|
||||
|
||||
// Extremely conservative transparency values for consistency and readability
|
||||
property real transparency: Config.options?.appearance.transparency ? (m3colors.darkmode ? 0.1 : 0.07) : 0
|
||||
property real contentTransparency: Config.options?.appearance.transparency ? (m3colors.darkmode ? 0.55 : 0.55) : 0
|
||||
// Transparency. The quadratic functions were derived from analysis of hand-picked transparency values.
|
||||
ColorQuantizer {
|
||||
id: wallColorQuant
|
||||
source: Qt.resolvedUrl(Config.options.background.wallpaperPath)
|
||||
depth: 0 // 2^0 = 1 color
|
||||
rescaleSize: 10
|
||||
}
|
||||
property real wallpaperVibrancy: (wallColorQuant.colors[0]?.hslSaturation + wallColorQuant.colors[0]?.hslLightness) / 2
|
||||
property real autoBackgroundTransparency: { // y = 0.5768x^2 - 0.759x + 0.2896
|
||||
let x = wallpaperVibrancy
|
||||
let y = 0.5768 * (x * x) - 0.759 * (x) + 0.2896
|
||||
return Math.max(0, Math.min(0.22, y))
|
||||
}
|
||||
property real autoContentTransparency: { // y = -10.1734x^2 + 3.4457x + 0.1872
|
||||
let x = autoBackgroundTransparency
|
||||
let y = -10.1734 * (x * x) + 3.4457 * (x) + 0.1872
|
||||
return Math.max(0, Math.min(0.6, y))
|
||||
}
|
||||
property real backgroundTransparency: Config?.options.appearance.transparency.enable ? Config?.options.appearance.transparency.automatic ? autoBackgroundTransparency : Config?.options.appearance.transparency.backgroundTransparency : 0
|
||||
property real contentTransparency: Config?.options.appearance.transparency.enable ? Config?.options.appearance.transparency.automatic ? autoContentTransparency : Config?.options.appearance.transparency.contentTransparency : 0
|
||||
|
||||
m3colors: QtObject {
|
||||
property bool darkmode: false
|
||||
@@ -100,26 +117,30 @@ Singleton {
|
||||
|
||||
colors: QtObject {
|
||||
property color colSubtext: m3colors.m3outline
|
||||
property color colLayer0: ColorUtils.mix(ColorUtils.transparentize(m3colors.m3background, root.transparency), m3colors.m3primary, Config.options.appearance.extraBackgroundTint ? 0.99 : 1)
|
||||
property color colLayer0: ColorUtils.mix(ColorUtils.transparentize(m3colors.m3background, root.backgroundTransparency), m3colors.m3primary, Config.options.appearance.extraBackgroundTint ? 0.99 : 1)
|
||||
property color colOnLayer0: m3colors.m3onBackground
|
||||
property color colLayer0Hover: ColorUtils.transparentize(ColorUtils.mix(colLayer0, colOnLayer0, 0.9, root.contentTransparency))
|
||||
property color colLayer0Active: ColorUtils.transparentize(ColorUtils.mix(colLayer0, colOnLayer0, 0.8, root.contentTransparency))
|
||||
property color colLayer0Border: ColorUtils.mix(root.m3colors.m3outlineVariant, colLayer0, 0.4)
|
||||
property color colLayer1: ColorUtils.transparentize(ColorUtils.mix(m3colors.m3surfaceContainerLow, m3colors.m3background, 0.8), root.contentTransparency);
|
||||
property color colLayer1: ColorUtils.transparentize(m3colors.m3surfaceContainerLow, root.contentTransparency);
|
||||
property color colOnLayer1: m3colors.m3onSurfaceVariant;
|
||||
property color colOnLayer1Inactive: ColorUtils.mix(colOnLayer1, colLayer1, 0.45);
|
||||
property color colLayer2: ColorUtils.transparentize(ColorUtils.mix(m3colors.m3surfaceContainer, m3colors.m3surfaceContainerHigh, 0.1), root.contentTransparency)
|
||||
property color colLayer2: ColorUtils.transparentize(m3colors.m3surfaceContainer, root.contentTransparency)
|
||||
property color colOnLayer2: m3colors.m3onSurface;
|
||||
property color colOnLayer2Disabled: ColorUtils.mix(colOnLayer2, m3colors.m3background, 0.4);
|
||||
property color colLayer3: ColorUtils.transparentize(ColorUtils.mix(m3colors.m3surfaceContainerHigh, m3colors.m3onSurface, 0.96), root.contentTransparency)
|
||||
property color colOnLayer3: m3colors.m3onSurface;
|
||||
property color colLayer1Hover: ColorUtils.transparentize(ColorUtils.mix(colLayer1, colOnLayer1, 0.92), root.contentTransparency)
|
||||
property color colLayer1Active: ColorUtils.transparentize(ColorUtils.mix(colLayer1, colOnLayer1, 0.85), root.contentTransparency);
|
||||
property color colLayer2Hover: ColorUtils.transparentize(ColorUtils.mix(colLayer2, colOnLayer2, 0.90), root.contentTransparency)
|
||||
property color colLayer2Active: ColorUtils.transparentize(ColorUtils.mix(colLayer2, colOnLayer2, 0.80), root.contentTransparency);
|
||||
property color colLayer2Disabled: ColorUtils.transparentize(ColorUtils.mix(colLayer2, m3colors.m3background, 0.8), root.contentTransparency);
|
||||
property color colLayer3: ColorUtils.transparentize(m3colors.m3surfaceContainerHigh, root.contentTransparency)
|
||||
property color colOnLayer3: m3colors.m3onSurface;
|
||||
property color colLayer3Hover: ColorUtils.transparentize(ColorUtils.mix(colLayer3, colOnLayer3, 0.90), root.contentTransparency)
|
||||
property color colLayer3Active: ColorUtils.transparentize(ColorUtils.mix(colLayer3, colOnLayer3, 0.80), root.contentTransparency);
|
||||
property color colLayer4: ColorUtils.transparentize(m3colors.m3surfaceContainerHighest, root.contentTransparency)
|
||||
property color colOnLayer4: m3colors.m3onSurface;
|
||||
property color colLayer4Hover: ColorUtils.transparentize(ColorUtils.mix(colLayer4, colOnLayer4, 0.90), root.contentTransparency)
|
||||
property color colLayer4Active: ColorUtils.transparentize(ColorUtils.mix(colLayer4, colOnLayer4, 0.80), root.contentTransparency);
|
||||
property color colPrimary: m3colors.m3primary
|
||||
property color colOnPrimary: m3colors.m3onPrimary
|
||||
property color colPrimaryHover: ColorUtils.mix(colors.colPrimary, colLayer1Hover, 0.87)
|
||||
@@ -148,6 +169,14 @@ Singleton {
|
||||
property color colScrim: ColorUtils.transparentize(m3colors.m3scrim, 0.5)
|
||||
property color colShadow: ColorUtils.transparentize(m3colors.m3shadow, 0.7)
|
||||
property color colOutlineVariant: m3colors.m3outlineVariant
|
||||
property color colError: m3colors.m3error
|
||||
property color colErrorHover: ColorUtils.mix(m3colors.m3error, colLayer1Hover, 0.85)
|
||||
property color colErrorActive: ColorUtils.mix(m3colors.m3error, colLayer1Active, 0.7)
|
||||
property color colOnError: m3colors.m3onError
|
||||
property color colErrorContainer: m3colors.m3errorContainer
|
||||
property color colErrorContainerHover: ColorUtils.mix(m3colors.m3errorContainer, m3colors.m3onErrorContainer, 0.90)
|
||||
property color colErrorContainerActive: ColorUtils.mix(m3colors.m3errorContainer, m3colors.m3onErrorContainer, 0.70)
|
||||
property color colOnErrorContainer: m3colors.m3onErrorContainer
|
||||
}
|
||||
|
||||
rounding: QtObject {
|
||||
@@ -268,7 +297,6 @@ Singleton {
|
||||
easing.bezierCurve: root.animation.elementMoveFast.bezierCurve
|
||||
}}
|
||||
}
|
||||
|
||||
property QtObject clickBounce: QtObject {
|
||||
property int duration: 200
|
||||
property int type: Easing.BezierSpline
|
||||
@@ -281,7 +309,7 @@ Singleton {
|
||||
}}
|
||||
}
|
||||
property QtObject scroll: QtObject {
|
||||
property int duration: 400
|
||||
property int duration: 200
|
||||
property int type: Easing.BezierSpline
|
||||
property list<real> bezierCurve: animationCurves.standardDecel
|
||||
}
|
||||
|
||||
@@ -81,7 +81,12 @@ Singleton {
|
||||
property JsonObject appearance: JsonObject {
|
||||
property bool extraBackgroundTint: true
|
||||
property int fakeScreenRounding: 2 // 0: None | 1: Always | 2: When not fullscreen
|
||||
property bool transparency: false
|
||||
property JsonObject transparency: JsonObject {
|
||||
property bool enable: true
|
||||
property bool automatic: true
|
||||
property real backgroundTransparency: 0.11
|
||||
property real contentTransparency: 0.57
|
||||
}
|
||||
property JsonObject wallpaperTheming: JsonObject {
|
||||
property bool enableAppsAndShell: true
|
||||
property bool enableQtApps: true
|
||||
@@ -124,6 +129,14 @@ Singleton {
|
||||
}
|
||||
|
||||
property JsonObject bar: JsonObject {
|
||||
property JsonObject autoHide: JsonObject {
|
||||
property bool enable: false
|
||||
property bool pushWindows: false
|
||||
property JsonObject showWhenPressingSuper: JsonObject {
|
||||
property bool enable: true
|
||||
property int delay: 140
|
||||
}
|
||||
}
|
||||
property bool bottom: false // Instead of top
|
||||
property int cornerStyle: 0 // 0: Hug | 1: Float | 2: Plain rectangle
|
||||
property bool borderless: false // true for no grouping of items
|
||||
@@ -181,6 +194,15 @@ Singleton {
|
||||
property list<string> ignoredAppRegexes: []
|
||||
}
|
||||
|
||||
property JsonObject interactions: JsonObject {
|
||||
property JsonObject scrolling: JsonObject {
|
||||
property bool fasterTouchpadScroll: true // Enable faster scrolling with touchpad
|
||||
property int mouseScrollDeltaThreshold: 120 // delta >= this then it gets detected as mouse scroll rather than touchpad
|
||||
property int mouseScrollFactor: 120
|
||||
property int touchpadScrollFactor: 450
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject language: JsonObject {
|
||||
property JsonObject translator: JsonObject {
|
||||
property string engine: "auto" // Run `trans -list-engines` for available engines. auto should use google
|
||||
@@ -198,6 +220,11 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject media: JsonObject {
|
||||
// Attempt to remove dupes (the aggregator playerctl one and browsers' native ones when there's plasma browser integration)
|
||||
property bool filterDuplicatePlayers: true
|
||||
}
|
||||
|
||||
property JsonObject networking: JsonObject {
|
||||
property string userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
|
||||
}
|
||||
@@ -253,6 +280,13 @@ Singleton {
|
||||
// https://doc.qt.io/qt-6/qtime.html#toString
|
||||
property string format: "hh:mm"
|
||||
property string dateFormat: "ddd, dd/MM"
|
||||
property JsonObject pomodoro: JsonObject {
|
||||
property string alertSound: ""
|
||||
property int breakTime: 300
|
||||
property int cyclesBeforeLongBreak: 4
|
||||
property int focus: 1500
|
||||
property int longBreak: 900
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject windows: JsonObject {
|
||||
|
||||
@@ -11,18 +11,35 @@ Singleton {
|
||||
property string fileName: "states.json"
|
||||
property string filePath: `${root.fileDir}/${root.fileName}`
|
||||
|
||||
Timer {
|
||||
id: fileReloadTimer
|
||||
interval: 100
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
persistentStatesFileView.reload()
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: fileWriteTimer
|
||||
interval: 100
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
persistentStatesFileView.writeAdapter()
|
||||
}
|
||||
}
|
||||
|
||||
FileView {
|
||||
id: persistentStatesFileView
|
||||
path: root.filePath
|
||||
|
||||
watchChanges: true
|
||||
onFileChanged: reload()
|
||||
onAdapterUpdated: {
|
||||
writeAdapter()
|
||||
}
|
||||
onFileChanged: fileReloadTimer.restart()
|
||||
onAdapterUpdated: fileWriteTimer.restart()
|
||||
onLoadFailed: error => {
|
||||
console.log("Failed to load persistent states file:", error);
|
||||
if (error == FileViewError.FileNotFound) {
|
||||
writeAdapter();
|
||||
fileWriteTimer.restart();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +61,20 @@ Singleton {
|
||||
property bool allowNsfw: false
|
||||
property string provider: "yandere"
|
||||
}
|
||||
|
||||
property JsonObject timer: JsonObject {
|
||||
property JsonObject pomodoro: JsonObject {
|
||||
property bool running: false
|
||||
property int start: 0
|
||||
property bool isBreak: false
|
||||
property int cycle: 0
|
||||
}
|
||||
property JsonObject stopwatch: JsonObject {
|
||||
property bool running: false
|
||||
property int start: 0
|
||||
property list<var> laps: []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import QtQuick.Layouts
|
||||
Rectangle {
|
||||
id: root
|
||||
default property alias data: rowLayout.data
|
||||
property alias uniformCellSizes: rowLayout.uniformCellSizes
|
||||
property real spacing: 5
|
||||
property real padding: 0
|
||||
property int clickIndex: rowLayout.clickIndex
|
||||
|
||||
@@ -12,9 +12,9 @@ RippleButton {
|
||||
leftPadding: 15
|
||||
rightPadding: 15
|
||||
buttonRadius: Appearance.rounding.small
|
||||
colBackground: (urgency == NotificationUrgency.Critical) ? Appearance.colors.colSecondaryContainer : Appearance.colors.colSurfaceContainerHighest
|
||||
colBackgroundHover: (urgency == NotificationUrgency.Critical) ? Appearance.colors.colSecondaryContainerHover : Appearance.colors.colSurfaceContainerHighestHover
|
||||
colRipple: (urgency == NotificationUrgency.Critical) ? Appearance.colors.colSecondaryContainerActive : Appearance.colors.colSurfaceContainerHighestActive
|
||||
colBackground: (urgency == NotificationUrgency.Critical) ? Appearance.colors.colSecondaryContainer : Appearance.colors.colLayer4
|
||||
colBackgroundHover: (urgency == NotificationUrgency.Critical) ? Appearance.colors.colSecondaryContainerHover : Appearance.colors.colLayer4Hover
|
||||
colRipple: (urgency == NotificationUrgency.Critical) ? Appearance.colors.colSecondaryContainerActive : Appearance.colors.colLayer4Active
|
||||
|
||||
contentItem: StyledText {
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
@@ -13,9 +13,9 @@ Rectangle { // App icon
|
||||
property var urgency: NotificationUrgency.Normal
|
||||
property var image: ""
|
||||
property real scale: 1
|
||||
property real size: 45 * scale
|
||||
property real size: 38 * scale
|
||||
property real materialIconScale: 0.57
|
||||
property real appIconScale: 0.7
|
||||
property real appIconScale: 0.8
|
||||
property real smallAppIconScale: 0.49
|
||||
property real materialIconSize: size * materialIconScale
|
||||
property real appIconSize: size * appIconScale
|
||||
|
||||
@@ -105,7 +105,7 @@ Item { // Notification group area
|
||||
id: background
|
||||
anchors.left: parent.left
|
||||
width: parent.width
|
||||
color: Appearance.colors.colSurfaceContainer
|
||||
color: Appearance.colors.colLayer2
|
||||
radius: Appearance.rounding.normal
|
||||
anchors.leftMargin: root.xOffset
|
||||
|
||||
|
||||
@@ -140,8 +140,8 @@ Item { // Notification item area
|
||||
color: (expanded && !onlyNotification) ?
|
||||
(notificationObject.urgency == NotificationUrgency.Critical) ?
|
||||
ColorUtils.mix(Appearance.colors.colSecondaryContainer, Appearance.colors.colLayer2, 0.35) :
|
||||
(Appearance.colors.colSurfaceContainerHigh) :
|
||||
ColorUtils.transparentize(Appearance.colors.colSurfaceContainerHighest)
|
||||
(Appearance.colors.colLayer3) :
|
||||
ColorUtils.transparentize(Appearance.colors.colLayer3)
|
||||
|
||||
implicitHeight: expanded ? (contentColumn.implicitHeight + padding * 2) : summaryRow.implicitHeight
|
||||
Behavior on implicitHeight {
|
||||
@@ -168,7 +168,7 @@ Item { // Notification item area
|
||||
id: summaryText
|
||||
visible: !root.onlyNotification
|
||||
font.pixelSize: root.fontSize
|
||||
color: Appearance.colors.colOnLayer2
|
||||
color: Appearance.colors.colOnLayer3
|
||||
elide: Text.ElideRight
|
||||
text: root.notificationObject.summary || ""
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ TabButton {
|
||||
|
||||
RippleAnim {
|
||||
id: rippleFadeAnim
|
||||
duration: rippleDuration * 2
|
||||
target: ripple
|
||||
property: "opacity"
|
||||
to: 0
|
||||
|
||||
@@ -29,6 +29,7 @@ Button {
|
||||
property color colRipple: Appearance?.colors.colLayer1Active ?? "#D6CEE2"
|
||||
property color colRippleToggled: Appearance?.colors.colPrimaryActive ?? "#D6CEE2"
|
||||
|
||||
opacity: root.enabled ? 1 : 0.4
|
||||
property color buttonColor: root.enabled ? (root.toggled ?
|
||||
(root.hovered ? colBackgroundToggledHover :
|
||||
colBackgroundToggled) :
|
||||
@@ -91,6 +92,7 @@ Button {
|
||||
|
||||
RippleAnim {
|
||||
id: rippleFadeAnim
|
||||
duration: rippleDuration * 2
|
||||
target: ripple
|
||||
property: "opacity"
|
||||
to: 0
|
||||
|
||||
@@ -51,6 +51,7 @@ TabButton {
|
||||
|
||||
RippleAnim {
|
||||
id: rippleFadeAnim
|
||||
duration: rippleDuration * 2
|
||||
target: ripple
|
||||
property: "opacity"
|
||||
to: 0
|
||||
@@ -106,13 +107,29 @@ TabButton {
|
||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Item {
|
||||
id: ripple
|
||||
|
||||
radius: Appearance.rounding.full
|
||||
color: root.colRipple
|
||||
width: ripple.implicitWidth
|
||||
height: ripple.implicitHeight
|
||||
opacity: 0
|
||||
|
||||
property real implicitWidth: 0
|
||||
property real implicitHeight: 0
|
||||
visible: width > 0 && height > 0
|
||||
|
||||
Behavior on opacity {
|
||||
animation: Appearance?.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||
}
|
||||
|
||||
RadialGradient {
|
||||
anchors.fill: parent
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: root.colRipple }
|
||||
GradientStop { position: 0.3; color: root.colRipple }
|
||||
GradientStop { position: 0.5 ; color: Qt.rgba(root.colRipple.r, root.colRipple.g, root.colRipple.b, 0) }
|
||||
}
|
||||
}
|
||||
|
||||
transform: Translate {
|
||||
x: -ripple.width / 2
|
||||
y: -ripple.height / 2
|
||||
|
||||
@@ -63,7 +63,7 @@ Item {
|
||||
Layout.rightMargin: dialogPadding
|
||||
}
|
||||
|
||||
ListView {
|
||||
StyledListView {
|
||||
id: choiceListView
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
@@ -71,9 +71,6 @@ Item {
|
||||
currentIndex: root.defaultChoice !== undefined ? root.items.indexOf(root.defaultChoice) : -1
|
||||
spacing: 6
|
||||
|
||||
maximumFlickVelocity: 3500
|
||||
boundsBehavior: Flickable.DragOverBounds
|
||||
|
||||
model: ScriptModel {
|
||||
id: choiceModel
|
||||
}
|
||||
|
||||
@@ -1,6 +1,50 @@
|
||||
import QtQuick
|
||||
import qs.modules.common
|
||||
|
||||
Flickable {
|
||||
id: root
|
||||
maximumFlickVelocity: 3500
|
||||
boundsBehavior: Flickable.DragOverBounds
|
||||
|
||||
property real touchpadScrollFactor: Config?.options.interactions.scrolling.touchpadScrollFactor ?? 100
|
||||
property real mouseScrollFactor: Config?.options.interactions.scrolling.mouseScrollFactor ?? 50
|
||||
property real mouseScrollDeltaThreshold: Config?.options.interactions.scrolling.mouseScrollDeltaThreshold ?? 120
|
||||
// Accumulated scroll destination so wheel deltas stack while animating
|
||||
property real scrollTargetY: 0
|
||||
|
||||
MouseArea {
|
||||
visible: Config?.options.interactions.scrolling.fasterTouchpadScroll
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
onWheel: function(wheelEvent) {
|
||||
const delta = wheelEvent.angleDelta.y / root.mouseScrollDeltaThreshold;
|
||||
// The angleDelta.y of a touchpad is usually small and continuous,
|
||||
// while that of a mouse wheel is typically in multiples of ±120.
|
||||
var scrollFactor = Math.abs(wheelEvent.angleDelta.y) >= root.mouseScrollDeltaThreshold ? root.mouseScrollFactor : root.touchpadScrollFactor;
|
||||
|
||||
const maxY = Math.max(0, root.contentHeight - root.height);
|
||||
const base = scrollAnim.running ? root.scrollTargetY : root.contentY;
|
||||
var targetY = Math.max(0, Math.min(base - delta * scrollFactor, maxY));
|
||||
|
||||
root.scrollTargetY = targetY;
|
||||
root.contentY = targetY;
|
||||
wheelEvent.accepted = true;
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on contentY {
|
||||
NumberAnimation {
|
||||
id: scrollAnim
|
||||
duration: Appearance.animation.scroll.duration
|
||||
easing.type: Appearance.animation.scroll.type
|
||||
easing.bezierCurve: Appearance.animation.scroll.bezierCurve
|
||||
}
|
||||
}
|
||||
|
||||
// Keep target synced when not animating (e.g., drag/flick or programmatic changes)
|
||||
onContentYChanged: {
|
||||
if (!scrollAnim.running) {
|
||||
root.scrollTargetY = root.contentY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,12 @@ ListView {
|
||||
property int dragIndex: -1
|
||||
property real dragDistance: 0
|
||||
property bool popin: true
|
||||
// Accumulated scroll destination so wheel deltas stack while animating
|
||||
property real scrollTargetY: 0
|
||||
|
||||
property real touchpadScrollFactor: Config?.options.interactions.scrolling.touchpadScrollFactor ?? 100
|
||||
property real mouseScrollFactor: Config?.options.interactions.scrolling.mouseScrollFactor ?? 50
|
||||
property real mouseScrollDeltaThreshold: Config?.options.interactions.scrolling.mouseScrollDeltaThreshold ?? 120
|
||||
|
||||
function resetDrag() {
|
||||
root.dragIndex = -1
|
||||
@@ -23,6 +29,42 @@ ListView {
|
||||
maximumFlickVelocity: 3500
|
||||
boundsBehavior: Flickable.DragOverBounds
|
||||
|
||||
MouseArea {
|
||||
visible: Config?.options.interactions.scrolling.fasterTouchpadScroll
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
onWheel: function(wheelEvent) {
|
||||
const delta = wheelEvent.angleDelta.y / root.mouseScrollDeltaThreshold;
|
||||
// The angleDelta.y of a touchpad is usually small and continuous,
|
||||
// while that of a mouse wheel is typically in multiples of ±120.
|
||||
var scrollFactor = Math.abs(wheelEvent.angleDelta.y) >= root.mouseScrollDeltaThreshold ? root.mouseScrollFactor : root.touchpadScrollFactor;
|
||||
|
||||
const maxY = Math.max(0, root.contentHeight - root.height);
|
||||
const base = scrollAnim.running ? root.scrollTargetY : root.contentY;
|
||||
var targetY = Math.max(0, Math.min(base - delta * scrollFactor, maxY));
|
||||
|
||||
root.scrollTargetY = targetY;
|
||||
root.contentY = targetY;
|
||||
wheelEvent.accepted = true;
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on contentY {
|
||||
NumberAnimation {
|
||||
id: scrollAnim
|
||||
duration: Appearance.animation.scroll.duration
|
||||
easing.type: Appearance.animation.scroll.type
|
||||
easing.bezierCurve: Appearance.animation.scroll.bezierCurve
|
||||
}
|
||||
}
|
||||
|
||||
// Keep target synced when not animating (e.g., drag/flick or programmatic changes)
|
||||
onContentYChanged: {
|
||||
if (!scrollAnim.running) {
|
||||
root.scrollTargetY = root.contentY;
|
||||
}
|
||||
}
|
||||
|
||||
add: Transition {
|
||||
animations: [
|
||||
Appearance?.animation.elementMove.numberAnimation.createObject(this, {
|
||||
|
||||
Reference in New Issue
Block a user