179 lines
5.3 KiB
QML
179 lines
5.3 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import qs.Commons
|
|
import qs.Widgets
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property string widgetId: "CustomButton"
|
|
property var widgetSettings: null
|
|
|
|
property string onClickedCommand: ""
|
|
property string onRightClickedCommand: ""
|
|
property string onMiddleClickedCommand: ""
|
|
property string stateChecksJson: "[]" // Store state checks as JSON string
|
|
|
|
property string generalTooltipText: ""
|
|
property bool enableOnStateLogic: false
|
|
property bool showExecTooltip: true
|
|
property bool _hasCustomTooltip: false
|
|
|
|
property string _currentIcon: "heart" // Default icon
|
|
property bool _isHot: false
|
|
property var _parsedStateChecks: [] // Local array for parsed state checks
|
|
|
|
property int _currentStateCheckIndex: -1
|
|
property string _activeStateIcon: ""
|
|
|
|
implicitWidth: button.implicitWidth
|
|
implicitHeight: button.implicitHeight
|
|
|
|
Connections {
|
|
target: root
|
|
|
|
function _updatePropertiesFromSettings() {
|
|
if (!widgetSettings) {
|
|
return;
|
|
}
|
|
|
|
onClickedCommand = widgetSettings.onClicked || "";
|
|
onRightClickedCommand = widgetSettings.onRightClicked || "";
|
|
onMiddleClickedCommand = widgetSettings.onMiddleClicked || "";
|
|
stateChecksJson = widgetSettings.stateChecksJson || "[]"; // Populate from widgetSettings
|
|
try {
|
|
_parsedStateChecks = JSON.parse(stateChecksJson);
|
|
} catch (e) {
|
|
Logger.e("CustomButton", "Failed to parse stateChecksJson:", e.message);
|
|
_parsedStateChecks = [];
|
|
}
|
|
generalTooltipText = widgetSettings.generalTooltipText || "";
|
|
_hasCustomTooltip = !!(widgetSettings.generalTooltipText && widgetSettings.generalTooltipText.trim() !== "");
|
|
enableOnStateLogic = widgetSettings.enableOnStateLogic || false;
|
|
showExecTooltip = widgetSettings.showExecTooltip !== undefined ? widgetSettings.showExecTooltip : true;
|
|
|
|
updateState();
|
|
}
|
|
|
|
function onWidgetSettingsChanged() {
|
|
if (widgetSettings) {
|
|
_updatePropertiesFromSettings();
|
|
}
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: stateCheckProcessExecutor
|
|
running: false
|
|
command: _currentStateCheckIndex !== -1 && _parsedStateChecks.length > _currentStateCheckIndex ? ["sh", "-lc", _parsedStateChecks[_currentStateCheckIndex].command] : []
|
|
onExited: function (exitCode, stdout, stderr) {
|
|
var currentCheckItem = _parsedStateChecks[_currentStateCheckIndex];
|
|
var currentCommand = currentCheckItem.command;
|
|
if (exitCode === 0) {
|
|
// Command succeeded, this is the active state
|
|
_isHot = true;
|
|
_activeStateIcon = currentCheckItem.icon || widgetSettings.icon || "heart";
|
|
} else {
|
|
// Command failed, try next one
|
|
_currentStateCheckIndex++;
|
|
_checkNextState();
|
|
}
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: stateUpdateTimer
|
|
interval: 200
|
|
running: false
|
|
repeat: false
|
|
onTriggered: {
|
|
if (enableOnStateLogic && _parsedStateChecks.length > 0) {
|
|
_currentStateCheckIndex = 0;
|
|
_checkNextState();
|
|
} else {
|
|
_isHot = false;
|
|
_activeStateIcon = widgetSettings.icon || "heart";
|
|
}
|
|
}
|
|
}
|
|
|
|
function _checkNextState() {
|
|
if (_currentStateCheckIndex < _parsedStateChecks.length) {
|
|
var currentCheckItem = _parsedStateChecks[_currentStateCheckIndex];
|
|
if (currentCheckItem && currentCheckItem.command) {
|
|
stateCheckProcessExecutor.running = true;
|
|
} else {
|
|
_currentStateCheckIndex++;
|
|
_checkNextState();
|
|
}
|
|
} else {
|
|
// All checks failed
|
|
_isHot = false;
|
|
_activeStateIcon = widgetSettings.icon || "heart";
|
|
}
|
|
}
|
|
|
|
function updateState() {
|
|
if (!enableOnStateLogic || _parsedStateChecks.length === 0) {
|
|
_isHot = false;
|
|
_activeStateIcon = widgetSettings.icon || "heart";
|
|
return;
|
|
}
|
|
stateUpdateTimer.restart();
|
|
}
|
|
|
|
function _buildTooltipText() {
|
|
// Build tooltip based on settings
|
|
let tooltip = "";
|
|
|
|
// If user set custom text, always show it
|
|
// If no custom text and showExecTooltip is off, show i18n default
|
|
if (_hasCustomTooltip) {
|
|
tooltip = generalTooltipText;
|
|
} else if (!showExecTooltip) {
|
|
tooltip = I18n.tr("bar.custom-button.default-tooltip");
|
|
}
|
|
|
|
// Add command details if enabled
|
|
if (showExecTooltip) {
|
|
if (onClickedCommand) {
|
|
tooltip += (tooltip ? "\n" : "") + I18n.tr("bar.custom-button.left-click-label") + `: ${onClickedCommand}`;
|
|
}
|
|
if (onRightClickedCommand) {
|
|
tooltip += (tooltip ? "\n" : "") + I18n.tr("bar.custom-button.right-click-label") + `: ${onRightClickedCommand}`;
|
|
}
|
|
if (onMiddleClickedCommand) {
|
|
tooltip += (tooltip ? "\n" : "") + I18n.tr("bar.custom-button.middle-click-label") + `: ${onMiddleClickedCommand}`;
|
|
}
|
|
}
|
|
|
|
return tooltip;
|
|
}
|
|
|
|
NIconButtonHot {
|
|
id: button
|
|
icon: _activeStateIcon
|
|
hot: _isHot
|
|
tooltipText: _buildTooltipText()
|
|
onClicked: {
|
|
if (onClickedCommand) {
|
|
Quickshell.execDetached(["sh", "-lc", onClickedCommand]);
|
|
updateState();
|
|
}
|
|
}
|
|
onRightClicked: {
|
|
if (onRightClickedCommand) {
|
|
Quickshell.execDetached(["sh", "-lc", onRightClickedCommand]);
|
|
updateState();
|
|
}
|
|
}
|
|
onMiddleClicked: {
|
|
if (onMiddleClickedCommand) {
|
|
Quickshell.execDetached(["sh", "-lc", onMiddleClickedCommand]);
|
|
updateState();
|
|
}
|
|
}
|
|
}
|
|
}
|