Merge branch 'main' into module/wifi
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 15s
JS/TS / lint (pull_request) Successful in 19s
Python / static (pull_request) Successful in 57s
Rust / fmt (pull_request) Successful in 1m9s
Rust / build (pull_request) Successful in 2m11s
C++ / build (pull_request) Successful in 2m34s
Rust / clippy (pull_request) Successful in 1m30s
Python / verify (pull_request) Successful in 2m55s
C++ / clang-tidy (pull_request) Successful in 3m59s
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 15s
JS/TS / lint (pull_request) Successful in 19s
Python / static (pull_request) Successful in 57s
Rust / fmt (pull_request) Successful in 1m9s
Rust / build (pull_request) Successful in 2m11s
C++ / build (pull_request) Successful in 2m34s
Rust / clippy (pull_request) Successful in 1m30s
Python / verify (pull_request) Successful in 2m55s
C++ / clang-tidy (pull_request) Successful in 3m59s
This commit is contained in:
@@ -1,24 +0,0 @@
|
||||
import QtQuick
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
property real idx1: index
|
||||
property int idx1Duration: 100
|
||||
property real idx2: index
|
||||
property int idx2Duration: 300
|
||||
required property int index
|
||||
|
||||
Behavior on idx1 {
|
||||
NumberAnimation {
|
||||
duration: root.idx1Duration
|
||||
easing.type: Easing.OutSine
|
||||
}
|
||||
}
|
||||
Behavior on idx2 {
|
||||
NumberAnimation {
|
||||
duration: root.idx2Duration
|
||||
easing.type: Easing.OutSine
|
||||
}
|
||||
}
|
||||
}
|
||||
+148
-130
@@ -18,13 +18,14 @@ Item {
|
||||
property real leftFadeStrength: overflowing && leftFadeEnabled ? fadeStrengthMoving : fadeStrengthIdle
|
||||
property int leftFadeWidth: 28
|
||||
property bool marqueeEnabled: true
|
||||
readonly property bool overflowing: metrics.width > root.width
|
||||
readonly property bool overflowing: metrics.width > content.width
|
||||
property int pauseMs: 1200
|
||||
property real pixelsPerSecond: 40
|
||||
property real rightFadeStrength: overflowing ? fadeStrengthMoving : fadeStrengthIdle
|
||||
property int rightFadeWidth: 28
|
||||
property bool sliding: false
|
||||
property alias text: elideText.text
|
||||
property bool vertical: false
|
||||
|
||||
function durationForDistance(px): int {
|
||||
return Math.max(1, Math.round(Math.abs(px) / root.pixelsPerSecond * 1000));
|
||||
@@ -41,8 +42,9 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
clip: true
|
||||
implicitHeight: elideText.implicitHeight
|
||||
clip: false
|
||||
implicitHeight: vertical ? elideText.implicitWidth : elideText.implicitHeight
|
||||
implicitWidth: vertical ? elideText.implicitHeight : elideText.implicitWidth
|
||||
|
||||
Behavior on leftFadeStrength {
|
||||
Anim {
|
||||
@@ -53,171 +55,187 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
onHeightChanged: resetMarquee()
|
||||
onTextChanged: resetMarquee()
|
||||
onVerticalChanged: resetMarquee()
|
||||
onVisibleChanged: if (!visible)
|
||||
resetMarquee()
|
||||
onWidthChanged: resetMarquee()
|
||||
|
||||
TextMetrics {
|
||||
id: metrics
|
||||
|
||||
font: elideText.font
|
||||
text: elideText.text
|
||||
}
|
||||
|
||||
CustomText {
|
||||
id: elideText
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
animate: root.animate
|
||||
animateProp: "scale,opacity"
|
||||
color: root.color
|
||||
elide: Text.ElideNone
|
||||
visible: !root.overflowing
|
||||
width: root.width
|
||||
}
|
||||
|
||||
Item {
|
||||
id: marqueeViewport
|
||||
id: content
|
||||
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
layer.enabled: true
|
||||
visible: root.overflowing
|
||||
anchors.centerIn: parent
|
||||
height: root.vertical ? root.width : root.height
|
||||
width: root.vertical ? root.height : root.width
|
||||
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: rightFadeMask
|
||||
transform: Rotation {
|
||||
angle: root.vertical ? -90 : 0
|
||||
origin.x: content.width / 2
|
||||
origin.y: content.height / 2
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: metrics
|
||||
|
||||
font: elideText.font
|
||||
text: elideText.text
|
||||
}
|
||||
|
||||
CustomText {
|
||||
id: elideText
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
animate: root.animate
|
||||
animateProp: "scale,opacity"
|
||||
color: root.color
|
||||
elide: Text.ElideNone
|
||||
visible: !root.overflowing
|
||||
width: content.width
|
||||
}
|
||||
|
||||
Item {
|
||||
id: strip
|
||||
id: marqueeViewport
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
height: t1.implicitHeight
|
||||
width: t1.width + root.gap + t2.width
|
||||
x: 0
|
||||
anchors.fill: parent
|
||||
clip: false
|
||||
layer.enabled: true
|
||||
visible: root.overflowing
|
||||
|
||||
CustomText {
|
||||
id: t1
|
||||
|
||||
animate: root.animate
|
||||
animateProp: "opacity"
|
||||
color: root.color
|
||||
font.pointSize: elideText.font.pointSize
|
||||
text: elideText.text
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: rightFadeMask
|
||||
}
|
||||
|
||||
CustomText {
|
||||
id: t2
|
||||
Item {
|
||||
id: strip
|
||||
|
||||
animate: root.animate
|
||||
animateProp: "opacity"
|
||||
color: root.color
|
||||
font.pointSize: elideText.font.pointSize
|
||||
text: t1.text
|
||||
x: t1.width + root.gap
|
||||
}
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
height: t1.implicitHeight
|
||||
width: t1.width + root.gap + t2.width
|
||||
x: 0
|
||||
|
||||
SequentialAnimation {
|
||||
id: marqueeAnim
|
||||
CustomText {
|
||||
id: t1
|
||||
|
||||
running: false
|
||||
animate: root.animate
|
||||
animateProp: "opacity"
|
||||
color: root.color
|
||||
font.pointSize: elideText.font.pointSize
|
||||
text: elideText.text
|
||||
}
|
||||
|
||||
onFinished: pauseTimer.restart()
|
||||
CustomText {
|
||||
id: t2
|
||||
|
||||
ScriptAction {
|
||||
script: {
|
||||
root.sliding = true;
|
||||
root.leftFadeEnabled = true;
|
||||
animate: root.animate
|
||||
animateProp: "opacity"
|
||||
color: root.color
|
||||
font.pointSize: elideText.font.pointSize
|
||||
text: t1.text
|
||||
x: t1.width + root.gap
|
||||
}
|
||||
}
|
||||
|
||||
Anim {
|
||||
duration: root.durationForDistance(t1.width)
|
||||
easing.bezierCurve: Easing.Linear
|
||||
easing.type: Easing.Linear
|
||||
from: 0
|
||||
property: "x"
|
||||
target: strip
|
||||
to: -t1.width
|
||||
}
|
||||
SequentialAnimation {
|
||||
id: marqueeAnim
|
||||
|
||||
ScriptAction {
|
||||
script: {
|
||||
root.leftFadeEnabled = false;
|
||||
running: false
|
||||
|
||||
onFinished: pauseTimer.restart()
|
||||
|
||||
ScriptAction {
|
||||
script: {
|
||||
root.sliding = true;
|
||||
root.leftFadeEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
Anim {
|
||||
duration: root.durationForDistance(t1.width)
|
||||
easing.bezierCurve: Easing.Linear
|
||||
easing.type: Easing.Linear
|
||||
from: 0
|
||||
property: "x"
|
||||
target: strip
|
||||
to: -t1.width
|
||||
}
|
||||
|
||||
ScriptAction {
|
||||
script: {
|
||||
root.leftFadeEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
Anim {
|
||||
duration: root.durationForDistance(root.gap)
|
||||
easing.bezierCurve: Easing.Linear
|
||||
easing.type: Easing.Linear
|
||||
from: -t1.width
|
||||
property: "x"
|
||||
target: strip
|
||||
to: -(t1.width + root.gap)
|
||||
}
|
||||
|
||||
ScriptAction {
|
||||
script: {
|
||||
root.sliding = false;
|
||||
strip.x = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Anim {
|
||||
duration: root.durationForDistance(root.gap)
|
||||
easing.bezierCurve: Easing.Linear
|
||||
easing.type: Easing.Linear
|
||||
from: -t1.width
|
||||
property: "x"
|
||||
target: strip
|
||||
to: -(t1.width + root.gap)
|
||||
}
|
||||
Timer {
|
||||
id: pauseTimer
|
||||
|
||||
ScriptAction {
|
||||
script: {
|
||||
root.sliding = false;
|
||||
strip.x = 0;
|
||||
interval: root.pauseMs
|
||||
repeat: false
|
||||
running: true
|
||||
|
||||
onTriggered: {
|
||||
if (root.marqueeEnabled)
|
||||
marqueeAnim.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: pauseTimer
|
||||
Rectangle {
|
||||
id: rightFadeMask
|
||||
|
||||
interval: root.pauseMs
|
||||
repeat: false
|
||||
running: true
|
||||
|
||||
onTriggered: {
|
||||
if (root.marqueeEnabled)
|
||||
marqueeAnim.start();
|
||||
readonly property real fadeStartPos: {
|
||||
const w = Math.max(1, width);
|
||||
return Math.max(0, Math.min(1, (w - root.rightFadeWidth) / w));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rightFadeMask
|
||||
|
||||
readonly property real fadeStartPos: {
|
||||
const w = Math.max(1, width);
|
||||
return Math.max(0, Math.min(1, (w - root.rightFadeWidth) / w));
|
||||
}
|
||||
readonly property real leftFadeEndPos: {
|
||||
const w = Math.max(1, width);
|
||||
return Math.max(0, Math.min(1, root.leftFadeWidth / w));
|
||||
}
|
||||
|
||||
anchors.fill: marqueeViewport
|
||||
layer.enabled: true
|
||||
visible: false
|
||||
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
|
||||
GradientStop {
|
||||
color: Qt.rgba(1, 1, 1, 1.0 - root.leftFadeStrength)
|
||||
position: 0.0
|
||||
readonly property real leftFadeEndPos: {
|
||||
const w = Math.max(1, width);
|
||||
return Math.max(0, Math.min(1, root.leftFadeWidth / w));
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
color: Qt.rgba(1, 1, 1, 1.0)
|
||||
position: rightFadeMask.leftFadeEndPos
|
||||
}
|
||||
anchors.fill: marqueeViewport
|
||||
layer.enabled: true
|
||||
visible: false
|
||||
|
||||
GradientStop {
|
||||
color: Qt.rgba(1, 1, 1, 1.0)
|
||||
position: rightFadeMask.fadeStartPos
|
||||
}
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
|
||||
GradientStop {
|
||||
color: Qt.rgba(1, 1, 1, 1.0 - root.rightFadeStrength)
|
||||
position: 1.0
|
||||
GradientStop {
|
||||
color: Qt.rgba(1, 1, 1, 1.0 - root.leftFadeStrength)
|
||||
position: 0.0
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
color: Qt.rgba(1, 1, 1, 1.0)
|
||||
position: rightFadeMask.leftFadeEndPos
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
color: Qt.rgba(1, 1, 1, 1.0)
|
||||
position: rightFadeMask.fadeStartPos
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
color: Qt.rgba(1, 1, 1, 1.0 - root.rightFadeStrength)
|
||||
position: 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -126,7 +126,7 @@ MouseArea {
|
||||
CustomRect {
|
||||
id: item
|
||||
|
||||
readonly property bool active: modelData === root.active
|
||||
readonly property bool active: modelData === root?.active
|
||||
required property int index
|
||||
required property MenuItem modelData
|
||||
|
||||
@@ -163,19 +163,19 @@ MouseArea {
|
||||
MaterialIcon {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurfaceVariant
|
||||
text: item.modelData.icon
|
||||
text: item.modelData?.icon ?? ""
|
||||
}
|
||||
|
||||
CustomText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface
|
||||
text: item.modelData.text
|
||||
text: item.modelData?.text ?? ""
|
||||
}
|
||||
|
||||
Loader {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
active: item.modelData.trailingIcon.length > 0
|
||||
active: item.modelData?.trailingIcon.length > 0
|
||||
asynchronous: true
|
||||
visible: active
|
||||
|
||||
|
||||
Reference in New Issue
Block a user