Files
TNCcat/qml/AppSlider.qml
T
JulianandClaude Opus 5 1581a760be Drop Qt Quick Controls and Qt Widgets
The binary now links Core, Gui, Quick and QuickShapes, nothing else.

Qt Widgets was there for one reason, QSystemTrayIcon, so the tray icon is gone
and QApplication is back to QGuiApplication. The cat itself is the whole
interface: right-click or long-press opens the settings window, which carries
the tricks and a quit button. Ctrl+C in the terminal works as well.

The settings window is rebuilt from Qt Quick primitives. AppButton, AppSlider,
AppToggle and SettingsGroup replace the Controls types, keyboard handling and
accessible roles included, and a Flickable with plain positioners replaces
QtQuick.Layouts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 08:58:51 +02:00

115 lines
3.4 KiB
QML

pragma ComponentBehavior: Bound
import QtQuick
// A horizontal slider built from primitives. Reports every change through
// moved() rather than writing back, so the owner stays the single source.
Item {
id: slider
property real from: 0
property real to: 100
property real stepSize: 1
property real value: 0
property string suffix: ""
signal moved(real value)
readonly property real span: Math.max(0.0001, to - from)
readonly property real position: Math.min(1, Math.max(0, (value - from) / span))
function valueAt(px) {
const usable = Math.max(1, track.width - handle.width)
const ratio = Math.min(1, Math.max(0, (px - handle.width / 2) / usable))
const raw = from + ratio * span
return Math.min(to, Math.max(from, Math.round(raw / stepSize) * stepSize))
}
function nudge(steps) {
slider.moved(Math.min(to, Math.max(from, value + steps * stepSize)))
}
implicitWidth: 220
implicitHeight: 26
activeFocusOnTab: true
Accessible.role: Accessible.Slider
Accessible.name: qsTr("Slider")
Accessible.onIncreaseAction: slider.nudge(1)
Accessible.onDecreaseAction: slider.nudge(-1)
Text {
id: readout
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
width: slider.suffix.length > 0 ? 52 : 0
visible: slider.suffix.length > 0
horizontalAlignment: Text.AlignRight
text: Math.round(slider.value) + " " + slider.suffix
color: "#7a7484"
font.pixelSize: 12
}
Item {
id: track
anchors.left: parent.left
anchors.right: readout.visible ? readout.left : parent.right
anchors.rightMargin: readout.visible ? 8 : 0
anchors.verticalCenter: parent.verticalCenter
height: parent.height
Rectangle {
anchors.verticalCenter: parent.verticalCenter
width: parent.width
height: 4
radius: 2
color: "#ded8cf"
antialiasing: true
Rectangle {
width: parent.width * slider.position
height: parent.height
radius: parent.radius
color: "#4d7ea8"
antialiasing: true
}
}
Rectangle {
id: handle
x: (track.width - width) * slider.position
anchors.verticalCenter: parent.verticalCenter
width: 18
height: 18
radius: 9
color: "white"
border.width: slider.activeFocus ? 3 : 2
border.color: slider.activeFocus ? "#2f5f85" : "#4d7ea8"
antialiasing: true
}
TapHandler {
onTapped: function(point) { slider.moved(slider.valueAt(point.position.x)) }
}
DragHandler {
target: null
xAxis.enabled: true
yAxis.enabled: false
onCentroidChanged: {
if (active)
slider.moved(slider.valueAt(centroid.position.x))
}
}
}
Keys.onPressed: function(event) {
if (event.key === Qt.Key_Left || event.key === Qt.Key_Down) {
slider.nudge(-1)
event.accepted = true
} else if (event.key === Qt.Key_Right || event.key === Qt.Key_Up) {
slider.nudge(1)
event.accepted = true
}
}
}