forked from Shinonome/dots-hyprland
Rearrange for tidier structure (#2212)
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import "./../bar" as Bar
|
||||
|
||||
MouseArea {
|
||||
id: root
|
||||
property bool borderless: Config.options.bar.borderless
|
||||
readonly property var chargeState: Battery.chargeState
|
||||
readonly property bool isCharging: Battery.isCharging
|
||||
readonly property bool isPluggedIn: Battery.isPluggedIn
|
||||
readonly property real percentage: Battery.percentage
|
||||
readonly property bool isLow: percentage <= Config.options.battery.low / 100
|
||||
|
||||
implicitHeight: batteryProgress.implicitHeight
|
||||
hoverEnabled: true
|
||||
|
||||
ClippedProgressBar {
|
||||
id: batteryProgress
|
||||
anchors.centerIn: parent
|
||||
vertical: true
|
||||
valueBarWidth: 21
|
||||
valueBarHeight: 40
|
||||
value: percentage
|
||||
highlightColor: (isLow && !isCharging) ? Appearance.m3colors.m3error : Appearance.colors.colOnSecondaryContainer
|
||||
|
||||
font {
|
||||
pixelSize: text.length > 2 ? 11 : 13
|
||||
weight: text.length > 2 ? Font.Medium : Font.DemiBold
|
||||
}
|
||||
|
||||
textMask: Item {
|
||||
anchors.centerIn: parent
|
||||
width: batteryProgress.valueBarWidth
|
||||
height: batteryProgress.valueBarHeight
|
||||
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: 0
|
||||
|
||||
MaterialSymbol {
|
||||
id: boltIcon
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
fill: 1
|
||||
text: isCharging ? "bolt" : "battery_android_full"
|
||||
iconSize: Appearance.font.pixelSize.normal
|
||||
animateChange: true
|
||||
}
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
font: batteryProgress.font
|
||||
text: batteryProgress.text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bar.BatteryPopup {
|
||||
id: batteryPopup
|
||||
hoverTarget: root
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
required property string iconName
|
||||
required property double percentage
|
||||
property int warningThreshold: 100
|
||||
implicitHeight: resourceProgress.implicitHeight
|
||||
implicitWidth: Appearance.sizes.verticalBarWidth
|
||||
|
||||
property bool warning: percentage * 100 >= warningThreshold
|
||||
|
||||
ClippedFilledCircularProgress {
|
||||
id: resourceProgress
|
||||
anchors.centerIn: parent
|
||||
value: percentage
|
||||
enableAnimation: false
|
||||
colPrimary: root.warning ? Appearance.colors.colError : Appearance.colors.colOnSecondaryContainer
|
||||
accountForLightBleeding: !root.warning
|
||||
|
||||
MaterialSymbol {
|
||||
font.weight: Font.Medium
|
||||
fill: 1
|
||||
text: root.iconName
|
||||
iconSize: 13
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.NoButton
|
||||
enabled: root.visible
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import "../bar" as Bar
|
||||
|
||||
MouseArea {
|
||||
id: root
|
||||
property bool alwaysShowAllResources: false
|
||||
implicitHeight: columnLayout.implicitHeight
|
||||
implicitWidth: columnLayout.implicitWidth
|
||||
hoverEnabled: true
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
spacing: 10
|
||||
anchors.fill: parent
|
||||
|
||||
Resource {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
iconName: "memory"
|
||||
percentage: ResourceUsage.memoryUsedPercentage
|
||||
warningThreshold: Config.options.bar.resources.memoryWarningThreshold
|
||||
}
|
||||
|
||||
Resource {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
iconName: "swap_horiz"
|
||||
percentage: ResourceUsage.swapUsedPercentage
|
||||
warningThreshold: Config.options.bar.resources.swapWarningThreshold
|
||||
}
|
||||
|
||||
Resource {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
iconName: "planner_review"
|
||||
percentage: ResourceUsage.cpuUsage
|
||||
warningThreshold: Config.options.bar.resources.cpuWarningThreshold
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Bar.ResourcesPopup {
|
||||
hoverTarget: root
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
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
|
||||
|
||||
Scope {
|
||||
id: bar
|
||||
property bool showBarBackground: Config.options.bar.showBackground
|
||||
|
||||
Variants {
|
||||
// For each monitor
|
||||
model: {
|
||||
const screens = Quickshell.screens;
|
||||
const list = Config.options.bar.screenList;
|
||||
if (!list || list.length === 0)
|
||||
return screens;
|
||||
return screens.filter(screen => list.includes(screen.name));
|
||||
}
|
||||
LazyLoader {
|
||||
id: barLoader
|
||||
active: GlobalStates.barOpen && !GlobalStates.screenLocked
|
||||
required property ShellScreen modelData
|
||||
component: PanelWindow { // Bar window
|
||||
id: barRoot
|
||||
screen: barLoader.modelData
|
||||
|
||||
property var brightnessMonitor: Brightness.getMonitorForScreen(barLoader.modelData)
|
||||
|
||||
Timer {
|
||||
id: showBarTimer
|
||||
interval: (Config?.options.bar.autoHide.showWhenPressingSuper.delay ?? 100)
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
barRoot.superShow = true
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: GlobalStates
|
||||
function onSuperDownChanged() {
|
||||
if (!Config?.options.bar.autoHide.showWhenPressingSuper.enable) return;
|
||||
if (GlobalStates.superDown) showBarTimer.restart();
|
||||
else {
|
||||
showBarTimer.stop();
|
||||
barRoot.superShow = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
property bool superShow: false
|
||||
property bool mustShow: hoverRegion.containsMouse || superShow
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
exclusiveZone: (Config?.options.bar.autoHide.enable && (!mustShow || !Config?.options.bar.autoHide.pushWindows)) ? 0 :
|
||||
Appearance.sizes.baseVerticalBarWidth + (Config.options.bar.cornerStyle === 1 ? Appearance.sizes.hyprlandGapsOut : 0)
|
||||
WlrLayershell.namespace: "quickshell:verticalBar"
|
||||
// WlrLayershell.layer: WlrLayer.Overlay // TODO enable this when bar can hide when fullscreen
|
||||
implicitWidth: Appearance.sizes.verticalBarWidth + Appearance.rounding.screenRounding
|
||||
mask: Region {
|
||||
item: hoverMaskRegion
|
||||
}
|
||||
color: "transparent"
|
||||
|
||||
anchors {
|
||||
left: !Config.options.bar.bottom
|
||||
right: Config.options.bar.bottom
|
||||
top: true
|
||||
bottom: true
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: hoverRegion
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
|
||||
Item {
|
||||
id: hoverMaskRegion
|
||||
anchors {
|
||||
fill: barContent
|
||||
leftMargin: -Config.options.bar.autoHide.hoverRegionWidth
|
||||
rightMargin: -Config.options.bar.autoHide.hoverRegionWidth
|
||||
}
|
||||
}
|
||||
|
||||
VerticalBarContent {
|
||||
id: barContent
|
||||
|
||||
implicitWidth: Appearance.sizes.verticalBarWidth
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
right: undefined
|
||||
leftMargin: (Config?.options.bar.autoHide.enable && !mustShow) ? -Appearance.sizes.verticalBarWidth : 0
|
||||
rightMargin: 0
|
||||
}
|
||||
Behavior on anchors.leftMargin {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
Behavior on anchors.rightMargin {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
states: State {
|
||||
name: "right"
|
||||
when: Config.options.bar.bottom
|
||||
AnchorChanges {
|
||||
target: barContent
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
left: undefined
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
PropertyChanges {
|
||||
target: barContent
|
||||
anchors.topMargin: 0
|
||||
anchors.rightMargin: (Config?.options.bar.autoHide.enable && !mustShow) ? -Appearance.sizes.barHeight : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Round decorators
|
||||
Loader {
|
||||
id: roundDecorators
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
left: barContent.right
|
||||
right: undefined
|
||||
}
|
||||
width: Appearance.rounding.screenRounding
|
||||
active: showBarBackground && Config.options.bar.cornerStyle === 0 // Hug
|
||||
|
||||
states: State {
|
||||
name: "right"
|
||||
when: Config.options.bar.bottom
|
||||
AnchorChanges {
|
||||
target: roundDecorators
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
left: undefined
|
||||
right: barContent.left
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceComponent: Item {
|
||||
implicitHeight: Appearance.rounding.screenRounding
|
||||
RoundCorner {
|
||||
id: topCorner
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
}
|
||||
|
||||
implicitSize: Appearance.rounding.screenRounding
|
||||
color: showBarBackground ? Appearance.colors.colLayer0 : "transparent"
|
||||
|
||||
corner: RoundCorner.CornerEnum.TopLeft
|
||||
states: State {
|
||||
name: "bottom"
|
||||
when: Config.options.bar.bottom
|
||||
PropertyChanges {
|
||||
topCorner.corner: RoundCorner.CornerEnum.TopRight
|
||||
}
|
||||
}
|
||||
}
|
||||
RoundCorner {
|
||||
id: bottomCorner
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
left: !Config.options.bar.bottom ? parent.left : undefined
|
||||
right: Config.options.bar.bottom ? parent.right : undefined
|
||||
}
|
||||
implicitSize: Appearance.rounding.screenRounding
|
||||
color: showBarBackground ? Appearance.colors.colLayer0 : "transparent"
|
||||
|
||||
corner: RoundCorner.CornerEnum.BottomLeft
|
||||
states: State {
|
||||
name: "bottom"
|
||||
when: Config.options.bar.bottom
|
||||
PropertyChanges {
|
||||
bottomCorner.corner: RoundCorner.CornerEnum.BottomRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "bar"
|
||||
|
||||
function toggle(): void {
|
||||
GlobalStates.barOpen = !GlobalStates.barOpen
|
||||
}
|
||||
|
||||
function close(): void {
|
||||
GlobalStates.barOpen = false
|
||||
}
|
||||
|
||||
function open(): void {
|
||||
GlobalStates.barOpen = true
|
||||
}
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
name: "barToggle"
|
||||
description: "Toggles bar on press"
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.barOpen = !GlobalStates.barOpen;
|
||||
}
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
name: "barOpen"
|
||||
description: "Opens bar on press"
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.barOpen = true;
|
||||
}
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
name: "barClose"
|
||||
description: "Closes bar on press"
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.barOpen = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Bluetooth
|
||||
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
|
||||
}
|
||||
|
||||
FocusedScrollMouseArea { // 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
|
||||
|
||||
onScrollDown: root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness - 0.05)
|
||||
onScrollUp: root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness + 0.05)
|
||||
onMovedAway: GlobalStates.osdBrightnessOpen = false
|
||||
onPressed: event => {
|
||||
if (event.button === Qt.LeftButton)
|
||||
GlobalStates.sidebarLeftOpen = !GlobalStates.sidebarLeftOpen;
|
||||
}
|
||||
|
||||
ColumnLayout { // Content
|
||||
id: topSectionColumnLayout
|
||||
anchors.fill: parent
|
||||
spacing: 10
|
||||
|
||||
Bar.LeftSidebarButton { // Left sidebar button
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: (Appearance.sizes.baseVerticalBarWidth - implicitWidth) / 2 + Appearance.sizes.hyprlandGapsOut
|
||||
colBackground: barTopSectionMouseArea.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1)
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Column { // Middle section
|
||||
id: middleSection
|
||||
anchors.centerIn: parent
|
||||
spacing: 4
|
||||
|
||||
Bar.BarGroup {
|
||||
vertical: true
|
||||
padding: 8
|
||||
Resources {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: false
|
||||
}
|
||||
|
||||
HorizontalBarSeparator {}
|
||||
|
||||
VerticalMedia {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: false
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalBarSeparator {
|
||||
visible: Config.options?.bar.borderless
|
||||
}
|
||||
|
||||
Bar.BarGroup {
|
||||
id: middleCenterGroup
|
||||
vertical: true
|
||||
padding: 6
|
||||
|
||||
Bar.Workspaces {
|
||||
id: workspacesWidget
|
||||
vertical: true
|
||||
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
|
||||
}
|
||||
|
||||
HorizontalBarSeparator {}
|
||||
|
||||
VerticalDateWidget {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: false
|
||||
}
|
||||
|
||||
HorizontalBarSeparator {
|
||||
visible: UPower.displayDevice.isLaptopBattery
|
||||
}
|
||||
|
||||
BatteryIndicator {
|
||||
visible: UPower.displayDevice.isLaptopBattery
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: false
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
FocusedScrollMouseArea { // 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
|
||||
|
||||
onScrollDown: {
|
||||
const currentVolume = Audio.value;
|
||||
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
|
||||
Audio.sink.audio.volume -= step;
|
||||
}
|
||||
onScrollUp: {
|
||||
const currentVolume = Audio.value;
|
||||
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
|
||||
Audio.sink.audio.volume = Math.min(1, Audio.sink.audio.volume + step);
|
||||
}
|
||||
onMovedAway: GlobalStates.osdVolumeOpen = false;
|
||||
onPressed: event => {
|
||||
if (event.button === Qt.LeftButton) {
|
||||
GlobalStates.sidebarRightOpen = !GlobalStates.sidebarRightOpen;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
invertSide: Config?.options.bar.bottom
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
Bar.HyprlandXkbIndicator {
|
||||
vertical: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.bottomMargin: indicatorsColumnLayout.realSpacing
|
||||
color: rightSidebarButton.colText
|
||||
}
|
||||
Revealer {
|
||||
vertical: true
|
||||
reveal: Notifications.silent || Notifications.unread > 0
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: reveal ? indicatorsColumnLayout.realSpacing : 0
|
||||
implicitHeight: reveal ? notificationUnreadCount.implicitHeight : 0
|
||||
implicitWidth: reveal ? notificationUnreadCount.implicitWidth : 0
|
||||
Behavior on Layout.bottomMargin {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
Bar.NotificationUnreadCount {
|
||||
id: notificationUnreadCount
|
||||
}
|
||||
}
|
||||
MaterialSymbol {
|
||||
Layout.bottomMargin: indicatorsColumnLayout.realSpacing
|
||||
text: Network.materialSymbol
|
||||
iconSize: Appearance.font.pixelSize.larger
|
||||
color: rightSidebarButton.colText
|
||||
}
|
||||
MaterialSymbol {
|
||||
visible: BluetoothStatus.available
|
||||
text: BluetoothStatus.connected ? "bluetooth_connected" : BluetoothStatus.enabled ? "bluetooth" : "bluetooth_disabled"
|
||||
iconSize: Appearance.font.pixelSize.larger
|
||||
color: rightSidebarButton.colText
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import "../bar" as Bar
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property bool borderless: Config.options.bar.borderless
|
||||
implicitHeight: clockColumn.implicitHeight
|
||||
implicitWidth: Appearance.sizes.verticalBarWidth
|
||||
|
||||
ColumnLayout {
|
||||
id: clockColumn
|
||||
anchors.centerIn: parent
|
||||
spacing: 0
|
||||
|
||||
Repeater {
|
||||
model: DateTime.time.split(/[: ]/)
|
||||
delegate: StyledText {
|
||||
required property string modelData
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
font.pixelSize: modelData.match(/am|pm/i) ?
|
||||
Appearance.font.pixelSize.smaller // Smaller "am"/"pm" text
|
||||
: Appearance.font.pixelSize.large
|
||||
color: Appearance.colors.colOnLayer1
|
||||
text: modelData.padStart(2, "0")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.NoButton
|
||||
|
||||
Bar.ClockWidgetTooltip {
|
||||
hoverTarget: mouseArea
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Shapes
|
||||
import QtQuick.Layouts
|
||||
import "../bar" as Bar
|
||||
|
||||
Item { // Full hitbox
|
||||
id: root
|
||||
|
||||
implicitHeight: content.implicitHeight
|
||||
implicitWidth: Appearance.sizes.verticalBarWidth
|
||||
property var dayOfMonth: DateTime.shortDate.split(/[-\/]/)[0] // What if 🍔murica🦅? good question
|
||||
property var monthOfYear: DateTime.shortDate.split(/[-\/]/)[1]
|
||||
|
||||
Item { // Boundaries for date numbers
|
||||
id: content
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: 24
|
||||
implicitHeight: 30
|
||||
|
||||
Shape {
|
||||
id: diagonalLine
|
||||
property real padding: 4
|
||||
anchors.fill: parent
|
||||
preferredRendererType: Shape.CurveRenderer
|
||||
|
||||
ShapePath {
|
||||
strokeWidth: 1.2
|
||||
strokeColor: Appearance.colors.colSubtext
|
||||
fillColor: "transparent"
|
||||
startX: content.width - diagonalLine.padding
|
||||
startY: diagonalLine.padding
|
||||
PathLine {
|
||||
x: diagonalLine.padding
|
||||
y: content.height - diagonalLine.padding
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: dayText
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
}
|
||||
font.pixelSize: 13
|
||||
color: Appearance.colors.colOnLayer1
|
||||
text: dayOfMonth
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: monthText
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
}
|
||||
font.pixelSize: 13
|
||||
color: Appearance.colors.colOnLayer1
|
||||
text: monthOfYear
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import qs
|
||||
import qs.modules.common.functions
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Services.Mpris
|
||||
|
||||
import "../bar" as Bar
|
||||
|
||||
MouseArea {
|
||||
id: root
|
||||
property bool borderless: Config.options.bar.borderless
|
||||
readonly property MprisPlayer activePlayer: MprisController.activePlayer
|
||||
readonly property string cleanedTitle: StringUtils.cleanMusicTitle(activePlayer?.trackTitle) || Translation.tr("No media")
|
||||
|
||||
Layout.fillHeight: true
|
||||
implicitHeight: mediaCircProg.implicitHeight
|
||||
implicitWidth: Appearance.sizes.verticalBarWidth
|
||||
|
||||
Timer {
|
||||
running: activePlayer?.playbackState == MprisPlaybackState.Playing
|
||||
interval: Config.options.resources.updateInterval
|
||||
repeat: true
|
||||
onTriggered: activePlayer.positionChanged()
|
||||
}
|
||||
|
||||
acceptedButtons: Qt.MiddleButton | Qt.BackButton | Qt.ForwardButton | Qt.RightButton | Qt.LeftButton
|
||||
hoverEnabled: true
|
||||
onPressed: (event) => {
|
||||
if (event.button === Qt.MiddleButton) {
|
||||
activePlayer.togglePlaying();
|
||||
} else if (event.button === Qt.BackButton) {
|
||||
activePlayer.previous();
|
||||
} else if (event.button === Qt.ForwardButton || event.button === Qt.RightButton) {
|
||||
activePlayer.next();
|
||||
} else if (event.button === Qt.LeftButton) {
|
||||
GlobalStates.mediaControlsOpen = !GlobalStates.mediaControlsOpen
|
||||
}
|
||||
}
|
||||
|
||||
ClippedFilledCircularProgress {
|
||||
id: mediaCircProg
|
||||
anchors.centerIn: parent
|
||||
implicitSize: 20
|
||||
|
||||
lineWidth: Appearance.rounding.unsharpen
|
||||
value: activePlayer?.position / activePlayer?.length
|
||||
colPrimary: Appearance.colors.colOnSecondaryContainer
|
||||
enableAnimation: false
|
||||
|
||||
Item {
|
||||
anchors.centerIn: parent
|
||||
width: mediaCircProg.implicitSize
|
||||
height: mediaCircProg.implicitSize
|
||||
|
||||
MaterialSymbol {
|
||||
anchors.centerIn: parent
|
||||
fill: 1
|
||||
text: activePlayer?.isPlaying ? "pause" : "music_note"
|
||||
iconSize: Appearance.font.pixelSize.normal
|
||||
color: Appearance.m3colors.m3onSecondaryContainer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bar.StyledPopup {
|
||||
hoverTarget: root
|
||||
active: GlobalStates.mediaControlsOpen ? false : root.containsMouse
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
spacing: 4
|
||||
|
||||
Row {
|
||||
spacing: 4
|
||||
|
||||
MaterialSymbol {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
fill: 0
|
||||
font.weight: Font.Medium
|
||||
text: "music_note"
|
||||
iconSize: Appearance.font.pixelSize.large
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "Media"
|
||||
font {
|
||||
weight: Font.Medium
|
||||
pixelSize: Appearance.font.pixelSize.normal
|
||||
}
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: `${cleanedTitle}${activePlayer?.trackArtist ? '\n' + activePlayer.trackArtist : ''}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user