forked from Shinonome/dots-hyprland
This commit is contained in:
@@ -3,8 +3,9 @@ import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
|
||||
Item {
|
||||
MouseArea {
|
||||
id: root
|
||||
property bool borderless: Config.options.bar.borderless
|
||||
readonly property var chargeState: Battery.chargeState
|
||||
@@ -18,6 +19,8 @@ Item {
|
||||
implicitWidth: rowLayout.implicitWidth + rowLayout.spacing * 2
|
||||
implicitHeight: 32
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
RowLayout {
|
||||
id: rowLayout
|
||||
|
||||
@@ -55,9 +58,7 @@ Item {
|
||||
iconSize: Appearance.font.pixelSize.normal
|
||||
color: (isLow && !isCharging) ? batteryLowOnBackground : Appearance.m3colors.m3onSecondaryContainer
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
@@ -69,7 +70,8 @@ Item {
|
||||
Connections {
|
||||
target: root
|
||||
function onIsChargingChanged() {
|
||||
if (isCharging) boltIconLoader.active = true
|
||||
if (isCharging)
|
||||
boltIconLoader.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,14 +84,18 @@ Item {
|
||||
visible: opacity > 0 // Only show when charging
|
||||
opacity: isCharging ? 1 : 0 // Keep opacity for visibility
|
||||
onVisibleChanged: {
|
||||
if (!visible) boltIconLoader.active = false
|
||||
if (!visible)
|
||||
boltIconLoader.active = false;
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BatteryPopup {
|
||||
id: batteryPopup
|
||||
hoverTarget: root
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import qs
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
StyledPopup {
|
||||
id: root
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.centerIn: parent
|
||||
spacing: 4
|
||||
|
||||
// Header
|
||||
RowLayout {
|
||||
id: header
|
||||
spacing: 5
|
||||
|
||||
MaterialSymbol {
|
||||
fill: 0
|
||||
font.weight: Font.Medium
|
||||
text: "battery_android_full"
|
||||
iconSize: Appearance.font.pixelSize.large
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: "Battery"
|
||||
font {
|
||||
weight: Font.Medium
|
||||
pixelSize: Appearance.font.pixelSize.normal
|
||||
}
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
|
||||
// This row is hidden when the battery is full.
|
||||
RowLayout {
|
||||
spacing: 5
|
||||
Layout.fillWidth: true
|
||||
property bool rowVisible: {
|
||||
let timeValue = Battery.isCharging ? Battery.timeToFull : Battery.timeToEmpty;
|
||||
let power = Battery.energyRate;
|
||||
return !(Battery.chargeState == 4 || timeValue <= 0 || power <= 0.01);
|
||||
}
|
||||
visible: rowVisible
|
||||
opacity: rowVisible ? 1 : 0
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 500
|
||||
}
|
||||
}
|
||||
|
||||
MaterialSymbol {
|
||||
text: "schedule"
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
iconSize: Appearance.font.pixelSize.large
|
||||
}
|
||||
StyledText {
|
||||
text: Battery.isCharging ? Translation.tr("Time to full:") : Translation.tr("Time to empty:")
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignRight
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
text: {
|
||||
function formatTime(seconds) {
|
||||
var h = Math.floor(seconds / 3600);
|
||||
var m = Math.floor((seconds % 3600) / 60);
|
||||
if (h > 0)
|
||||
return `${h}h, ${m}m`;
|
||||
else
|
||||
return `${m}m`;
|
||||
}
|
||||
if (Battery.isCharging)
|
||||
return formatTime(Battery.timeToFull);
|
||||
else
|
||||
return formatTime(Battery.timeToEmpty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 5
|
||||
Layout.fillWidth: true
|
||||
|
||||
property bool rowVisible: !(Battery.chargeState != 4 && Battery.energyRate == 0)
|
||||
visible: rowVisible
|
||||
opacity: rowVisible ? 1 : 0
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 500
|
||||
}
|
||||
}
|
||||
|
||||
MaterialSymbol {
|
||||
text: "bolt"
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
iconSize: Appearance.font.pixelSize.large
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: {
|
||||
if (Battery.chargeState == 4) {
|
||||
return Translation.tr("Fully charged");
|
||||
} else if (Battery.chargeState == 1) {
|
||||
return Translation.tr("Charging:");
|
||||
} else {
|
||||
return Translation.tr("Discharging:");
|
||||
}
|
||||
}
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignRight
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
text: {
|
||||
if (Battery.chargeState == 4) {
|
||||
return "";
|
||||
} else {
|
||||
return `${Battery.energyRate.toFixed(2)}W`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
import qs
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
|
||||
Item {
|
||||
id: root
|
||||
@@ -35,7 +37,16 @@ Item {
|
||||
color: Appearance.colors.colOnLayer1
|
||||
text: DateTime.date
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.NoButton
|
||||
|
||||
ClockWidgetTooltip {
|
||||
hoverTarget: mouseArea
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
import qs
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
StyledPopup {
|
||||
id: root
|
||||
property string formattedDate: Qt.locale().toString(DateTime.clock.date, "dddd, MMMM dd, yyyy")
|
||||
property string formattedTime: DateTime.time
|
||||
property string formattedUptime: DateTime.uptime
|
||||
property string todosSection: getUpcomingTodos()
|
||||
|
||||
function getUpcomingTodos() {
|
||||
const unfinishedTodos = Todo.list.filter(function (item) {
|
||||
return !item.done;
|
||||
});
|
||||
if (unfinishedTodos.length === 0) {
|
||||
return Translation.tr("No pending tasks");
|
||||
}
|
||||
|
||||
// Limit to first 5 todos to keep popup manageable
|
||||
const limitedTodos = unfinishedTodos.slice(0, 5);
|
||||
let todoText = limitedTodos.map(function (item, index) {
|
||||
return `${index + 1}. ${item.content}`;
|
||||
}).join('\n');
|
||||
|
||||
if (unfinishedTodos.length > 5) {
|
||||
todoText += `\n${Translation.tr("... and %1 more").arg(unfinishedTodos.length - 5)}`;
|
||||
}
|
||||
|
||||
return todoText;
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.centerIn: parent
|
||||
spacing: 4
|
||||
|
||||
// Date + Time row
|
||||
RowLayout {
|
||||
spacing: 5
|
||||
|
||||
MaterialSymbol {
|
||||
fill: 0
|
||||
font.weight: Font.Medium
|
||||
text: "calendar_month"
|
||||
iconSize: Appearance.font.pixelSize.large
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
StyledText {
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
text: `${root.formattedDate} • ${root.formattedTime}`
|
||||
font.weight: Font.Medium
|
||||
}
|
||||
}
|
||||
|
||||
// Uptime row
|
||||
RowLayout {
|
||||
spacing: 5
|
||||
Layout.fillWidth: true
|
||||
MaterialSymbol {
|
||||
text: "timelapse"
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
font.pixelSize: Appearance.font.pixelSize.large
|
||||
}
|
||||
StyledText {
|
||||
text: Translation.tr("System uptime:")
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignRight
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
text: root.formattedUptime
|
||||
}
|
||||
}
|
||||
|
||||
// Tasks
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
spacing: 4
|
||||
Layout.fillWidth: true
|
||||
MaterialSymbol {
|
||||
text: "checklist"
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
font.pixelSize: Appearance.font.pixelSize.large
|
||||
}
|
||||
StyledText {
|
||||
text: Translation.tr("To Do:")
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
wrapMode: Text.Wrap
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
text: root.todosSection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,38 @@
|
||||
import qs
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
|
||||
Item {
|
||||
id: root
|
||||
required property string iconName
|
||||
required property double percentage
|
||||
property var tooltipData: [
|
||||
{
|
||||
icon: "info",
|
||||
label: "System resource",
|
||||
value: ""
|
||||
}
|
||||
]
|
||||
property var tooltipHeaderIcon
|
||||
property var tooltipHeaderText
|
||||
property bool shown: true
|
||||
clip: true
|
||||
visible: width > 0 && height > 0
|
||||
implicitWidth: resourceRowLayout.x < 0 ? 0 : childrenRect.width
|
||||
implicitHeight: childrenRect.height
|
||||
implicitWidth: resourceRowLayout.x < 0 ? 0 : resourceRowLayout.implicitWidth
|
||||
implicitHeight: resourceRowLayout.implicitHeight
|
||||
|
||||
// Helper function to format KB to GB
|
||||
function formatKB(kb) {
|
||||
return (kb / (1024 * 1024)).toFixed(1) + " GB";
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 4
|
||||
id: resourceRowLayout
|
||||
spacing: 4
|
||||
x: shown ? 0 : -resourceRowLayout.width
|
||||
|
||||
CircularProgress {
|
||||
@@ -30,10 +48,9 @@ Item {
|
||||
anchors.centerIn: parent
|
||||
fill: 1
|
||||
text: iconName
|
||||
iconSize: Appearance.font.pixelSize.normal
|
||||
iconSize: Appearance.font.pixelSize.large
|
||||
color: Appearance.m3colors.m3onSecondaryContainer
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
StyledText {
|
||||
@@ -45,7 +62,73 @@ Item {
|
||||
Behavior on x {
|
||||
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.NoButton
|
||||
enabled: resourceRowLayout.x >= 0 && root.width > 0 && root.visible
|
||||
}
|
||||
|
||||
StyledPopup {
|
||||
hoverTarget: mouseArea
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.centerIn: parent
|
||||
spacing: 4
|
||||
|
||||
// Header
|
||||
RowLayout {
|
||||
id: header
|
||||
spacing: 5
|
||||
|
||||
MaterialSymbol {
|
||||
fill: 0
|
||||
font.weight: Font.Medium
|
||||
text: root.tooltipHeaderIcon
|
||||
iconSize: Appearance.font.pixelSize.large
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: root.tooltipHeaderText
|
||||
font {
|
||||
weight: Font.Medium
|
||||
pixelSize: Appearance.font.pixelSize.normal
|
||||
}
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
|
||||
// Info rows
|
||||
Repeater {
|
||||
model: root.tooltipData
|
||||
delegate: RowLayout {
|
||||
spacing: 5
|
||||
Layout.fillWidth: true
|
||||
|
||||
MaterialSymbol {
|
||||
text: modelData.icon
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
iconSize: Appearance.font.pixelSize.large
|
||||
}
|
||||
StyledText {
|
||||
text: modelData.label
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignRight
|
||||
visible: modelData.value !== ""
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
text: modelData.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on implicitWidth {
|
||||
@@ -55,4 +138,4 @@ Item {
|
||||
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import qs
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
StyledPopup {
|
||||
hoverTarget: mouseArea
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.centerIn: parent
|
||||
spacing: 4
|
||||
|
||||
// Header
|
||||
RowLayout {
|
||||
id: header
|
||||
spacing: 5
|
||||
|
||||
MaterialSymbol {
|
||||
fill: 0
|
||||
font.weight: Font.Medium
|
||||
text: root.tooltipHeaderIcon
|
||||
iconSize: Appearance.font.pixelSize.large
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: root.tooltipHeaderText
|
||||
font {
|
||||
weight: Font.Medium
|
||||
pixelSize: Appearance.font.pixelSize.normal
|
||||
}
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
|
||||
// Info rows
|
||||
Repeater {
|
||||
model: root.tooltipData
|
||||
delegate: RowLayout {
|
||||
spacing: 5
|
||||
Layout.fillWidth: true
|
||||
|
||||
MaterialSymbol {
|
||||
text: modelData.icon
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
iconSize: Appearance.font.pixelSize.large
|
||||
}
|
||||
StyledText {
|
||||
text: modelData.label
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignRight
|
||||
visible: modelData.value !== ""
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
text: modelData.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import qs
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
@@ -22,6 +23,14 @@ Item {
|
||||
Resource {
|
||||
iconName: "memory"
|
||||
percentage: ResourceUsage.memoryUsedPercentage
|
||||
|
||||
tooltipHeaderIcon: "memory"
|
||||
tooltipHeaderText: Translation.tr("Memory usage")
|
||||
tooltipData: [
|
||||
{ icon: "clock_loader_60", label: Translation.tr("Used:"), value: formatKB(ResourceUsage.memoryUsed) },
|
||||
{ icon: "check_circle", label: Translation.tr("Free:"), value: formatKB(ResourceUsage.memoryFree) },
|
||||
{ icon: "empty_dashboard", label: Translation.tr("Total:"), value: formatKB(ResourceUsage.memoryTotal) },
|
||||
]
|
||||
}
|
||||
|
||||
Resource {
|
||||
@@ -31,6 +40,16 @@ Item {
|
||||
(MprisController.activePlayer?.trackTitle == null) ||
|
||||
root.alwaysShowAllResources
|
||||
Layout.leftMargin: shown ? 4 : 0
|
||||
|
||||
tooltipHeaderIcon: "swap_horiz"
|
||||
tooltipHeaderText: Translation.tr("Swap usage")
|
||||
tooltipData: ResourceUsage.swapTotal > 0 ? [
|
||||
{ icon: "clock_loader_60", label: Translation.tr("Used:"), value: formatKB(ResourceUsage.swapUsed) },
|
||||
{ icon: "check_circle", label: Translation.tr("Free:"), value: formatKB(ResourceUsage.swapFree) },
|
||||
{ icon: "empty_dashboard", label: Translation.tr("Total:"), value: formatKB(ResourceUsage.swapTotal) },
|
||||
] : [
|
||||
{ icon: "swap_horiz", label: Translation.tr("Swap:"), value: Translation.tr("Not configured") }
|
||||
]
|
||||
}
|
||||
|
||||
Resource {
|
||||
@@ -40,6 +59,16 @@ Item {
|
||||
!(MprisController.activePlayer?.trackTitle?.length > 0) ||
|
||||
root.alwaysShowAllResources
|
||||
Layout.leftMargin: shown ? 4 : 0
|
||||
|
||||
tooltipHeaderIcon: "settings_slow_motion"
|
||||
tooltipHeaderText: Translation.tr("CPU usage")
|
||||
tooltipData: [
|
||||
{ icon: "bolt", label: Translation.tr("Load:"), value: (ResourceUsage.cpuUsage > 0.8 ?
|
||||
Translation.tr("High") :
|
||||
ResourceUsage.cpuUsage > 0.4 ? Translation.tr("Medium") : Translation.tr("Low"))
|
||||
+ ` (${Math.round(ResourceUsage.cpuUsage * 100)}%)`
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,10 +18,10 @@ MouseArea {
|
||||
RowLayout {
|
||||
id: rowLayout
|
||||
anchors.centerIn: parent
|
||||
|
||||
|
||||
MaterialSymbol {
|
||||
fill: 0
|
||||
text: WeatherIcons.codeToName[Weather.data?.wCode] ?? "question_mark"
|
||||
text: WeatherIcons.codeToName[Weather.data.wCode] ?? "cloud"
|
||||
iconSize: Appearance.font.pixelSize.large
|
||||
color: Appearance.colors.colOnLayer1
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
@@ -36,25 +36,8 @@ MouseArea {
|
||||
}
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
id: popupLoader
|
||||
active: root.containsMouse
|
||||
|
||||
component: PopupWindow {
|
||||
id: popupWindow
|
||||
visible: true
|
||||
implicitWidth: weatherPopup.implicitWidth
|
||||
implicitHeight: weatherPopup.implicitHeight
|
||||
anchor.item: root
|
||||
anchor.edges: Edges.Top
|
||||
anchor.rect.x: (root.implicitWidth - popupWindow.implicitWidth) / 2
|
||||
anchor.rect.y: Config.options.bar.bottom ?
|
||||
(-weatherPopup.implicitHeight - 15) :
|
||||
(root.implicitHeight + 15 )
|
||||
color: "transparent"
|
||||
WeatherPopup {
|
||||
id: weatherPopup
|
||||
}
|
||||
}
|
||||
WeatherPopup {
|
||||
id: weatherPopup
|
||||
hoverTarget: root
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@ import qs.modules.common.widgets
|
||||
Rectangle {
|
||||
id: root
|
||||
radius: Appearance.rounding.small
|
||||
color: Appearance.colors.colLayer1
|
||||
implicitWidth: columnLayout.implicitWidth * 2
|
||||
implicitHeight: columnLayout.implicitHeight * 2
|
||||
color: Appearance.colors.colSurfaceContainerHigh
|
||||
implicitWidth: columnLayout.implicitWidth + 14 * 2
|
||||
implicitHeight: columnLayout.implicitHeight + 14 * 2
|
||||
Layout.fillWidth: parent
|
||||
|
||||
property alias title: title.text
|
||||
@@ -26,18 +26,19 @@ Rectangle {
|
||||
id: symbol
|
||||
fill: 0
|
||||
iconSize: Appearance.font.pixelSize.normal
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
StyledText {
|
||||
id: title
|
||||
font.pixelSize: Appearance.font.pixelSize.smaller
|
||||
color: Appearance.colors.colOnLayer1
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
StyledText {
|
||||
id: value
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
font.pixelSize: Appearance.font.pixelSize.normal
|
||||
color: Appearance.colors.colOnLayer1
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,41 +6,37 @@ import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
Rectangle {
|
||||
StyledPopup {
|
||||
id: root
|
||||
readonly property real margin: 10
|
||||
implicitWidth: columnLayout.implicitWidth + margin * 2
|
||||
implicitHeight: columnLayout.implicitHeight + margin * 2
|
||||
color: Appearance.colors.colLayer0
|
||||
radius: Appearance.rounding.small
|
||||
border.width: 1
|
||||
border.color: Appearance.colors.colLayer0Border
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
spacing: 5
|
||||
anchors.centerIn: root
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: Math.max(header.implicitWidth, gridLayout.implicitWidth)
|
||||
implicitHeight: gridLayout.implicitHeight
|
||||
spacing: 5
|
||||
|
||||
// Header
|
||||
RowLayout {
|
||||
id: header
|
||||
spacing: 5
|
||||
Layout.fillWidth: parent
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
MaterialSymbol {
|
||||
fill: 0
|
||||
font.weight: Font.Medium
|
||||
text: "location_on"
|
||||
iconSize: Appearance.font.pixelSize.huge
|
||||
iconSize: Appearance.font.pixelSize.large
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: Weather.data.city
|
||||
font.pixelSize: Appearance.font.pixelSize.title
|
||||
font.family: Appearance.font.family.title
|
||||
color: Appearance.colors.colOnLayer0
|
||||
font {
|
||||
weight: Font.Medium
|
||||
pixelSize: Appearance.font.pixelSize.normal
|
||||
}
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,4 +90,4 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,8 @@ Singleton {
|
||||
property color colSurfaceContainerHighest: ColorUtils.transparentize(m3colors.m3surfaceContainerHighest, root.contentTransparency)
|
||||
property color colSurfaceContainerHighestHover: ColorUtils.mix(m3colors.m3surfaceContainerHighest, m3colors.m3onSurface, 0.95)
|
||||
property color colSurfaceContainerHighestActive: ColorUtils.mix(m3colors.m3surfaceContainerHighest, m3colors.m3onSurface, 0.85)
|
||||
property color colOnSurface: m3colors.m3onSurface
|
||||
property color colOnSurfaceVariant: m3colors.m3onSurfaceVariant
|
||||
property color colTooltip: m3colors.m3inverseSurface
|
||||
property color colOnTooltip: m3colors.m3inverseOnSurface
|
||||
property color colScrim: ColorUtils.transparentize(m3colors.m3scrim, 0.5)
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import qs
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Effects
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
|
||||
LazyLoader {
|
||||
id: root
|
||||
|
||||
property MouseArea hoverTarget
|
||||
default property Item contentItem
|
||||
|
||||
active: hoverTarget && hoverTarget.containsMouse
|
||||
|
||||
component: PanelWindow {
|
||||
id: popupWindow
|
||||
visible: true
|
||||
color: "transparent"
|
||||
exclusiveZone: 0
|
||||
|
||||
anchors.left: true
|
||||
anchors.top: !Config.options.bar.bottom
|
||||
anchors.bottom: Config.options.bar.bottom
|
||||
|
||||
implicitWidth: popupBackground.implicitWidth + Appearance.sizes.hyprlandGapsOut * 2
|
||||
implicitHeight: popupBackground.implicitHeight + Appearance.sizes.hyprlandGapsOut * 2
|
||||
|
||||
margins {
|
||||
left: root.QsWindow?.mapFromItem(
|
||||
root.hoverTarget,
|
||||
(root.hoverTarget.width - popupBackground.implicitWidth) / 2, 0
|
||||
).x
|
||||
}
|
||||
WlrLayershell.namespace: "quickshell:popup"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
|
||||
RectangularShadow {
|
||||
property var target: popupBackground
|
||||
anchors.fill: target
|
||||
radius: target.radius
|
||||
blur: 0.9 * Appearance.sizes.hyprlandGapsOut
|
||||
offset: Qt.vector2d(0.0, 1.0)
|
||||
spread: 0.7
|
||||
color: Appearance.colors.colShadow
|
||||
cached: true
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: popupBackground
|
||||
readonly property real margin: 10
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: root.contentItem.implicitWidth + margin * 2
|
||||
implicitHeight: root.contentItem.implicitHeight + margin * 2
|
||||
color: Appearance.colors.colSurfaceContainer
|
||||
radius: Appearance.rounding.small
|
||||
children: [root.contentItem]
|
||||
|
||||
border.width: 1
|
||||
border.color: Appearance.colors.colLayer0Border
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import qs
|
||||
import qs.modules.common
|
||||
import Quickshell
|
||||
import Quickshell.Services.UPower
|
||||
import QtQuick
|
||||
import Quickshell.Io
|
||||
|
||||
Singleton {
|
||||
property bool available: UPower.displayDevice.isLaptopBattery
|
||||
@@ -21,6 +23,10 @@ Singleton {
|
||||
property bool isCriticalAndNotCharging: isCritical && !isCharging
|
||||
property bool isSuspendingAndNotCharging: allowAutomaticSuspend && isSuspending && !isCharging
|
||||
|
||||
property real energyRate: UPower.displayDevice.changeRate
|
||||
property real timeToEmpty: UPower.displayDevice.timeToEmpty
|
||||
property real timeToFull: UPower.displayDevice.timeToFull
|
||||
|
||||
onIsLowAndNotChargingChanged: {
|
||||
if (available && isLowAndNotCharging) Quickshell.execDetached([
|
||||
"notify-send",
|
||||
|
||||
@@ -310,5 +310,29 @@
|
||||
"Sunrise": "Sunrise",
|
||||
"Pressure": "Pressure",
|
||||
"Visibility": "Visibility",
|
||||
"Precipitation": "Precipitation"
|
||||
"Precipitation": "Precipitation",
|
||||
"Time to full:": "Time to full:",
|
||||
"Time to empty:": "Time to empty:",
|
||||
"Fully charged": "Fully charged",
|
||||
"Charging:": "Charging:",
|
||||
"Discharging:": "Discharging:",
|
||||
"Uptime:": "Uptime:",
|
||||
"Upcoming Tasks:": "Upcoming Tasks:",
|
||||
"No pending tasks": "No pending tasks",
|
||||
"... and %1 more": "... and %1 more",
|
||||
"Memory Usage": "Memory Usage",
|
||||
"Used:": "Used:",
|
||||
"Free:": "Free:",
|
||||
"Total:": "Total:",
|
||||
"Usage:": "Usage:",
|
||||
"Swap Usage": "Swap Usage",
|
||||
"Swap:": "Swap:",
|
||||
"Not configured": "Not configured",
|
||||
"CPU Usage": "CPU Usage",
|
||||
"Current:": "Current:",
|
||||
"Load:": "Load:",
|
||||
"High": "High",
|
||||
"Medium": "Medium",
|
||||
"Low": "Low",
|
||||
"System Resource": "System Resource"
|
||||
}
|
||||
@@ -302,6 +302,30 @@
|
||||
"Humidity": "湿度",
|
||||
"Wind": "风",
|
||||
"Precipitation": "降水量",
|
||||
"Time to full:": "距离充满:",
|
||||
"Time to empty:": "距离耗尽:",
|
||||
"Fully charged": "已充满电",
|
||||
"Charging:": "充电功率:",
|
||||
"Discharging:": "放电功率:",
|
||||
"Uptime:": "运行时间:",
|
||||
"Upcoming Tasks:": "待办任务:",
|
||||
"No pending tasks": "没有待办任务",
|
||||
"... and %1 more": "... 还有 %1 个",
|
||||
"Memory Usage": "内存使用情况",
|
||||
"Used:": "已用:",
|
||||
"Free:": "可用:",
|
||||
"Total:": "总计:",
|
||||
"Usage:": "占比:",
|
||||
"Swap Usage": "交换区使用情况",
|
||||
"Swap:": "交换区:",
|
||||
"Not configured": "未配置",
|
||||
"CPU Usage": "CPU 使用情况",
|
||||
"Current:": "当前占比:",
|
||||
"Load:": "负载:",
|
||||
"High": "高",
|
||||
"Medium": "中",
|
||||
"Low": "低",
|
||||
"System Resource": "系统资源",
|
||||
"Tint icons": "图标着色",
|
||||
"Performance Profile toggle": "性能配置文件切换",
|
||||
"**Instructions**: Log into Mistral account, go to Keys on the sidebar, click Create new key": "**说明**:登录 Mistral 账户,在侧边栏中选择 Keys,点击创建新密钥",
|
||||
@@ -345,4 +369,4 @@
|
||||
"Invalid tool. Supported tools:\n- %1": "无效工具。支持的工具:\n- %1",
|
||||
"Keep right sidebar loaded": "保持右侧边栏加载",
|
||||
"Reject": "拒绝"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user