194 lines
6.5 KiB
QML
194 lines
6.5 KiB
QML
import QtQuick
|
|
import QtQuick.Effects
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import qs.Commons
|
|
import qs.Modules.Bar.Extras
|
|
import qs.Services.UI
|
|
import qs.Widgets
|
|
import qs.Services.System
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property var pluginApi: null
|
|
property ShellScreen screen
|
|
property string widgetId: ""
|
|
property string section: ""
|
|
property int sectionWidgetIndex: -1
|
|
property int sectionWidgetsCount: 0
|
|
|
|
// Per-screen bar properties
|
|
readonly property string screenName: screen?.name ?? ""
|
|
readonly property string barPosition: Settings.getBarPositionForScreen(screenName)
|
|
readonly property bool barIsVertical: barPosition === "left" || barPosition === "right"
|
|
readonly property real capsuleHeight: Style.getCapsuleHeightForScreen(screenName)
|
|
|
|
property url currentIconSource
|
|
|
|
property string tooltipText: {
|
|
if (!pluginApi) return "";
|
|
return root.isRunning ? (pluginApi.tr("tooltip.running") || "Running") : (pluginApi.tr("tooltip.sleeping") || "Sleeping");
|
|
}
|
|
|
|
property string tooltipDirection: BarService.getTooltipDirection()
|
|
property bool enabled: true
|
|
property bool allowClickWhenDisabled: false
|
|
property bool hovering: false
|
|
|
|
property color colorBg: Color.mSurfaceVariant
|
|
property color colorFg: Color.mPrimary
|
|
property color colorBgHover: Color.mHover
|
|
property color colorFgHover: Color.mOnHover
|
|
property color colorBorder: Color.mOutline
|
|
property color colorBorderHover: Color.mOutline
|
|
property real customRadius: Style.radiusL
|
|
|
|
signal entered
|
|
signal exited
|
|
signal clicked
|
|
signal rightClicked
|
|
signal middleClicked
|
|
signal wheel(int angleDelta)
|
|
|
|
readonly property real contentWidth: barIsVertical ? capsuleHeight : Math.round(capsuleHeight + Style.marginXS * 2)
|
|
readonly property real contentHeight: capsuleHeight
|
|
|
|
implicitWidth: contentWidth
|
|
implicitHeight: contentHeight
|
|
|
|
// --- Catwalk Specific Logic ---
|
|
property int frameIndex: 0
|
|
property int idleFrameIndex: 0
|
|
readonly property bool isRunning: root.pluginApi?.mainInstance?.isRunning ?? false
|
|
readonly property var icons: root.pluginApi?.mainInstance?.icons || []
|
|
readonly property var idleIcons: root.pluginApi?.mainInstance?.idleIcons || []
|
|
readonly property real cpuUsage: root.pluginApi?.mainInstance?.cpuUsage ?? 0
|
|
|
|
function openPanel() {
|
|
if (pluginApi) {
|
|
var result = pluginApi.openPanel(root.screen);
|
|
Logger.i("Catwalk", "OpenPanel result:", result);
|
|
} else {
|
|
Logger.e("Catwalk", "PluginAPI is null");
|
|
}
|
|
}
|
|
|
|
function openExternalMonitor() {
|
|
Quickshell.execDetached(["sh", "-c", Settings.data.systemMonitor.externalMonitor]);
|
|
}
|
|
|
|
Timer {
|
|
interval: Math.max(30, 200 - root.cpuUsage * 1.7)
|
|
running: root.isRunning
|
|
repeat: true
|
|
onTriggered: {
|
|
root.frameIndex = (root.frameIndex + 1) % root.icons.length
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
interval: 400
|
|
running: !root.isRunning
|
|
repeat: true
|
|
onTriggered: {
|
|
root.idleFrameIndex = (root.idleFrameIndex + 1) % root.idleIcons.length
|
|
}
|
|
}
|
|
|
|
currentIconSource: (root.icons && root.icons.length > 0 && root.idleIcons && root.idleIcons.length > 0)
|
|
? (root.isRunning
|
|
? Qt.resolvedUrl(root.icons[root.frameIndex % root.icons.length])
|
|
: Qt.resolvedUrl(root.idleIcons[root.idleFrameIndex % root.idleIcons.length]))
|
|
: ""
|
|
|
|
Rectangle {
|
|
id: visualCapsule
|
|
x: Style.pixelAlignCenter(parent.width, width)
|
|
y: Style.pixelAlignCenter(parent.height, height)
|
|
width: root.contentWidth
|
|
height: root.contentHeight
|
|
opacity: root.enabled ? Style.opacityFull : Style.opacityMedium
|
|
color: mouseArea.containsMouse ? Color.mHover : Style.capsuleColor
|
|
radius: Math.min((customRadius >= 0 ? customRadius : Style.iRadiusL), width / 2)
|
|
border.color: Style.capsuleBorderColor
|
|
border.width: Style.capsuleBorderWidth
|
|
|
|
Behavior on color {
|
|
ColorAnimation {
|
|
duration: Style.animationNormal
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
|
|
Image {
|
|
id: iconImage
|
|
source: root.currentIconSource
|
|
x: Style.pixelAlignCenter(parent.width, width)
|
|
y: Style.pixelAlignCenter(parent.height, height)
|
|
|
|
width: Style.toOdd(visualCapsule.width - Style.marginXS * 2)
|
|
height: width
|
|
|
|
// Render SVG at exact target size for crisp output
|
|
sourceSize: Qt.size(width, height)
|
|
fillMode: Image.PreserveAspectFit
|
|
smooth: true
|
|
mipmap: false
|
|
|
|
// This enables the "mask" behavior to recolor the icon
|
|
layer.enabled: true
|
|
layer.effect: MultiEffect {
|
|
colorization: 1.0
|
|
colorizationColor: Settings.data.colorSchemes.darkMode ? "white" : "black"
|
|
}
|
|
}
|
|
}
|
|
|
|
MouseArea {
|
|
id: mouseArea
|
|
anchors.fill: parent
|
|
cursorShape: root.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
|
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
|
hoverEnabled: true
|
|
onEntered: {
|
|
root.hovering = true;
|
|
if (root.tooltipText) {
|
|
TooltipService.show(root, root.tooltipText, root.tooltipDirection);
|
|
}
|
|
root.entered();
|
|
}
|
|
onExited: {
|
|
root.hovering = false;
|
|
if (root.tooltipText) {
|
|
TooltipService.hide();
|
|
}
|
|
root.exited();
|
|
}
|
|
onClicked: function (mouse) {
|
|
if (root.tooltipText) {
|
|
TooltipService.hide();
|
|
}
|
|
|
|
Logger.i("Catwalk", "Clicked! API:", !!pluginApi, "Screen:", root.screen ? root.screen.name : "null");
|
|
|
|
if (!root.enabled && !root.allowClickWhenDisabled) {
|
|
return;
|
|
}
|
|
// Open Panel on left/right click
|
|
// Open external monitor on middle click
|
|
if (mouse.button === Qt.LeftButton) {
|
|
root.openPanel();
|
|
root.clicked();
|
|
} else if (mouse.button === Qt.RightButton) {
|
|
root.openPanel();
|
|
root.rightClicked();
|
|
} else if (mouse.button === Qt.MiddleButton) {
|
|
root.openExternalMonitor();
|
|
root.middleClicked();
|
|
}
|
|
}
|
|
onWheel: wheel => root.wheel(wheel.angleDelta.y)
|
|
}
|
|
}
|