diff --git a/.config/quickshell/modules/common/widgets/ButtonGroup.qml b/.config/quickshell/modules/common/widgets/ButtonGroup.qml new file mode 100644 index 00000000..15e0a8dd --- /dev/null +++ b/.config/quickshell/modules/common/widgets/ButtonGroup.qml @@ -0,0 +1,49 @@ +import "root:/modules/common" +import "root:/modules/common/widgets" +import "root:/modules/common/functions/color_utils.js" as ColorUtils +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +/** + * A container that supports bouncy children. + * https://m3.material.io/components/button-groups/overview + */ +Rectangle { + id: root + default property alias content: rowLayout.data + property real spacing: 5 + property real padding: 5 + + property real contentWidth: { + let total = 0; + for (let i = 0; i < rowLayout.children.length; ++i) { + if (rowLayout.children[i].baseWidth !== undefined) + total += rowLayout.children[i].baseWidth; + } + return total + rowLayout.spacing * (rowLayout.children.length - 1); + } + + topLeftRadius: rowLayout.children.length > 0 ? (rowLayout.children[0].radius + padding) : + Appearance?.rounding?.small + bottomLeftRadius: topLeftRadius + topRightRadius: { + console.log(rowLayout.children.length > 0 ? (rowLayout.children[rowLayout.children.length - 1].radius + padding) : + Appearance?.rounding?.small) + return rowLayout.children.length > 0 ? (rowLayout.children[rowLayout.children.length - 1].radius + padding) : + Appearance?.rounding?.small + } + bottomRightRadius: topRightRadius + + color: "transparent" + width: root.contentWidth + padding * 2 + implicitHeight: rowLayout.implicitHeight + padding * 2 + + children: [RowLayout { + id: rowLayout + anchors.fill: parent + anchors.margins: root.padding + spacing: root.spacing + property int clickIndex: -1 + }] +} diff --git a/.config/quickshell/modules/common/widgets/GroupButton.qml b/.config/quickshell/modules/common/widgets/GroupButton.qml new file mode 100644 index 00000000..1d6f15f0 --- /dev/null +++ b/.config/quickshell/modules/common/widgets/GroupButton.qml @@ -0,0 +1,82 @@ +import "root:/modules/common" +import "root:/modules/common/widgets" +import "root:/modules/common/functions/color_utils.js" as ColorUtils +import Qt5Compat.GraphicalEffects +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell.Io +import Quickshell.Widgets + +Button { + id: root + property bool toggled + property string buttonText + property real buttonRadius: Appearance?.rounding?.small ?? 4 + property real buttonRadiusPressed: buttonRadius + property var altAction + property real baseWidth: 40 + property real baseHeight: 40 + property real clickedWidth: 60 + property real clickedHeight: 40 + property int clickIndex: parent?.clickIndex ?? -1 + + Layout.fillWidth: (clickIndex - 1 <= parent.children.indexOf(button) && parent.children.indexOf(button) <= clickIndex + 1) + implicitWidth: button.down ? clickedWidth : baseWidth + implicitHeight: button.down ? clickedHeight : baseHeight + + Behavior on implicitWidth { + animation: Appearance.animation.clickBounce.numberAnimation.createObject(this) + } + + Behavior on radius { + animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) + } + + property color colBackground: ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1) + property color colBackgroundHover: Appearance.colors.colLayer1Hover + property color colBackgroundToggled: Appearance.m3colors.m3primary + property color colBackgroundToggledHover: Appearance.colors.colPrimaryHover + + property real radius: root.down ? root.buttonRadiusPressed : root.buttonRadius + property color color: root.enabled ? (root.toggled ? + (root.hovered ? colBackgroundToggledHover : + colBackgroundToggled) : + (root.hovered ? colBackgroundHover : + colBackground)) : colBackground + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + acceptedButtons: Qt.LeftButton | Qt.RightButton + onPressed: (event) => { + if(event.button === Qt.RightButton) { + if (root.altAction) root.altAction(); + return; + } + root.down = true + } + onReleased: (event) => { + root.down = false + root.click() // Because the MouseArea already consumed the event + } + onCanceled: (event) => { + root.down = false + } + } + + background: Rectangle { + id: buttonBackground + radius: root.radius + implicitHeight: 50 + + color: root.color + Behavior on color { + animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) + } + } + + contentItem: StyledText { + text: root.buttonText + } +} diff --git a/.config/quickshell/modules/sidebarRight/SidebarRight.qml b/.config/quickshell/modules/sidebarRight/SidebarRight.qml index 95f081d3..e509efc6 100644 --- a/.config/quickshell/modules/sidebarRight/SidebarRight.qml +++ b/.config/quickshell/modules/sidebarRight/SidebarRight.qml @@ -132,29 +132,17 @@ Scope { } } - Rectangle { + ButtonGroup { Layout.alignment: Qt.AlignHCenter - Layout.fillHeight: false - radius: Appearance.rounding.full + spacing: 5 + padding: 5 color: Appearance.colors.colLayer1 - width: 40 * sidebarQuickControlsRow.children.length + sidebarQuickControlsRow.spacing * (sidebarQuickControlsRow.children.length-1) + 10 - implicitHeight: sidebarQuickControlsRow.implicitHeight + 10 - - - RowLayout { - id: sidebarQuickControlsRow - anchors.fill: parent - anchors.margins: 5 - spacing: 5 - width: 40 * sidebarQuickControlsRow.children.length - property int clickIndex: -1 - NetworkToggle {} - BluetoothToggle {} - NightLight {} - GameMode {} - IdleInhibitor {} - } + NetworkToggle {} + BluetoothToggle {} + NightLight {} + GameMode {} + IdleInhibitor {} } // Center widget group diff --git a/.config/quickshell/modules/sidebarRight/quickToggles/QuickToggleButton.qml b/.config/quickshell/modules/sidebarRight/quickToggles/QuickToggleButton.qml index 873abda8..437283ce 100644 --- a/.config/quickshell/modules/sidebarRight/quickToggles/QuickToggleButton.qml +++ b/.config/quickshell/modules/sidebarRight/quickToggles/QuickToggleButton.qml @@ -6,23 +6,17 @@ import QtQuick.Controls import QtQuick.Layouts import Quickshell.Io -RippleButton { +GroupButton { id: button - rippleEnabled: false property string buttonIcon - property int clickIndex: parent?.clickIndex ?? -1 + baseWidth: 40 + baseHeight: 40 + clickedWidth: 60 + clickedHeight: 40 toggled: false - buttonRadius: Appearance?.rounding?.full + buttonRadius: Math.min(baseHeight, baseWidth) / 2 buttonRadiusPressed: Appearance?.rounding?.small - Layout.fillWidth: (clickIndex - 1 <= parent.children.indexOf(button) && parent.children.indexOf(button) <= clickIndex + 1) - implicitWidth: button.down ? 60 : 40 - implicitHeight: 40 - - Behavior on implicitWidth { - animation: Appearance.animation.clickBounce.numberAnimation.createObject(this) - } - onDownChanged: { if (button.down) { if (button.parent.clickIndex !== undefined) {