controlcenter: inner scrollbar for larger sections such as fonts
This commit is contained in:
parent
ba094963bc
commit
678f7e3343
2 changed files with 103 additions and 7 deletions
|
|
@ -19,14 +19,51 @@ ScrollBar {
|
||||||
shouldBeActive = flickable.moving;
|
shouldBeActive = flickable.moving;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property bool _updatingFromFlickable: false
|
||||||
|
property bool _updatingFromUser: false
|
||||||
|
|
||||||
|
// Sync nonAnimPosition with Qt's automatic position binding
|
||||||
onPositionChanged: {
|
onPositionChanged: {
|
||||||
if (position === nonAnimPosition)
|
if (_updatingFromUser) {
|
||||||
|
_updatingFromUser = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (position === nonAnimPosition) {
|
||||||
animating = false;
|
animating = false;
|
||||||
else if (!animating)
|
return;
|
||||||
|
}
|
||||||
|
if (!animating && !_updatingFromFlickable && !fullMouse.pressed) {
|
||||||
nonAnimPosition = position;
|
nonAnimPosition = position;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
position: nonAnimPosition
|
// Sync nonAnimPosition with flickable when not animating
|
||||||
|
Connections {
|
||||||
|
target: flickable
|
||||||
|
function onContentYChanged() {
|
||||||
|
if (!animating && !fullMouse.pressed) {
|
||||||
|
_updatingFromFlickable = true;
|
||||||
|
const contentHeight = flickable.contentHeight;
|
||||||
|
const height = flickable.height;
|
||||||
|
if (contentHeight > height) {
|
||||||
|
nonAnimPosition = Math.max(0, Math.min(1, flickable.contentY / (contentHeight - height)));
|
||||||
|
} else {
|
||||||
|
nonAnimPosition = 0;
|
||||||
|
}
|
||||||
|
_updatingFromFlickable = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (flickable) {
|
||||||
|
const contentHeight = flickable.contentHeight;
|
||||||
|
const height = flickable.height;
|
||||||
|
if (contentHeight > height) {
|
||||||
|
nonAnimPosition = Math.max(0, Math.min(1, flickable.contentY / (contentHeight - height)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
implicitWidth: Appearance.padding.small
|
implicitWidth: Appearance.padding.small
|
||||||
|
|
||||||
contentItem: StyledRect {
|
contentItem: StyledRect {
|
||||||
|
|
@ -86,17 +123,62 @@ ScrollBar {
|
||||||
|
|
||||||
onPressed: event => {
|
onPressed: event => {
|
||||||
root.animating = true;
|
root.animating = true;
|
||||||
root.nonAnimPosition = Math.max(0, Math.min(1 - root.size, event.y / root.height - root.size / 2));
|
root._updatingFromUser = true;
|
||||||
|
const newPos = Math.max(0, Math.min(1 - root.size, event.y / root.height - root.size / 2));
|
||||||
|
root.nonAnimPosition = newPos;
|
||||||
|
// Update flickable position
|
||||||
|
// Map scrollbar position [0, 1-size] to contentY [0, maxContentY]
|
||||||
|
if (root.flickable) {
|
||||||
|
const contentHeight = root.flickable.contentHeight;
|
||||||
|
const height = root.flickable.height;
|
||||||
|
if (contentHeight > height) {
|
||||||
|
const maxContentY = contentHeight - height;
|
||||||
|
const maxPos = 1 - root.size;
|
||||||
|
const contentY = maxPos > 0 ? (newPos / maxPos) * maxContentY : 0;
|
||||||
|
root.flickable.contentY = Math.max(0, Math.min(maxContentY, contentY));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onPositionChanged: event => root.nonAnimPosition = Math.max(0, Math.min(1 - root.size, event.y / root.height - root.size / 2))
|
onPositionChanged: event => {
|
||||||
|
root._updatingFromUser = true;
|
||||||
|
const newPos = Math.max(0, Math.min(1 - root.size, event.y / root.height - root.size / 2));
|
||||||
|
root.nonAnimPosition = newPos;
|
||||||
|
// Update flickable position
|
||||||
|
// Map scrollbar position [0, 1-size] to contentY [0, maxContentY]
|
||||||
|
if (root.flickable) {
|
||||||
|
const contentHeight = root.flickable.contentHeight;
|
||||||
|
const height = root.flickable.height;
|
||||||
|
if (contentHeight > height) {
|
||||||
|
const maxContentY = contentHeight - height;
|
||||||
|
const maxPos = 1 - root.size;
|
||||||
|
const contentY = maxPos > 0 ? (newPos / maxPos) * maxContentY : 0;
|
||||||
|
root.flickable.contentY = Math.max(0, Math.min(maxContentY, contentY));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onWheel(event: WheelEvent): void {
|
function onWheel(event: WheelEvent): void {
|
||||||
root.animating = true;
|
root.animating = true;
|
||||||
|
root._updatingFromUser = true;
|
||||||
|
let newPos = root.nonAnimPosition;
|
||||||
if (event.angleDelta.y > 0)
|
if (event.angleDelta.y > 0)
|
||||||
root.nonAnimPosition = Math.max(0, root.nonAnimPosition - 0.1);
|
newPos = Math.max(0, root.nonAnimPosition - 0.1);
|
||||||
else if (event.angleDelta.y < 0)
|
else if (event.angleDelta.y < 0)
|
||||||
root.nonAnimPosition = Math.min(1 - root.size, root.nonAnimPosition + 0.1);
|
newPos = Math.min(1 - root.size, root.nonAnimPosition + 0.1);
|
||||||
|
root.nonAnimPosition = newPos;
|
||||||
|
// Update flickable position
|
||||||
|
// Map scrollbar position [0, 1-size] to contentY [0, maxContentY]
|
||||||
|
if (root.flickable) {
|
||||||
|
const contentHeight = root.flickable.contentHeight;
|
||||||
|
const height = root.flickable.height;
|
||||||
|
if (contentHeight > height) {
|
||||||
|
const maxContentY = contentHeight - height;
|
||||||
|
const maxPos = 1 - root.size;
|
||||||
|
const contentY = maxPos > 0 ? (newPos / maxPos) * maxContentY : 0;
|
||||||
|
root.flickable.contentY = Math.max(0, Math.min(maxContentY, contentY));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -526,6 +526,7 @@ RowLayout {
|
||||||
showBackground: true
|
showBackground: true
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
id: materialFontLoader
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: item ? Math.min(item.contentHeight, 300) : 0
|
Layout.preferredHeight: item ? Math.min(item.contentHeight, 300) : 0
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
@ -539,6 +540,10 @@ RowLayout {
|
||||||
spacing: Appearance.spacing.small / 2
|
spacing: Appearance.spacing.small / 2
|
||||||
model: Qt.fontFamilies()
|
model: Qt.fontFamilies()
|
||||||
|
|
||||||
|
StyledScrollBar.vertical: StyledScrollBar {
|
||||||
|
flickable: materialFontList
|
||||||
|
}
|
||||||
|
|
||||||
delegate: StyledRect {
|
delegate: StyledRect {
|
||||||
required property string modelData
|
required property string modelData
|
||||||
required property int index
|
required property int index
|
||||||
|
|
@ -592,6 +597,7 @@ RowLayout {
|
||||||
implicitHeight: fontFamilyMaterialRow.implicitHeight + Appearance.padding.normal * 2
|
implicitHeight: fontFamilyMaterialRow.implicitHeight + Appearance.padding.normal * 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -615,6 +621,10 @@ RowLayout {
|
||||||
spacing: Appearance.spacing.small / 2
|
spacing: Appearance.spacing.small / 2
|
||||||
model: Qt.fontFamilies()
|
model: Qt.fontFamilies()
|
||||||
|
|
||||||
|
StyledScrollBar.vertical: StyledScrollBar {
|
||||||
|
flickable: monoFontList
|
||||||
|
}
|
||||||
|
|
||||||
delegate: StyledRect {
|
delegate: StyledRect {
|
||||||
required property string modelData
|
required property string modelData
|
||||||
required property int index
|
required property int index
|
||||||
|
|
@ -691,6 +701,10 @@ RowLayout {
|
||||||
spacing: Appearance.spacing.small / 2
|
spacing: Appearance.spacing.small / 2
|
||||||
model: Qt.fontFamilies()
|
model: Qt.fontFamilies()
|
||||||
|
|
||||||
|
StyledScrollBar.vertical: StyledScrollBar {
|
||||||
|
flickable: sansFontList
|
||||||
|
}
|
||||||
|
|
||||||
delegate: StyledRect {
|
delegate: StyledRect {
|
||||||
required property string modelData
|
required property string modelData
|
||||||
required property int index
|
required property int index
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue