NTabBar + NTabBarButton

This commit is contained in:
ItsLemmy
2025-11-05 00:54:22 -05:00
parent 569a5ba8df
commit a0cdafc0e2
4 changed files with 109 additions and 51 deletions

View File

@@ -124,18 +124,21 @@ ColumnLayout {
}
// Monitor tabs - only visible when not syncing
TabBar {
NTabBar {
id: monitorTabBar
Layout.fillWidth: true
visible: !Settings.data.bar.syncAcrossMonitors
currentIndex: currentMonitorIndex
onCurrentIndexChanged: currentMonitorIndex = currentIndex
Repeater {
model: Quickshell.screens
TabButton {
NTabButton {
required property var modelData
required property int index
text: modelData.name
onClicked: currentMonitorIndex = index
tabIndex: index
checked: monitorTabBar.currentIndex === index
}
}
}
@@ -150,6 +153,7 @@ ColumnLayout {
NToggle {
Layout.fillWidth: true
visible: !Settings.data.bar.syncAcrossMonitors
//TODO TRANSLATE
label: `Show bar on ${currentMonitorName}`
description: `Enable or disable the bar on this monitor`
checked: (Settings.data.bar.monitors || []).length === 0 || (Settings.data.bar.monitors || []).indexOf(currentMonitorName) !== -1

View File

@@ -222,7 +222,7 @@ NPanel {
}
// Monitor tabs
TabBar {
NTabBar {
id: screenTabBar
visible: !Settings.data.wallpaper.setWallpaperOnAllMonitors || Settings.data.wallpaper.enableMultiMonitorDirectories
Layout.fillWidth: true
@@ -230,56 +230,14 @@ NPanel {
onCurrentIndexChanged: currentScreenIndex = currentIndex
spacing: Style.marginM
background: Rectangle {
color: Color.transparent
}
Repeater {
model: Quickshell.screens
delegate: TabButton {
NTabButton {
required property var modelData
required property int index
text: modelData.name || `Screen ${index + 1}`
width: implicitWidth + Style.marginS * 2
background: Rectangle {
color: screenTabBar.currentIndex === index ? Color.mSecondary : Color.transparent
radius: Style.radiusS
border.width: screenTabBar.currentIndex === index ? 0 : Style.borderS
border.color: Color.mOutline
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
}
contentItem: NText {
text: parent.text
pointSize: Style.fontSizeL
font.weight: screenTabBar.currentIndex === index ? Style.fontWeightBold : Style.fontWeightRegular
family: Settings.data.ui.fontDefault
color: screenTabBar.currentIndex === index ? Color.mOnSecondary : Color.mOnSurfaceVariant
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
// Add hover effect
HoverHandler {
id: tabHover
}
Rectangle {
anchors.fill: parent
color: Color.mOnSurface
opacity: tabHover.hovered && screenTabBar.currentIndex !== index ? 0.08 : 0
radius: Style.radiusS
Behavior on opacity {
NumberAnimation {
duration: Style.animationFast
}
}
}
tabIndex: index
checked: screenTabBar.currentIndex === index
}
}
}

28
Widgets/NTabBar.qml Normal file
View File

@@ -0,0 +1,28 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.Commons
import qs.Services
import qs.Widgets
Rectangle {
id: root
// Public properties
property int currentIndex: 0
property int spacing: Style.marginS
default property alias content: tabRow.children
// Styling
Layout.fillWidth: true
implicitHeight: Style.baseWidgetSize + Style.marginXS * 2
color: Color.mSurfaceVariant
radius: Style.radiusS
RowLayout {
id: tabRow
anchors.fill: parent
anchors.margins: Style.marginXS
spacing: root.spacing
}
}

68
Widgets/NTabButton.qml Normal file
View File

@@ -0,0 +1,68 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.Commons
import qs.Services
import qs.Widgets
Rectangle {
id: root
// Public properties
property string text: ""
property bool checked: false
property int tabIndex: 0
// Internal state
property bool isHovered: false
signal clicked
// Sizing
Layout.fillWidth: true
Layout.fillHeight: true
// Styling
radius: Style.radiusXS
color: root.checked ? Color.mPrimary : (root.isHovered ? Color.mHover : Color.mSurface)
Behavior on color {
ColorAnimation {
duration: Style.animationFast
easing.type: Easing.OutCubic
}
}
NText {
id: tabText
anchors.centerIn: parent
text: root.text
pointSize: Style.fontSizeM
font.weight: root.checked ? Style.fontWeightSemiBold : Style.fontWeightRegular
color: root.checked ? Color.mOnPrimary : root.isHovered ? Color.mOnHover : Color.mOnSurface
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
Behavior on color {
ColorAnimation {
duration: Style.animationFast
easing.type: Easing.OutCubic
}
}
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onEntered: root.isHovered = true
onExited: root.isHovered = false
onClicked: {
root.clicked()
// Update parent NTabBar's currentIndex
if (root.parent && root.parent.parent && root.parent.parent.currentIndex !== undefined) {
root.parent.parent.currentIndex = root.tabIndex
}
}
}
}