nosignal-shell/components/controls/FilledSlider.qml
28allday dcce2440f6 fix(nosignal): square the OSD (volume/brightness) to match the design
The volume/brightness OSD popped out as a rounded caelestia blob in the dynamic
surface colour. Square it + match the design glass:
- osd/Content: draw a flat square Theme.panelBg + 1px border background.
- ContentWindow: osdBg blob deformAmount 0 + radius 0 + opacity 0 (hidden;
  the OSD now owns its background).
- FilledSlider: track + handle radius -> 0 (Tokens.rounding.full ignored
  rounding.scale, so it stayed round).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 11:54:35 +01:00

128 lines
3.2 KiB
QML

import "../effects"
import QtQuick
import QtQuick.Templates
import Caelestia.Config
import qs.components
import qs.services
Slider {
id: root
required property string icon
property real oldValue
property bool initialized
orientation: Qt.Vertical
background: StyledRect {
color: Colours.layer(Colours.palette.m3surfaceContainer, 2)
radius: 0
StyledRect {
anchors.left: parent.left
anchors.right: parent.right
y: root.handle.y
implicitHeight: parent.height - y
color: Colours.palette.m3secondary
radius: parent.radius
}
}
handle: Item {
id: handle
property alias moving: icon.moving
y: root.visualPosition * (root.availableHeight - height)
implicitWidth: root.width
implicitHeight: root.width
Elevation {
anchors.fill: parent
radius: rect.radius
level: handleInteraction.containsMouse ? 2 : 1
}
StyledRect {
id: rect
anchors.fill: parent
color: Colours.palette.m3inverseSurface
radius: 0
MouseArea {
id: handleInteraction
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.NoButton
}
MaterialIcon {
id: icon
property bool moving
anchors.centerIn: parent
anchors.verticalCenterOffset: 1
text: moving ? Math.round(root.value * 100) : root.icon
color: Colours.palette.m3inverseOnSurface
font: moving ? Tokens.font.body.small : Tokens.font.icon.medium
Behavior on moving {
SequentialAnimation {
Anim {
target: icon
property: "scale"
to: 0.3
duration: Tokens.anim.durations.small / 2
easing: Tokens.anim.standardAccel
}
PropertyAction {}
Anim {
target: icon
property: "scale"
to: 1
duration: Tokens.anim.durations.normal / 2
easing: Tokens.anim.standardDecel
}
}
}
}
}
}
onPressedChanged: handle.moving = pressed
onValueChanged: {
if (!initialized) {
initialized = true;
return;
}
if (Math.abs(value - oldValue) < 0.01)
return;
oldValue = value;
handle.moving = true;
stateChangeDelay.restart();
}
Timer {
id: stateChangeDelay
interval: 500
onTriggered: {
if (!root.pressed)
handle.moving = false;
}
}
Behavior on value {
Anim {
type: Anim.StandardLarge
}
}
}