bar: keep ripple and press morph on the pressed clock segment

fixes #4008
port 2.0
This commit is contained in:
bbedward committed 2026-10-29 09:51:19 -04:00
1 parent a1c8db2558
commit 2308934453
1 file changed
+39 -25
+39 -25
View File
@@ -37,6 +37,7 @@ Item {
property real crossEdgeExtension: 0
property string segmentRole: "solo"
property real splitOffset: 0
property int pressedSegment: 0
readonly property color defaultContentColor: Theme.widgetTextColor
property color contentColor: defaultContentColor
readonly property real dpr: parentScreen ? CompositorService.getScreenScale(parentScreen) : 1
@@ -113,22 +114,34 @@ Item {
signal rightClicked(real rootX, real rootY)
signal wheel(var wheelEvent)
function cornerRadius(joined) {
function cornerRadius(joined, progress = pressProgress) {
if (noBackground)
return 0;
return BarMetrics.cornerRadius(widgetThickness, BarMetrics.widgetStyle(barConfig), joined, pressProgress);
return BarMetrics.cornerRadius(widgetThickness, BarMetrics.widgetStyle(barConfig), joined, progress);
}
function segmentIndexAt(sourceItem, x, y) {
if (!visualContent.split)
return 0;
const pos = sourceItem.mapToItem(visualContent, x, y);
return (isVerticalOrientation ? pos.y : pos.x) >= splitOffset ? 1 : 0;
}
function triggerRipple(sourceItem, mouseX, mouseY) {
if (sourceItem !== root && "pressed" in sourceItem)
pressSource = sourceItem;
const pos = sourceItem.mapToItem(visualContent, mouseX, mouseY);
rippleLayer.trigger(pos.x, pos.y);
pressedSegment = segmentIndexAt(sourceItem, mouseX, mouseY);
const segment = segmentRepeater.itemAt(pressedSegment);
if (!segment)
return;
const pos = sourceItem.mapToItem(segment, mouseX, mouseY);
segment.ripple.trigger(pos.x, pos.y);
}
function handlePress(mouse, source) {
if (source !== root && "pressed" in source)
pressSource = source;
pressedSegment = segmentIndexAt(source, mouse.x, mouse.y);
if (mouse.button === Qt.RightButton) {
const rPos = source.mapToItem(root, mouse.x, mouse.y);
root.rightClicked(rPos.x, rPos.y);
@@ -220,11 +233,13 @@ Item {
property bool hovered: false
Repeater {
id: segmentRepeater
model: visualContent.split ? 2 : 1
Item {
id: segment
required property int index
readonly property alias ripple: ripple
readonly property bool leading: index === 0
readonly property bool joinedStart: visualContent.split && !leading
readonly property bool joinedEnd: visualContent.split && leading
@@ -235,10 +250,9 @@ Item {
return full;
return leading ? root.splitOffset - visualContent.splitGap / 2 : full - root.splitOffset - visualContent.splitGap / 2;
}
readonly property real startRadiusA: joinedStart ? root.cornerRadius(true) : root.topLeftRadius
readonly property real startRadiusB: joinedStart ? root.cornerRadius(true) : (root.isVerticalOrientation ? root.topRightRadius : root.bottomLeftRadius)
readonly property real endRadiusA: joinedEnd ? root.cornerRadius(true) : (root.isVerticalOrientation ? root.bottomLeftRadius : root.topRightRadius)
readonly property real endRadiusB: joinedEnd ? root.cornerRadius(true) : root.bottomRightRadius
readonly property real pressProgress: !visualContent.split || index === root.pressedSegment ? root.pressProgress : 0
readonly property real startRadius: root.cornerRadius(joinedStart || root.startJoined, pressProgress)
readonly property real endRadius: root.cornerRadius(joinedEnd || root.endJoined, pressProgress)
x: root.isVerticalOrientation ? 0 : along
y: root.isVerticalOrientation ? along : 0
@@ -263,10 +277,10 @@ Item {
Rectangle {
anchors.fill: parent
anchors.margins: -root.outlineThickness
topLeftRadius: segment.startRadiusA + root.outlineThickness
topRightRadius: (root.isVerticalOrientation ? segment.startRadiusB : segment.endRadiusA) + root.outlineThickness
bottomLeftRadius: (root.isVerticalOrientation ? segment.endRadiusA : segment.startRadiusB) + root.outlineThickness
bottomRightRadius: segment.endRadiusB + root.outlineThickness
topLeftRadius: fill.topLeftRadius + root.outlineThickness
topRightRadius: fill.topRightRadius + root.outlineThickness
bottomLeftRadius: fill.bottomLeftRadius + root.outlineThickness
bottomRightRadius: fill.bottomRightRadius + root.outlineThickness
color: "transparent"
border.width: root.outlineThickness
border.color: root.outlineColor
@@ -276,10 +290,10 @@ Item {
Rectangle {
id: fill
anchors.fill: parent
topLeftRadius: segment.startRadiusA
topRightRadius: root.isVerticalOrientation ? segment.startRadiusB : segment.endRadiusA
bottomLeftRadius: root.isVerticalOrientation ? segment.endRadiusA : segment.startRadiusB
bottomRightRadius: segment.endRadiusB
topLeftRadius: segment.startRadius
topRightRadius: root.isVerticalOrientation ? segment.startRadius : segment.endRadius
bottomLeftRadius: root.isVerticalOrientation ? segment.endRadius : segment.startRadius
bottomRightRadius: segment.endRadius
color: root.fillColor
}
@@ -297,16 +311,16 @@ Item {
onContainsMouseChanged: visualContent.hovered = containsMouse
onPressed: mouse => root.handlePress(mouse, stateLayer)
}
}
}
DRipple {
id: rippleLayer
rippleColor: Theme.surfaceText
topLeftRadius: root.topLeftRadius
topRightRadius: root.topRightRadius
bottomLeftRadius: root.bottomLeftRadius
bottomRightRadius: root.bottomRightRadius
DRipple {
id: ripple
rippleColor: Theme.surfaceText
topLeftRadius: fill.topLeftRadius
topRightRadius: fill.topRightRadius
bottomLeftRadius: fill.bottomLeftRadius
bottomRightRadius: fill.bottomRightRadius
}
}
}
FocusRing {