settings
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
import QtQuick
|
||||
import QtQuick.Effects
|
||||
import qs.Config
|
||||
|
||||
Elevation {
|
||||
id: root
|
||||
|
||||
required property int currentIndex
|
||||
property bool expanded
|
||||
required property int from
|
||||
property color insideTextColor: DynamicColors.palette.m3onPrimary
|
||||
property int itemHeight
|
||||
property int listHeight: 200
|
||||
property color outsideTextColor: DynamicColors.palette.m3onSurfaceVariant
|
||||
readonly property var spinnerModel: root.range(root.from, root.to)
|
||||
required property int to
|
||||
property Item triggerItem
|
||||
|
||||
signal itemSelected(item: int)
|
||||
|
||||
function range(first, last) {
|
||||
let out = [];
|
||||
for (let i = first; i <= last; ++i)
|
||||
out.push(i);
|
||||
return out;
|
||||
}
|
||||
|
||||
implicitHeight: root.expanded ? view.implicitHeight : 0
|
||||
level: root.expanded ? 2 : 0
|
||||
radius: itemHeight / 2
|
||||
visible: implicitHeight > 0
|
||||
|
||||
Behavior on implicitHeight {
|
||||
Anim {
|
||||
}
|
||||
}
|
||||
|
||||
onExpandedChanged: {
|
||||
if (!root.expanded)
|
||||
root.itemSelected(view.currentIndex + 1);
|
||||
}
|
||||
|
||||
Component {
|
||||
id: spinnerDelegate
|
||||
|
||||
Item {
|
||||
id: wrapper
|
||||
|
||||
readonly property color delegateTextColor: wrapper.PathView.view ? wrapper.PathView.view.delegateTextColor : "white"
|
||||
required property var modelData
|
||||
|
||||
height: root.itemHeight
|
||||
opacity: wrapper.PathView.itemOpacity
|
||||
visible: wrapper.PathView.onPath
|
||||
width: wrapper.PathView.view ? wrapper.PathView.view.width : 0
|
||||
z: wrapper.PathView.isCurrentItem ? 100 : Math.round(wrapper.PathView.itemScale * 100)
|
||||
|
||||
CustomText {
|
||||
anchors.centerIn: parent
|
||||
color: wrapper.delegateTextColor
|
||||
font.pointSize: Appearance.font.size.large
|
||||
text: wrapper.modelData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CustomClippingRect {
|
||||
anchors.fill: parent
|
||||
color: DynamicColors.palette.m3surfaceContainer
|
||||
radius: parent.radius
|
||||
|
||||
// Main visible spinner: normal/outside text color
|
||||
PathView {
|
||||
id: view
|
||||
|
||||
property color delegateTextColor: root.outsideTextColor
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
clip: true
|
||||
currentIndex: root.currentIndex - 1
|
||||
delegate: spinnerDelegate
|
||||
dragMargin: width
|
||||
highlightRangeMode: PathView.StrictlyEnforceRange
|
||||
implicitHeight: root.listHeight
|
||||
model: root.spinnerModel
|
||||
pathItemCount: 7
|
||||
preferredHighlightBegin: 0.5
|
||||
preferredHighlightEnd: 0.5
|
||||
snapMode: PathView.SnapToItem
|
||||
|
||||
path: PathMenu {
|
||||
viewHeight: view.height
|
||||
viewWidth: view.width
|
||||
}
|
||||
}
|
||||
|
||||
// The selection rectangle itself
|
||||
CustomRect {
|
||||
id: selectionRect
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: DynamicColors.palette.m3primary
|
||||
height: root.itemHeight
|
||||
radius: root.itemHeight / 2
|
||||
width: parent.width
|
||||
z: 2
|
||||
}
|
||||
|
||||
// Hidden source: same PathView, but with the "inside selection" text color
|
||||
Item {
|
||||
id: selectedTextSource
|
||||
|
||||
anchors.fill: parent
|
||||
layer.enabled: true
|
||||
visible: false
|
||||
|
||||
PathView {
|
||||
id: selectedTextView
|
||||
|
||||
property color delegateTextColor: root.insideTextColor
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
clip: true
|
||||
currentIndex: view.currentIndex
|
||||
delegate: spinnerDelegate
|
||||
dragMargin: view.dragMargin
|
||||
highlightRangeMode: view.highlightRangeMode
|
||||
implicitHeight: root.listHeight
|
||||
interactive: false
|
||||
model: view.model
|
||||
|
||||
// Keep this PathView visually locked to the real one
|
||||
offset: view.offset
|
||||
pathItemCount: view.pathItemCount
|
||||
preferredHighlightBegin: view.preferredHighlightBegin
|
||||
preferredHighlightEnd: view.preferredHighlightEnd
|
||||
snapMode: view.snapMode
|
||||
|
||||
path: PathMenu {
|
||||
viewHeight: selectedTextView.height
|
||||
viewWidth: selectedTextView.width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mask matching the selection rectangle
|
||||
Item {
|
||||
id: selectionMask
|
||||
|
||||
anchors.fill: parent
|
||||
layer.enabled: true
|
||||
visible: false
|
||||
|
||||
CustomRect {
|
||||
color: "white"
|
||||
height: selectionRect.height
|
||||
radius: selectionRect.radius
|
||||
width: selectionRect.width
|
||||
x: selectionRect.x
|
||||
y: selectionRect.y
|
||||
}
|
||||
}
|
||||
|
||||
// Only show the "inside selection" text where the mask exists
|
||||
MultiEffect {
|
||||
anchors.fill: selectedTextSource
|
||||
maskEnabled: true
|
||||
maskInverted: false
|
||||
maskSource: selectionMask
|
||||
source: selectedTextSource
|
||||
z: 3
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user