Add NSpinBox, use in BrightnessTab, AudioTab
This commit is contained in:
parent
07705bb59c
commit
c3206881a3
7 changed files with 238 additions and 29 deletions
|
|
@ -217,6 +217,7 @@ Singleton {
|
||||||
|
|
||||||
audio: JsonObject {
|
audio: JsonObject {
|
||||||
property string visualizerType: "linear"
|
property string visualizerType: "linear"
|
||||||
|
property int volumeStep: 5
|
||||||
}
|
}
|
||||||
|
|
||||||
// ui
|
// ui
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,27 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Volume Step Size
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: Style.marginS * scaling
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.marginM * scaling
|
||||||
|
|
||||||
|
NSpinBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
label: "Volume Step Size"
|
||||||
|
description: "Adjust the step size for volume changes (scroll wheel, keyboard shortcuts)."
|
||||||
|
minimum: 1
|
||||||
|
maximum: 25
|
||||||
|
value: Settings.data.audio.volumeStep
|
||||||
|
stepSize: 1
|
||||||
|
suffix: "%"
|
||||||
|
onValueChanged: {
|
||||||
|
Settings.data.audio.volumeStep = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NDivider {
|
NDivider {
|
||||||
|
|
|
||||||
|
|
@ -49,34 +49,17 @@ Item {
|
||||||
spacing: Style.marginS * scaling
|
spacing: Style.marginS * scaling
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
NLabel {
|
NSpinBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
label: "Brightness Step Size"
|
label: "Brightness Step Size"
|
||||||
description: "Adjust the step size for brightness changes (scroll wheel, keyboard shortcuts)."
|
description: "Adjust the step size for brightness changes (scroll wheel, keyboard shortcuts)."
|
||||||
}
|
minimum: 1
|
||||||
|
maximum: 50
|
||||||
RowLayout {
|
value: Settings.data.brightness.brightnessStep
|
||||||
Layout.fillWidth: true
|
stepSize: 1
|
||||||
spacing: Style.marginM * scaling
|
suffix: "%"
|
||||||
|
onValueChanged: {
|
||||||
NSlider {
|
Settings.data.brightness.brightnessStep = value
|
||||||
Layout.fillWidth: true
|
|
||||||
from: 1
|
|
||||||
to: 50
|
|
||||||
value: Settings.data.brightness.brightnessStep
|
|
||||||
stepSize: 1
|
|
||||||
onPressedChanged: {
|
|
||||||
if (!pressed) {
|
|
||||||
Settings.data.brightness.brightnessStep = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: Settings.data.brightness.brightnessStep + "%"
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
color: Color.mOnSurface
|
|
||||||
font.pointSize: Style.fontSizeM * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -250,4 +250,4 @@ Thank you to everyone who supports me and this project 💜!
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under the terms of the [MIT License](./LICENSE).
|
This project is licensed under the terms of the [MIT License](./LICENSE).
|
||||||
|
|
@ -4,6 +4,7 @@ import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import Quickshell.Services.Pipewire
|
import Quickshell.Services.Pipewire
|
||||||
|
import qs.Commons
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
@ -34,7 +35,7 @@ Singleton {
|
||||||
readonly property alias muted: root._muted
|
readonly property alias muted: root._muted
|
||||||
property bool _muted: !!sink?.audio?.muted
|
property bool _muted: !!sink?.audio?.muted
|
||||||
|
|
||||||
readonly property real stepVolume: 0.05
|
readonly property real stepVolume: Settings.data.audio.volumeStep / 100.0
|
||||||
|
|
||||||
PwObjectTracker {
|
PwObjectTracker {
|
||||||
objects: [...root.sinks, ...root.sources]
|
objects: [...root.sinks, ...root.sources]
|
||||||
|
|
|
||||||
|
|
@ -47,4 +47,4 @@ Image {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
203
Widgets/NSpinBox.qml
Normal file
203
Widgets/NSpinBox.qml
Normal file
|
|
@ -0,0 +1,203 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.Commons
|
||||||
|
import qs.Services
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
// Public properties
|
||||||
|
property alias value: spinBox.value
|
||||||
|
property alias from: spinBox.from
|
||||||
|
property alias to: spinBox.to
|
||||||
|
property alias stepSize: spinBox.stepSize
|
||||||
|
property string suffix: ""
|
||||||
|
property string prefix: ""
|
||||||
|
property string label: ""
|
||||||
|
property string description: ""
|
||||||
|
property bool enabled: true
|
||||||
|
property bool hovering: false
|
||||||
|
property int baseSize: Style.baseWidgetSize
|
||||||
|
|
||||||
|
// Convenience properties for common naming
|
||||||
|
property alias minimum: spinBox.from
|
||||||
|
property alias maximum: spinBox.to
|
||||||
|
|
||||||
|
signal entered
|
||||||
|
signal exited
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: Style.marginXXS * scaling
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: label
|
||||||
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
|
font.weight: Style.fontWeightBold
|
||||||
|
color: Color.mOnSurface
|
||||||
|
visible: label !== ""
|
||||||
|
}
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: description
|
||||||
|
font.pointSize: Style.fontSizeS * scaling
|
||||||
|
color: Color.mOnSurfaceVariant
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
Layout.fillWidth: true
|
||||||
|
visible: description !== ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple value display with subtle controls
|
||||||
|
Rectangle {
|
||||||
|
id: spinBoxContainer
|
||||||
|
|
||||||
|
implicitWidth: 100 * scaling // Wider for better proportions
|
||||||
|
implicitHeight: (root.baseSize - 4) * scaling // Slightly shorter than toggle
|
||||||
|
radius: height * 0.5 // Fully rounded like toggle
|
||||||
|
color: Color.mSurfaceVariant
|
||||||
|
border.color: root.hovering ? Color.mPrimary : Color.mOutline
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Style.animationFast
|
||||||
|
easing.type: Easing.InOutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mouse area for scroll wheel and hover
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
hoverEnabled: true
|
||||||
|
onEntered: {
|
||||||
|
root.hovering = true
|
||||||
|
root.entered()
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
root.hovering = false
|
||||||
|
root.exited()
|
||||||
|
}
|
||||||
|
onWheel: function(wheel) {
|
||||||
|
if (wheel.angleDelta.y > 0 && spinBox.value < spinBox.to) {
|
||||||
|
spinBox.increase()
|
||||||
|
} else if (wheel.angleDelta.y < 0 && spinBox.value > spinBox.from) {
|
||||||
|
spinBox.decrease()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrease button (left)
|
||||||
|
Rectangle {
|
||||||
|
id: decreaseButton
|
||||||
|
width: parent.height * 0.8 // Make it circular
|
||||||
|
height: parent.height * 0.8
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: parent.height * 0.1
|
||||||
|
radius: width * 0.5 // Perfect circle
|
||||||
|
color: decreaseArea.containsMouse ? Color.mPrimary : "transparent"
|
||||||
|
opacity: root.enabled && spinBox.value > spinBox.from ? 1.0 : 0.3
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Style.animationFast
|
||||||
|
easing.type: Easing.InOutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "remove"
|
||||||
|
font.pointSize: Style.fontSizeS * scaling
|
||||||
|
color: decreaseArea.containsMouse ? Color.mOnPrimary : Color.mPrimary
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: decreaseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
enabled: root.enabled && spinBox.value > spinBox.from
|
||||||
|
onClicked: spinBox.decrease()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increase button (right)
|
||||||
|
Rectangle {
|
||||||
|
id: increaseButton
|
||||||
|
width: parent.height * 0.8 // Make it circular
|
||||||
|
height: parent.height * 0.8
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: parent.height * 0.1
|
||||||
|
radius: width * 0.5 // Perfect circle
|
||||||
|
color: increaseArea.containsMouse ? Color.mPrimary : "transparent"
|
||||||
|
opacity: root.enabled && spinBox.value < spinBox.to ? 1.0 : 0.3
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Style.animationFast
|
||||||
|
easing.type: Easing.InOutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "add"
|
||||||
|
font.pointSize: Style.fontSizeS * scaling
|
||||||
|
color: increaseArea.containsMouse ? Color.mOnPrimary : Color.mPrimary
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: increaseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
enabled: root.enabled && spinBox.value < spinBox.to
|
||||||
|
onClicked: spinBox.increase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Center value display
|
||||||
|
SpinBox {
|
||||||
|
id: spinBox
|
||||||
|
anchors.left: decreaseButton.right
|
||||||
|
anchors.right: increaseButton.left
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.margins: 4 * scaling
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
background: Item {}
|
||||||
|
up.indicator: Item {}
|
||||||
|
down.indicator: Item {}
|
||||||
|
|
||||||
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
|
font.family: Settings.data.ui.fontDefault
|
||||||
|
|
||||||
|
from: 0
|
||||||
|
to: 100
|
||||||
|
stepSize: 1
|
||||||
|
editable: false // Only use buttons/scroll
|
||||||
|
enabled: root.enabled
|
||||||
|
|
||||||
|
contentItem: Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
NText {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: root.prefix + spinBox.value + root.suffix
|
||||||
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
|
font.weight: Style.fontWeightMedium
|
||||||
|
color: Color.mOnSurface
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue