mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-07 22:15:38 -05:00
dankbar: enhance widget click targets
- Fitt's law stuff, whole height on horiz, whole width in vertical - Probably missed stuff or breaks stuff, pretty big refactor
This commit is contained in:
@@ -374,4 +374,15 @@ Item {
|
|||||||
|
|
||||||
target: "hypr"
|
target: "hypr"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
function wallpaper(): string {
|
||||||
|
if (root.dankBarLoader.item && root.dankBarLoader.item.triggerWallpaperBrowserOnFocusedScreen()) {
|
||||||
|
return "SUCCESS: Toggled wallpaper browser"
|
||||||
|
}
|
||||||
|
return "ERROR: Failed to toggle wallpaper browser"
|
||||||
|
}
|
||||||
|
|
||||||
|
target: "dankdash"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -546,9 +546,9 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: !barWindow.isVertical ? Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8) : SettingsData.dankBarInnerPadding / 2
|
anchors.leftMargin: !barWindow.isVertical ? Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8) : SettingsData.dankBarInnerPadding / 2
|
||||||
anchors.rightMargin: !barWindow.isVertical ? Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8) : SettingsData.dankBarInnerPadding / 2
|
anchors.rightMargin: !barWindow.isVertical ? Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8) : SettingsData.dankBarInnerPadding / 2
|
||||||
anchors.topMargin: !barWindow.isVertical ? SettingsData.dankBarInnerPadding / 2 : Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8)
|
anchors.topMargin: !barWindow.isVertical ? 0 : Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8)
|
||||||
anchors.bottomMargin: !barWindow.isVertical ? SettingsData.dankBarInnerPadding / 2 : Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8)
|
anchors.bottomMargin: !barWindow.isVertical ? 0 : Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8)
|
||||||
clip: true
|
clip: false
|
||||||
|
|
||||||
property int componentMapRevision: 0
|
property int componentMapRevision: 0
|
||||||
|
|
||||||
@@ -801,6 +801,7 @@ Item {
|
|||||||
ClipboardButton {
|
ClipboardButton {
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
|
axis: barWindow.axis
|
||||||
section: topBarContent.getWidgetSection(parent)
|
section: topBarContent.getWidgetSection(parent)
|
||||||
parentScreen: barWindow.screen
|
parentScreen: barWindow.screen
|
||||||
onClicked: {
|
onClicked: {
|
||||||
@@ -817,7 +818,7 @@ Item {
|
|||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
section: topBarContent.getWidgetSection(parent)
|
section: topBarContent.getWidgetSection(parent)
|
||||||
popupTarget: appDrawerLoader.item
|
popoutTarget: appDrawerLoader.item
|
||||||
parentScreen: barWindow.screen
|
parentScreen: barWindow.screen
|
||||||
hyprlandOverviewLoader: root.hyprlandOverviewLoader
|
hyprlandOverviewLoader: root.hyprlandOverviewLoader
|
||||||
onClicked: {
|
onClicked: {
|
||||||
@@ -831,8 +832,11 @@ Item {
|
|||||||
id: workspaceSwitcherComponent
|
id: workspaceSwitcherComponent
|
||||||
|
|
||||||
WorkspaceSwitcher {
|
WorkspaceSwitcher {
|
||||||
|
axis: barWindow.axis
|
||||||
screenName: barWindow.screenName
|
screenName: barWindow.screenName
|
||||||
widgetHeight: barWindow.widgetThickness
|
widgetHeight: barWindow.widgetThickness
|
||||||
|
barThickness: barWindow.effectiveBarThickness
|
||||||
|
parentScreen: barWindow.screen
|
||||||
hyprlandOverviewLoader: root.hyprlandOverviewLoader
|
hyprlandOverviewLoader: root.hyprlandOverviewLoader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -841,8 +845,10 @@ Item {
|
|||||||
id: focusedWindowComponent
|
id: focusedWindowComponent
|
||||||
|
|
||||||
FocusedApp {
|
FocusedApp {
|
||||||
|
axis: barWindow.axis
|
||||||
availableWidth: topBarContent.leftToMediaGap
|
availableWidth: topBarContent.leftToMediaGap
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
|
barThickness: barWindow.effectiveBarThickness
|
||||||
parentScreen: barWindow.screen
|
parentScreen: barWindow.screen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -862,11 +868,12 @@ Item {
|
|||||||
id: clockComponent
|
id: clockComponent
|
||||||
|
|
||||||
Clock {
|
Clock {
|
||||||
|
axis: barWindow.axis
|
||||||
compactMode: topBarContent.overlapping
|
compactMode: topBarContent.overlapping
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
section: topBarContent.getWidgetSection(parent) || "center"
|
section: topBarContent.getWidgetSection(parent) || "center"
|
||||||
popupTarget: {
|
popoutTarget: {
|
||||||
dankDashPopoutLoader.active = true
|
dankDashPopoutLoader.active = true
|
||||||
return dankDashPopoutLoader.item
|
return dankDashPopoutLoader.item
|
||||||
}
|
}
|
||||||
@@ -896,11 +903,12 @@ Item {
|
|||||||
id: mediaComponent
|
id: mediaComponent
|
||||||
|
|
||||||
Media {
|
Media {
|
||||||
|
axis: barWindow.axis
|
||||||
compactMode: topBarContent.spacingTight || topBarContent.overlapping
|
compactMode: topBarContent.spacingTight || topBarContent.overlapping
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
section: topBarContent.getWidgetSection(parent) || "center"
|
section: topBarContent.getWidgetSection(parent) || "center"
|
||||||
popupTarget: {
|
popoutTarget: {
|
||||||
dankDashPopoutLoader.active = true
|
dankDashPopoutLoader.active = true
|
||||||
return dankDashPopoutLoader.item
|
return dankDashPopoutLoader.item
|
||||||
}
|
}
|
||||||
@@ -919,10 +927,11 @@ Item {
|
|||||||
id: weatherComponent
|
id: weatherComponent
|
||||||
|
|
||||||
Weather {
|
Weather {
|
||||||
|
axis: barWindow.axis
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
section: topBarContent.getWidgetSection(parent) || "center"
|
section: topBarContent.getWidgetSection(parent) || "center"
|
||||||
popupTarget: {
|
popoutTarget: {
|
||||||
dankDashPopoutLoader.active = true
|
dankDashPopoutLoader.active = true
|
||||||
return dankDashPopoutLoader.item
|
return dankDashPopoutLoader.item
|
||||||
}
|
}
|
||||||
@@ -965,8 +974,9 @@ Item {
|
|||||||
CpuMonitor {
|
CpuMonitor {
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
|
axis: barWindow.axis
|
||||||
section: topBarContent.getWidgetSection(parent) || "right"
|
section: topBarContent.getWidgetSection(parent) || "right"
|
||||||
popupTarget: {
|
popoutTarget: {
|
||||||
processListPopoutLoader.active = true
|
processListPopoutLoader.active = true
|
||||||
return processListPopoutLoader.item
|
return processListPopoutLoader.item
|
||||||
}
|
}
|
||||||
@@ -985,8 +995,9 @@ Item {
|
|||||||
RamMonitor {
|
RamMonitor {
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
|
axis: barWindow.axis
|
||||||
section: topBarContent.getWidgetSection(parent) || "right"
|
section: topBarContent.getWidgetSection(parent) || "right"
|
||||||
popupTarget: {
|
popoutTarget: {
|
||||||
processListPopoutLoader.active = true
|
processListPopoutLoader.active = true
|
||||||
return processListPopoutLoader.item
|
return processListPopoutLoader.item
|
||||||
}
|
}
|
||||||
@@ -1015,8 +1026,9 @@ Item {
|
|||||||
CpuTemperature {
|
CpuTemperature {
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
|
axis: barWindow.axis
|
||||||
section: topBarContent.getWidgetSection(parent) || "right"
|
section: topBarContent.getWidgetSection(parent) || "right"
|
||||||
popupTarget: {
|
popoutTarget: {
|
||||||
processListPopoutLoader.active = true
|
processListPopoutLoader.active = true
|
||||||
return processListPopoutLoader.item
|
return processListPopoutLoader.item
|
||||||
}
|
}
|
||||||
@@ -1035,8 +1047,9 @@ Item {
|
|||||||
GpuTemperature {
|
GpuTemperature {
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
|
axis: barWindow.axis
|
||||||
section: topBarContent.getWidgetSection(parent) || "right"
|
section: topBarContent.getWidgetSection(parent) || "right"
|
||||||
popupTarget: {
|
popoutTarget: {
|
||||||
processListPopoutLoader.active = true
|
processListPopoutLoader.active = true
|
||||||
return processListPopoutLoader.item
|
return processListPopoutLoader.item
|
||||||
}
|
}
|
||||||
@@ -1063,8 +1076,9 @@ Item {
|
|||||||
isActive: notificationCenterLoader.item ? notificationCenterLoader.item.shouldBeVisible : false
|
isActive: notificationCenterLoader.item ? notificationCenterLoader.item.shouldBeVisible : false
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
|
axis: barWindow.axis
|
||||||
section: topBarContent.getWidgetSection(parent) || "right"
|
section: topBarContent.getWidgetSection(parent) || "right"
|
||||||
popupTarget: {
|
popoutTarget: {
|
||||||
notificationCenterLoader.active = true
|
notificationCenterLoader.active = true
|
||||||
return notificationCenterLoader.item
|
return notificationCenterLoader.item
|
||||||
}
|
}
|
||||||
@@ -1083,8 +1097,9 @@ Item {
|
|||||||
batteryPopupVisible: batteryPopoutLoader.item ? batteryPopoutLoader.item.shouldBeVisible : false
|
batteryPopupVisible: batteryPopoutLoader.item ? batteryPopoutLoader.item.shouldBeVisible : false
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
|
axis: barWindow.axis
|
||||||
section: topBarContent.getWidgetSection(parent) || "right"
|
section: topBarContent.getWidgetSection(parent) || "right"
|
||||||
popupTarget: {
|
popoutTarget: {
|
||||||
batteryPopoutLoader.active = true
|
batteryPopoutLoader.active = true
|
||||||
return batteryPopoutLoader.item
|
return batteryPopoutLoader.item
|
||||||
}
|
}
|
||||||
@@ -1102,8 +1117,9 @@ Item {
|
|||||||
Vpn {
|
Vpn {
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
|
axis: barWindow.axis
|
||||||
section: topBarContent.getWidgetSection(parent) || "right"
|
section: topBarContent.getWidgetSection(parent) || "right"
|
||||||
popupTarget: {
|
popoutTarget: {
|
||||||
vpnPopoutLoader.active = true
|
vpnPopoutLoader.active = true
|
||||||
return vpnPopoutLoader.item
|
return vpnPopoutLoader.item
|
||||||
}
|
}
|
||||||
@@ -1122,8 +1138,9 @@ Item {
|
|||||||
isActive: controlCenterLoader.item ? controlCenterLoader.item.shouldBeVisible : false
|
isActive: controlCenterLoader.item ? controlCenterLoader.item.shouldBeVisible : false
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
|
axis: barWindow.axis
|
||||||
section: topBarContent.getWidgetSection(parent) || "right"
|
section: topBarContent.getWidgetSection(parent) || "right"
|
||||||
popupTarget: {
|
popoutTarget: {
|
||||||
controlCenterLoader.active = true
|
controlCenterLoader.active = true
|
||||||
return controlCenterLoader.item
|
return controlCenterLoader.item
|
||||||
}
|
}
|
||||||
@@ -1217,9 +1234,9 @@ Item {
|
|||||||
id: notepadButtonComponent
|
id: notepadButtonComponent
|
||||||
|
|
||||||
NotepadButton {
|
NotepadButton {
|
||||||
isVertical: barWindow.isVertical
|
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
|
axis: barWindow.axis
|
||||||
section: topBarContent.getWidgetSection(parent) || "right"
|
section: topBarContent.getWidgetSection(parent) || "right"
|
||||||
parentScreen: barWindow.screen
|
parentScreen: barWindow.screen
|
||||||
}
|
}
|
||||||
@@ -1246,8 +1263,9 @@ Item {
|
|||||||
isActive: systemUpdateLoader.item ? systemUpdateLoader.item.shouldBeVisible : false
|
isActive: systemUpdateLoader.item ? systemUpdateLoader.item.shouldBeVisible : false
|
||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
|
axis: barWindow.axis
|
||||||
section: topBarContent.getWidgetSection(parent) || "right"
|
section: topBarContent.getWidgetSection(parent) || "right"
|
||||||
popupTarget: {
|
popoutTarget: {
|
||||||
systemUpdateLoader.active = true
|
systemUpdateLoader.active = true
|
||||||
return systemUpdateLoader.item
|
return systemUpdateLoader.item
|
||||||
}
|
}
|
||||||
@@ -1265,15 +1283,4 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IpcHandler {
|
|
||||||
target: "dankdash"
|
|
||||||
|
|
||||||
function wallpaper(): string {
|
|
||||||
if (root.triggerWallpaperBrowserOnFocusedScreen()) {
|
|
||||||
return "SUCCESS: Toggled wallpaper browser"
|
|
||||||
}
|
|
||||||
return "ERROR: Failed to toggle wallpaper browser"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,124 +1,112 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell.Services.UPower
|
import Quickshell.Services.UPower
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: battery
|
id: battery
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property bool batteryPopupVisible: false
|
property bool batteryPopupVisible: false
|
||||||
property string section: "right"
|
property var popoutTarget: null
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal toggleBatteryPopup()
|
signal toggleBatteryPopup()
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (batteryContent.implicitWidth + horizontalPadding * 2)
|
|
||||||
height: isVertical ? (batteryColumn.implicitHeight + horizontalPadding * 2) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = batteryArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
visible: true
|
visible: true
|
||||||
|
|
||||||
Column {
|
content: Component {
|
||||||
id: batteryColumn
|
Item {
|
||||||
visible: battery.isVertical
|
implicitWidth: battery.isVerticalOrientation ? (battery.widgetThickness - battery.horizontalPadding * 2) : batteryContent.implicitWidth
|
||||||
anchors.centerIn: parent
|
implicitHeight: battery.isVerticalOrientation ? batteryColumn.implicitHeight : (battery.widgetThickness - battery.horizontalPadding * 2)
|
||||||
spacing: 1
|
|
||||||
|
|
||||||
DankIcon {
|
Column {
|
||||||
name: BatteryService.getBatteryIcon()
|
id: batteryColumn
|
||||||
size: Theme.barIconSize(barThickness)
|
visible: battery.isVerticalOrientation
|
||||||
color: {
|
anchors.centerIn: parent
|
||||||
if (!BatteryService.batteryAvailable) {
|
spacing: 1
|
||||||
return Theme.surfaceText
|
|
||||||
|
DankIcon {
|
||||||
|
name: BatteryService.getBatteryIcon()
|
||||||
|
size: Theme.barIconSize(battery.barThickness)
|
||||||
|
color: {
|
||||||
|
if (!BatteryService.batteryAvailable) {
|
||||||
|
return Theme.surfaceText
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BatteryService.isLowBattery && !BatteryService.isCharging) {
|
||||||
|
return Theme.error
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BatteryService.isCharging || BatteryService.isPluggedIn) {
|
||||||
|
return Theme.primary
|
||||||
|
}
|
||||||
|
|
||||||
|
return Theme.surfaceText
|
||||||
|
}
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.isLowBattery && !BatteryService.isCharging) {
|
StyledText {
|
||||||
return Theme.error
|
text: BatteryService.batteryLevel.toString()
|
||||||
|
font.pixelSize: Theme.barTextSize(battery.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
visible: BatteryService.batteryAvailable
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.isCharging || BatteryService.isPluggedIn) {
|
|
||||||
return Theme.primary
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.surfaceText
|
|
||||||
}
|
}
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
Row {
|
||||||
text: BatteryService.batteryLevel.toString()
|
id: batteryContent
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
visible: !battery.isVerticalOrientation
|
||||||
font.weight: Font.Medium
|
anchors.centerIn: parent
|
||||||
color: Theme.surfaceText
|
spacing: SettingsData.dankBarNoBackground ? 1 : 2
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: BatteryService.batteryAvailable
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
DankIcon {
|
||||||
id: batteryContent
|
name: BatteryService.getBatteryIcon()
|
||||||
visible: !battery.isVertical
|
size: Theme.barIconSize(battery.barThickness, -4)
|
||||||
anchors.centerIn: parent
|
color: {
|
||||||
spacing: SettingsData.dankBarNoBackground ? 1 : 2
|
if (!BatteryService.batteryAvailable) {
|
||||||
|
return Theme.surfaceText;
|
||||||
|
}
|
||||||
|
|
||||||
DankIcon {
|
if (BatteryService.isLowBattery && !BatteryService.isCharging) {
|
||||||
name: BatteryService.getBatteryIcon()
|
return Theme.error;
|
||||||
size: Theme.barIconSize(barThickness, -4)
|
}
|
||||||
color: {
|
|
||||||
if (!BatteryService.batteryAvailable) {
|
if (BatteryService.isCharging || BatteryService.isPluggedIn) {
|
||||||
return Theme.surfaceText;
|
return Theme.primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Theme.surfaceText;
|
||||||
|
}
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.isLowBattery && !BatteryService.isCharging) {
|
StyledText {
|
||||||
return Theme.error;
|
text: `${BatteryService.batteryLevel}%`
|
||||||
|
font.pixelSize: Theme.barTextSize(battery.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: BatteryService.batteryAvailable
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.isCharging || BatteryService.isPluggedIn) {
|
|
||||||
return Theme.primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.surfaceText;
|
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: `${BatteryService.batteryLevel}%`
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: BatteryService.batteryAvailable
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: batteryArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
onPressed: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popoutTarget && popoutTarget.setTriggerPosition) {
|
||||||
const globalPos = mapToGlobal(0, 0)
|
const globalPos = battery.visualContent.mapToGlobal(0, 0)
|
||||||
const currentScreen = parentScreen || Screen
|
const currentScreen = parentScreen || Screen
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, battery.visualWidth)
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
||||||
}
|
}
|
||||||
toggleBatteryPopup();
|
toggleBatteryPopup();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,57 +1,25 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Item {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isActive: false
|
property bool isActive: false
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property string section: "right"
|
|
||||||
property var clipboardHistoryModal: null
|
property var clipboardHistoryModal: null
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal clicked()
|
content: Component {
|
||||||
|
Item {
|
||||||
|
implicitWidth: root.widgetThickness - root.horizontalPadding * 2
|
||||||
|
implicitHeight: root.widgetThickness - root.horizontalPadding * 2
|
||||||
|
|
||||||
width: widgetThickness
|
DankIcon {
|
||||||
height: widgetThickness
|
anchors.centerIn: parent
|
||||||
|
name: "content_paste"
|
||||||
MouseArea {
|
size: Theme.barIconSize(root.barThickness)
|
||||||
id: clipboardArea
|
color: Theme.surfaceText
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
acceptedButtons: Qt.LeftButton
|
|
||||||
onPressed: {
|
|
||||||
root.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: clipboardContent
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseColor = clipboardArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency)
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
name: "content_paste"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,270 +1,254 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property bool compactMode: false
|
property bool compactMode: false
|
||||||
property string section: "center"
|
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real barThickness: 48
|
|
||||||
property real widgetThickness: 30
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 2 : Theme.spacingS
|
|
||||||
|
|
||||||
signal clockClicked
|
signal clockClicked
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (clockRow.implicitWidth + horizontalPadding * 2)
|
content: Component {
|
||||||
height: isVertical ? (clockColumn.implicitHeight + horizontalPadding * 2) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = clockMouseArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: clockColumn
|
|
||||||
visible: root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: -2
|
|
||||||
|
|
||||||
Row {
|
|
||||||
spacing: 0
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (SettingsData.use24HourClock) {
|
|
||||||
return String(systemClock?.date?.getHours()).padStart(2, '0').charAt(0)
|
|
||||||
} else {
|
|
||||||
const hours = systemClock?.date?.getHours()
|
|
||||||
const display = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours
|
|
||||||
return String(display).padStart(2, '0').charAt(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (SettingsData.use24HourClock) {
|
|
||||||
return String(systemClock?.date?.getHours()).padStart(2, '0').charAt(1)
|
|
||||||
} else {
|
|
||||||
const hours = systemClock?.date?.getHours()
|
|
||||||
const display = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours
|
|
||||||
return String(display).padStart(2, '0').charAt(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
spacing: 0
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(0)
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(1)
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
visible: SettingsData.showSeconds
|
|
||||||
spacing: 0
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: String(systemClock?.date?.getSeconds()).padStart(2, '0').charAt(0)
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: String(systemClock?.date?.getSeconds()).padStart(2, '0').charAt(1)
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
width: 12
|
implicitWidth: root.isVerticalOrientation ? (root.widgetThickness - root.horizontalPadding * 2) : clockRow.implicitWidth
|
||||||
height: Theme.spacingM
|
implicitHeight: root.isVerticalOrientation ? clockColumn.implicitHeight : (root.widgetThickness - root.horizontalPadding * 2)
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
Rectangle {
|
Column {
|
||||||
width: 12
|
id: clockColumn
|
||||||
height: 1
|
visible: root.isVerticalOrientation
|
||||||
color: Theme.outlineButton
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
}
|
spacing: -2
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
const locale = Qt.locale()
|
if (SettingsData.use24HourClock) {
|
||||||
const dateFormatShort = locale.dateFormat(Locale.ShortFormat)
|
return String(systemClock?.date?.getHours()).padStart(2, '0').charAt(0)
|
||||||
const dayFirst = dateFormatShort.indexOf('d') < dateFormatShort.indexOf('M')
|
} else {
|
||||||
const value = dayFirst ? String(systemClock?.date?.getDate()).padStart(2, '0') : String(systemClock?.date?.getMonth() + 1).padStart(2, '0')
|
const hours = systemClock?.date?.getHours()
|
||||||
return value.charAt(0)
|
const display = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours
|
||||||
}
|
return String(display).padStart(2, '0').charAt(0)
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
}
|
||||||
color: Theme.primary
|
}
|
||||||
font.weight: Font.Light
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
width: 9
|
color: Theme.surfaceText
|
||||||
horizontalAlignment: Text.AlignHCenter
|
font.weight: Font.Normal
|
||||||
}
|
width: 9
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
const locale = Qt.locale()
|
if (SettingsData.use24HourClock) {
|
||||||
const dateFormatShort = locale.dateFormat(Locale.ShortFormat)
|
return String(systemClock?.date?.getHours()).padStart(2, '0').charAt(1)
|
||||||
const dayFirst = dateFormatShort.indexOf('d') < dateFormatShort.indexOf('M')
|
} else {
|
||||||
const value = dayFirst ? String(systemClock?.date?.getDate()).padStart(2, '0') : String(systemClock?.date?.getMonth() + 1).padStart(2, '0')
|
const hours = systemClock?.date?.getHours()
|
||||||
return value.charAt(1)
|
const display = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours
|
||||||
}
|
return String(display).padStart(2, '0').charAt(1)
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
}
|
||||||
color: Theme.primary
|
}
|
||||||
font.weight: Font.Light
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
width: 9
|
color: Theme.surfaceText
|
||||||
horizontalAlignment: Text.AlignHCenter
|
font.weight: Font.Normal
|
||||||
}
|
width: 9
|
||||||
}
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
Row {
|
|
||||||
spacing: 0
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
const locale = Qt.locale()
|
|
||||||
const dateFormatShort = locale.dateFormat(Locale.ShortFormat)
|
|
||||||
const dayFirst = dateFormatShort.indexOf('d') < dateFormatShort.indexOf('M')
|
|
||||||
const value = dayFirst ? String(systemClock?.date?.getMonth() + 1).padStart(2, '0') : String(systemClock?.date?.getDate()).padStart(2, '0')
|
|
||||||
return value.charAt(0)
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.primary
|
|
||||||
font.weight: Font.Light
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
const locale = Qt.locale()
|
|
||||||
const dateFormatShort = locale.dateFormat(Locale.ShortFormat)
|
|
||||||
const dayFirst = dateFormatShort.indexOf('d') < dateFormatShort.indexOf('M')
|
|
||||||
const value = dayFirst ? String(systemClock?.date?.getMonth() + 1).padStart(2, '0') : String(systemClock?.date?.getDate()).padStart(2, '0')
|
|
||||||
return value.charAt(1)
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.primary
|
|
||||||
font.weight: Font.Light
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: clockRow
|
|
||||||
|
|
||||||
visible: !root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
return systemClock?.date?.toLocaleTimeString(Qt.locale(), SettingsData.getEffectiveTimeFormat())
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "•"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.outlineButton
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: !SettingsData.clockCompactMode
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (SettingsData.clockDateFormat && SettingsData.clockDateFormat.length > 0) {
|
|
||||||
return systemClock?.date?.toLocaleDateString(Qt.locale(), SettingsData.clockDateFormat)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return systemClock?.date?.toLocaleDateString(Qt.locale(), "ddd d")
|
Row {
|
||||||
}
|
spacing: 0
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: !SettingsData.clockCompactMode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemClock {
|
StyledText {
|
||||||
id: systemClock
|
text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(0)
|
||||||
precision: SystemClock.Seconds
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Normal
|
||||||
|
width: 9
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(1)
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Normal
|
||||||
|
width: 9
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
visible: SettingsData.showSeconds
|
||||||
|
spacing: 0
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: String(systemClock?.date?.getSeconds()).padStart(2, '0').charAt(0)
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Normal
|
||||||
|
width: 9
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: String(systemClock?.date?.getSeconds()).padStart(2, '0').charAt(1)
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Normal
|
||||||
|
width: 9
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 12
|
||||||
|
height: Theme.spacingM
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 12
|
||||||
|
height: 1
|
||||||
|
color: Theme.outlineButton
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 0
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
const locale = Qt.locale()
|
||||||
|
const dateFormatShort = locale.dateFormat(Locale.ShortFormat)
|
||||||
|
const dayFirst = dateFormatShort.indexOf('d') < dateFormatShort.indexOf('M')
|
||||||
|
const value = dayFirst ? String(systemClock?.date?.getDate()).padStart(2, '0') : String(systemClock?.date?.getMonth() + 1).padStart(2, '0')
|
||||||
|
return value.charAt(0)
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.primary
|
||||||
|
font.weight: Font.Light
|
||||||
|
width: 9
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
const locale = Qt.locale()
|
||||||
|
const dateFormatShort = locale.dateFormat(Locale.ShortFormat)
|
||||||
|
const dayFirst = dateFormatShort.indexOf('d') < dateFormatShort.indexOf('M')
|
||||||
|
const value = dayFirst ? String(systemClock?.date?.getDate()).padStart(2, '0') : String(systemClock?.date?.getMonth() + 1).padStart(2, '0')
|
||||||
|
return value.charAt(1)
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.primary
|
||||||
|
font.weight: Font.Light
|
||||||
|
width: 9
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 0
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
const locale = Qt.locale()
|
||||||
|
const dateFormatShort = locale.dateFormat(Locale.ShortFormat)
|
||||||
|
const dayFirst = dateFormatShort.indexOf('d') < dateFormatShort.indexOf('M')
|
||||||
|
const value = dayFirst ? String(systemClock?.date?.getMonth() + 1).padStart(2, '0') : String(systemClock?.date?.getDate()).padStart(2, '0')
|
||||||
|
return value.charAt(0)
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.primary
|
||||||
|
font.weight: Font.Light
|
||||||
|
width: 9
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
const locale = Qt.locale()
|
||||||
|
const dateFormatShort = locale.dateFormat(Locale.ShortFormat)
|
||||||
|
const dayFirst = dateFormatShort.indexOf('d') < dateFormatShort.indexOf('M')
|
||||||
|
const value = dayFirst ? String(systemClock?.date?.getMonth() + 1).padStart(2, '0') : String(systemClock?.date?.getDate()).padStart(2, '0')
|
||||||
|
return value.charAt(1)
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.primary
|
||||||
|
font.weight: Font.Light
|
||||||
|
width: 9
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: clockRow
|
||||||
|
visible: !root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
return systemClock?.date?.toLocaleTimeString(Qt.locale(), SettingsData.getEffectiveTimeFormat())
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "•"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.outlineButton
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: !SettingsData.clockCompactMode
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (SettingsData.clockDateFormat && SettingsData.clockDateFormat.length > 0) {
|
||||||
|
return systemClock?.date?.toLocaleDateString(Qt.locale(), SettingsData.clockDateFormat)
|
||||||
|
}
|
||||||
|
|
||||||
|
return systemClock?.date?.toLocaleDateString(Qt.locale(), "ddd d")
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: !SettingsData.clockCompactMode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemClock {
|
||||||
|
id: systemClock
|
||||||
|
precision: SystemClock.Seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: clockMouseArea
|
id: clockMouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onPressed: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (root.popoutTarget && root.popoutTarget.setTriggerPosition) {
|
||||||
const globalPos = mapToGlobal(0, 0)
|
const globalPos = mapToGlobal(0, 0)
|
||||||
const currentScreen = parentScreen || Screen
|
const currentScreen = root.parentScreen || Screen
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, root.barThickness, width)
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
root.popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, root.section, currentScreen)
|
||||||
}
|
}
|
||||||
root.clockClicked()
|
root.clockClicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,54 +1,36 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property bool isActive: false
|
property bool isActive: false
|
||||||
property string section: "right"
|
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal clicked()
|
signal colorPickerRequested()
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (colorPickerIcon.width + horizontalPadding * 2)
|
content: Component {
|
||||||
height: isVertical ? (colorPickerIcon.height + horizontalPadding * 2) : widgetThickness
|
Item {
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
implicitWidth: root.widgetThickness - root.horizontalPadding * 2
|
||||||
color: {
|
implicitHeight: root.widgetThickness - root.horizontalPadding * 2
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "palette"
|
||||||
|
size: Theme.barIconSize(root.barThickness, -4)
|
||||||
|
color: root.isActive ? Theme.primary : Theme.surfaceText
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseColor = colorPickerArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
id: colorPickerIcon
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
name: "palette"
|
|
||||||
size: Theme.barIconSize(barThickness, -4)
|
|
||||||
color: colorPickerArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: colorPickerArea
|
z: 1
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onPressed: {
|
onPressed: {
|
||||||
root.colorPickerRequested();
|
root.colorPickerRequested()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signal colorPickerRequested()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,266 +1,245 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property bool isActive: false
|
property bool isActive: false
|
||||||
property string section: "right"
|
property var popoutTarget: null
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property var widgetData: null
|
property var widgetData: null
|
||||||
property bool showNetworkIcon: SettingsData.controlCenterShowNetworkIcon
|
property bool showNetworkIcon: SettingsData.controlCenterShowNetworkIcon
|
||||||
property bool showBluetoothIcon: SettingsData.controlCenterShowBluetoothIcon
|
property bool showBluetoothIcon: SettingsData.controlCenterShowBluetoothIcon
|
||||||
property bool showAudioIcon: SettingsData.controlCenterShowAudioIcon
|
property bool showAudioIcon: SettingsData.controlCenterShowAudioIcon
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal clicked()
|
content: Component {
|
||||||
|
Item {
|
||||||
|
implicitWidth: root.isVerticalOrientation ? (root.widgetThickness - root.horizontalPadding * 2) : controlIndicators.implicitWidth
|
||||||
|
implicitHeight: root.isVerticalOrientation ? controlColumn.implicitHeight : (root.widgetThickness - root.horizontalPadding * 2)
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (controlIndicators.implicitWidth + horizontalPadding * 2)
|
Column {
|
||||||
height: isVertical ? (controlColumn.implicitHeight + horizontalPadding * 2) : widgetThickness
|
id: controlColumn
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
visible: root.isVerticalOrientation
|
||||||
color: {
|
anchors.centerIn: parent
|
||||||
if (SettingsData.dankBarNoBackground) {
|
spacing: Theme.spacingXS
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = controlCenterArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
DankIcon {
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
name: {
|
||||||
}
|
if (NetworkService.wifiToggling) {
|
||||||
|
return "sync"
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
if (NetworkService.networkStatus === "ethernet") {
|
||||||
id: controlColumn
|
return "lan"
|
||||||
visible: root.isVertical
|
}
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
|
|
||||||
DankIcon {
|
return NetworkService.wifiSignalIcon
|
||||||
name: {
|
}
|
||||||
if (NetworkService.wifiToggling) {
|
size: Theme.barIconSize(root.barThickness)
|
||||||
return "sync"
|
color: {
|
||||||
|
if (NetworkService.wifiToggling) {
|
||||||
|
return Theme.primary
|
||||||
|
}
|
||||||
|
|
||||||
|
return NetworkService.networkStatus !== "disconnected" ? Theme.primary : Theme.outlineButton
|
||||||
|
}
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
visible: root.showNetworkIcon && NetworkService.networkAvailable
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NetworkService.networkStatus === "ethernet") {
|
DankIcon {
|
||||||
return "lan"
|
name: "bluetooth"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: BluetoothService.connected ? Theme.primary : Theme.outlineButton
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
visible: root.showBluetoothIcon && BluetoothService.available && BluetoothService.enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
return NetworkService.wifiSignalIcon
|
Rectangle {
|
||||||
}
|
width: audioIconV.implicitWidth + 4
|
||||||
size: Theme.barIconSize(barThickness)
|
height: audioIconV.implicitHeight + 4
|
||||||
color: {
|
color: "transparent"
|
||||||
if (NetworkService.wifiToggling) {
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
return Theme.primary
|
visible: root.showAudioIcon
|
||||||
}
|
|
||||||
|
|
||||||
return NetworkService.networkStatus !== "disconnected" ? Theme.primary : Theme.outlineButton
|
DankIcon {
|
||||||
}
|
id: audioIconV
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: root.showNetworkIcon && NetworkService.networkAvailable
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
name: {
|
||||||
name: "bluetooth"
|
if (AudioService.sink && AudioService.sink.audio) {
|
||||||
size: Theme.barIconSize(barThickness)
|
if (AudioService.sink.audio.muted || AudioService.sink.audio.volume === 0) {
|
||||||
color: BluetoothService.connected ? Theme.primary : Theme.outlineButton
|
return "volume_off"
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
} else if (AudioService.sink.audio.volume * 100 < 33) {
|
||||||
visible: root.showBluetoothIcon && BluetoothService.available && BluetoothService.enabled
|
return "volume_down"
|
||||||
}
|
} else {
|
||||||
|
return "volume_up"
|
||||||
Rectangle {
|
}
|
||||||
width: audioIconV.implicitWidth + 4
|
}
|
||||||
height: audioIconV.implicitHeight + 4
|
|
||||||
color: "transparent"
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: root.showAudioIcon
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
id: audioIconV
|
|
||||||
|
|
||||||
name: {
|
|
||||||
if (AudioService.sink && AudioService.sink.audio) {
|
|
||||||
if (AudioService.sink.audio.muted || AudioService.sink.audio.volume === 0) {
|
|
||||||
return "volume_off"
|
|
||||||
} else if (AudioService.sink.audio.volume * 100 < 33) {
|
|
||||||
return "volume_down"
|
|
||||||
} else {
|
|
||||||
return "volume_up"
|
return "volume_up"
|
||||||
}
|
}
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
return "volume_up"
|
|
||||||
}
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
acceptedButtons: Qt.NoButton
|
acceptedButtons: Qt.NoButton
|
||||||
onWheel: function(wheelEvent) {
|
onWheel: function(wheelEvent) {
|
||||||
let delta = wheelEvent.angleDelta.y
|
let delta = wheelEvent.angleDelta.y
|
||||||
let currentVolume = (AudioService.sink && AudioService.sink.audio && AudioService.sink.audio.volume * 100) || 0
|
let currentVolume = (AudioService.sink && AudioService.sink.audio && AudioService.sink.audio.volume * 100) || 0
|
||||||
let newVolume
|
let newVolume
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
newVolume = Math.min(100, currentVolume + 5)
|
newVolume = Math.min(100, currentVolume + 5)
|
||||||
} else {
|
} else {
|
||||||
newVolume = Math.max(0, currentVolume - 5)
|
newVolume = Math.max(0, currentVolume - 5)
|
||||||
}
|
}
|
||||||
if (AudioService.sink && AudioService.sink.audio) {
|
if (AudioService.sink && AudioService.sink.audio) {
|
||||||
AudioService.sink.audio.muted = false
|
AudioService.sink.audio.muted = false
|
||||||
AudioService.sink.audio.volume = newVolume / 100
|
AudioService.sink.audio.volume = newVolume / 100
|
||||||
}
|
}
|
||||||
wheelEvent.accepted = true
|
wheelEvent.accepted = true
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "settings"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: controlCenterArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: !root.showNetworkIcon && !root.showBluetoothIcon && !root.showAudioIcon
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: controlIndicators
|
|
||||||
visible: !root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
id: networkIcon
|
|
||||||
|
|
||||||
name: {
|
|
||||||
if (NetworkService.wifiToggling) {
|
|
||||||
return "sync";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NetworkService.networkStatus === "ethernet") {
|
|
||||||
return "lan";
|
|
||||||
}
|
|
||||||
|
|
||||||
return NetworkService.wifiSignalIcon;
|
|
||||||
}
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: {
|
|
||||||
if (NetworkService.wifiToggling) {
|
|
||||||
return Theme.primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NetworkService.networkStatus !== "disconnected" ? Theme.primary : Theme.outlineButton;
|
|
||||||
}
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: root.showNetworkIcon && NetworkService.networkAvailable
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
id: bluetoothIcon
|
|
||||||
|
|
||||||
name: "bluetooth"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: BluetoothService.connected ? Theme.primary : Theme.outlineButton
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: root.showBluetoothIcon && BluetoothService.available && BluetoothService.enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: audioIcon.implicitWidth + 4
|
|
||||||
height: audioIcon.implicitHeight + 4
|
|
||||||
color: "transparent"
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: root.showAudioIcon
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
id: audioIcon
|
|
||||||
|
|
||||||
name: {
|
|
||||||
if (AudioService.sink && AudioService.sink.audio) {
|
|
||||||
if (AudioService.sink.audio.muted || AudioService.sink.audio.volume === 0) {
|
|
||||||
return "volume_off";
|
|
||||||
} else if (AudioService.sink.audio.volume * 100 < 33) {
|
|
||||||
return "volume_down";
|
|
||||||
} else {
|
|
||||||
return "volume_up";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "volume_up";
|
|
||||||
}
|
}
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
DankIcon {
|
||||||
|
name: "settings"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: root.isActive ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
visible: !root.showNetworkIcon && !root.showBluetoothIcon && !root.showAudioIcon
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: controlIndicators
|
||||||
|
visible: !root.isVerticalOrientation
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
}
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
MouseArea {
|
DankIcon {
|
||||||
id: audioWheelArea
|
id: networkIcon
|
||||||
|
|
||||||
anchors.fill: parent
|
name: {
|
||||||
hoverEnabled: true
|
if (NetworkService.wifiToggling) {
|
||||||
acceptedButtons: Qt.NoButton
|
return "sync";
|
||||||
onWheel: function(wheelEvent) {
|
}
|
||||||
let delta = wheelEvent.angleDelta.y;
|
|
||||||
let currentVolume = (AudioService.sink && AudioService.sink.audio && AudioService.sink.audio.volume * 100) || 0;
|
if (NetworkService.networkStatus === "ethernet") {
|
||||||
let newVolume;
|
return "lan";
|
||||||
if (delta > 0) {
|
}
|
||||||
newVolume = Math.min(100, currentVolume + 5);
|
|
||||||
} else {
|
return NetworkService.wifiSignalIcon;
|
||||||
newVolume = Math.max(0, currentVolume - 5);
|
|
||||||
}
|
}
|
||||||
if (AudioService.sink && AudioService.sink.audio) {
|
size: Theme.barIconSize(root.barThickness)
|
||||||
AudioService.sink.audio.muted = false;
|
color: {
|
||||||
AudioService.sink.audio.volume = newVolume / 100;
|
if (NetworkService.wifiToggling) {
|
||||||
|
return Theme.primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NetworkService.networkStatus !== "disconnected" ? Theme.primary : Theme.outlineButton;
|
||||||
}
|
}
|
||||||
wheelEvent.accepted = true;
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: root.showNetworkIcon && NetworkService.networkAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
id: bluetoothIcon
|
||||||
|
|
||||||
|
name: "bluetooth"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: BluetoothService.connected ? Theme.primary : Theme.outlineButton
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: root.showBluetoothIcon && BluetoothService.available && BluetoothService.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: audioIcon.implicitWidth + 4
|
||||||
|
height: audioIcon.implicitHeight + 4
|
||||||
|
color: "transparent"
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: root.showAudioIcon
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
id: audioIcon
|
||||||
|
|
||||||
|
name: {
|
||||||
|
if (AudioService.sink && AudioService.sink.audio) {
|
||||||
|
if (AudioService.sink.audio.muted || AudioService.sink.audio.volume === 0) {
|
||||||
|
return "volume_off";
|
||||||
|
} else if (AudioService.sink.audio.volume * 100 < 33) {
|
||||||
|
return "volume_down";
|
||||||
|
} else {
|
||||||
|
return "volume_up";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "volume_up";
|
||||||
|
}
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: audioWheelArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
onWheel: function(wheelEvent) {
|
||||||
|
let delta = wheelEvent.angleDelta.y;
|
||||||
|
let currentVolume = (AudioService.sink && AudioService.sink.audio && AudioService.sink.audio.volume * 100) || 0;
|
||||||
|
let newVolume;
|
||||||
|
if (delta > 0) {
|
||||||
|
newVolume = Math.min(100, currentVolume + 5);
|
||||||
|
} else {
|
||||||
|
newVolume = Math.max(0, currentVolume - 5);
|
||||||
|
}
|
||||||
|
if (AudioService.sink && AudioService.sink.audio) {
|
||||||
|
AudioService.sink.audio.muted = false;
|
||||||
|
AudioService.sink.audio.volume = newVolume / 100;
|
||||||
|
}
|
||||||
|
wheelEvent.accepted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "mic"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "settings"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: root.isActive ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: !root.showNetworkIcon && !root.showBluetoothIcon && !root.showAudioIcon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "mic"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: false // TODO: Add mic detection
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback settings icon when all other icons are hidden
|
|
||||||
DankIcon {
|
|
||||||
name: "settings"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: controlCenterArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: !root.showNetworkIcon && !root.showBluetoothIcon && !root.showAudioIcon
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: controlCenterArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
onPressed: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popoutTarget && popoutTarget.setTriggerPosition) {
|
||||||
const globalPos = mapToGlobal(0, 0)
|
const globalPos = root.visualContent.mapToGlobal(0, 0)
|
||||||
const currentScreen = parentScreen || Screen
|
const currentScreen = parentScreen || Screen
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
||||||
}
|
}
|
||||||
root.clicked();
|
root.clicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,20 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property bool showPercentage: true
|
property bool showPercentage: true
|
||||||
property bool showIcon: true
|
property bool showIcon: true
|
||||||
property var toggleProcessList
|
property var toggleProcessList
|
||||||
property string section: "right"
|
property var popoutTarget: null
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real barThickness: 48
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property var widgetData: null
|
property var widgetData: null
|
||||||
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
|
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (cpuContent.implicitWidth + horizontalPadding * 2)
|
|
||||||
height: isVertical ? (cpuColumn.implicitHeight + horizontalPadding * 2) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = cpuArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
DgopService.addRef(["cpu"]);
|
DgopService.addRef(["cpu"]);
|
||||||
}
|
}
|
||||||
@@ -39,120 +22,123 @@ Rectangle {
|
|||||||
DgopService.removeRef(["cpu"]);
|
DgopService.removeRef(["cpu"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
content: Component {
|
||||||
id: cpuArea
|
Item {
|
||||||
|
implicitWidth: root.isVerticalOrientation ? (root.widgetThickness - root.horizontalPadding * 2) : cpuContent.implicitWidth
|
||||||
|
implicitHeight: root.isVerticalOrientation ? cpuColumn.implicitHeight : (root.widgetThickness - root.horizontalPadding * 2)
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: cpuColumn
|
||||||
|
visible: root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 1
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "memory"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: {
|
||||||
|
if (DgopService.cpuUsage > 80) {
|
||||||
|
return Theme.tempDanger;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DgopService.cpuUsage > 60) {
|
||||||
|
return Theme.tempWarning;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Theme.surfaceText;
|
||||||
|
}
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (DgopService.cpuUsage === undefined || DgopService.cpuUsage === null || DgopService.cpuUsage === 0) {
|
||||||
|
return "--";
|
||||||
|
}
|
||||||
|
|
||||||
|
return DgopService.cpuUsage.toFixed(0);
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: cpuContent
|
||||||
|
visible: !root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 3
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "memory"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: {
|
||||||
|
if (DgopService.cpuUsage > 80) {
|
||||||
|
return Theme.tempDanger;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DgopService.cpuUsage > 60) {
|
||||||
|
return Theme.tempWarning;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Theme.surfaceText;
|
||||||
|
}
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (DgopService.cpuUsage === undefined || DgopService.cpuUsage === null || DgopService.cpuUsage === 0) {
|
||||||
|
return "--%";
|
||||||
|
}
|
||||||
|
|
||||||
|
return DgopService.cpuUsage.toFixed(0) + "%";
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
elide: Text.ElideNone
|
||||||
|
|
||||||
|
StyledTextMetrics {
|
||||||
|
id: cpuBaseline
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
text: "100%"
|
||||||
|
}
|
||||||
|
|
||||||
|
width: root.minimumWidth ? Math.max(cpuBaseline.width, paintedWidth) : paintedWidth
|
||||||
|
|
||||||
|
Behavior on width {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 120
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
onPressed: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popoutTarget && popoutTarget.setTriggerPosition) {
|
||||||
const globalPos = mapToGlobal(0, 0)
|
const globalPos = root.visualContent.mapToGlobal(0, 0)
|
||||||
const currentScreen = parentScreen || Screen
|
const currentScreen = parentScreen || Screen
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
||||||
}
|
}
|
||||||
DgopService.setSortBy("cpu");
|
DgopService.setSortBy("cpu");
|
||||||
if (root.toggleProcessList) {
|
if (root.toggleProcessList) {
|
||||||
root.toggleProcessList();
|
root.toggleProcessList();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
|
||||||
id: cpuColumn
|
|
||||||
visible: root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 1
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "memory"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: {
|
|
||||||
if (DgopService.cpuUsage > 80) {
|
|
||||||
return Theme.tempDanger;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DgopService.cpuUsage > 60) {
|
|
||||||
return Theme.tempWarning;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.surfaceText;
|
|
||||||
}
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (DgopService.cpuUsage === undefined || DgopService.cpuUsage === null || DgopService.cpuUsage === 0) {
|
|
||||||
return "--";
|
|
||||||
}
|
|
||||||
|
|
||||||
return DgopService.cpuUsage.toFixed(0);
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: cpuContent
|
|
||||||
visible: !root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 3
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "memory"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: {
|
|
||||||
if (DgopService.cpuUsage > 80) {
|
|
||||||
return Theme.tempDanger;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DgopService.cpuUsage > 60) {
|
|
||||||
return Theme.tempWarning;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.surfaceText;
|
|
||||||
}
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (DgopService.cpuUsage === undefined || DgopService.cpuUsage === null || DgopService.cpuUsage === 0) {
|
|
||||||
return "--%";
|
|
||||||
}
|
|
||||||
|
|
||||||
return DgopService.cpuUsage.toFixed(0) + "%";
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
elide: Text.ElideNone
|
|
||||||
|
|
||||||
StyledTextMetrics {
|
|
||||||
id: cpuBaseline
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
text: "100%"
|
|
||||||
}
|
|
||||||
|
|
||||||
width: root.minimumWidth ? Math.max(cpuBaseline.width, paintedWidth) : paintedWidth
|
|
||||||
|
|
||||||
Behavior on width {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 120
|
|
||||||
easing.type: Easing.OutCubic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,20 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property bool showPercentage: true
|
property bool showPercentage: true
|
||||||
property bool showIcon: true
|
property bool showIcon: true
|
||||||
property var toggleProcessList
|
property var toggleProcessList
|
||||||
property string section: "right"
|
property var popoutTarget: null
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real barThickness: 48
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property var widgetData: null
|
property var widgetData: null
|
||||||
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
|
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (cpuTempContent.implicitWidth + horizontalPadding * 2)
|
|
||||||
height: isVertical ? (cpuTempColumn.implicitHeight + horizontalPadding * 2) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = cpuTempArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
DgopService.addRef(["cpu"]);
|
DgopService.addRef(["cpu"]);
|
||||||
}
|
}
|
||||||
@@ -39,121 +22,123 @@ Rectangle {
|
|||||||
DgopService.removeRef(["cpu"]);
|
DgopService.removeRef(["cpu"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
content: Component {
|
||||||
id: cpuTempArea
|
Item {
|
||||||
|
implicitWidth: root.isVerticalOrientation ? (root.widgetThickness - root.horizontalPadding * 2) : cpuTempContent.implicitWidth
|
||||||
|
implicitHeight: root.isVerticalOrientation ? cpuTempColumn.implicitHeight : (root.widgetThickness - root.horizontalPadding * 2)
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: cpuTempColumn
|
||||||
|
visible: root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 1
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "device_thermostat"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: {
|
||||||
|
if (DgopService.cpuTemperature > 85) {
|
||||||
|
return Theme.tempDanger;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DgopService.cpuTemperature > 69) {
|
||||||
|
return Theme.tempWarning;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Theme.surfaceText;
|
||||||
|
}
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (DgopService.cpuTemperature === undefined || DgopService.cpuTemperature === null || DgopService.cpuTemperature < 0) {
|
||||||
|
return "--";
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.round(DgopService.cpuTemperature).toString();
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: cpuTempContent
|
||||||
|
visible: !root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 3
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "device_thermostat"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: {
|
||||||
|
if (DgopService.cpuTemperature > 85) {
|
||||||
|
return Theme.tempDanger;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DgopService.cpuTemperature > 69) {
|
||||||
|
return Theme.tempWarning;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Theme.surfaceText;
|
||||||
|
}
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (DgopService.cpuTemperature === undefined || DgopService.cpuTemperature === null || DgopService.cpuTemperature < 0) {
|
||||||
|
return "--°";
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.round(DgopService.cpuTemperature) + "°";
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
elide: Text.ElideNone
|
||||||
|
|
||||||
|
StyledTextMetrics {
|
||||||
|
id: tempBaseline
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
text: "100°"
|
||||||
|
}
|
||||||
|
|
||||||
|
width: root.minimumWidth ? Math.max(tempBaseline.width, paintedWidth) : paintedWidth
|
||||||
|
|
||||||
|
Behavior on width {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 120
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
onPressed: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popoutTarget && popoutTarget.setTriggerPosition) {
|
||||||
const globalPos = mapToGlobal(0, 0)
|
const globalPos = root.visualContent.mapToGlobal(0, 0)
|
||||||
const currentScreen = parentScreen || Screen
|
const currentScreen = parentScreen || Screen
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
||||||
}
|
}
|
||||||
DgopService.setSortBy("cpu");
|
DgopService.setSortBy("cpu");
|
||||||
if (root.toggleProcessList) {
|
if (root.toggleProcessList) {
|
||||||
root.toggleProcessList();
|
root.toggleProcessList();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
|
||||||
id: cpuTempColumn
|
|
||||||
visible: root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 1
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "device_thermostat"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: {
|
|
||||||
if (DgopService.cpuTemperature > 85) {
|
|
||||||
return Theme.tempDanger;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DgopService.cpuTemperature > 69) {
|
|
||||||
return Theme.tempWarning;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.surfaceText;
|
|
||||||
}
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (DgopService.cpuTemperature === undefined || DgopService.cpuTemperature === null || DgopService.cpuTemperature < 0) {
|
|
||||||
return "--";
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.round(DgopService.cpuTemperature).toString();
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: cpuTempContent
|
|
||||||
visible: !root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 3
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "device_thermostat"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: {
|
|
||||||
if (DgopService.cpuTemperature > 85) {
|
|
||||||
return Theme.tempDanger;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DgopService.cpuTemperature > 69) {
|
|
||||||
return Theme.tempWarning;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.surfaceText;
|
|
||||||
}
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (DgopService.cpuTemperature === undefined || DgopService.cpuTemperature === null || DgopService.cpuTemperature < 0) {
|
|
||||||
return "--°";
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.round(DgopService.cpuTemperature) + "°";
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
elide: Text.ElideNone
|
|
||||||
|
|
||||||
StyledTextMetrics {
|
|
||||||
id: tempBaseline
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
text: "100°"
|
|
||||||
}
|
|
||||||
|
|
||||||
width: root.minimumWidth ? Math.max(tempBaseline.width, paintedWidth) : paintedWidth
|
|
||||||
|
|
||||||
Behavior on width {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 120
|
|
||||||
easing.type: Easing.OutCubic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,35 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property var widgetData: null
|
property var widgetData: null
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
property string mountPath: (widgetData && widgetData.mountPath !== undefined) ? widgetData.mountPath : "/"
|
property string mountPath: (widgetData && widgetData.mountPath !== undefined) ? widgetData.mountPath : "/"
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
property var selectedMount: {
|
property var selectedMount: {
|
||||||
if (!DgopService.diskMounts || DgopService.diskMounts.length === 0) {
|
if (!DgopService.diskMounts || DgopService.diskMounts.length === 0) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force re-evaluation when mountPath changes
|
|
||||||
const currentMountPath = root.mountPath || "/"
|
const currentMountPath = root.mountPath || "/"
|
||||||
|
|
||||||
// First try to find exact match
|
|
||||||
for (let i = 0; i < DgopService.diskMounts.length; i++) {
|
for (let i = 0; i < DgopService.diskMounts.length; i++) {
|
||||||
if (DgopService.diskMounts[i].mount === currentMountPath) {
|
if (DgopService.diskMounts[i].mount === currentMountPath) {
|
||||||
return DgopService.diskMounts[i]
|
return DgopService.diskMounts[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to root
|
|
||||||
for (let i = 0; i < DgopService.diskMounts.length; i++) {
|
for (let i = 0; i < DgopService.diskMounts.length; i++) {
|
||||||
if (DgopService.diskMounts[i].mount === "/") {
|
if (DgopService.diskMounts[i].mount === "/") {
|
||||||
return DgopService.diskMounts[i]
|
return DgopService.diskMounts[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last resort - first mount
|
|
||||||
return DgopService.diskMounts[0] || null
|
return DgopService.diskMounts[0] || null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,17 +41,6 @@ Rectangle {
|
|||||||
return parseFloat(percentStr) || 0
|
return parseFloat(percentStr) || 0
|
||||||
}
|
}
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (diskContent.implicitWidth + horizontalPadding * 2)
|
|
||||||
height: isVertical ? (diskColumn.implicitHeight + horizontalPadding * 2) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent"
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = Theme.widgetBaseBackgroundColor
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency)
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
DgopService.addRef(["diskmounts"])
|
DgopService.addRef(["diskmounts"])
|
||||||
}
|
}
|
||||||
@@ -70,7 +50,6 @@ Rectangle {
|
|||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onWidgetDataChanged() {
|
function onWidgetDataChanged() {
|
||||||
// Force property re-evaluation by triggering change detection
|
|
||||||
root.mountPath = Qt.binding(() => {
|
root.mountPath = Qt.binding(() => {
|
||||||
return (root.widgetData && root.widgetData.mountPath !== undefined) ? root.widgetData.mountPath : "/"
|
return (root.widgetData && root.widgetData.mountPath !== undefined) ? root.widgetData.mountPath : "/"
|
||||||
})
|
})
|
||||||
@@ -82,21 +61,18 @@ Rectangle {
|
|||||||
|
|
||||||
const currentMountPath = root.mountPath || "/"
|
const currentMountPath = root.mountPath || "/"
|
||||||
|
|
||||||
// First try to find exact match
|
|
||||||
for (let i = 0; i < DgopService.diskMounts.length; i++) {
|
for (let i = 0; i < DgopService.diskMounts.length; i++) {
|
||||||
if (DgopService.diskMounts[i].mount === currentMountPath) {
|
if (DgopService.diskMounts[i].mount === currentMountPath) {
|
||||||
return DgopService.diskMounts[i]
|
return DgopService.diskMounts[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to root
|
|
||||||
for (let i = 0; i < DgopService.diskMounts.length; i++) {
|
for (let i = 0; i < DgopService.diskMounts.length; i++) {
|
||||||
if (DgopService.diskMounts[i].mount === "/") {
|
if (DgopService.diskMounts[i].mount === "/") {
|
||||||
return DgopService.diskMounts[i]
|
return DgopService.diskMounts[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last resort - first mount
|
|
||||||
return DgopService.diskMounts[0] || null
|
return DgopService.diskMounts[0] || null
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -104,6 +80,116 @@ Rectangle {
|
|||||||
target: SettingsData
|
target: SettingsData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
content: Component {
|
||||||
|
Item {
|
||||||
|
implicitWidth: root.isVerticalOrientation ? (root.widgetThickness - root.horizontalPadding * 2) : diskContent.implicitWidth
|
||||||
|
implicitHeight: root.isVerticalOrientation ? diskColumn.implicitHeight : (root.widgetThickness - root.horizontalPadding * 2)
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: diskColumn
|
||||||
|
visible: root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 1
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "storage"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: {
|
||||||
|
if (root.diskUsagePercent > 90) {
|
||||||
|
return Theme.tempDanger
|
||||||
|
}
|
||||||
|
if (root.diskUsagePercent > 75) {
|
||||||
|
return Theme.tempWarning
|
||||||
|
}
|
||||||
|
return Theme.surfaceText
|
||||||
|
}
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (root.diskUsagePercent === undefined || root.diskUsagePercent === null || root.diskUsagePercent === 0) {
|
||||||
|
return "--"
|
||||||
|
}
|
||||||
|
return root.diskUsagePercent.toFixed(0)
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: diskContent
|
||||||
|
visible: !root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 3
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "storage"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: {
|
||||||
|
if (root.diskUsagePercent > 90) {
|
||||||
|
return Theme.tempDanger
|
||||||
|
}
|
||||||
|
if (root.diskUsagePercent > 75) {
|
||||||
|
return Theme.tempWarning
|
||||||
|
}
|
||||||
|
return Theme.surfaceText
|
||||||
|
}
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (!root.selectedMount) {
|
||||||
|
return "--"
|
||||||
|
}
|
||||||
|
return root.selectedMount.mount
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
elide: Text.ElideNone
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (root.diskUsagePercent === undefined || root.diskUsagePercent === null || root.diskUsagePercent === 0) {
|
||||||
|
return "--%"
|
||||||
|
}
|
||||||
|
return root.diskUsagePercent.toFixed(0) + "%"
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
elide: Text.ElideNone
|
||||||
|
|
||||||
|
StyledTextMetrics {
|
||||||
|
id: diskBaseline
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
text: "100%"
|
||||||
|
}
|
||||||
|
|
||||||
|
width: Math.max(diskBaseline.width, paintedWidth)
|
||||||
|
|
||||||
|
Behavior on width {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 120
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: tooltipLoader
|
id: tooltipLoader
|
||||||
active: false
|
active: false
|
||||||
@@ -111,11 +197,11 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: diskArea
|
z: 1
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: root.isVertical
|
hoverEnabled: root.isVerticalOrientation
|
||||||
onEntered: {
|
onEntered: {
|
||||||
if (root.isVertical && root.selectedMount) {
|
if (root.isVerticalOrientation && root.selectedMount) {
|
||||||
tooltipLoader.active = true
|
tooltipLoader.active = true
|
||||||
if (tooltipLoader.item) {
|
if (tooltipLoader.item) {
|
||||||
const globalPos = mapToGlobal(width / 2, height / 2)
|
const globalPos = mapToGlobal(width / 2, height / 2)
|
||||||
@@ -136,107 +222,4 @@ Rectangle {
|
|||||||
tooltipLoader.active = false
|
tooltipLoader.active = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
|
||||||
id: diskColumn
|
|
||||||
visible: root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 1
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "storage"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: {
|
|
||||||
if (root.diskUsagePercent > 90) {
|
|
||||||
return Theme.tempDanger
|
|
||||||
}
|
|
||||||
if (root.diskUsagePercent > 75) {
|
|
||||||
return Theme.tempWarning
|
|
||||||
}
|
|
||||||
return Theme.surfaceText
|
|
||||||
}
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (root.diskUsagePercent === undefined || root.diskUsagePercent === null || root.diskUsagePercent === 0) {
|
|
||||||
return "--"
|
|
||||||
}
|
|
||||||
return root.diskUsagePercent.toFixed(0)
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: diskContent
|
|
||||||
visible: !root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 3
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "storage"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: {
|
|
||||||
if (root.diskUsagePercent > 90) {
|
|
||||||
return Theme.tempDanger
|
|
||||||
}
|
|
||||||
if (root.diskUsagePercent > 75) {
|
|
||||||
return Theme.tempWarning
|
|
||||||
}
|
|
||||||
return Theme.surfaceText
|
|
||||||
}
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (!root.selectedMount) {
|
|
||||||
return "--"
|
|
||||||
}
|
|
||||||
return root.selectedMount.mount
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
elide: Text.ElideNone
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (root.diskUsagePercent === undefined || root.diskUsagePercent === null || root.diskUsagePercent === 0) {
|
|
||||||
return "--%"
|
|
||||||
}
|
|
||||||
return root.diskUsagePercent.toFixed(0) + "%"
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
elide: Text.ElideNone
|
|
||||||
|
|
||||||
StyledTextMetrics {
|
|
||||||
id: diskBaseline
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
text: "100%"
|
|
||||||
}
|
|
||||||
|
|
||||||
width: Math.max(diskBaseline.width, paintedWidth)
|
|
||||||
|
|
||||||
Behavior on width {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 120
|
|
||||||
easing.type: Easing.OutCubic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -4,21 +4,15 @@ import Quickshell.Wayland
|
|||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property var parentScreen
|
|
||||||
property bool compactMode: SettingsData.focusedWindowCompactMode
|
property bool compactMode: SettingsData.focusedWindowCompactMode
|
||||||
property int availableWidth: 400
|
property int availableWidth: 400
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 2 : Theme.spacingS
|
|
||||||
readonly property int baseWidth: contentRow.implicitWidth + horizontalPadding * 2
|
|
||||||
readonly property int maxNormalWidth: 456
|
readonly property int maxNormalWidth: 456
|
||||||
readonly property int maxCompactWidth: 288
|
readonly property int maxCompactWidth: 288
|
||||||
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
|
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
|
||||||
@@ -93,148 +87,141 @@ Rectangle {
|
|||||||
return activeWindow && activeWindow.title
|
return activeWindow && activeWindow.title
|
||||||
}
|
}
|
||||||
|
|
||||||
width: !hasWindowsOnCurrentWorkspace ? 0 : (isVertical ? widgetThickness : (compactMode ? Math.min(baseWidth, maxCompactWidth) : Math.min(baseWidth, maxNormalWidth)))
|
|
||||||
height: !hasWindowsOnCurrentWorkspace ? 0 : (isVertical ? widgetThickness : widgetThickness)
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (!activeWindow || !activeWindow.title) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = mouseArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
clip: true
|
|
||||||
visible: hasWindowsOnCurrentWorkspace
|
visible: hasWindowsOnCurrentWorkspace
|
||||||
|
|
||||||
IconImage {
|
content: Component {
|
||||||
id: appIcon
|
Item {
|
||||||
anchors.centerIn: parent
|
implicitWidth: {
|
||||||
width: 18
|
if (!root.hasWindowsOnCurrentWorkspace) return 0
|
||||||
height: 18
|
if (root.isVerticalOrientation) return root.widgetThickness - root.horizontalPadding * 2
|
||||||
visible: root.isVertical && activeWindow && status === Image.Ready
|
const baseWidth = contentRow.implicitWidth
|
||||||
source: {
|
return compactMode ? Math.min(baseWidth, maxCompactWidth - root.horizontalPadding * 2) : Math.min(baseWidth, maxNormalWidth - root.horizontalPadding * 2)
|
||||||
if (!activeWindow || !activeWindow.appId) return ""
|
|
||||||
const moddedId = Paths.moddedAppId(activeWindow.appId)
|
|
||||||
if (moddedId.toLowerCase().includes("steam_app")) return ""
|
|
||||||
return Quickshell.iconPath(activeDesktopEntry?.icon, true)
|
|
||||||
}
|
|
||||||
smooth: true
|
|
||||||
mipmap: true
|
|
||||||
asynchronous: true
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
size: 18
|
|
||||||
name: "sports_esports"
|
|
||||||
color: Theme.surfaceText
|
|
||||||
visible: {
|
|
||||||
if (!root.isVertical || !activeWindow || !activeWindow.appId) return false
|
|
||||||
const moddedId = Paths.moddedAppId(activeWindow.appId)
|
|
||||||
return moddedId.toLowerCase().includes("steam_app")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
visible: {
|
|
||||||
if (!root.isVertical || !activeWindow || !activeWindow.appId) return false
|
|
||||||
if (appIcon.status === Image.Ready) return false
|
|
||||||
const moddedId = Paths.moddedAppId(activeWindow.appId)
|
|
||||||
return !moddedId.toLowerCase().includes("steam_app")
|
|
||||||
}
|
|
||||||
text: {
|
|
||||||
if (!activeWindow || !activeWindow.appId) return "?"
|
|
||||||
if (activeDesktopEntry && activeDesktopEntry.name) {
|
|
||||||
return activeDesktopEntry.name.charAt(0).toUpperCase()
|
|
||||||
}
|
}
|
||||||
return activeWindow.appId.charAt(0).toUpperCase()
|
implicitHeight: root.widgetThickness - root.horizontalPadding * 2
|
||||||
}
|
clip: true
|
||||||
font.pixelSize: 10
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Medium
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
IconImage {
|
||||||
id: contentRow
|
id: appIcon
|
||||||
|
anchors.centerIn: parent
|
||||||
anchors.centerIn: parent
|
width: 18
|
||||||
spacing: Theme.spacingS
|
height: 18
|
||||||
visible: !root.isVertical
|
visible: root.isVerticalOrientation && activeWindow && status === Image.Ready
|
||||||
|
source: {
|
||||||
StyledText {
|
if (!activeWindow || !activeWindow.appId) return ""
|
||||||
id: appText
|
const moddedId = Paths.moddedAppId(activeWindow.appId)
|
||||||
|
if (moddedId.toLowerCase().includes("steam_app")) return ""
|
||||||
text: {
|
return Quickshell.iconPath(activeDesktopEntry?.icon, true)
|
||||||
if (!activeWindow || !activeWindow.appId) {
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
smooth: true
|
||||||
const desktopEntry = DesktopEntries.heuristicLookup(activeWindow.appId);
|
mipmap: true
|
||||||
return desktopEntry && desktopEntry.name ? desktopEntry.name : activeWindow.appId;
|
asynchronous: true
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
elide: Text.ElideRight
|
|
||||||
maximumLineCount: 1
|
|
||||||
width: Math.min(implicitWidth, compactMode ? 80 : 180)
|
|
||||||
visible: !compactMode && text.length > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
DankIcon {
|
||||||
text: "•"
|
anchors.centerIn: parent
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
size: 18
|
||||||
color: Theme.outlineButton
|
name: "sports_esports"
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
color: Theme.surfaceText
|
||||||
visible: !compactMode && appText.text && titleText.text
|
visible: {
|
||||||
}
|
if (!root.isVerticalOrientation || !activeWindow || !activeWindow.appId) return false
|
||||||
|
const moddedId = Paths.moddedAppId(activeWindow.appId)
|
||||||
StyledText {
|
return moddedId.toLowerCase().includes("steam_app")
|
||||||
id: titleText
|
|
||||||
|
|
||||||
text: {
|
|
||||||
const title = activeWindow && activeWindow.title ? activeWindow.title : "";
|
|
||||||
const appName = appText.text;
|
|
||||||
if (!title || !appName) {
|
|
||||||
return title;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (title.endsWith(" - " + appName)) {
|
|
||||||
return title.substring(0, title.length - (" - " + appName).length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (title.endsWith(appName)) {
|
|
||||||
return title.substring(0, title.length - appName.length).replace(/ - $/, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
return title;
|
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
elide: Text.ElideRight
|
|
||||||
maximumLineCount: 1
|
|
||||||
width: Math.min(implicitWidth, compactMode ? 280 : 250)
|
|
||||||
visible: text.length > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
visible: {
|
||||||
|
if (!root.isVerticalOrientation || !activeWindow || !activeWindow.appId) return false
|
||||||
|
if (appIcon.status === Image.Ready) return false
|
||||||
|
const moddedId = Paths.moddedAppId(activeWindow.appId)
|
||||||
|
return !moddedId.toLowerCase().includes("steam_app")
|
||||||
|
}
|
||||||
|
text: {
|
||||||
|
if (!activeWindow || !activeWindow.appId) return "?"
|
||||||
|
if (activeDesktopEntry && activeDesktopEntry.name) {
|
||||||
|
return activeDesktopEntry.name.charAt(0).toUpperCase()
|
||||||
|
}
|
||||||
|
return activeWindow.appId.charAt(0).toUpperCase()
|
||||||
|
}
|
||||||
|
font.pixelSize: 10
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: contentRow
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
visible: !root.isVerticalOrientation
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: appText
|
||||||
|
text: {
|
||||||
|
if (!activeWindow || !activeWindow.appId) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const desktopEntry = DesktopEntries.heuristicLookup(activeWindow.appId);
|
||||||
|
return desktopEntry && desktopEntry.name ? desktopEntry.name : activeWindow.appId;
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
width: Math.min(implicitWidth, compactMode ? 80 : 180)
|
||||||
|
visible: !compactMode && text.length > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "•"
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.outlineButton
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: !compactMode && appText.text && titleText.text
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: titleText
|
||||||
|
text: {
|
||||||
|
const title = activeWindow && activeWindow.title ? activeWindow.title : "";
|
||||||
|
const appName = appText.text;
|
||||||
|
if (!title || !appName) {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (title.endsWith(" - " + appName)) {
|
||||||
|
return title.substring(0, title.length - (" - " + appName).length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (title.endsWith(appName)) {
|
||||||
|
return title.substring(0, title.length - appName.length).replace(/ - $/, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
width: Math.min(implicitWidth, compactMode ? 280 : 250)
|
||||||
|
visible: text.length > 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: root.isVertical
|
hoverEnabled: root.isVerticalOrientation
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
onEntered: {
|
onEntered: {
|
||||||
if (root.isVertical && activeWindow && activeWindow.appId && root.parentScreen) {
|
if (root.isVerticalOrientation && activeWindow && activeWindow.appId && root.parentScreen) {
|
||||||
tooltipLoader.active = true
|
tooltipLoader.active = true
|
||||||
if (tooltipLoader.item) {
|
if (tooltipLoader.item) {
|
||||||
const globalPos = mapToGlobal(width / 2, height / 2)
|
const globalPos = mapToGlobal(width / 2, height / 2)
|
||||||
@@ -266,14 +253,4 @@ Rectangle {
|
|||||||
active: false
|
active: false
|
||||||
sourceComponent: DankTooltip {}
|
sourceComponent: DankTooltip {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Behavior on width {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.standardEasing
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,20 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property bool showPercentage: true
|
property bool showPercentage: true
|
||||||
property bool showIcon: true
|
property bool showIcon: true
|
||||||
property var toggleProcessList
|
property var toggleProcessList
|
||||||
property string section: "right"
|
property var popoutTarget: null
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property var widgetData: null
|
property var widgetData: null
|
||||||
property real barThickness: 48
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property int selectedGpuIndex: (widgetData && widgetData.selectedGpuIndex !== undefined) ? widgetData.selectedGpuIndex : 0
|
property int selectedGpuIndex: (widgetData && widgetData.selectedGpuIndex !== undefined) ? widgetData.selectedGpuIndex : 0
|
||||||
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
|
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
property real displayTemp: {
|
property real displayTemp: {
|
||||||
if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) {
|
if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -34,7 +28,6 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateWidgetPciId(pciId) {
|
function updateWidgetPciId(pciId) {
|
||||||
// Find and update this widget's pciId in the settings
|
|
||||||
const sections = ["left", "center", "right"];
|
const sections = ["left", "center", "right"];
|
||||||
for (let s = 0; s < sections.length; s++) {
|
for (let s = 0; s < sections.length; s++) {
|
||||||
const sectionId = sections[s];
|
const sectionId = sections[s];
|
||||||
@@ -68,17 +61,6 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (gpuTempContent.implicitWidth + horizontalPadding * 2)
|
|
||||||
height: isVertical ? (gpuTempColumn.implicitHeight + horizontalPadding * 2) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = gpuArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
DgopService.addRef(["gpu"]);
|
DgopService.addRef(["gpu"]);
|
||||||
if (widgetData && widgetData.pciId) {
|
if (widgetData && widgetData.pciId) {
|
||||||
@@ -92,12 +74,10 @@ Rectangle {
|
|||||||
if (widgetData && widgetData.pciId) {
|
if (widgetData && widgetData.pciId) {
|
||||||
DgopService.removeGpuPciId(widgetData.pciId);
|
DgopService.removeGpuPciId(widgetData.pciId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onWidgetDataChanged() {
|
function onWidgetDataChanged() {
|
||||||
// Force property re-evaluation by triggering change detection
|
|
||||||
root.selectedGpuIndex = Qt.binding(() => {
|
root.selectedGpuIndex = Qt.binding(() => {
|
||||||
return (root.widgetData && root.widgetData.selectedGpuIndex !== undefined) ? root.widgetData.selectedGpuIndex : 0;
|
return (root.widgetData && root.widgetData.selectedGpuIndex !== undefined) ? root.widgetData.selectedGpuIndex : 0;
|
||||||
});
|
});
|
||||||
@@ -106,122 +86,126 @@ Rectangle {
|
|||||||
target: SettingsData
|
target: SettingsData
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
content: Component {
|
||||||
id: gpuArea
|
Item {
|
||||||
|
implicitWidth: root.isVerticalOrientation ? (root.widgetThickness - root.horizontalPadding * 2) : gpuTempContent.implicitWidth
|
||||||
|
implicitHeight: root.isVerticalOrientation ? gpuTempColumn.implicitHeight : (root.widgetThickness - root.horizontalPadding * 2)
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: gpuTempColumn
|
||||||
|
visible: root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 1
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "auto_awesome_mosaic"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: {
|
||||||
|
if (root.displayTemp > 80) {
|
||||||
|
return Theme.tempDanger;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (root.displayTemp > 65) {
|
||||||
|
return Theme.tempWarning;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Theme.surfaceText;
|
||||||
|
}
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (root.displayTemp === undefined || root.displayTemp === null || root.displayTemp === 0) {
|
||||||
|
return "--";
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.round(root.displayTemp).toString();
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: gpuTempContent
|
||||||
|
visible: !root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 3
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "auto_awesome_mosaic"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: {
|
||||||
|
if (root.displayTemp > 80) {
|
||||||
|
return Theme.tempDanger;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (root.displayTemp > 65) {
|
||||||
|
return Theme.tempWarning;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Theme.surfaceText;
|
||||||
|
}
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (root.displayTemp === undefined || root.displayTemp === null || root.displayTemp === 0) {
|
||||||
|
return "--°";
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.round(root.displayTemp) + "°";
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
elide: Text.ElideNone
|
||||||
|
|
||||||
|
StyledTextMetrics {
|
||||||
|
id: gpuTempBaseline
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
text: "100°"
|
||||||
|
}
|
||||||
|
|
||||||
|
width: root.minimumWidth ? Math.max(gpuTempBaseline.width, paintedWidth) : paintedWidth
|
||||||
|
|
||||||
|
Behavior on width {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 120
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
onPressed: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popoutTarget && popoutTarget.setTriggerPosition) {
|
||||||
const globalPos = mapToGlobal(0, 0)
|
const globalPos = root.visualContent.mapToGlobal(0, 0)
|
||||||
const currentScreen = parentScreen || Screen
|
const currentScreen = parentScreen || Screen
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
||||||
}
|
}
|
||||||
DgopService.setSortBy("cpu");
|
DgopService.setSortBy("cpu");
|
||||||
if (root.toggleProcessList) {
|
if (root.toggleProcessList) {
|
||||||
root.toggleProcessList();
|
root.toggleProcessList();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
|
||||||
id: gpuTempColumn
|
|
||||||
visible: root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 1
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "auto_awesome_mosaic"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: {
|
|
||||||
if (root.displayTemp > 80) {
|
|
||||||
return Theme.tempDanger;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (root.displayTemp > 65) {
|
|
||||||
return Theme.tempWarning;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.surfaceText;
|
|
||||||
}
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (root.displayTemp === undefined || root.displayTemp === null || root.displayTemp === 0) {
|
|
||||||
return "--";
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.round(root.displayTemp).toString();
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: gpuTempContent
|
|
||||||
visible: !root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 3
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "auto_awesome_mosaic"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: {
|
|
||||||
if (root.displayTemp > 80) {
|
|
||||||
return Theme.tempDanger;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (root.displayTemp > 65) {
|
|
||||||
return Theme.tempWarning;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.surfaceText;
|
|
||||||
}
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (root.displayTemp === undefined || root.displayTemp === null || root.displayTemp === 0) {
|
|
||||||
return "--°";
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.round(root.displayTemp) + "°";
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
elide: Text.ElideNone
|
|
||||||
|
|
||||||
StyledTextMetrics {
|
|
||||||
id: gpuTempBaseline
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
text: "100°"
|
|
||||||
}
|
|
||||||
|
|
||||||
width: root.minimumWidth ? Math.max(gpuTempBaseline.width, paintedWidth) : paintedWidth
|
|
||||||
|
|
||||||
Behavior on width {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 120
|
|
||||||
easing.type: Easing.OutCubic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: autoSaveTimer
|
id: autoSaveTimer
|
||||||
|
|
||||||
@@ -231,13 +215,10 @@ Rectangle {
|
|||||||
if (DgopService.availableGpus && DgopService.availableGpus.length > 0) {
|
if (DgopService.availableGpus && DgopService.availableGpus.length > 0) {
|
||||||
const firstGpu = DgopService.availableGpus[0];
|
const firstGpu = DgopService.availableGpus[0];
|
||||||
if (firstGpu && firstGpu.pciId) {
|
if (firstGpu && firstGpu.pciId) {
|
||||||
// Save the first GPU's PCI ID to this widget's settings
|
|
||||||
updateWidgetPciId(firstGpu.pciId);
|
updateWidgetPciId(firstGpu.pciId);
|
||||||
DgopService.addGpuPciId(firstGpu.pciId);
|
DgopService.addGpuPciId(firstGpu.pciId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,51 +2,34 @@ import QtQuick
|
|||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
content: Component {
|
||||||
property var axis: null
|
Item {
|
||||||
property string section: "right"
|
implicitWidth: root.widgetThickness - root.horizontalPadding * 2
|
||||||
property var popupTarget: null
|
implicitHeight: root.widgetThickness - root.horizontalPadding * 2
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (idleIcon.width + horizontalPadding * 2)
|
DankIcon {
|
||||||
height: isVertical ? (idleIcon.height + horizontalPadding * 2) : widgetThickness
|
anchors.centerIn: parent
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
name: SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle"
|
||||||
color: {
|
size: Theme.barIconSize(root.barThickness, -4)
|
||||||
if (SettingsData.dankBarNoBackground) {
|
color: Theme.surfaceText
|
||||||
return "transparent";
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseColor = mouseArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
id: idleIcon
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
name: SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle"
|
|
||||||
size: Theme.barIconSize(barThickness, -4)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
z: 1
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
SessionService.toggleIdleInhibit();
|
SessionService.toggleIdleInhibit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,36 +3,69 @@ import QtQuick.Controls
|
|||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Modules.ProcessList
|
import qs.Modules.ProcessList
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
property string currentLayout: ""
|
property string currentLayout: ""
|
||||||
property string hyprlandKeyboard: ""
|
property string hyprlandKeyboard: ""
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (contentRow.implicitWidth + horizontalPadding * 2)
|
content: Component {
|
||||||
height: isVertical ? (contentColumn.implicitHeight + horizontalPadding * 2) : widgetThickness
|
Item {
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
implicitWidth: root.isVerticalOrientation ? (root.widgetThickness - root.horizontalPadding * 2) : contentRow.implicitWidth
|
||||||
color: {
|
implicitHeight: root.isVerticalOrientation ? contentColumn.implicitHeight : (root.widgetThickness - root.horizontalPadding * 2)
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = mouseArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
Column {
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
id: contentColumn
|
||||||
|
visible: root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 1
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "keyboard"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (!root.currentLayout) return ""
|
||||||
|
const parts = root.currentLayout.split(" ")
|
||||||
|
if (parts.length > 0) {
|
||||||
|
return parts[0].substring(0, 2).toUpperCase()
|
||||||
|
}
|
||||||
|
return root.currentLayout.substring(0, 2).toUpperCase()
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: contentRow
|
||||||
|
visible: !root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: root.currentLayout
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
z: 1
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
@@ -51,53 +84,6 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
|
||||||
id: contentColumn
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 1
|
|
||||||
visible: root.isVertical
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "keyboard"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (!currentLayout) return ""
|
|
||||||
const parts = currentLayout.split(" ")
|
|
||||||
if (parts.length > 0) {
|
|
||||||
return parts[0].substring(0, 2).toUpperCase()
|
|
||||||
}
|
|
||||||
return currentLayout.substring(0, 2).toUpperCase()
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: contentRow
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
visible: !root.isVertical
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: currentLayout
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: updateTimer
|
id: updateTimer
|
||||||
interval: 1000
|
interval: 1000
|
||||||
|
|||||||
@@ -3,127 +3,95 @@ import QtQuick.Effects
|
|||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Item {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isActive: false
|
property bool isActive: false
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property string section: "left"
|
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
property var hyprlandOverviewLoader: null
|
property var hyprlandOverviewLoader: null
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal clicked()
|
content: Component {
|
||||||
|
Item {
|
||||||
|
implicitWidth: root.widgetThickness - root.horizontalPadding * 2
|
||||||
|
implicitHeight: root.widgetThickness - root.horizontalPadding * 2
|
||||||
|
|
||||||
width: widgetThickness
|
DankIcon {
|
||||||
height: widgetThickness
|
visible: SettingsData.launcherLogoMode === "apps"
|
||||||
|
anchors.centerIn: parent
|
||||||
MouseArea {
|
name: "apps"
|
||||||
id: launcherArea
|
size: Theme.barIconSize(root.barThickness, -4)
|
||||||
|
color: Theme.surfaceText
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
|
||||||
onPressed: function (mouse){
|
|
||||||
if (mouse.button === Qt.RightButton) {
|
|
||||||
if (CompositorService.isNiri) {
|
|
||||||
NiriService.toggleOverview()
|
|
||||||
} else if (CompositorService.isHyprland && root.hyprlandOverviewLoader?.item) {
|
|
||||||
root.hyprlandOverviewLoader.item.overviewOpen = !root.hyprlandOverviewLoader.item.overviewOpen
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
root.clicked();
|
SystemLogo {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
visible: SettingsData.launcherLogoMode === "os"
|
||||||
const globalPos = mapToGlobal(0, 0);
|
anchors.centerIn: parent
|
||||||
const currentScreen = parentScreen || Screen;
|
width: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width);
|
height: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen);
|
colorOverride: Theme.effectiveLogoColor
|
||||||
|
brightnessOverride: SettingsData.launcherLogoBrightness
|
||||||
|
contrastOverride: SettingsData.launcherLogoContrast
|
||||||
|
}
|
||||||
|
|
||||||
|
IconImage {
|
||||||
|
visible: SettingsData.launcherLogoMode === "compositor"
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
|
||||||
|
height: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
|
||||||
|
smooth: true
|
||||||
|
asynchronous: true
|
||||||
|
source: {
|
||||||
|
if (CompositorService.isNiri) {
|
||||||
|
return "file://" + Theme.shellDir + "/assets/niri.svg"
|
||||||
|
} else if (CompositorService.isHyprland) {
|
||||||
|
return "file://" + Theme.shellDir + "/assets/hyprland.svg"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
layer.enabled: Theme.effectiveLogoColor !== ""
|
||||||
|
layer.effect: MultiEffect {
|
||||||
|
saturation: 0
|
||||||
|
colorization: 1
|
||||||
|
colorizationColor: Theme.effectiveLogoColor
|
||||||
|
brightness: SettingsData.launcherLogoBrightness
|
||||||
|
contrast: SettingsData.launcherLogoContrast
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IconImage {
|
||||||
|
visible: SettingsData.launcherLogoMode === "custom" && SettingsData.launcherLogoCustomPath !== ""
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
|
||||||
|
height: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
|
||||||
|
smooth: true
|
||||||
|
asynchronous: true
|
||||||
|
source: SettingsData.launcherLogoCustomPath ? "file://" + SettingsData.launcherLogoCustomPath.replace("file://", "") : ""
|
||||||
|
layer.enabled: Theme.effectiveLogoColor !== ""
|
||||||
|
layer.effect: MultiEffect {
|
||||||
|
saturation: 0
|
||||||
|
colorization: 1
|
||||||
|
colorizationColor: Theme.effectiveLogoColor
|
||||||
|
brightness: SettingsData.launcherLogoBrightness
|
||||||
|
contrast: SettingsData.launcherLogoContrast
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
MouseArea {
|
||||||
id: launcherContent
|
id: customMouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
hoverEnabled: true
|
||||||
color: {
|
cursorShape: Qt.PointingHandCursor
|
||||||
if (SettingsData.dankBarNoBackground) {
|
acceptedButtons: Qt.RightButton
|
||||||
return "transparent";
|
onPressed: function (mouse){
|
||||||
}
|
if (CompositorService.isNiri) {
|
||||||
|
NiriService.toggleOverview()
|
||||||
const baseColor = launcherArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
} else if (root.hyprlandOverviewLoader?.item) {
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
root.hyprlandOverviewLoader.item.overviewOpen = !root.hyprlandOverviewLoader.item.overviewOpen
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
visible: SettingsData.launcherLogoMode === "apps"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
name: "apps"
|
|
||||||
size: Theme.barIconSize(barThickness, -4)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemLogo {
|
|
||||||
visible: SettingsData.launcherLogoMode === "os"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: Theme.barIconSize(barThickness, SettingsData.launcherLogoSizeOffset)
|
|
||||||
height: Theme.barIconSize(barThickness, SettingsData.launcherLogoSizeOffset)
|
|
||||||
colorOverride: Theme.effectiveLogoColor
|
|
||||||
brightnessOverride: SettingsData.launcherLogoBrightness
|
|
||||||
contrastOverride: SettingsData.launcherLogoContrast
|
|
||||||
}
|
|
||||||
|
|
||||||
IconImage {
|
|
||||||
visible: SettingsData.launcherLogoMode === "compositor"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: Theme.barIconSize(barThickness, SettingsData.launcherLogoSizeOffset)
|
|
||||||
height: Theme.barIconSize(barThickness, SettingsData.launcherLogoSizeOffset)
|
|
||||||
smooth: true
|
|
||||||
asynchronous: true
|
|
||||||
source: {
|
|
||||||
if (CompositorService.isNiri) {
|
|
||||||
return "file://" + Theme.shellDir + "/assets/niri.svg"
|
|
||||||
} else if (CompositorService.isHyprland) {
|
|
||||||
return "file://" + Theme.shellDir + "/assets/hyprland.svg"
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
layer.enabled: Theme.effectiveLogoColor !== ""
|
|
||||||
layer.effect: MultiEffect {
|
|
||||||
saturation: 0
|
|
||||||
colorization: 1
|
|
||||||
colorizationColor: Theme.effectiveLogoColor
|
|
||||||
brightness: SettingsData.launcherLogoBrightness
|
|
||||||
contrast: SettingsData.launcherLogoContrast
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IconImage {
|
|
||||||
visible: SettingsData.launcherLogoMode === "custom" && SettingsData.launcherLogoCustomPath !== ""
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: Theme.barIconSize(barThickness, SettingsData.launcherLogoSizeOffset)
|
|
||||||
height: Theme.barIconSize(barThickness, SettingsData.launcherLogoSizeOffset)
|
|
||||||
smooth: true
|
|
||||||
asynchronous: true
|
|
||||||
source: SettingsData.launcherLogoCustomPath ? "file://" + SettingsData.launcherLogoCustomPath.replace("file://", "") : ""
|
|
||||||
layer.enabled: Theme.effectiveLogoColor !== ""
|
|
||||||
layer.effect: MultiEffect {
|
|
||||||
saturation: 0
|
|
||||||
colorization: 1
|
|
||||||
colorizationColor: Theme.effectiveLogoColor
|
|
||||||
brightness: SettingsData.launcherLogoBrightness
|
|
||||||
contrast: SettingsData.launcherLogoContrast
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,412 +1,358 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell.Services.Mpris
|
import Quickshell.Services.Mpris
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
readonly property MprisPlayer activePlayer: MprisController.activePlayer
|
readonly property MprisPlayer activePlayer: MprisController.activePlayer
|
||||||
readonly property bool playerAvailable: activePlayer !== null
|
readonly property bool playerAvailable: activePlayer !== null
|
||||||
property bool compactMode: false
|
property bool compactMode: false
|
||||||
readonly property int textWidth: {
|
readonly property int textWidth: {
|
||||||
switch (SettingsData.mediaSize) {
|
switch (SettingsData.mediaSize) {
|
||||||
case 0:
|
case 0:
|
||||||
return 0; // No text in small mode
|
return 0;
|
||||||
case 2:
|
case 2:
|
||||||
return 180; // Large text area
|
return 180;
|
||||||
default:
|
default:
|
||||||
return 120; // Medium text area
|
return 120;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
readonly property int currentContentWidth: {
|
readonly property int currentContentWidth: {
|
||||||
if (isVertical) {
|
if (isVerticalOrientation) {
|
||||||
return widgetThickness;
|
return widgetThickness - horizontalPadding * 2;
|
||||||
}
|
}
|
||||||
const controlsWidth = 20 + Theme.spacingXS + 24 + Theme.spacingXS + 20;
|
const controlsWidth = 20 + Theme.spacingXS + 24 + Theme.spacingXS + 20;
|
||||||
const audioVizWidth = 20;
|
const audioVizWidth = 20;
|
||||||
const contentWidth = audioVizWidth + Theme.spacingXS + controlsWidth;
|
const contentWidth = audioVizWidth + Theme.spacingXS + controlsWidth;
|
||||||
return contentWidth + (textWidth > 0 ? textWidth + Theme.spacingXS : 0) + horizontalPadding * 2;
|
return contentWidth + (textWidth > 0 ? textWidth + Theme.spacingXS : 0);
|
||||||
}
|
}
|
||||||
readonly property int currentContentHeight: {
|
readonly property int currentContentHeight: {
|
||||||
if (!isVertical) {
|
if (!isVerticalOrientation) {
|
||||||
return widgetThickness;
|
return widgetThickness - horizontalPadding * 2;
|
||||||
}
|
}
|
||||||
const audioVizHeight = 20;
|
const audioVizHeight = 20;
|
||||||
const playButtonHeight = 24;
|
const playButtonHeight = 24;
|
||||||
return audioVizHeight + Theme.spacingXS + playButtonHeight + horizontalPadding * 2;
|
return audioVizHeight + Theme.spacingXS + playButtonHeight;
|
||||||
}
|
|
||||||
property string section: "center"
|
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real barThickness: 48
|
|
||||||
property real widgetThickness: 30
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal clicked()
|
|
||||||
|
|
||||||
width: currentContentWidth
|
|
||||||
height: currentContentHeight
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: "shown"
|
|
||||||
when: playerAvailable
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
target: root
|
|
||||||
opacity: 1
|
|
||||||
width: currentContentWidth
|
|
||||||
height: currentContentHeight
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "hidden"
|
|
||||||
when: !playerAvailable
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
target: root
|
|
||||||
opacity: 0
|
|
||||||
width: isVertical ? widgetThickness : 0
|
|
||||||
height: isVertical ? 0 : widgetThickness
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
]
|
|
||||||
transitions: [
|
|
||||||
Transition {
|
|
||||||
from: "shown"
|
|
||||||
to: "hidden"
|
|
||||||
|
|
||||||
SequentialAnimation {
|
|
||||||
PauseAnimation {
|
|
||||||
duration: 500
|
|
||||||
}
|
|
||||||
|
|
||||||
NumberAnimation {
|
|
||||||
properties: isVertical ? "opacity,height" : "opacity,width"
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.standardEasing
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
Transition {
|
|
||||||
from: "hidden"
|
|
||||||
to: "shown"
|
|
||||||
|
|
||||||
NumberAnimation {
|
|
||||||
properties: isVertical ? "opacity,height" : "opacity,width"
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.standardEasing
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: verticalLayout
|
|
||||||
visible: root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
|
|
||||||
AudioVisualization {
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
if (root.popupTarget && root.popupTarget.setTriggerPosition) {
|
|
||||||
const globalPos = parent.mapToGlobal(0, 0)
|
|
||||||
const currentScreen = root.parentScreen || Screen
|
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, root.barThickness, parent.width)
|
|
||||||
root.popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, root.section, currentScreen)
|
|
||||||
}
|
|
||||||
root.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 24
|
|
||||||
height: 24
|
|
||||||
radius: 12
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
color: activePlayer && activePlayer.playbackState === 1 ? Theme.primary : Theme.primaryHover
|
|
||||||
visible: root.playerAvailable
|
|
||||||
opacity: activePlayer ? 1 : 0.3
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
name: activePlayer && activePlayer.playbackState === 1 ? "pause" : "play_arrow"
|
|
||||||
size: 14
|
|
||||||
color: activePlayer && activePlayer.playbackState === 1 ? Theme.background : Theme.primary
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
enabled: root.playerAvailable
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
|
|
||||||
onClicked: (mouse) => {
|
|
||||||
if (!activePlayer) return
|
|
||||||
if (mouse.button === Qt.LeftButton) {
|
|
||||||
activePlayer.togglePlaying()
|
|
||||||
} else if (mouse.button === Qt.MiddleButton) {
|
|
||||||
activePlayer.previous()
|
|
||||||
} else if (mouse.button === Qt.RightButton) {
|
|
||||||
activePlayer.next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
content: Component {
|
||||||
id: mediaRow
|
Item {
|
||||||
|
implicitWidth: root.playerAvailable ? root.currentContentWidth : 0
|
||||||
|
implicitHeight: root.playerAvailable ? root.currentContentHeight : 0
|
||||||
|
opacity: root.playerAvailable ? 1 : 0
|
||||||
|
|
||||||
visible: !root.isVertical
|
states: [
|
||||||
anchors.centerIn: parent
|
State {
|
||||||
spacing: Theme.spacingXS
|
name: "shown"
|
||||||
|
when: root.playerAvailable
|
||||||
Row {
|
PropertyChanges {
|
||||||
id: mediaInfo
|
target: parent
|
||||||
|
opacity: 1
|
||||||
spacing: Theme.spacingXS
|
implicitWidth: root.currentContentWidth
|
||||||
|
implicitHeight: root.currentContentHeight
|
||||||
AudioVisualization {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: textContainer
|
|
||||||
|
|
||||||
property string displayText: {
|
|
||||||
if (!activePlayer || !activePlayer.trackTitle) {
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
let identity = activePlayer.identity || "";
|
State {
|
||||||
let isWebMedia = identity.toLowerCase().includes("firefox") || identity.toLowerCase().includes("chrome") || identity.toLowerCase().includes("chromium") || identity.toLowerCase().includes("edge") || identity.toLowerCase().includes("safari");
|
name: "hidden"
|
||||||
let title = "";
|
when: !root.playerAvailable
|
||||||
let subtitle = "";
|
PropertyChanges {
|
||||||
if (isWebMedia && activePlayer.trackTitle) {
|
target: parent
|
||||||
title = activePlayer.trackTitle;
|
opacity: 0
|
||||||
subtitle = activePlayer.trackArtist || identity;
|
implicitWidth: 0
|
||||||
} else {
|
implicitHeight: 0
|
||||||
title = activePlayer.trackTitle || "Unknown Track";
|
|
||||||
subtitle = activePlayer.trackArtist || "";
|
|
||||||
}
|
}
|
||||||
return subtitle.length > 0 ? title + " • " + subtitle : title;
|
|
||||||
}
|
}
|
||||||
|
]
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
transitions: [
|
||||||
width: textWidth
|
Transition {
|
||||||
height: 20
|
from: "shown"
|
||||||
visible: SettingsData.mediaSize > 0
|
to: "hidden"
|
||||||
clip: true
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: mediaText
|
|
||||||
|
|
||||||
property bool needsScrolling: implicitWidth > textContainer.width
|
|
||||||
property real scrollOffset: 0
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
text: textContainer.displayText
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Medium
|
|
||||||
wrapMode: Text.NoWrap
|
|
||||||
x: needsScrolling ? -scrollOffset : 0
|
|
||||||
onTextChanged: {
|
|
||||||
scrollOffset = 0;
|
|
||||||
scrollAnimation.restart();
|
|
||||||
}
|
|
||||||
|
|
||||||
SequentialAnimation {
|
SequentialAnimation {
|
||||||
id: scrollAnimation
|
|
||||||
|
|
||||||
running: mediaText.needsScrolling && textContainer.visible
|
|
||||||
loops: Animation.Infinite
|
|
||||||
|
|
||||||
PauseAnimation {
|
PauseAnimation {
|
||||||
duration: 2000
|
duration: 500
|
||||||
}
|
}
|
||||||
|
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
target: mediaText
|
properties: "opacity,implicitWidth,implicitHeight"
|
||||||
property: "scrollOffset"
|
duration: Theme.shortDuration
|
||||||
from: 0
|
easing.type: Theme.standardEasing
|
||||||
to: mediaText.implicitWidth - textContainer.width + 5
|
|
||||||
duration: Math.max(1000, (mediaText.implicitWidth - textContainer.width + 5) * 60)
|
|
||||||
easing.type: Easing.Linear
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PauseAnimation {
|
|
||||||
duration: 2000
|
|
||||||
}
|
|
||||||
|
|
||||||
NumberAnimation {
|
|
||||||
target: mediaText
|
|
||||||
property: "scrollOffset"
|
|
||||||
to: 0
|
|
||||||
duration: Math.max(1000, (mediaText.implicitWidth - textContainer.width + 5) * 60)
|
|
||||||
easing.type: Easing.Linear
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
Transition {
|
||||||
|
from: "hidden"
|
||||||
|
to: "shown"
|
||||||
|
NumberAnimation {
|
||||||
|
properties: "opacity,implicitWidth,implicitHeight"
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
|
||||||
MouseArea {
|
Column {
|
||||||
anchors.fill: parent
|
id: verticalLayout
|
||||||
enabled: root.playerAvailable
|
visible: root.isVerticalOrientation
|
||||||
cursorShape: Qt.PointingHandCursor
|
anchors.centerIn: parent
|
||||||
onPressed: {
|
spacing: Theme.spacingXS
|
||||||
if (root.popupTarget && root.popupTarget.setTriggerPosition) {
|
|
||||||
const globalPos = mapToGlobal(0, 0)
|
AudioVisualization {
|
||||||
const currentScreen = root.parentScreen || Screen
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.width)
|
|
||||||
root.popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, root.section, currentScreen)
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
if (root.popoutTarget && root.popoutTarget.setTriggerPosition) {
|
||||||
|
const globalPos = parent.mapToGlobal(0, 0)
|
||||||
|
const currentScreen = root.parentScreen || Screen
|
||||||
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, root.barThickness, parent.width)
|
||||||
|
root.popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, root.section, currentScreen)
|
||||||
|
}
|
||||||
|
root.clicked()
|
||||||
}
|
}
|
||||||
root.clicked()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 24
|
||||||
|
height: 24
|
||||||
|
radius: 12
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
color: activePlayer && activePlayer.playbackState === 1 ? Theme.primary : Theme.primaryHover
|
||||||
|
visible: root.playerAvailable
|
||||||
|
opacity: activePlayer ? 1 : 0.3
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: activePlayer && activePlayer.playbackState === 1 ? "pause" : "play_arrow"
|
||||||
|
size: 14
|
||||||
|
color: activePlayer && activePlayer.playbackState === 1 ? Theme.background : Theme.primary
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: root.playerAvailable
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
|
||||||
|
onClicked: (mouse) => {
|
||||||
|
if (!activePlayer) return
|
||||||
|
if (mouse.button === Qt.LeftButton) {
|
||||||
|
activePlayer.togglePlaying()
|
||||||
|
} else if (mouse.button === Qt.MiddleButton) {
|
||||||
|
activePlayer.previous()
|
||||||
|
} else if (mouse.button === Qt.RightButton) {
|
||||||
|
activePlayer.next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
Row {
|
||||||
|
id: mediaRow
|
||||||
|
visible: !root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: Theme.spacingXS
|
id: mediaInfo
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
Rectangle {
|
AudioVisualization {
|
||||||
width: 20
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
height: 20
|
}
|
||||||
radius: 10
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
color: prevArea.containsMouse ? Theme.primaryHover : "transparent"
|
|
||||||
visible: root.playerAvailable
|
|
||||||
opacity: (activePlayer && activePlayer.canGoPrevious) ? 1 : 0.3
|
|
||||||
|
|
||||||
DankIcon {
|
Rectangle {
|
||||||
anchors.centerIn: parent
|
id: textContainer
|
||||||
name: "skip_previous"
|
property string displayText: {
|
||||||
size: 12
|
if (!activePlayer || !activePlayer.trackTitle) {
|
||||||
color: Theme.surfaceText
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
let identity = activePlayer.identity || "";
|
||||||
id: prevArea
|
let isWebMedia = identity.toLowerCase().includes("firefox") || identity.toLowerCase().includes("chrome") || identity.toLowerCase().includes("chromium") || identity.toLowerCase().includes("edge") || identity.toLowerCase().includes("safari");
|
||||||
|
let title = "";
|
||||||
|
let subtitle = "";
|
||||||
|
if (isWebMedia && activePlayer.trackTitle) {
|
||||||
|
title = activePlayer.trackTitle;
|
||||||
|
subtitle = activePlayer.trackArtist || identity;
|
||||||
|
} else {
|
||||||
|
title = activePlayer.trackTitle || "Unknown Track";
|
||||||
|
subtitle = activePlayer.trackArtist || "";
|
||||||
|
}
|
||||||
|
return subtitle.length > 0 ? title + " • " + subtitle : title;
|
||||||
|
}
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
enabled: root.playerAvailable
|
width: textWidth
|
||||||
hoverEnabled: true
|
height: 20
|
||||||
cursorShape: Qt.PointingHandCursor
|
visible: SettingsData.mediaSize > 0
|
||||||
onClicked: {
|
clip: true
|
||||||
if (activePlayer) {
|
color: "transparent"
|
||||||
activePlayer.previous();
|
|
||||||
|
StyledText {
|
||||||
|
id: mediaText
|
||||||
|
property bool needsScrolling: implicitWidth > textContainer.width
|
||||||
|
property real scrollOffset: 0
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: textContainer.displayText
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
wrapMode: Text.NoWrap
|
||||||
|
x: needsScrolling ? -scrollOffset : 0
|
||||||
|
onTextChanged: {
|
||||||
|
scrollOffset = 0;
|
||||||
|
scrollAnimation.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
id: scrollAnimation
|
||||||
|
running: mediaText.needsScrolling && textContainer.visible
|
||||||
|
loops: Animation.Infinite
|
||||||
|
|
||||||
|
PauseAnimation {
|
||||||
|
duration: 2000
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
target: mediaText
|
||||||
|
property: "scrollOffset"
|
||||||
|
from: 0
|
||||||
|
to: mediaText.implicitWidth - textContainer.width + 5
|
||||||
|
duration: Math.max(1000, (mediaText.implicitWidth - textContainer.width + 5) * 60)
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
}
|
||||||
|
|
||||||
|
PauseAnimation {
|
||||||
|
duration: 2000
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
target: mediaText
|
||||||
|
property: "scrollOffset"
|
||||||
|
to: 0
|
||||||
|
duration: Math.max(1000, (mediaText.implicitWidth - textContainer.width + 5) * 60)
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: root.playerAvailable
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onPressed: {
|
||||||
|
if (root.popoutTarget && root.popoutTarget.setTriggerPosition) {
|
||||||
|
const globalPos = mapToGlobal(0, 0)
|
||||||
|
const currentScreen = root.parentScreen || Screen
|
||||||
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, root.barThickness, root.width)
|
||||||
|
root.popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, root.section, currentScreen)
|
||||||
|
}
|
||||||
|
root.clicked()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
Row {
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 24
|
width: 20
|
||||||
height: 24
|
height: 20
|
||||||
radius: 12
|
radius: 10
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
color: activePlayer && activePlayer.playbackState === 1 ? Theme.primary : Theme.primaryHover
|
color: prevArea.containsMouse ? Theme.primaryHover : "transparent"
|
||||||
visible: root.playerAvailable
|
visible: root.playerAvailable
|
||||||
opacity: activePlayer ? 1 : 0.3
|
opacity: (activePlayer && activePlayer.canGoPrevious) ? 1 : 0.3
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
name: activePlayer && activePlayer.playbackState === 1 ? "pause" : "play_arrow"
|
name: "skip_previous"
|
||||||
size: 14
|
size: 12
|
||||||
color: activePlayer && activePlayer.playbackState === 1 ? Theme.background : Theme.primary
|
color: Theme.surfaceText
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
id: prevArea
|
||||||
enabled: root.playerAvailable
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
enabled: root.playerAvailable
|
||||||
onClicked: {
|
hoverEnabled: true
|
||||||
if (activePlayer) {
|
cursorShape: Qt.PointingHandCursor
|
||||||
activePlayer.togglePlaying();
|
onClicked: {
|
||||||
|
if (activePlayer) {
|
||||||
|
activePlayer.previous();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 24
|
||||||
|
height: 24
|
||||||
|
radius: 12
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: activePlayer && activePlayer.playbackState === 1 ? Theme.primary : Theme.primaryHover
|
||||||
|
visible: root.playerAvailable
|
||||||
|
opacity: activePlayer ? 1 : 0.3
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: activePlayer && activePlayer.playbackState === 1 ? "pause" : "play_arrow"
|
||||||
|
size: 14
|
||||||
|
color: activePlayer && activePlayer.playbackState === 1 ? Theme.background : Theme.primary
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: root.playerAvailable
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
if (activePlayer) {
|
||||||
|
activePlayer.togglePlaying();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 20
|
||||||
|
height: 20
|
||||||
|
radius: 10
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: nextArea.containsMouse ? Theme.primaryHover : "transparent"
|
||||||
|
visible: playerAvailable
|
||||||
|
opacity: (activePlayer && activePlayer.canGoNext) ? 1 : 0.3
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "skip_next"
|
||||||
|
size: 12
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: nextArea
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: root.playerAvailable
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
if (activePlayer) {
|
||||||
|
activePlayer.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 20
|
|
||||||
height: 20
|
|
||||||
radius: 10
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
color: nextArea.containsMouse ? Theme.primaryHover : "transparent"
|
|
||||||
visible: playerAvailable
|
|
||||||
opacity: (activePlayer && activePlayer.canGoNext) ? 1 : 0.3
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
name: "skip_next"
|
|
||||||
size: 12
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: nextArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
enabled: root.playerAvailable
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
if (activePlayer) {
|
|
||||||
activePlayer.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Behavior on width {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.standardEasing
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on height {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.standardEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,194 +1,167 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Modules.ProcessList
|
import qs.Modules.ProcessList
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property int availableWidth: 400
|
|
||||||
readonly property int baseWidth: contentRow.implicitWidth + Theme.spacingS * 2
|
|
||||||
readonly property int maxNormalWidth: 456
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
function formatNetworkSpeed(bytesPerSec) {
|
function formatNetworkSpeed(bytesPerSec) {
|
||||||
if (bytesPerSec < 1024) {
|
if (bytesPerSec < 1024) {
|
||||||
return bytesPerSec.toFixed(0) + " B/s";
|
return bytesPerSec.toFixed(0) + " B/s"
|
||||||
} else if (bytesPerSec < 1024 * 1024) {
|
} else if (bytesPerSec < 1024 * 1024) {
|
||||||
return (bytesPerSec / 1024).toFixed(1) + " KB/s";
|
return (bytesPerSec / 1024).toFixed(1) + " KB/s"
|
||||||
} else if (bytesPerSec < 1024 * 1024 * 1024) {
|
} else if (bytesPerSec < 1024 * 1024 * 1024) {
|
||||||
return (bytesPerSec / (1024 * 1024)).toFixed(1) + " MB/s";
|
return (bytesPerSec / (1024 * 1024)).toFixed(1) + " MB/s"
|
||||||
} else {
|
} else {
|
||||||
return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(1) + " GB/s";
|
return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(1) + " GB/s"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (contentRow.implicitWidth + horizontalPadding * 2)
|
|
||||||
height: isVertical ? (contentColumn.implicitHeight + horizontalPadding * 2) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = networkArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
DgopService.addRef(["network"]);
|
DgopService.addRef(["network"])
|
||||||
}
|
}
|
||||||
Component.onDestruction: {
|
Component.onDestruction: {
|
||||||
DgopService.removeRef(["network"]);
|
DgopService.removeRef(["network"])
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
content: Component {
|
||||||
id: networkArea
|
Item {
|
||||||
|
implicitWidth: root.isVerticalOrientation ? (root.widgetThickness - root.horizontalPadding * 2) : contentRow.implicitWidth
|
||||||
|
implicitHeight: root.isVerticalOrientation ? contentColumn.implicitHeight : (root.widgetThickness - root.horizontalPadding * 2)
|
||||||
|
|
||||||
anchors.fill: parent
|
Column {
|
||||||
hoverEnabled: true
|
id: contentColumn
|
||||||
cursorShape: Qt.PointingHandCursor
|
anchors.centerIn: parent
|
||||||
}
|
spacing: 2
|
||||||
|
visible: root.isVerticalOrientation
|
||||||
|
|
||||||
Column {
|
DankIcon {
|
||||||
id: contentColumn
|
name: "network_check"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
anchors.centerIn: parent
|
color: Theme.surfaceText
|
||||||
spacing: 2
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: root.isVertical
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "network_check"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
const rate = DgopService.networkRxRate
|
|
||||||
if (rate < 1024) return rate.toFixed(0)
|
|
||||||
if (rate < 1024 * 1024) return (rate / 1024).toFixed(0) + "K"
|
|
||||||
return (rate / (1024 * 1024)).toFixed(0) + "M"
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.info
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
const rate = DgopService.networkTxRate
|
|
||||||
if (rate < 1024) return rate.toFixed(0)
|
|
||||||
if (rate < 1024 * 1024) return (rate / 1024).toFixed(0) + "K"
|
|
||||||
return (rate / (1024 * 1024)).toFixed(0) + "M"
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.error
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: contentRow
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
visible: !root.isVertical
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "network_check"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: 4
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "↓"
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.info
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: DgopService.networkRxRate > 0 ? formatNetworkSpeed(DgopService.networkRxRate) : "0 B/s"
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
elide: Text.ElideNone
|
|
||||||
wrapMode: Text.NoWrap
|
|
||||||
|
|
||||||
StyledTextMetrics {
|
|
||||||
id: rxBaseline
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
text: "88.8 MB/s"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
width: Math.max(rxBaseline.width, paintedWidth)
|
StyledText {
|
||||||
|
text: {
|
||||||
|
const rate = DgopService.networkRxRate
|
||||||
|
if (rate < 1024) return rate.toFixed(0)
|
||||||
|
if (rate < 1024 * 1024) return (rate / 1024).toFixed(0) + "K"
|
||||||
|
return (rate / (1024 * 1024)).toFixed(0) + "M"
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.info
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
Behavior on width {
|
StyledText {
|
||||||
NumberAnimation {
|
text: {
|
||||||
duration: 120
|
const rate = DgopService.networkTxRate
|
||||||
easing.type: Easing.OutCubic
|
if (rate < 1024) return rate.toFixed(0)
|
||||||
|
if (rate < 1024 * 1024) return (rate / 1024).toFixed(0) + "K"
|
||||||
|
return (rate / (1024 * 1024)).toFixed(0) + "M"
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.error
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: contentRow
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
visible: !root.isVerticalOrientation
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "network_check"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "↓"
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.info
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: DgopService.networkRxRate > 0 ? root.formatNetworkSpeed(DgopService.networkRxRate) : "0 B/s"
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
elide: Text.ElideNone
|
||||||
|
wrapMode: Text.NoWrap
|
||||||
|
|
||||||
|
StyledTextMetrics {
|
||||||
|
id: rxBaseline
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
text: "88.8 MB/s"
|
||||||
|
}
|
||||||
|
|
||||||
|
width: Math.max(rxBaseline.width, paintedWidth)
|
||||||
|
|
||||||
|
Behavior on width {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 120
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "↑"
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.error
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: DgopService.networkTxRate > 0 ? root.formatNetworkSpeed(DgopService.networkTxRate) : "0 B/s"
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
elide: Text.ElideNone
|
||||||
|
wrapMode: Text.NoWrap
|
||||||
|
|
||||||
|
StyledTextMetrics {
|
||||||
|
id: txBaseline
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
text: "88.8 MB/s"
|
||||||
|
}
|
||||||
|
|
||||||
|
width: Math.max(txBaseline.width, paintedWidth)
|
||||||
|
|
||||||
|
Behavior on width {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 120
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: 4
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "↑"
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.error
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: DgopService.networkTxRate > 0 ? formatNetworkSpeed(DgopService.networkTxRate) : "0 B/s"
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
elide: Text.ElideNone
|
|
||||||
wrapMode: Text.NoWrap
|
|
||||||
|
|
||||||
StyledTextMetrics {
|
|
||||||
id: txBaseline
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
text: "88.8 MB/s"
|
|
||||||
}
|
|
||||||
|
|
||||||
width: Math.max(txBaseline.width, paintedWidth)
|
|
||||||
|
|
||||||
Behavior on width {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 120
|
|
||||||
easing.type: Easing.OutCubic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,13 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property string section: "right"
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal clicked()
|
|
||||||
|
|
||||||
readonly property string focusedScreenName: (
|
readonly property string focusedScreenName: (
|
||||||
CompositorService.isHyprland && typeof Hyprland !== "undefined" && Hyprland.focusedWorkspace && Hyprland.focusedWorkspace.monitor ? (Hyprland.focusedWorkspace.monitor.name || "") :
|
CompositorService.isHyprland && typeof Hyprland !== "undefined" && Hyprland.focusedWorkspace && Hyprland.focusedWorkspace.monitor ? (Hyprland.focusedWorkspace.monitor.name || "") :
|
||||||
CompositorService.isNiri && typeof NiriService !== "undefined" && NiriService.currentOutput ? NiriService.currentOutput : ""
|
CompositorService.isNiri && typeof NiriService !== "undefined" && NiriService.currentOutput ? NiriService.currentOutput : ""
|
||||||
@@ -43,54 +34,43 @@ Rectangle {
|
|||||||
readonly property var notepadInstance: resolveNotepadInstance()
|
readonly property var notepadInstance: resolveNotepadInstance()
|
||||||
readonly property bool isActive: notepadInstance?.isVisible ?? false
|
readonly property bool isActive: notepadInstance?.isVisible ?? false
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (notepadIcon.width + horizontalPadding * 2)
|
content: Component {
|
||||||
height: isVertical ? (notepadIcon.height + horizontalPadding * 2) : widgetThickness
|
Item {
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
implicitWidth: root.widgetThickness - root.horizontalPadding * 2
|
||||||
color: {
|
implicitHeight: root.widgetThickness - root.horizontalPadding * 2
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
DankIcon {
|
||||||
|
id: notepadIcon
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "assignment"
|
||||||
|
size: Theme.barIconSize(root.barThickness, -4)
|
||||||
|
color: root.isActive ? Theme.primary : Theme.surfaceText
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 6
|
||||||
|
height: 6
|
||||||
|
radius: 3
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.rightMargin: SettingsData.dankBarNoBackground ? 0 : 4
|
||||||
|
anchors.topMargin: SettingsData.dankBarNoBackground ? 0 : 4
|
||||||
|
visible: NotepadStorageService.tabs && NotepadStorageService.tabs.length > 0
|
||||||
|
opacity: 0.8
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseColor = notepadArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
id: notepadIcon
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
name: "assignment"
|
|
||||||
size: Theme.barIconSize(barThickness, -4)
|
|
||||||
color: notepadArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 6
|
|
||||||
height: 6
|
|
||||||
radius: 3
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.rightMargin: SettingsData.dankBarNoBackground ? 0 : 4
|
|
||||||
anchors.topMargin: SettingsData.dankBarNoBackground ? 0 : 4
|
|
||||||
visible: NotepadStorageService.tabs && NotepadStorageService.tabs.length > 0
|
|
||||||
opacity: 0.8
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: notepadArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
acceptedButtons: Qt.LeftButton
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onPressed: {
|
onPressed: {
|
||||||
const inst = root.notepadInstance
|
const inst = root.notepadInstance
|
||||||
if (inst) {
|
if (inst) {
|
||||||
inst.toggle()
|
inst.toggle()
|
||||||
}
|
}
|
||||||
root.clicked()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,76 +1,37 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Item {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool hasUnread: false
|
property bool hasUnread: false
|
||||||
property bool isActive: false
|
property bool isActive: false
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property string section: "right"
|
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal clicked()
|
content: Component {
|
||||||
|
Item {
|
||||||
|
implicitWidth: root.widgetThickness - root.horizontalPadding * 2
|
||||||
|
implicitHeight: root.widgetThickness - root.horizontalPadding * 2
|
||||||
|
|
||||||
width: widgetThickness
|
DankIcon {
|
||||||
height: widgetThickness
|
anchors.centerIn: parent
|
||||||
|
name: SessionData.doNotDisturb ? "notifications_off" : "notifications"
|
||||||
MouseArea {
|
size: Theme.barIconSize(root.barThickness, -4)
|
||||||
id: notificationArea
|
color: SessionData.doNotDisturb ? Theme.error : (root.isActive ? Theme.primary : Theme.surfaceText)
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
acceptedButtons: Qt.LeftButton
|
|
||||||
onPressed: {
|
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
|
||||||
const globalPos = mapToGlobal(0, 0)
|
|
||||||
const currentScreen = parentScreen || Screen
|
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
|
||||||
}
|
|
||||||
root.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: notificationContent
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseColor = notificationArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor
|
Rectangle {
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency)
|
width: 8
|
||||||
}
|
height: 8
|
||||||
|
radius: 4
|
||||||
DankIcon {
|
color: Theme.error
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.top: parent.top
|
||||||
name: SessionData.doNotDisturb ? "notifications_off" : "notifications"
|
anchors.rightMargin: SettingsData.dankBarNoBackground ? 0 : 6
|
||||||
size: Theme.barIconSize(barThickness, -4)
|
anchors.topMargin: SettingsData.dankBarNoBackground ? 0 : 6
|
||||||
color: SessionData.doNotDisturb ? Theme.error : (notificationArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText)
|
visible: root.hasUnread
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 8
|
|
||||||
height: 8
|
|
||||||
radius: 4
|
|
||||||
color: Theme.error
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.rightMargin: SettingsData.dankBarNoBackground ? 0 : 6
|
|
||||||
anchors.topMargin: SettingsData.dankBarNoBackground ? 0 : 6
|
|
||||||
visible: root.hasUnread
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import qs.Common
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
property bool isVertical: axis?.isVertical ?? false
|
||||||
@@ -19,26 +19,167 @@ Rectangle {
|
|||||||
readonly property int activeCount: PrivacyService.microphoneActive + PrivacyService.cameraActive + PrivacyService.screensharingActive
|
readonly property int activeCount: PrivacyService.microphoneActive + PrivacyService.cameraActive + PrivacyService.screensharingActive
|
||||||
readonly property real contentWidth: hasActivePrivacy ? (activeCount * 18 + (activeCount - 1) * Theme.spacingXS) : 0
|
readonly property real contentWidth: hasActivePrivacy ? (activeCount * 18 + (activeCount - 1) * Theme.spacingXS) : 0
|
||||||
readonly property real contentHeight: hasActivePrivacy ? (activeCount * 18 + (activeCount - 1) * Theme.spacingXS) : 0
|
readonly property real contentHeight: hasActivePrivacy ? (activeCount * 18 + (activeCount - 1) * Theme.spacingXS) : 0
|
||||||
|
readonly property real visualWidth: isVertical ? widgetThickness : (hasActivePrivacy ? (contentWidth + horizontalPadding * 2) : 0)
|
||||||
|
readonly property real visualHeight: isVertical ? (hasActivePrivacy ? (contentHeight + horizontalPadding * 2) : 0) : widgetThickness
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (hasActivePrivacy ? (contentWidth + horizontalPadding * 2) : 0)
|
width: isVertical ? barThickness : visualWidth
|
||||||
height: isVertical ? (hasActivePrivacy ? (contentHeight + horizontalPadding * 2) : 0) : (hasActivePrivacy ? widgetThickness : 0)
|
height: isVertical ? visualHeight : barThickness
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
visible: hasActivePrivacy
|
visible: hasActivePrivacy
|
||||||
opacity: hasActivePrivacy ? 1 : 0
|
opacity: hasActivePrivacy ? 1 : 0
|
||||||
enabled: hasActivePrivacy
|
enabled: hasActivePrivacy
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
Rectangle {
|
||||||
return "transparent";
|
id: visualContent
|
||||||
|
width: root.visualWidth
|
||||||
|
height: root.visualHeight
|
||||||
|
anchors.centerIn: parent
|
||||||
|
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
||||||
|
color: {
|
||||||
|
if (SettingsData.dankBarNoBackground) {
|
||||||
|
return "transparent"
|
||||||
|
}
|
||||||
|
|
||||||
|
return Qt.rgba(privacyArea.containsMouse ? Theme.errorPressed.r : Theme.errorHover.r, privacyArea.containsMouse ? Theme.errorPressed.g : Theme.errorHover.g, privacyArea.containsMouse ? Theme.errorPressed.b : Theme.errorHover.b, (privacyArea.containsMouse ? Theme.errorPressed.a : Theme.errorHover.a) * Theme.widgetTransparency)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Qt.rgba(privacyArea.containsMouse ? Theme.errorPressed.r : Theme.errorHover.r, privacyArea.containsMouse ? Theme.errorPressed.g : Theme.errorHover.g, privacyArea.containsMouse ? Theme.errorPressed.b : Theme.errorHover.b, (privacyArea.containsMouse ? Theme.errorPressed.a : Theme.errorHover.a) * Theme.widgetTransparency);
|
Column {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
visible: root.isVertical && root.hasActivePrivacy
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 18
|
||||||
|
height: 18
|
||||||
|
visible: PrivacyService.microphoneActive
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: {
|
||||||
|
const sourceAudio = AudioService.source?.audio
|
||||||
|
const muted = !sourceAudio || sourceAudio.muted || sourceAudio.volume === 0.0
|
||||||
|
if (muted) return "mic_off"
|
||||||
|
return "mic"
|
||||||
|
}
|
||||||
|
size: Theme.iconSizeSmall
|
||||||
|
color: Theme.error
|
||||||
|
filled: true
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 18
|
||||||
|
height: 18
|
||||||
|
visible: PrivacyService.cameraActive
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "camera_video"
|
||||||
|
size: Theme.iconSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
filled: true
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 6
|
||||||
|
height: 6
|
||||||
|
radius: 3
|
||||||
|
color: Theme.error
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.rightMargin: -2
|
||||||
|
anchors.topMargin: -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 18
|
||||||
|
height: 18
|
||||||
|
visible: PrivacyService.screensharingActive
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "screen_share"
|
||||||
|
size: Theme.iconSizeSmall
|
||||||
|
color: Theme.warning
|
||||||
|
filled: true
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
visible: !root.isVertical && root.hasActivePrivacy
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 18
|
||||||
|
height: 18
|
||||||
|
visible: PrivacyService.microphoneActive
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: {
|
||||||
|
const sourceAudio = AudioService.source?.audio
|
||||||
|
const muted = !sourceAudio || sourceAudio.muted || sourceAudio.volume === 0.0
|
||||||
|
if (muted) return "mic_off"
|
||||||
|
return "mic"
|
||||||
|
}
|
||||||
|
size: Theme.iconSizeSmall
|
||||||
|
color: Theme.error
|
||||||
|
filled: true
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 18
|
||||||
|
height: 18
|
||||||
|
visible: PrivacyService.cameraActive
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "camera_video"
|
||||||
|
size: Theme.iconSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
filled: true
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 6
|
||||||
|
height: 6
|
||||||
|
radius: 3
|
||||||
|
color: Theme.error
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.rightMargin: -2
|
||||||
|
anchors.topMargin: -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 18
|
||||||
|
height: 18
|
||||||
|
visible: PrivacyService.screensharingActive
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "screen_share"
|
||||||
|
size: Theme.iconSizeSmall
|
||||||
|
color: Theme.warning
|
||||||
|
filled: true
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
// Privacy indicator click handler
|
|
||||||
|
|
||||||
id: privacyArea
|
id: privacyArea
|
||||||
|
z: -1
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: hasActivePrivacy
|
hoverEnabled: hasActivePrivacy
|
||||||
enabled: hasActivePrivacy
|
enabled: hasActivePrivacy
|
||||||
@@ -47,151 +188,8 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
visible: root.isVertical && hasActivePrivacy
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: 18
|
|
||||||
height: 18
|
|
||||||
visible: PrivacyService.microphoneActive
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: {
|
|
||||||
const sourceAudio = AudioService.source?.audio
|
|
||||||
const muted = !sourceAudio || sourceAudio.muted || sourceAudio.volume === 0.0
|
|
||||||
if (muted) return "mic_off"
|
|
||||||
return "mic"
|
|
||||||
}
|
|
||||||
size: Theme.iconSizeSmall
|
|
||||||
color: Theme.error
|
|
||||||
filled: true
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: 18
|
|
||||||
height: 18
|
|
||||||
visible: PrivacyService.cameraActive
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "camera_video"
|
|
||||||
size: Theme.iconSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
filled: true
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 6
|
|
||||||
height: 6
|
|
||||||
radius: 3
|
|
||||||
color: Theme.error
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.rightMargin: -2
|
|
||||||
anchors.topMargin: -1
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: 18
|
|
||||||
height: 18
|
|
||||||
visible: PrivacyService.screensharingActive
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "screen_share"
|
|
||||||
size: Theme.iconSizeSmall
|
|
||||||
color: Theme.warning
|
|
||||||
filled: true
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
visible: !root.isVertical && hasActivePrivacy
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: 18
|
|
||||||
height: 18
|
|
||||||
visible: PrivacyService.microphoneActive
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: {
|
|
||||||
const sourceAudio = AudioService.source?.audio
|
|
||||||
const muted = !sourceAudio || sourceAudio.muted || sourceAudio.volume === 0.0
|
|
||||||
if (muted) return "mic_off"
|
|
||||||
return "mic"
|
|
||||||
}
|
|
||||||
size: Theme.iconSizeSmall
|
|
||||||
color: Theme.error
|
|
||||||
filled: true
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: 18
|
|
||||||
height: 18
|
|
||||||
visible: PrivacyService.cameraActive
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "camera_video"
|
|
||||||
size: Theme.iconSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
filled: true
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 6
|
|
||||||
height: 6
|
|
||||||
radius: 3
|
|
||||||
color: Theme.error
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.rightMargin: -2
|
|
||||||
anchors.topMargin: -1
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: 18
|
|
||||||
height: 18
|
|
||||||
visible: PrivacyService.screensharingActive
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "screen_share"
|
|
||||||
size: Theme.iconSizeSmall
|
|
||||||
color: Theme.warning
|
|
||||||
filled: true
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: tooltip
|
id: tooltip
|
||||||
|
|
||||||
width: tooltipText.contentWidth + Theme.spacingM * 2
|
width: tooltipText.contentWidth + Theme.spacingM * 2
|
||||||
height: tooltipText.contentHeight + Theme.spacingS * 2
|
height: tooltipText.contentHeight + Theme.spacingS * 2
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
@@ -206,7 +204,6 @@ Rectangle {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: tooltipText
|
id: tooltipText
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: PrivacyService.getPrivacySummary()
|
text: PrivacyService.getPrivacySummary()
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
font.pixelSize: Theme.barTextSize(barThickness)
|
||||||
@@ -232,9 +229,7 @@ Rectangle {
|
|||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on width {
|
Behavior on width {
|
||||||
@@ -244,7 +239,6 @@ Rectangle {
|
|||||||
duration: Theme.mediumDuration
|
duration: Theme.mediumDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on height {
|
Behavior on height {
|
||||||
@@ -254,7 +248,5 @@ Rectangle {
|
|||||||
duration: Theme.mediumDuration
|
duration: Theme.mediumDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,19 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property bool showPercentage: true
|
property bool showPercentage: true
|
||||||
property bool showIcon: true
|
property bool showIcon: true
|
||||||
property var toggleProcessList
|
property var toggleProcessList
|
||||||
property string section: "right"
|
property var popoutTarget: null
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real barThickness: 48
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property var widgetData: null
|
property var widgetData: null
|
||||||
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
|
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (ramContent.implicitWidth + horizontalPadding * 2)
|
|
||||||
height: isVertical ? (ramColumn.implicitHeight + horizontalPadding * 2) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = ramArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
DgopService.addRef(["memory"]);
|
DgopService.addRef(["memory"]);
|
||||||
@@ -40,120 +22,123 @@ Rectangle {
|
|||||||
DgopService.removeRef(["memory"]);
|
DgopService.removeRef(["memory"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
content: Component {
|
||||||
id: ramArea
|
Item {
|
||||||
|
implicitWidth: root.isVerticalOrientation ? (root.widgetThickness - root.horizontalPadding * 2) : ramContent.implicitWidth
|
||||||
|
implicitHeight: root.isVerticalOrientation ? ramColumn.implicitHeight : (root.widgetThickness - root.horizontalPadding * 2)
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: ramColumn
|
||||||
|
visible: root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 1
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "developer_board"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: {
|
||||||
|
if (DgopService.memoryUsage > 90) {
|
||||||
|
return Theme.tempDanger;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DgopService.memoryUsage > 75) {
|
||||||
|
return Theme.tempWarning;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Theme.surfaceText;
|
||||||
|
}
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (DgopService.memoryUsage === undefined || DgopService.memoryUsage === null || DgopService.memoryUsage === 0) {
|
||||||
|
return "--";
|
||||||
|
}
|
||||||
|
|
||||||
|
return DgopService.memoryUsage.toFixed(0);
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: ramContent
|
||||||
|
visible: !root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 3
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "developer_board"
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
color: {
|
||||||
|
if (DgopService.memoryUsage > 90) {
|
||||||
|
return Theme.tempDanger;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DgopService.memoryUsage > 75) {
|
||||||
|
return Theme.tempWarning;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Theme.surfaceText;
|
||||||
|
}
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (DgopService.memoryUsage === undefined || DgopService.memoryUsage === null || DgopService.memoryUsage === 0) {
|
||||||
|
return "--%";
|
||||||
|
}
|
||||||
|
|
||||||
|
return DgopService.memoryUsage.toFixed(0) + "%";
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
elide: Text.ElideNone
|
||||||
|
|
||||||
|
StyledTextMetrics {
|
||||||
|
id: ramBaseline
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
text: "100%"
|
||||||
|
}
|
||||||
|
|
||||||
|
width: root.minimumWidth ? Math.max(ramBaseline.width, paintedWidth) : paintedWidth
|
||||||
|
|
||||||
|
Behavior on width {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 120
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
onPressed: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popoutTarget && popoutTarget.setTriggerPosition) {
|
||||||
const globalPos = mapToGlobal(0, 0)
|
const globalPos = root.visualContent.mapToGlobal(0, 0)
|
||||||
const currentScreen = parentScreen || Screen
|
const currentScreen = parentScreen || Screen
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
||||||
}
|
}
|
||||||
DgopService.setSortBy("memory");
|
DgopService.setSortBy("memory");
|
||||||
if (root.toggleProcessList) {
|
if (root.toggleProcessList) {
|
||||||
root.toggleProcessList();
|
root.toggleProcessList();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
|
||||||
id: ramColumn
|
|
||||||
visible: root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 1
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "developer_board"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: {
|
|
||||||
if (DgopService.memoryUsage > 90) {
|
|
||||||
return Theme.tempDanger;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DgopService.memoryUsage > 75) {
|
|
||||||
return Theme.tempWarning;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.surfaceText;
|
|
||||||
}
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (DgopService.memoryUsage === undefined || DgopService.memoryUsage === null || DgopService.memoryUsage === 0) {
|
|
||||||
return "--";
|
|
||||||
}
|
|
||||||
|
|
||||||
return DgopService.memoryUsage.toFixed(0);
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: ramContent
|
|
||||||
visible: !root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 3
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "developer_board"
|
|
||||||
size: Theme.barIconSize(barThickness)
|
|
||||||
color: {
|
|
||||||
if (DgopService.memoryUsage > 90) {
|
|
||||||
return Theme.tempDanger;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DgopService.memoryUsage > 75) {
|
|
||||||
return Theme.tempWarning;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.surfaceText;
|
|
||||||
}
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (DgopService.memoryUsage === undefined || DgopService.memoryUsage === null || DgopService.memoryUsage === 0) {
|
|
||||||
return "--%";
|
|
||||||
}
|
|
||||||
|
|
||||||
return DgopService.memoryUsage.toFixed(0) + "%";
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
elide: Text.ElideNone
|
|
||||||
|
|
||||||
StyledTextMetrics {
|
|
||||||
id: ramBaseline
|
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
font.weight: Font.Medium
|
|
||||||
text: "100%"
|
|
||||||
}
|
|
||||||
|
|
||||||
width: root.minimumWidth ? Math.max(ramBaseline.width, paintedWidth) : paintedWidth
|
|
||||||
|
|
||||||
Behavior on width {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 120
|
|
||||||
easing.type: Easing.OutCubic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import qs.Common
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
property bool isVertical: axis?.isVertical ?? false
|
||||||
@@ -66,22 +66,29 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : calculatedSize
|
width: isVertical ? barThickness : calculatedSize
|
||||||
height: isVertical ? calculatedSize : widgetThickness
|
height: isVertical ? calculatedSize : barThickness
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
visible: windowCount > 0
|
visible: windowCount > 0
|
||||||
clip: false
|
|
||||||
color: {
|
|
||||||
if (windowCount === 0) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
Rectangle {
|
||||||
return "transparent";
|
id: visualBackground
|
||||||
}
|
width: root.isVertical ? root.widgetThickness : root.calculatedSize
|
||||||
|
height: root.isVertical ? root.calculatedSize : root.widgetThickness
|
||||||
|
anchors.centerIn: parent
|
||||||
|
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
||||||
|
clip: false
|
||||||
|
color: {
|
||||||
|
if (windowCount === 0) {
|
||||||
|
return "transparent";
|
||||||
|
}
|
||||||
|
|
||||||
const baseColor = Theme.widgetBaseBackgroundColor;
|
if (SettingsData.dankBarNoBackground) {
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
return "transparent";
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseColor = Theme.widgetBaseBackgroundColor;
|
||||||
|
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -210,12 +217,16 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
return appName + (windowTitle ? " • " + windowTitle : "")
|
return appName + (windowTitle ? " • " + windowTitle : "")
|
||||||
}
|
}
|
||||||
|
readonly property real visualWidth: SettingsData.runningAppsCompactMode ? 24 : (24 + Theme.spacingXS + 120)
|
||||||
|
|
||||||
width: SettingsData.runningAppsCompactMode ? 24 : (24 + Theme.spacingXS + 120)
|
width: visualWidth
|
||||||
height: 24
|
height: root.barThickness
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
id: visualContent
|
||||||
|
width: delegateItem.visualWidth
|
||||||
|
height: 24
|
||||||
|
anchors.centerIn: parent
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: {
|
color: {
|
||||||
if (isFocused) {
|
if (isFocused) {
|
||||||
@@ -237,8 +248,6 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// App icon
|
// App icon
|
||||||
IconImage {
|
IconImage {
|
||||||
id: iconImg
|
id: iconImg
|
||||||
@@ -334,10 +343,10 @@ Rectangle {
|
|||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
maximumLineCount: 1
|
maximumLineCount: 1
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
@@ -442,12 +451,16 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
return appName + (windowTitle ? " • " + windowTitle : "")
|
return appName + (windowTitle ? " • " + windowTitle : "")
|
||||||
}
|
}
|
||||||
|
readonly property real visualWidth: SettingsData.runningAppsCompactMode ? 24 : (24 + Theme.spacingXS + 120)
|
||||||
|
|
||||||
width: SettingsData.runningAppsCompactMode ? 24 : (24 + Theme.spacingXS + 120)
|
width: root.barThickness
|
||||||
height: 24
|
height: 24
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
id: visualContent
|
||||||
|
width: delegateItem.visualWidth
|
||||||
|
height: 24
|
||||||
|
anchors.centerIn: parent
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: {
|
color: {
|
||||||
if (isFocused) {
|
if (isFocused) {
|
||||||
@@ -469,8 +482,6 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
IconImage {
|
IconImage {
|
||||||
id: iconImg
|
id: iconImg
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -563,10 +574,10 @@ Rectangle {
|
|||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
maximumLineCount: 1
|
maximumLineCount: 1
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import Quickshell.Widgets
|
|||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
property bool isVertical: axis?.isVertical ?? false
|
||||||
@@ -15,6 +15,7 @@ Rectangle {
|
|||||||
property var parentWindow: null
|
property var parentWindow: null
|
||||||
property var parentScreen: null
|
property var parentScreen: null
|
||||||
property real widgetThickness: 30
|
property real widgetThickness: 30
|
||||||
|
property real barThickness: 48
|
||||||
property bool isAtBottom: false
|
property bool isAtBottom: false
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 2 : Theme.spacingS
|
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 2 : Theme.spacingS
|
||||||
readonly property var hiddenTrayIds: {
|
readonly property var hiddenTrayIds: {
|
||||||
@@ -31,24 +32,33 @@ Rectangle {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
readonly property int calculatedSize: visibleTrayItems.length > 0 ? visibleTrayItems.length * 24 + horizontalPadding * 2 : 0
|
readonly property int calculatedSize: visibleTrayItems.length > 0 ? visibleTrayItems.length * 24 + horizontalPadding * 2 : 0
|
||||||
|
readonly property real visualWidth: isVertical ? widgetThickness : calculatedSize
|
||||||
|
readonly property real visualHeight: isVertical ? calculatedSize : widgetThickness
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : calculatedSize
|
width: isVertical ? barThickness : visualWidth
|
||||||
height: isVertical ? calculatedSize : widgetThickness
|
height: isVertical ? visualHeight : barThickness
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (visibleTrayItems.length === 0) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
visible: visibleTrayItems.length > 0
|
visible: visibleTrayItems.length > 0
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: visualBackground
|
||||||
|
width: root.visualWidth
|
||||||
|
height: root.visualHeight
|
||||||
|
anchors.centerIn: parent
|
||||||
|
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
||||||
|
color: {
|
||||||
|
if (visibleTrayItems.length === 0) {
|
||||||
|
return "transparent";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SettingsData.dankBarNoBackground) {
|
||||||
|
return "transparent";
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseColor = Theme.widgetBaseBackgroundColor;
|
||||||
|
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: layoutLoader
|
id: layoutLoader
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -64,81 +74,81 @@ Rectangle {
|
|||||||
model: root.visibleTrayItems
|
model: root.visibleTrayItems
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
property var trayItem: modelData
|
id: delegateRoot
|
||||||
property string iconSource: {
|
property var trayItem: modelData
|
||||||
let icon = trayItem && trayItem.icon;
|
property string iconSource: {
|
||||||
if (typeof icon === 'string' || icon instanceof String) {
|
let icon = trayItem && trayItem.icon;
|
||||||
if (icon === "") {
|
if (typeof icon === 'string' || icon instanceof String) {
|
||||||
return "";
|
if (icon === "") {
|
||||||
}
|
return "";
|
||||||
if (icon.includes("?path=")) {
|
|
||||||
const split = icon.split("?path=");
|
|
||||||
if (split.length !== 2) {
|
|
||||||
return icon;
|
|
||||||
}
|
}
|
||||||
|
if (icon.includes("?path=")) {
|
||||||
|
const split = icon.split("?path=");
|
||||||
|
if (split.length !== 2) {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
const name = split[0];
|
const name = split[0];
|
||||||
const path = split[1];
|
const path = split[1];
|
||||||
let fileName = name.substring(name.lastIndexOf("/") + 1);
|
let fileName = name.substring(name.lastIndexOf("/") + 1);
|
||||||
if (fileName.startsWith("dropboxstatus")) {
|
if (fileName.startsWith("dropboxstatus")) {
|
||||||
fileName = `hicolor/16x16/status/${fileName}`;
|
fileName = `hicolor/16x16/status/${fileName}`;
|
||||||
|
}
|
||||||
|
return `file://${path}/${fileName}`;
|
||||||
}
|
}
|
||||||
return `file://${path}/${fileName}`;
|
if (icon.startsWith("/") && !icon.startsWith("file://")) {
|
||||||
|
return `file://${icon}`;
|
||||||
|
}
|
||||||
|
return icon;
|
||||||
}
|
}
|
||||||
if (icon.startsWith("/") && !icon.startsWith("file://")) {
|
return "";
|
||||||
return `file://${icon}`;
|
|
||||||
}
|
|
||||||
return icon;
|
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
width: 24
|
width: 24
|
||||||
height: 24
|
height: root.barThickness
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
id: visualContent
|
||||||
radius: Theme.cornerRadius
|
width: 24
|
||||||
color: trayItemArea.containsMouse ? Theme.primaryHover : "transparent"
|
height: 24
|
||||||
|
anchors.centerIn: parent
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: trayItemArea.containsMouse ? Theme.primaryHover : "transparent"
|
||||||
|
|
||||||
|
IconImage {
|
||||||
}
|
anchors.centerIn: parent
|
||||||
|
width: 16
|
||||||
IconImage {
|
height: 16
|
||||||
anchors.centerIn: parent
|
source: delegateRoot.iconSource
|
||||||
width: 16
|
asynchronous: true
|
||||||
height: 16
|
smooth: true
|
||||||
source: parent.iconSource
|
mipmap: true
|
||||||
asynchronous: true
|
|
||||||
smooth: true
|
|
||||||
mipmap: true
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: trayItemArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: (mouse) => {
|
|
||||||
if (!trayItem) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mouse.button === Qt.LeftButton && !trayItem.onlyMenu) {
|
MouseArea {
|
||||||
trayItem.activate();
|
id: trayItemArea
|
||||||
return ;
|
|
||||||
}
|
anchors.fill: parent
|
||||||
if (trayItem.hasMenu) {
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
root.showForTrayItem(trayItem, parent, parentScreen, root.isAtBottom, root.isVertical, root.axis);
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: (mouse) => {
|
||||||
|
if (!delegateRoot.trayItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mouse.button === Qt.LeftButton && !delegateRoot.trayItem.onlyMenu) {
|
||||||
|
delegateRoot.trayItem.activate();
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
if (delegateRoot.trayItem.hasMenu) {
|
||||||
|
root.showForTrayItem(delegateRoot.trayItem, visualContent, parentScreen, root.isAtBottom, root.isVertical, root.axis);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,79 +161,81 @@ Rectangle {
|
|||||||
model: root.visibleTrayItems
|
model: root.visibleTrayItems
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
property var trayItem: modelData
|
id: delegateRoot
|
||||||
property string iconSource: {
|
property var trayItem: modelData
|
||||||
let icon = trayItem && trayItem.icon;
|
property string iconSource: {
|
||||||
if (typeof icon === 'string' || icon instanceof String) {
|
let icon = trayItem && trayItem.icon;
|
||||||
if (icon === "") {
|
if (typeof icon === 'string' || icon instanceof String) {
|
||||||
return "";
|
if (icon === "") {
|
||||||
}
|
return "";
|
||||||
if (icon.includes("?path=")) {
|
|
||||||
const split = icon.split("?path=");
|
|
||||||
if (split.length !== 2) {
|
|
||||||
return icon;
|
|
||||||
}
|
}
|
||||||
|
if (icon.includes("?path=")) {
|
||||||
|
const split = icon.split("?path=");
|
||||||
|
if (split.length !== 2) {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
const name = split[0];
|
const name = split[0];
|
||||||
const path = split[1];
|
const path = split[1];
|
||||||
let fileName = name.substring(name.lastIndexOf("/") + 1);
|
let fileName = name.substring(name.lastIndexOf("/") + 1);
|
||||||
if (fileName.startsWith("dropboxstatus")) {
|
if (fileName.startsWith("dropboxstatus")) {
|
||||||
fileName = `hicolor/16x16/status/${fileName}`;
|
fileName = `hicolor/16x16/status/${fileName}`;
|
||||||
|
}
|
||||||
|
return `file://${path}/${fileName}`;
|
||||||
}
|
}
|
||||||
return `file://${path}/${fileName}`;
|
if (icon.startsWith("/") && !icon.startsWith("file://")) {
|
||||||
|
return `file://${icon}`;
|
||||||
|
}
|
||||||
|
return icon;
|
||||||
}
|
}
|
||||||
if (icon.startsWith("/") && !icon.startsWith("file://")) {
|
return "";
|
||||||
return `file://${icon}`;
|
|
||||||
}
|
|
||||||
return icon;
|
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
width: 24
|
width: root.barThickness
|
||||||
height: 24
|
height: 24
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
id: visualContent
|
||||||
radius: Theme.cornerRadius
|
width: 24
|
||||||
color: trayItemArea.containsMouse ? Theme.primaryHover : "transparent"
|
height: 24
|
||||||
}
|
anchors.centerIn: parent
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: trayItemArea.containsMouse ? Theme.primaryHover : "transparent"
|
||||||
|
|
||||||
IconImage {
|
IconImage {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: 16
|
width: 16
|
||||||
height: 16
|
height: 16
|
||||||
source: parent.iconSource
|
source: delegateRoot.iconSource
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
smooth: true
|
smooth: true
|
||||||
mipmap: true
|
mipmap: true
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: trayItemArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: (mouse) => {
|
|
||||||
if (!trayItem) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mouse.button === Qt.LeftButton && !trayItem.onlyMenu) {
|
MouseArea {
|
||||||
trayItem.activate();
|
id: trayItemArea
|
||||||
return ;
|
|
||||||
}
|
anchors.fill: parent
|
||||||
if (trayItem.hasMenu) {
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
root.showForTrayItem(trayItem, parent, parentScreen, root.isAtBottom, root.isVertical, root.axis);
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: (mouse) => {
|
||||||
|
if (!delegateRoot.trayItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mouse.button === Qt.LeftButton && !delegateRoot.trayItem.onlyMenu) {
|
||||||
|
delegateRoot.trayItem.activate();
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
if (delegateRoot.trayItem.hasMenu) {
|
||||||
|
root.showForTrayItem(delegateRoot.trayItem, visualContent, parentScreen, root.isAtBottom, root.isVertical, root.axis);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,158 +1,138 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property bool isActive: false
|
property bool isActive: false
|
||||||
property string section: "right"
|
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
readonly property bool hasUpdates: SystemUpdateService.updateCount > 0
|
readonly property bool hasUpdates: SystemUpdateService.updateCount > 0
|
||||||
readonly property bool isChecking: SystemUpdateService.isChecking
|
readonly property bool isChecking: SystemUpdateService.isChecking
|
||||||
|
|
||||||
signal clicked()
|
|
||||||
|
|
||||||
Ref {
|
Ref {
|
||||||
service: SystemUpdateService
|
service: SystemUpdateService
|
||||||
}
|
}
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (updaterIcon.width + horizontalPadding * 2)
|
content: Component {
|
||||||
height: isVertical ? widgetThickness : widgetThickness
|
Item {
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
implicitWidth: root.isVerticalOrientation ? (root.widgetThickness - root.horizontalPadding * 2) : updaterIcon.implicitWidth
|
||||||
color: {
|
implicitHeight: root.widgetThickness - root.horizontalPadding * 2
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = updaterArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
DankIcon {
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
id: statusIcon
|
||||||
}
|
anchors.centerIn: parent
|
||||||
|
visible: root.isVerticalOrientation
|
||||||
DankIcon {
|
name: {
|
||||||
id: statusIcon
|
if (root.isChecking) return "refresh"
|
||||||
|
if (SystemUpdateService.hasError) return "error"
|
||||||
anchors.centerIn: parent
|
if (root.hasUpdates) return "system_update_alt"
|
||||||
visible: root.isVertical
|
return "check_circle"
|
||||||
name: {
|
}
|
||||||
if (isChecking) return "refresh";
|
size: Theme.barIconSize(root.barThickness, -4)
|
||||||
if (SystemUpdateService.hasError) return "error";
|
color: {
|
||||||
if (hasUpdates) return "system_update_alt";
|
if (SystemUpdateService.hasError) return Theme.error
|
||||||
return "check_circle";
|
if (root.hasUpdates) return Theme.primary
|
||||||
}
|
return root.isActive ? Theme.primary : Theme.surfaceText
|
||||||
size: Theme.barIconSize(barThickness, -4)
|
|
||||||
color: {
|
|
||||||
if (SystemUpdateService.hasError) return Theme.error;
|
|
||||||
if (hasUpdates) return Theme.primary;
|
|
||||||
return (updaterArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText);
|
|
||||||
}
|
|
||||||
|
|
||||||
RotationAnimation {
|
|
||||||
id: rotationAnimation
|
|
||||||
target: statusIcon
|
|
||||||
property: "rotation"
|
|
||||||
from: 0
|
|
||||||
to: 360
|
|
||||||
duration: 1000
|
|
||||||
running: isChecking
|
|
||||||
loops: Animation.Infinite
|
|
||||||
|
|
||||||
onRunningChanged: {
|
|
||||||
if (!running) {
|
|
||||||
statusIcon.rotation = 0
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
RotationAnimation {
|
||||||
width: 8
|
id: rotationAnimation
|
||||||
height: 8
|
target: statusIcon
|
||||||
radius: 4
|
property: "rotation"
|
||||||
color: Theme.error
|
from: 0
|
||||||
anchors.right: parent.right
|
to: 360
|
||||||
anchors.top: parent.top
|
duration: 1000
|
||||||
anchors.rightMargin: SettingsData.dankBarNoBackground ? 0 : 6
|
running: root.isChecking
|
||||||
anchors.topMargin: SettingsData.dankBarNoBackground ? 0 : 6
|
loops: Animation.Infinite
|
||||||
visible: root.isVertical && root.hasUpdates && !root.isChecking
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
onRunningChanged: {
|
||||||
id: updaterIcon
|
if (!running) {
|
||||||
|
statusIcon.rotation = 0
|
||||||
anchors.centerIn: parent
|
}
|
||||||
spacing: Theme.spacingXS
|
|
||||||
visible: !root.isVertical
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
id: statusIconHorizontal
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
name: {
|
|
||||||
if (isChecking) return "refresh";
|
|
||||||
if (SystemUpdateService.hasError) return "error";
|
|
||||||
if (hasUpdates) return "system_update_alt";
|
|
||||||
return "check_circle";
|
|
||||||
}
|
|
||||||
size: Theme.barIconSize(barThickness, -4)
|
|
||||||
color: {
|
|
||||||
if (SystemUpdateService.hasError) return Theme.error;
|
|
||||||
if (hasUpdates) return Theme.primary;
|
|
||||||
return (updaterArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText);
|
|
||||||
}
|
|
||||||
|
|
||||||
RotationAnimation {
|
|
||||||
id: rotationAnimationHorizontal
|
|
||||||
target: statusIconHorizontal
|
|
||||||
property: "rotation"
|
|
||||||
from: 0
|
|
||||||
to: 360
|
|
||||||
duration: 1000
|
|
||||||
running: isChecking
|
|
||||||
loops: Animation.Infinite
|
|
||||||
|
|
||||||
onRunningChanged: {
|
|
||||||
if (!running) {
|
|
||||||
statusIconHorizontal.rotation = 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
Rectangle {
|
||||||
id: countText
|
width: 8
|
||||||
|
height: 8
|
||||||
|
radius: 4
|
||||||
|
color: Theme.error
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.rightMargin: SettingsData.dankBarNoBackground ? 0 : 6
|
||||||
|
anchors.topMargin: SettingsData.dankBarNoBackground ? 0 : 6
|
||||||
|
visible: root.isVerticalOrientation && root.hasUpdates && !root.isChecking
|
||||||
|
}
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
Row {
|
||||||
text: SystemUpdateService.updateCount.toString()
|
id: updaterIcon
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
anchors.centerIn: parent
|
||||||
font.weight: Font.Medium
|
spacing: Theme.spacingXS
|
||||||
color: Theme.surfaceText
|
visible: !root.isVerticalOrientation
|
||||||
visible: hasUpdates && !isChecking
|
|
||||||
|
DankIcon {
|
||||||
|
id: statusIconHorizontal
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
name: {
|
||||||
|
if (root.isChecking) return "refresh"
|
||||||
|
if (SystemUpdateService.hasError) return "error"
|
||||||
|
if (root.hasUpdates) return "system_update_alt"
|
||||||
|
return "check_circle"
|
||||||
|
}
|
||||||
|
size: Theme.barIconSize(root.barThickness, -4)
|
||||||
|
color: {
|
||||||
|
if (SystemUpdateService.hasError) return Theme.error
|
||||||
|
if (root.hasUpdates) return Theme.primary
|
||||||
|
return root.isActive ? Theme.primary : Theme.surfaceText
|
||||||
|
}
|
||||||
|
|
||||||
|
RotationAnimation {
|
||||||
|
id: rotationAnimationHorizontal
|
||||||
|
target: statusIconHorizontal
|
||||||
|
property: "rotation"
|
||||||
|
from: 0
|
||||||
|
to: 360
|
||||||
|
duration: 1000
|
||||||
|
running: root.isChecking
|
||||||
|
loops: Animation.Infinite
|
||||||
|
|
||||||
|
onRunningChanged: {
|
||||||
|
if (!running) {
|
||||||
|
statusIconHorizontal.rotation = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: countText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: SystemUpdateService.updateCount.toString()
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
visible: root.hasUpdates && !root.isChecking
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: updaterArea
|
z: 1
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onPressed: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popoutTarget && popoutTarget.setTriggerPosition) {
|
||||||
const globalPos = mapToGlobal(0, 0)
|
const globalPos = root.visualContent.mapToGlobal(0, 0)
|
||||||
const currentScreen = parentScreen || Screen
|
const currentScreen = parentScreen || Screen
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
||||||
}
|
}
|
||||||
root.clicked();
|
root.clicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,46 +1,35 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
Ref {
|
Ref {
|
||||||
service: VpnService
|
service: VpnService
|
||||||
}
|
}
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
property var popoutTarget: null
|
||||||
property var axis: null
|
|
||||||
property int widgetThickness: 28
|
|
||||||
property int barThickness: 32
|
|
||||||
property string section: "right"
|
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal toggleVpnPopup()
|
signal toggleVpnPopup()
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (Theme.iconSize + horizontalPadding * 2)
|
content: Component {
|
||||||
height: isVertical ? (Theme.iconSize + horizontalPadding * 2) : widgetThickness
|
Item {
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
implicitWidth: root.widgetThickness - root.horizontalPadding * 2
|
||||||
color: {
|
implicitHeight: root.widgetThickness - root.horizontalPadding * 2
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
DankIcon {
|
||||||
|
id: icon
|
||||||
|
|
||||||
|
name: VpnService.isBusy ? "sync" : (VpnService.connected ? "vpn_lock" : "vpn_key_off")
|
||||||
|
size: Theme.barIconSize(root.barThickness, -4)
|
||||||
|
color: VpnService.connected ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseColor = clickArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
id: icon
|
|
||||||
|
|
||||||
name: VpnService.isBusy ? "sync" : (VpnService.connected ? "vpn_lock" : "vpn_key_off")
|
|
||||||
size: Theme.barIconSize(barThickness, -4)
|
|
||||||
color: VpnService.connected ? Theme.primary : Theme.surfaceText
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
@@ -55,17 +44,18 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
onPressed: {
|
onPressed: {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
if (popoutTarget && popoutTarget.setTriggerPosition) {
|
||||||
const globalPos = mapToGlobal(0, 0)
|
const globalPos = root.visualContent.mapToGlobal(0, 0)
|
||||||
const currentScreen = parentScreen || Screen
|
const currentScreen = parentScreen || Screen
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
||||||
}
|
}
|
||||||
root.toggleVpnPopup();
|
root.toggleVpnPopup();
|
||||||
}
|
}
|
||||||
onEntered: {
|
onEntered: {
|
||||||
if (root.parentScreen && !(popupTarget && popupTarget.shouldBeVisible)) {
|
if (root.parentScreen && !(popoutTarget && popoutTarget.shouldBeVisible)) {
|
||||||
tooltipLoader.active = true
|
tooltipLoader.active = true
|
||||||
if (tooltipLoader.item) {
|
if (tooltipLoader.item) {
|
||||||
let tooltipText = ""
|
let tooltipText = ""
|
||||||
@@ -80,7 +70,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root.isVertical) {
|
if (root.isVerticalOrientation) {
|
||||||
const globalPos = mapToGlobal(width / 2, height / 2)
|
const globalPos = mapToGlobal(width / 2, height / 2)
|
||||||
const screenX = root.parentScreen ? root.parentScreen.x : 0
|
const screenX = root.parentScreen ? root.parentScreen.x : 0
|
||||||
const screenY = root.parentScreen ? root.parentScreen.y : 0
|
const screenY = root.parentScreen ? root.parentScreen.y : 0
|
||||||
@@ -103,5 +93,4 @@ Rectangle {
|
|||||||
tooltipLoader.active = false
|
tooltipLoader.active = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,120 +1,81 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.Plugins
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
BasePill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property string section: "center"
|
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real barThickness: 48
|
|
||||||
property real widgetThickness: 30
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 2 : Theme.spacingS
|
|
||||||
|
|
||||||
signal clicked()
|
|
||||||
|
|
||||||
visible: SettingsData.weatherEnabled
|
visible: SettingsData.weatherEnabled
|
||||||
width: isVertical ? widgetThickness : (visible ? Math.min(100, weatherRow.implicitWidth + horizontalPadding * 2) : 0)
|
|
||||||
height: isVertical ? (weatherColumn.implicitHeight + horizontalPadding * 2) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = weatherArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref {
|
Ref {
|
||||||
service: WeatherService
|
service: WeatherService
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
content: Component {
|
||||||
id: weatherColumn
|
Item {
|
||||||
visible: root.isVertical
|
implicitWidth: {
|
||||||
anchors.centerIn: parent
|
if (!SettingsData.weatherEnabled) return 0
|
||||||
spacing: 1
|
if (root.isVerticalOrientation) return root.widgetThickness - root.horizontalPadding * 2
|
||||||
|
return Math.min(100 - root.horizontalPadding * 2, weatherRow.implicitWidth)
|
||||||
DankIcon {
|
|
||||||
name: WeatherService.getWeatherIcon(WeatherService.weather.wCode)
|
|
||||||
size: Theme.barIconSize(barThickness, -6)
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
|
|
||||||
if (temp === undefined || temp === null || temp === 0) {
|
|
||||||
return "--";
|
|
||||||
}
|
|
||||||
return temp;
|
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
implicitHeight: root.isVerticalOrientation ? weatherColumn.implicitHeight : (root.widgetThickness - root.horizontalPadding * 2)
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
Column {
|
||||||
id: weatherRow
|
id: weatherColumn
|
||||||
|
visible: root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 1
|
||||||
|
|
||||||
visible: !root.isVertical
|
DankIcon {
|
||||||
anchors.centerIn: parent
|
name: WeatherService.getWeatherIcon(WeatherService.weather.wCode)
|
||||||
spacing: Theme.spacingXS
|
size: Theme.barIconSize(root.barThickness, -6)
|
||||||
|
color: Theme.primary
|
||||||
DankIcon {
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
name: WeatherService.getWeatherIcon(WeatherService.weather.wCode)
|
|
||||||
size: Theme.barIconSize(barThickness, -6)
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
|
|
||||||
if (temp === undefined || temp === null || temp === 0) {
|
|
||||||
return "--°" + (SettingsData.useFahrenheit ? "F" : "C");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return temp + "°" + (SettingsData.useFahrenheit ? "F" : "C");
|
StyledText {
|
||||||
|
text: {
|
||||||
|
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
|
||||||
|
if (temp === undefined || temp === null || temp === 0) {
|
||||||
|
return "--";
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.barTextSize(barThickness)
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
Row {
|
||||||
|
id: weatherRow
|
||||||
|
visible: !root.isVerticalOrientation
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
MouseArea {
|
DankIcon {
|
||||||
id: weatherArea
|
name: WeatherService.getWeatherIcon(WeatherService.weather.wCode)
|
||||||
|
size: Theme.barIconSize(root.barThickness, -6)
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
anchors.fill: parent
|
StyledText {
|
||||||
hoverEnabled: true
|
text: {
|
||||||
cursorShape: Qt.PointingHandCursor
|
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
|
||||||
onPressed: {
|
if (temp === undefined || temp === null || temp === 0) {
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
return "--°" + (SettingsData.useFahrenheit ? "F" : "C");
|
||||||
const globalPos = mapToGlobal(0, 0)
|
}
|
||||||
const currentScreen = parentScreen || Screen
|
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
return temp + "°" + (SettingsData.useFahrenheit ? "F" : "C");
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
}
|
||||||
|
font.pixelSize: Theme.barTextSize(root.barThickness)
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
root.clicked();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Behavior on width {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.standardEasing
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import qs.Common
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
property bool isVertical: axis?.isVertical ?? false
|
||||||
@@ -16,6 +16,7 @@ Rectangle {
|
|||||||
property real widgetHeight: 30
|
property real widgetHeight: 30
|
||||||
property real barThickness: 48
|
property real barThickness: 48
|
||||||
property var hyprlandOverviewLoader: null
|
property var hyprlandOverviewLoader: null
|
||||||
|
property var parentScreen: null
|
||||||
readonly property var sortedToplevels: {
|
readonly property var sortedToplevels: {
|
||||||
return CompositorService.filterCurrentWorkspace(CompositorService.sortedToplevels, parentScreen?.name);
|
return CompositorService.filterCurrentWorkspace(CompositorService.sortedToplevels, parentScreen?.name);
|
||||||
}
|
}
|
||||||
@@ -201,9 +202,9 @@ Rectangle {
|
|||||||
return currentMonitor.activeWorkspace?.id ?? 1
|
return currentMonitor.activeWorkspace?.id ?? 1
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property real padding: isVertical
|
readonly property real padding: Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30))
|
||||||
? Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30))
|
readonly property real visualWidth: isVertical ? widgetHeight : (workspaceRow.implicitWidth + padding * 2)
|
||||||
: (widgetHeight - workspaceRow.implicitHeight) / 2
|
readonly property real visualHeight: isVertical ? (workspaceRow.implicitHeight + padding * 2) : widgetHeight
|
||||||
|
|
||||||
function getRealWorkspaces() {
|
function getRealWorkspaces() {
|
||||||
return root.workspaceList.filter(ws => {
|
return root.workspaceList.filter(ws => {
|
||||||
@@ -232,17 +233,24 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
width: isVertical ? widgetHeight : (workspaceRow.implicitWidth + padding * 2)
|
width: isVertical ? barThickness : visualWidth
|
||||||
height: isVertical ? (workspaceRow.implicitHeight + padding * 2) : widgetHeight
|
height: isVertical ? visualHeight : barThickness
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground)
|
|
||||||
return "transparent"
|
|
||||||
const baseColor = Theme.widgetBaseBackgroundColor
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency)
|
|
||||||
}
|
|
||||||
visible: CompositorService.isNiri || CompositorService.isHyprland
|
visible: CompositorService.isNiri || CompositorService.isHyprland
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: visualBackground
|
||||||
|
width: root.visualWidth
|
||||||
|
height: root.visualHeight
|
||||||
|
anchors.centerIn: parent
|
||||||
|
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
||||||
|
color: {
|
||||||
|
if (SettingsData.dankBarNoBackground)
|
||||||
|
return "transparent"
|
||||||
|
const baseColor = Theme.widgetBaseBackgroundColor
|
||||||
|
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
acceptedButtons: Qt.RightButton
|
acceptedButtons: Qt.RightButton
|
||||||
@@ -357,7 +365,7 @@ Rectangle {
|
|||||||
Repeater {
|
Repeater {
|
||||||
model: root.workspaceList
|
model: root.workspaceList
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
id: delegateRoot
|
id: delegateRoot
|
||||||
|
|
||||||
property bool isActive: {
|
property bool isActive: {
|
||||||
@@ -389,6 +397,33 @@ Rectangle {
|
|||||||
property bool loadedHasIcon: false
|
property bool loadedHasIcon: false
|
||||||
property var loadedIcons: []
|
property var loadedIcons: []
|
||||||
|
|
||||||
|
readonly property real visualWidth: {
|
||||||
|
if (root.isVertical) {
|
||||||
|
return SettingsData.showWorkspaceApps ? widgetHeight * 0.7 : widgetHeight * 0.5
|
||||||
|
} else {
|
||||||
|
if (SettingsData.showWorkspaceApps && loadedIcons.length > 0) {
|
||||||
|
const numIcons = Math.min(loadedIcons.length, SettingsData.maxWorkspaceIcons)
|
||||||
|
const iconsWidth = numIcons * 18 + (numIcons > 0 ? (numIcons - 1) * Theme.spacingXS : 0)
|
||||||
|
const baseWidth = isActive ? root.widgetHeight * 0.9 + Theme.spacingXS : root.widgetHeight * 0.7
|
||||||
|
return baseWidth + iconsWidth
|
||||||
|
}
|
||||||
|
return isActive ? root.widgetHeight * 1.05 : root.widgetHeight * 0.7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
readonly property real visualHeight: {
|
||||||
|
if (root.isVertical) {
|
||||||
|
if (SettingsData.showWorkspaceApps && loadedIcons.length > 0) {
|
||||||
|
const numIcons = Math.min(loadedIcons.length, SettingsData.maxWorkspaceIcons)
|
||||||
|
const iconsHeight = numIcons * 18 + (numIcons > 0 ? (numIcons - 1) * Theme.spacingXS : 0)
|
||||||
|
const baseHeight = isActive ? root.widgetHeight * 0.9 + Theme.spacingXS : root.widgetHeight * 0.7
|
||||||
|
return baseHeight + iconsHeight
|
||||||
|
}
|
||||||
|
return isActive ? root.widgetHeight * 1.05 : root.widgetHeight * 0.7
|
||||||
|
} else {
|
||||||
|
return SettingsData.showWorkspaceApps ? widgetHeight * 0.7 : widgetHeight * 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: dataUpdateTimer
|
id: dataUpdateTimer
|
||||||
interval: 50
|
interval: 50
|
||||||
@@ -430,92 +465,54 @@ Rectangle {
|
|||||||
dataUpdateTimer.restart()
|
dataUpdateTimer.restart()
|
||||||
}
|
}
|
||||||
|
|
||||||
width: {
|
width: root.isVertical ? root.barThickness : visualWidth
|
||||||
if (root.isVertical) {
|
height: root.isVertical ? visualHeight : root.barThickness
|
||||||
return SettingsData.showWorkspaceApps ? widgetHeight * 0.7 : widgetHeight * 0.5;
|
|
||||||
} else {
|
|
||||||
if (SettingsData.showWorkspaceApps && loadedIcons.length > 0) {
|
|
||||||
const numIcons = Math.min(loadedIcons.length, SettingsData.maxWorkspaceIcons);
|
|
||||||
const iconsWidth = numIcons * 18 + (numIcons > 0 ? (numIcons - 1) * Theme.spacingXS : 0);
|
|
||||||
const baseWidth = isActive ? root.widgetHeight * 0.9 + Theme.spacingXS : root.widgetHeight * 0.7;
|
|
||||||
return baseWidth + iconsWidth;
|
|
||||||
}
|
|
||||||
return isActive ? root.widgetHeight * 1.05 : root.widgetHeight * 0.7;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
height: {
|
|
||||||
if (root.isVertical) {
|
|
||||||
if (SettingsData.showWorkspaceApps && loadedIcons.length > 0) {
|
|
||||||
const numIcons = Math.min(loadedIcons.length, SettingsData.maxWorkspaceIcons);
|
|
||||||
const iconsHeight = numIcons * 18 + (numIcons > 0 ? (numIcons - 1) * Theme.spacingXS : 0);
|
|
||||||
const baseHeight = isActive ? root.widgetHeight * 0.9 + Theme.spacingXS : root.widgetHeight * 0.7;
|
|
||||||
return baseHeight + iconsHeight;
|
|
||||||
}
|
|
||||||
return isActive ? root.widgetHeight * 1.05 : root.widgetHeight * 0.7;
|
|
||||||
} else {
|
|
||||||
return SettingsData.showWorkspaceApps ? widgetHeight * 0.7 : widgetHeight * 0.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: isActive ? Theme.primary : isUrgent ? Theme.error : isPlaceholder ? Theme.surfaceTextLight : isHovered ? Theme.outlineButton : Theme.surfaceTextAlpha
|
|
||||||
|
|
||||||
border.width: isUrgent && !isActive ? 2 : 0
|
Rectangle {
|
||||||
border.color: isUrgent && !isActive ? Theme.error : Theme.withAlpha(Theme.error, 0)
|
id: visualContent
|
||||||
|
width: delegateRoot.visualWidth
|
||||||
|
height: delegateRoot.visualHeight
|
||||||
|
anchors.centerIn: parent
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: isActive ? Theme.primary : isUrgent ? Theme.error : isPlaceholder ? Theme.surfaceTextLight : isHovered ? Theme.outlineButton : Theme.surfaceTextAlpha
|
||||||
|
|
||||||
Behavior on width {
|
border.width: isUrgent && !isActive ? 2 : 0
|
||||||
enabled: (!SettingsData.showWorkspaceApps || SettingsData.maxWorkspaceIcons <= 3)
|
border.color: isUrgent && !isActive ? Theme.error : Theme.withAlpha(Theme.error, 0)
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on height {
|
Behavior on width {
|
||||||
enabled: root.isVertical && (!SettingsData.showWorkspaceApps || SettingsData.maxWorkspaceIcons <= 3)
|
enabled: (!SettingsData.showWorkspaceApps || SettingsData.maxWorkspaceIcons <= 3)
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.mediumDuration
|
duration: Theme.mediumDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on border.width {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: mouseArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: !isPlaceholder
|
|
||||||
cursorShape: isPlaceholder ? Qt.ArrowCursor : Qt.PointingHandCursor
|
|
||||||
enabled: !isPlaceholder
|
|
||||||
onClicked: {
|
|
||||||
if (isPlaceholder) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CompositorService.isNiri) {
|
|
||||||
NiriService.switchToWorkspace(modelData - 1)
|
|
||||||
} else if (CompositorService.isHyprland && modelData?.id) {
|
|
||||||
Hyprland.dispatch(`workspace ${modelData.id}`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
Behavior on height {
|
||||||
id: appIconsLoader
|
enabled: root.isVertical && (!SettingsData.showWorkspaceApps || SettingsData.maxWorkspaceIcons <= 3)
|
||||||
anchors.fill: parent
|
NumberAnimation {
|
||||||
active: SettingsData.showWorkspaceApps
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on border.width {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: appIconsLoader
|
||||||
|
anchors.fill: parent
|
||||||
|
active: SettingsData.showWorkspaceApps
|
||||||
sourceComponent: Item {
|
sourceComponent: Item {
|
||||||
Loader {
|
Loader {
|
||||||
id: contentRow
|
id: contentRow
|
||||||
@@ -716,8 +713,27 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: !isPlaceholder
|
||||||
|
cursorShape: isPlaceholder ? Qt.ArrowCursor : Qt.PointingHandCursor
|
||||||
|
enabled: !isPlaceholder
|
||||||
|
onClicked: {
|
||||||
|
if (isPlaceholder) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CompositorService.isNiri) {
|
||||||
|
NiriService.switchToWorkspace(modelData - 1)
|
||||||
|
} else if (CompositorService.isHyprland && modelData?.id) {
|
||||||
|
Hyprland.dispatch(`workspace ${modelData.id}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- LOGIC / TRIGGERS ---
|
|
||||||
Component.onCompleted: updateAllData()
|
Component.onCompleted: updateAllData()
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import qs.Common
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property var axis: null
|
property var axis: null
|
||||||
@@ -12,44 +12,54 @@ Rectangle {
|
|||||||
property var parentScreen: null
|
property var parentScreen: null
|
||||||
property real widgetThickness: 30
|
property real widgetThickness: 30
|
||||||
property real barThickness: 48
|
property real barThickness: 48
|
||||||
property bool isVerticalOrientation: false
|
|
||||||
property alias content: contentLoader.sourceComponent
|
property alias content: contentLoader.sourceComponent
|
||||||
|
property bool isVerticalOrientation: axis?.isVertical ?? false
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
||||||
|
readonly property real visualWidth: isVerticalOrientation ? widgetThickness : (contentLoader.item ? (contentLoader.item.implicitWidth + horizontalPadding * 2) : 0)
|
||||||
|
readonly property real visualHeight: isVerticalOrientation ? (contentLoader.item ? (contentLoader.item.implicitHeight + horizontalPadding * 2) : 0) : widgetThickness
|
||||||
|
readonly property alias visualContent: visualContent
|
||||||
|
|
||||||
signal clicked()
|
signal clicked()
|
||||||
|
|
||||||
width: isVerticalOrientation ? widgetThickness : contentLoader.item ? (contentLoader.item.implicitWidth + horizontalPadding * 2) : 0
|
width: isVerticalOrientation ? barThickness : visualWidth
|
||||||
height: isVerticalOrientation ? (contentLoader.item ? (contentLoader.item.implicitHeight + horizontalPadding * 2) : 0) : widgetThickness
|
height: isVerticalOrientation ? visualHeight : barThickness
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
Rectangle {
|
||||||
if (SettingsData.dankBarNoBackground) {
|
id: visualContent
|
||||||
return "transparent"
|
width: root.visualWidth
|
||||||
|
height: root.visualHeight
|
||||||
|
anchors.centerIn: parent
|
||||||
|
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
||||||
|
color: {
|
||||||
|
if (SettingsData.dankBarNoBackground) {
|
||||||
|
return "transparent"
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseColor = mouseArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor
|
||||||
|
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency)
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseColor = mouseArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor
|
Loader {
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency)
|
id: contentLoader
|
||||||
}
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
Loader {
|
}
|
||||||
id: contentLoader
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
z: -1
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onPressed: {
|
onClicked: {
|
||||||
|
root.clicked()
|
||||||
if (popoutTarget && popoutTarget.setTriggerPosition) {
|
if (popoutTarget && popoutTarget.setTriggerPosition) {
|
||||||
const globalPos = mapToGlobal(0, 0)
|
const globalPos = mapToGlobal(0, 0)
|
||||||
const currentScreen = parentScreen || Screen
|
const currentScreen = parentScreen || Screen
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
|
||||||
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
||||||
}
|
}
|
||||||
root.clicked()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user