Add animations everywhere

This commit is contained in:
Ly-sec 2025-08-13 15:09:49 +02:00
commit c3304818f1
16 changed files with 637 additions and 174 deletions

View file

@ -10,6 +10,8 @@ import qs.Widgets
NLoader {
id: root
property int currentTabIndex: 0
content: Component {
NPanel {
id: panel
@ -52,7 +54,6 @@ NLoader {
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
property int currentTabIndex: 0
property var tabsModel: [{
"label": "General",
"icon": "tune",
@ -89,11 +90,12 @@ NLoader {
"label": "Wallpaper Selector",
"icon": "wallpaper_slideshow",
"source": "Tabs/WallpaperSelector.qml"
}, {
"label": "Misc",
"icon": "more_horiz",
"source": "Tabs/Misc.qml"
}, {
}, // {
// "label": "Misc",
// "icon": "more_horiz",
// "source": "Tabs/Misc.qml"
// },
{
"label": "About",
"icon": "info",
"source": "Tabs/About.qml"
@ -186,7 +188,7 @@ NLoader {
delegate: Rectangle {
id: tabItem
readonly property bool selected: index === panel.currentTabIndex
width: parent.width
height: 32 * scaling // Back to original height
radius: Style.radiusSmall * scaling
@ -194,6 +196,8 @@ NLoader {
border.color: "transparent"
border.width: 0
readonly property bool selected: index === currentTabIndex
// Subtle hover effect: only icon/text color tint on hover
property bool hovering: false
@ -227,7 +231,7 @@ NLoader {
onEntered: tabItem.hovering = true
onExited: tabItem.hovering = false
onCanceled: tabItem.hovering = false
onClicked: panel.currentTabIndex = index
onClicked: currentTabIndex = index
}
}
}
@ -258,7 +262,7 @@ NLoader {
// Tab label on the main right
NText {
text: panel.tabsModel[panel.currentTabIndex].label
text: panel.tabsModel[currentTabIndex].label
font.pointSize: Style.fontSizeLarge * scaling
font.weight: Style.fontWeightBold
color: Colors.accentPrimary
@ -282,7 +286,7 @@ NLoader {
id: stack
Layout.fillWidth: true
Layout.fillHeight: true
currentIndex: panel.currentTabIndex
currentIndex: currentTabIndex
Tabs.General {}
Tabs.Bar {}

View file

@ -88,14 +88,14 @@ ColumnLayout {
}
}
NToggle {
id: allowOverdrive
label: "Allow Volume Overdrive"
description: "Enable volume levels above 100% (up to 200%)"
value: Settings.data.audio ? Settings.data.audio.volumeOverdrive : false
onToggled: function (checked) {
Settings.data.audio.volumeOverdrive = checked
NToggle {
id: allowOverdrive
label: "Allow Volume Overdrive"
description: "Enable volume levels above 100% (up to 200%)"
value: Settings.data.audio ? Settings.data.audio.volumeOverdrive : false
onToggled: function (checked) {
Settings.data.audio.volumeOverdrive = checked
// If overdrive is disabled and current volume is above 100%, cap it
if (!checked && Audio.volume > 1.0) {
Audio.volumeSet(1.0)
@ -140,58 +140,56 @@ ColumnLayout {
font.weight: Style.fontWeightBold
color: Colors.textPrimary
Layout.bottomMargin: Style.marginSmall * scaling
}
// Output Device
NComboBox {
id: outputDeviceCombo
label: "Output Device"
description: "Default audio output device"
optionsKeys: outputDeviceKeys
optionsLabels: outputDeviceLabels
currentKey: Audio.sink ? Audio.sink.id.toString() : ""
onSelected: function (key) {
// Find the node by ID and set it as preferred
for (let i = 0; i < Pipewire.nodes.count; i++) {
let node = Pipewire.nodes.get(i)
if (node.id.toString() === key && node.isSink) {
Pipewire.preferredDefaultAudioSink = node
break
}
}
}
}
// Input Device
NComboBox {
id: inputDeviceCombo
label: "Input Device"
description: "Default audio input device"
optionsKeys: inputDeviceKeys
optionsLabels: inputDeviceLabels
currentKey: Audio.source ? Audio.source.id.toString() : ""
onSelected: function (key) {
// Find the node by ID and set it as preferred
for (let i = 0; i < Pipewire.nodes.count; i++) {
let node = Pipewire.nodes.get(i)
if (node.id.toString() === key && !node.isSink) {
Pipewire.preferredDefaultAudioSource = node
break
}
}
}
}
}
// Divider
NDivider {
Layout.fillWidth: true
Layout.topMargin: Style.marginLarge * scaling
Layout.bottomMargin: Style.marginMedium * scaling
}
// Output Device
NComboBox {
id: outputDeviceCombo
label: "Output Device"
description: "Default audio output device"
optionsKeys: outputDeviceKeys
optionsLabels: outputDeviceLabels
currentKey: Audio.sink ? Audio.sink.id.toString() : ""
onSelected: function (key) {
// Find the node by ID and set it as preferred
for (var i = 0; i < Pipewire.nodes.count; i++) {
let node = Pipewire.nodes.get(i)
if (node.id.toString() === key && node.isSink) {
Pipewire.preferredDefaultAudioSink = node
break
}
}
}
}
// Input Device
NComboBox {
id: inputDeviceCombo
label: "Input Device"
description: "Default audio input device"
optionsKeys: inputDeviceKeys
optionsLabels: inputDeviceLabels
currentKey: Audio.source ? Audio.source.id.toString() : ""
onSelected: function (key) {
// Find the node by ID and set it as preferred
for (var i = 0; i < Pipewire.nodes.count; i++) {
let node = Pipewire.nodes.get(i)
if (node.id.toString() === key && !node.isSink) {
Pipewire.preferredDefaultAudioSource = node
break
}
}
}
}
}
// Divider
NDivider {
Layout.fillWidth: true
Layout.topMargin: Style.marginLarge * scaling
Layout.bottomMargin: Style.marginMedium * scaling
}
// Audio Visualizer Category
ColumnLayout {
spacing: Style.marginSmall * scaling
@ -298,11 +296,11 @@ ColumnLayout {
outputDeviceCombo.optionsKeys = outputDeviceKeys
outputDeviceCombo.optionsLabels = outputDeviceLabels
}
if (inputDeviceCombo) {
inputDeviceCombo.optionsKeys = inputDeviceKeys
inputDeviceCombo.optionsLabels = inputDeviceLabels
}
}
}
}
}

View file

@ -39,8 +39,6 @@ ColumnLayout {
color: Colors.textPrimary
Layout.bottomMargin: Style.marginSmall * scaling
}
}
}
}