Files
illogical-impulse/.config/quickshell/ii/modules/verticalBar/VerticalBarContent.qml
T

372 lines
14 KiB
QML

import QtQuick
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
import Quickshell.Wayland
import Quickshell.Hyprland
import Quickshell.Services.UPower
import qs
import qs.services
import qs.modules.common
import qs.modules.common.widgets
import qs.modules.common.functions
import "../bar" as Bar
Item { // Bar content region
id: root
property var screen: root.QsWindow.window?.screen
property var brightnessMonitor: Brightness.getMonitorForScreen(screen)
component HorizontalBarSeparator: Rectangle {
Layout.leftMargin: Appearance.sizes.baseBarHeight / 3
Layout.rightMargin: Appearance.sizes.baseBarHeight / 3
Layout.fillWidth: true
implicitHeight: 1
color: Appearance.colors.colOutlineVariant
}
// Background shadow
Loader {
active: Config.options.bar.showBackground && Config.options.bar.cornerStyle === 1
anchors.fill: barBackground
sourceComponent: StyledRectangularShadow {
anchors.fill: undefined // The loader's anchors act on this, and this should not have any anchor
target: barBackground
}
}
// Background
Rectangle {
id: barBackground
anchors {
fill: parent
margins: Config.options.bar.cornerStyle === 1 ? (Appearance.sizes.hyprlandGapsOut) : 0 // idk why but +1 is needed
}
color: Config.options.bar.showBackground ? Appearance.colors.colLayer0 : "transparent"
radius: Config.options.bar.cornerStyle === 1 ? Appearance.rounding.windowRounding : 0
border.width: Config.options.bar.cornerStyle === 1 ? 1 : 0
border.color: Appearance.colors.colLayer0Border
}
MouseArea { // Top section | scroll to change brightness
id: barTopSectionMouseArea
anchors.top: parent.top
implicitHeight: topSectionColumnLayout.implicitHeight
implicitWidth: Appearance.sizes.baseVerticalBarWidth
height: (root.height - middleSection.height) / 2
width: Appearance.sizes.verticalBarWidth
property bool hovered: false
property real lastScrollX: 0
property real lastScrollY: 0
property bool trackingScroll: false
acceptedButtons: Qt.LeftButton
hoverEnabled: true
propagateComposedEvents: true
onEntered: event => {
barTopSectionMouseArea.hovered = true;
}
onExited: event => {
barTopSectionMouseArea.hovered = false;
barTopSectionMouseArea.trackingScroll = false;
}
onPressed: event => {
if (event.button === Qt.LeftButton) {
GlobalStates.sidebarLeftOpen = !GlobalStates.sidebarLeftOpen;
}
}
// Scroll to change brightness
WheelHandler {
onWheel: event => {
if (event.angleDelta.y < 0)
root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness - 0.05);
else if (event.angleDelta.y > 0)
root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness + 0.05);
// Store the mouse position and start tracking
barTopSectionMouseArea.lastScrollX = event.x;
barTopSectionMouseArea.lastScrollY = event.y;
barTopSectionMouseArea.trackingScroll = true;
}
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
}
onPositionChanged: mouse => {
if (barTopSectionMouseArea.trackingScroll) {
const dx = mouse.x - barTopSectionMouseArea.lastScrollX;
const dy = mouse.y - barTopSectionMouseArea.lastScrollY;
if (Math.sqrt(dx * dx + dy * dy) > osdHideMouseMoveThreshold) {
GlobalStates.osdBrightnessOpen = false;
barTopSectionMouseArea.trackingScroll = false;
}
}
}
ColumnLayout { // Content
id: topSectionColumnLayout
anchors.fill: parent
spacing: 10
RippleButton { // Left sidebar button
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
Layout.topMargin: (Appearance.sizes.baseVerticalBarWidth - implicitWidth) / 2 + Appearance.sizes.hyprlandGapsOut
Layout.fillHeight: false
property real buttonPadding: 5
implicitWidth: distroIcon.width + buttonPadding * 2
implicitHeight: distroIcon.height + buttonPadding * 2
buttonRadius: Appearance.rounding.full
colBackground: barTopSectionMouseArea.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1)
colBackgroundHover: Appearance.colors.colLayer1Hover
colRipple: Appearance.colors.colLayer1Active
colBackgroundToggled: Appearance.colors.colSecondaryContainer
colBackgroundToggledHover: Appearance.colors.colSecondaryContainerHover
colRippleToggled: Appearance.colors.colSecondaryContainerActive
toggled: GlobalStates.sidebarLeftOpen
property color colText: toggled ? Appearance.m3colors.m3onSecondaryContainer : Appearance.colors.colOnLayer0
onPressed: {
GlobalStates.sidebarLeftOpen = !GlobalStates.sidebarLeftOpen;
}
CustomIcon {
id: distroIcon
anchors.centerIn: parent
width: 19.5
height: 19.5
source: Config.options.bar.topLeftIcon == 'distro' ? SystemInfo.distroIcon : `${Config.options.bar.topLeftIcon}-symbolic`
colorize: true
color: Appearance.colors.colOnLayer0
}
}
Item {
Layout.fillHeight: true
}
}
}
ColumnLayout { // Middle section
id: middleSection
anchors.centerIn: parent
spacing: 4
Bar.BarGroup {
vertical: true
padding: 8
Resources {
Layout.fillWidth: true
Layout.fillHeight: false
}
}
HorizontalBarSeparator {
visible: Config.options?.bar.borderless
}
Bar.BarGroup {
id: middleCenterGroup
vertical: true
padding: 6
Layout.fillHeight: true
Workspaces {
id: workspacesWidget
MouseArea {
// Right-click to toggle overview
anchors.fill: parent
acceptedButtons: Qt.RightButton
onPressed: event => {
if (event.button === Qt.RightButton) {
GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
}
}
}
}
}
HorizontalBarSeparator {
visible: Config.options?.bar.borderless
}
Bar.BarGroup {
vertical: true
padding: 8
VerticalClockWidget {
Layout.fillWidth: true
Layout.fillHeight: false
}
BatteryIndicator {
Layout.fillWidth: true
Layout.fillHeight: false
}
}
}
MouseArea { // Bottom section | scroll to change volume
id: barBottomSectionMouseArea
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
}
implicitWidth: Appearance.sizes.baseVerticalBarWidth
implicitHeight: bottomSectionColumnLayout.implicitHeight
width: Appearance.sizes.verticalBarWidth
property bool hovered: false
property real lastScrollX: 0
property real lastScrollY: 0
property bool trackingScroll: false
acceptedButtons: Qt.LeftButton
hoverEnabled: true
propagateComposedEvents: true
onEntered: event => {
barBottomSectionMouseArea.hovered = true;
}
onExited: event => {
barBottomSectionMouseArea.hovered = false;
barBottomSectionMouseArea.trackingScroll = false;
}
onPressed: event => {
if (event.button === Qt.LeftButton) {
GlobalStates.sidebarRightOpen = !GlobalStates.sidebarRightOpen;
} else if (event.button === Qt.RightButton) {
MprisController.activePlayer.next();
}
}
// Scroll to change volume
WheelHandler {
onWheel: event => {
const currentVolume = Audio.value;
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
if (event.angleDelta.y < 0)
Audio.sink.audio.volume -= step;
else if (event.angleDelta.y > 0)
Audio.sink.audio.volume = Math.min(1, Audio.sink.audio.volume + step);
// Store the mouse position and start tracking
barBottomSectionMouseArea.lastScrollX = event.x;
barBottomSectionMouseArea.lastScrollY = event.y;
barBottomSectionMouseArea.trackingScroll = true;
}
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
}
onPositionChanged: mouse => {
if (barBottomSectionMouseArea.trackingScroll) {
const dx = mouse.x - barBottomSectionMouseArea.lastScrollX;
const dy = mouse.y - barBottomSectionMouseArea.lastScrollY;
if (Math.sqrt(dx * dx + dy * dy) > osdHideMouseMoveThreshold) {
GlobalStates.osdVolumeOpen = false;
barBottomSectionMouseArea.trackingScroll = false;
}
}
}
ColumnLayout {
id: bottomSectionColumnLayout
anchors.fill: parent
spacing: 4
Item {
Layout.fillWidth: true
Layout.fillHeight: true
}
Bar.SysTray {
vertical: true
Layout.fillWidth: true
Layout.fillHeight: false
}
RippleButton { // Right sidebar button
id: rightSidebarButton
Layout.alignment: Qt.AlignBottom | Qt.AlignHCenter
Layout.bottomMargin: Appearance.rounding.screenRounding
Layout.fillHeight: false
implicitHeight: indicatorsColumnLayout.implicitHeight + 4 * 2
implicitWidth: indicatorsColumnLayout.implicitWidth + 6 * 2
buttonRadius: Appearance.rounding.full
colBackground: barBottomSectionMouseArea.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1)
colBackgroundHover: Appearance.colors.colLayer1Hover
colRipple: Appearance.colors.colLayer1Active
colBackgroundToggled: Appearance.colors.colSecondaryContainer
colBackgroundToggledHover: Appearance.colors.colSecondaryContainerHover
colRippleToggled: Appearance.colors.colSecondaryContainerActive
toggled: GlobalStates.sidebarRightOpen
property color colText: toggled ? Appearance.m3colors.m3onSecondaryContainer : Appearance.colors.colOnLayer0
Behavior on colText {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
onPressed: {
GlobalStates.sidebarRightOpen = !GlobalStates.sidebarRightOpen;
}
ColumnLayout {
id: indicatorsColumnLayout
anchors.centerIn: parent
property real realSpacing: 6
spacing: 0
Revealer {
vertical: true
reveal: Audio.sink?.audio?.muted ?? false
Layout.fillWidth: true
Layout.bottomMargin: reveal ? indicatorsColumnLayout.realSpacing : 0
Behavior on Layout.bottomMargin {
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
}
MaterialSymbol {
text: "volume_off"
iconSize: Appearance.font.pixelSize.larger
color: rightSidebarButton.colText
}
}
Revealer {
vertical: true
reveal: Audio.source?.audio?.muted ?? false
Layout.fillWidth: true
Layout.bottomMargin: reveal ? indicatorsColumnLayout.realSpacing : 0
Behavior on Layout.topMargin {
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
}
MaterialSymbol {
text: "mic_off"
iconSize: Appearance.font.pixelSize.larger
color: rightSidebarButton.colText
}
}
Loader {
active: HyprlandXkb.layoutCodes.length > 1
visible: active
Layout.bottomMargin: indicatorsColumnLayout.realSpacing
sourceComponent: StyledText {
text: HyprlandXkb.currentLayoutCode
font.pixelSize: Appearance.font.pixelSize.small
color: rightSidebarButton.colText
}
}
MaterialSymbol {
Layout.bottomMargin: indicatorsColumnLayout.realSpacing
text: Network.materialSymbol
iconSize: Appearance.font.pixelSize.larger
color: rightSidebarButton.colText
}
MaterialSymbol {
text: Bluetooth.bluetoothConnected ? "bluetooth_connected" : Bluetooth.bluetoothEnabled ? "bluetooth" : "bluetooth_disabled"
iconSize: Appearance.font.pixelSize.larger
color: rightSidebarButton.colText
}
}
}
}
}
}