quickshell: steal wifi & bluetooth panel

This commit is contained in:
2025-10-19 04:08:22 +02:00
parent ffa502e0c3
commit acf6f69268
27 changed files with 2355 additions and 124 deletions

View File

@@ -15,10 +15,10 @@ Rectangle {
property color textColor: Color.mOnPrimary
property color hoverColor: Color.mTertiary
property bool enabled: true
property real fontSize: Style.fontSizeM * scaling
property real fontSize: Style.fontSizeM
property int fontWeight: Style.fontWeightBold
property string fontFamily: Fonts.primary
property real iconSize: Style.fontSizeL * scaling
property real iconSize: Style.fontSizeL
property bool outlined: false
// Internal properties
property bool hovered: false
@@ -30,10 +30,10 @@ Rectangle {
signal middleClicked()
// Dimensions
implicitWidth: contentRow.implicitWidth + (Style.marginL * 2 * scaling)
implicitHeight: Math.max(Style.baseWidgetSize * scaling, contentRow.implicitHeight + (Style.marginM * scaling))
implicitWidth: contentRow.implicitWidth + (Style.marginL * 2)
implicitHeight: Math.max(Style.baseWidgetSize, contentRow.implicitHeight + (Style.marginM))
// Appearance
radius: Style.radiusS * scaling
radius: Style.radiusS
color: {
if (!enabled)
return outlined ? Color.transparent : Qt.lighter(Color.mSurfaceVariant, 1.2);
@@ -43,7 +43,7 @@ Rectangle {
return outlined ? Color.transparent : backgroundColor;
}
border.width: outlined ? Math.max(1, Style.borderS * scaling) : 0
border.width: outlined ? Math.max(1, Style.borderS) : 0
border.color: {
if (!enabled)
return Color.mOutline;
@@ -60,7 +60,7 @@ Rectangle {
id: contentRow
anchors.centerIn: parent
spacing: Style.marginXS * scaling
spacing: Style.marginXS
// Icon (optional)
NIcon {

View File

@@ -0,0 +1,34 @@
import QtQuick
import QtQuick.Layouts
import qs.Constants
ColumnLayout {
id: root
property string label: ""
property string description: ""
property color labelColor: Color.mOnSurface
property color descriptionColor: Color.mOnSurfaceVariant
spacing: Style.marginXXS
Layout.fillWidth: true
NText {
text: label
pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: labelColor
visible: label !== ""
Layout.fillWidth: true
}
NText {
text: description
pointSize: Style.fontSizeS
color: descriptionColor
wrapMode: Text.WordWrap
visible: description !== ""
Layout.fillWidth: true
}
}

View File

@@ -0,0 +1,152 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Templates as T
import qs.Constants
T.ScrollView {
id: root
property color handleColor: Qt.alpha(Color.mTertiary, 0.8)
property color handleHoverColor: handleColor
property color handlePressedColor: handleColor
property color trackColor: Color.transparent
property real handleWidth: 6
property real handleRadius: Style.radiusM
property int verticalPolicy: ScrollBar.AsNeeded
property int horizontalPolicy: ScrollBar.AsNeeded
property bool preventHorizontalScroll: horizontalPolicy === ScrollBar.AlwaysOff
property int boundsBehavior: Flickable.StopAtBounds
property int flickableDirection: Flickable.VerticalFlick
// Function to configure the underlying Flickable
function configureFlickable() {
// Find the internal Flickable (it's usually the first child)
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (child.toString().indexOf("Flickable") !== -1) {
// Configure the flickable to prevent horizontal scrolling
child.boundsBehavior = root.boundsBehavior;
if (root.preventHorizontalScroll) {
child.flickableDirection = Flickable.VerticalFlick;
child.contentWidth = Qt.binding(() => {
return child.width;
});
} else {
child.flickableDirection = root.flickableDirection;
}
break;
}
}
}
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, contentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, contentHeight + topPadding + bottomPadding)
// Configure the internal flickable when it becomes available
Component.onCompleted: {
configureFlickable();
}
// Watch for changes in horizontalPolicy
onHorizontalPolicyChanged: {
preventHorizontalScroll = (horizontalPolicy === ScrollBar.AlwaysOff);
configureFlickable();
}
ScrollBar.vertical: ScrollBar {
parent: root
x: root.mirrored ? 0 : root.width - width
y: root.topPadding
height: root.availableHeight
active: root.ScrollBar.horizontal.active
policy: root.verticalPolicy
contentItem: Rectangle {
implicitWidth: root.handleWidth
implicitHeight: 100
radius: root.handleRadius
color: parent.pressed ? root.handlePressedColor : parent.hovered ? root.handleHoverColor : root.handleColor
opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: Style.animationFast
}
}
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
}
background: Rectangle {
implicitWidth: root.handleWidth
implicitHeight: 100
color: root.trackColor
opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 0.3 : 0
radius: root.handleRadius / 2
Behavior on opacity {
NumberAnimation {
duration: Style.animationFast
}
}
}
}
ScrollBar.horizontal: ScrollBar {
parent: root
x: root.leftPadding
y: root.height - height
width: root.availableWidth
active: root.ScrollBar.vertical.active
policy: root.horizontalPolicy
contentItem: Rectangle {
implicitWidth: 100
implicitHeight: root.handleWidth
radius: root.handleRadius
color: parent.pressed ? root.handlePressedColor : parent.hovered ? root.handleHoverColor : root.handleColor
opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: Style.animationFast
}
}
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
}
background: Rectangle {
implicitWidth: 100
implicitHeight: root.handleWidth
color: root.trackColor
opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 0.3 : 0
radius: root.handleRadius / 2
Behavior on opacity {
NumberAnimation {
duration: Style.animationFast
}
}
}
}
}

View File

@@ -0,0 +1,90 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.Constants
RowLayout {
id: root
property string label: ""
property string description: ""
property bool checked: false
property bool hovering: false
property int baseSize: Math.round(Style.baseWidgetSize * 0.8)
signal toggled(bool checked)
signal entered()
signal exited()
Layout.fillWidth: true
NLabel {
label: root.label
description: root.description
}
Rectangle {
id: switcher
implicitWidth: Math.round(root.baseSize * 0.85) * 2
implicitHeight: Math.round(root.baseSize * 0.5) * 2
radius: height * 0.5
color: root.checked ? Color.mPrimary : Color.mSurface
border.color: Color.mOutline
border.width: Math.max(1, Style.borderS)
Rectangle {
implicitWidth: Math.round(root.baseSize * 0.4) * 2
implicitHeight: Math.round(root.baseSize * 0.4) * 2
radius: height * 0.5
color: root.checked ? Color.mOnPrimary : Color.mPrimary
border.color: root.checked ? Color.mSurface : Color.mSurface
border.width: Math.max(1, Style.borderM)
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: 0
x: root.checked ? switcher.width - width - 3 : 3
Behavior on x {
NumberAnimation {
duration: Style.animationFast
easing.type: Easing.OutCubic
}
}
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onEntered: {
hovering = true;
root.entered();
}
onExited: {
hovering = false;
root.exited();
}
onClicked: {
root.toggled(!root.checked);
}
}
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
Behavior on border.color {
ColorAnimation {
duration: Style.animationFast
}
}
}
}