diff options
Diffstat (limited to '.config/noctalia/plugins/timer/BarWidget.qml')
| -rw-r--r-- | .config/noctalia/plugins/timer/BarWidget.qml | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/.config/noctalia/plugins/timer/BarWidget.qml b/.config/noctalia/plugins/timer/BarWidget.qml new file mode 100644 index 0000000..81d2cb9 --- /dev/null +++ b/.config/noctalia/plugins/timer/BarWidget.qml @@ -0,0 +1,179 @@ +import QtQuick +import QtQuick.Layouts +import Quickshell +import qs.Commons +import qs.Widgets +import qs.Services.UI +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 + + readonly property bool pillDirection: BarService.getPillDirection(root) + + readonly property var mainInstance: pluginApi?.mainInstance + readonly property bool isActive: mainInstance && (mainInstance.cdRunning || mainInstance.swRunning || mainInstance.swElapsedSeconds > 0 || mainInstance.cdRemainingSeconds > 0 || mainInstance.cdSoundPlaying) + + property var cfg: pluginApi?.pluginSettings || ({}) + property var defaults: pluginApi?.manifest?.metadata?.defaultSettings || ({}) + + readonly property string iconColorKey: cfg.iconColor ?? defaults.iconColor ?? "none" + readonly property color iconColor: Color.resolveColorKey(iconColorKey) + + readonly property string textColorKey: cfg.textColor ?? defaults.textColor ?? "none" + readonly property color textColor: Color.resolveColorKey(textColorKey) + + // Bar positioning properties + readonly property string screenName: screen ? screen.name : "" + readonly property string barPosition: Settings.getBarPositionForScreen(screenName) + readonly property bool isVertical: barPosition === "left" || barPosition === "right" + readonly property real barHeight: Style.getBarHeightForScreen(screenName) + readonly property real capsuleHeight: Style.getCapsuleHeightForScreen(screenName) + readonly property real barFontSize: Style.getBarFontSizeForScreen(screenName) + + readonly property real contentWidth: { + if (isVertical) return root.capsuleHeight + if (isActive) return contentRow.implicitWidth + Style.marginM * 2 + return root.capsuleHeight + } + readonly property real contentHeight: root.capsuleHeight + + implicitWidth: contentWidth + implicitHeight: contentHeight + + function formatTime(seconds) { + const hours = Math.floor(seconds / 3600); + const minutes = Math.floor((seconds % 3600) / 60); + const secs = seconds % 60; + + if (hours > 0) { + return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; + } + return `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; + } + + Rectangle { + id: visualCapsule + x: Style.pixelAlignCenter(parent.width, width) + y: Style.pixelAlignCenter(parent.height, height) + width: root.contentWidth + height: root.contentHeight + color: mouseArea.containsMouse ? Color.mHover : Style.capsuleColor + radius: Style.radiusL + border.color: Style.capsuleBorderColor + border.width: Style.capsuleBorderWidth + + RowLayout { + id: contentRow + anchors.centerIn: parent + spacing: Style.marginS + layoutDirection: pillDirection ? Qt.LeftToRight : Qt.RightToLeft + + NIcon { + icon: { + if (mainInstance && mainInstance.timerSoundPlaying) return "bell-ringing" + if (mainInstance && mainInstance.timerStopwatchMode) return "stopwatch" + return "hourglass" + } + applyUiScale: false + color: mouseArea.containsMouse ? Color.mOnHover : root.iconColor + } + + NText { + visible: !isVertical && mainInstance && (mainInstance.cdRunning || mainInstance.swRunning || mainInstance.swElapsedSeconds > 0 || mainInstance.cdRemainingSeconds > 0 || mainInstance.cdSoundPlaying) + family: Settings.data.ui.fontFixed + pointSize: root.barFontSize + font.weight: Style.fontWeightBold + color: mouseArea.containsMouse ? Color.mOnHover : root.textColor + text: { + if (!mainInstance) return "" + if (mainInstance.timerStopwatchMode) { + return formatTime(mainInstance.timerElapsedSeconds) + } + return formatTime(mainInstance.timerRemainingSeconds) + } + } + } + } + + NPopupContextMenu { + id: contextMenu + + model: { + var items = []; + + if (mainInstance) { + // Pause / Resume & Reset + const modeActive = mainInstance.timerStopwatchMode + ? (mainInstance.swRunning || mainInstance.swElapsedSeconds > 0) + : (mainInstance.cdRunning || mainInstance.cdRemainingSeconds > 0 || mainInstance.cdSoundPlaying); + if (modeActive) { + items.push({ + "label": mainInstance.timerRunning ? pluginApi.tr("panel.pause") : pluginApi.tr("panel.resume"), + "action": "toggle", + "icon": mainInstance.timerRunning ? "media-pause" : "media-play" + }); + + items.push({ + "label": pluginApi.tr("panel.reset"), + "action": "reset", + "icon": "refresh" + }); + } + } + + // Settings + items.push({ + "label": pluginApi.tr("panel.settings"), + "action": "widget-settings", + "icon": "settings" + }); + + return items; + } + + onTriggered: action => { + contextMenu.close(); + PanelService.closeContextMenu(screen); + + if (action === "widget-settings") { + BarService.openPluginSettings(screen, pluginApi.manifest); + } else if (mainInstance) { + if (action === "toggle") { + if (mainInstance.timerRunning) { + mainInstance.timerPause(); + } else { + mainInstance.timerStart(); + } + } else if (action === "reset") { + mainInstance.timerReset(); + } + } + } + } + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + acceptedButtons: Qt.LeftButton | Qt.RightButton + + onClicked: (mouse) => { + if (mouse.button === Qt.LeftButton) { + if (pluginApi) { + pluginApi.openPanel(root.screen, root) + } + } else if (mouse.button === Qt.RightButton) { + PanelService.showContextMenu(contextMenu, root, screen); + } + } + } +} |