add noctalia and fuzzel
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Modules.Bar.Extras
|
||||
import qs.Services.UI
|
||||
import qs.Widgets
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
property string section: ""
|
||||
property int sectionWidgetIndex: -1
|
||||
property int sectionWidgetsCount: 0
|
||||
|
||||
property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId] ?? {}
|
||||
// Explicit screenName property ensures reactive binding when screen changes
|
||||
readonly property string screenName: screen ? screen.name : ""
|
||||
property var widgetSettings: {
|
||||
if (section && sectionWidgetIndex >= 0 && screenName) {
|
||||
var widgets = Settings.getBarWidgetsForScreen(screenName)[section];
|
||||
if (widgets && sectionWidgetIndex < widgets.length) {
|
||||
return widgets[sectionWidgetIndex];
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
readonly property string barPosition: Settings.getBarPositionForScreen(screenName)
|
||||
readonly property bool isBarVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property real capsuleHeight: Style.getCapsuleHeightForScreen(screenName)
|
||||
readonly property real barFontSize: Style.getBarFontSizeForScreen(screenName)
|
||||
readonly property var now: Time.now
|
||||
|
||||
// Resolve settings: try user settings or defaults from BarWidgetRegistry
|
||||
readonly property string clockColor: widgetSettings.clockColor !== undefined ? widgetSettings.clockColor : widgetMetadata.clockColor
|
||||
readonly property bool useCustomFont: widgetSettings.useCustomFont !== undefined ? widgetSettings.useCustomFont : widgetMetadata.useCustomFont
|
||||
readonly property string customFont: widgetSettings.customFont !== undefined ? widgetSettings.customFont : widgetMetadata.customFont
|
||||
readonly property string formatHorizontal: widgetSettings.formatHorizontal !== undefined ? widgetSettings.formatHorizontal : widgetMetadata.formatHorizontal
|
||||
readonly property string formatVertical: widgetSettings.formatVertical !== undefined ? widgetSettings.formatVertical : widgetMetadata.formatVertical
|
||||
readonly property string tooltipFormat: widgetSettings.tooltipFormat !== undefined ? widgetSettings.tooltipFormat : widgetMetadata.tooltipFormat
|
||||
|
||||
readonly property color textColor: Color.resolveColorKey(clockColor)
|
||||
|
||||
// Content dimensions for implicit sizing
|
||||
readonly property real contentWidth: isBarVertical ? capsuleHeight : Math.round((isBarVertical ? verticalLoader.implicitWidth : horizontalLoader.implicitWidth) + Style.margin2M)
|
||||
readonly property real contentHeight: isBarVertical ? Math.round(verticalLoader.implicitHeight + Style.margin2S) : capsuleHeight
|
||||
|
||||
// Size: use implicit width/height
|
||||
// BarWidgetLoader sets explicit width/height to extend click area
|
||||
implicitWidth: contentWidth
|
||||
implicitHeight: contentHeight
|
||||
|
||||
// Visual clock capsule - stays at content size, centered in parent
|
||||
Rectangle {
|
||||
id: visualClock
|
||||
width: root.contentWidth
|
||||
height: root.contentHeight
|
||||
anchors.centerIn: parent
|
||||
|
||||
radius: Style.radiusL
|
||||
color: Style.capsuleColor
|
||||
border.color: Style.capsuleBorderColor
|
||||
border.width: Style.capsuleBorderWidth
|
||||
|
||||
Item {
|
||||
id: clockContainer
|
||||
anchors.centerIn: parent
|
||||
|
||||
// Horizontal
|
||||
Loader {
|
||||
id: horizontalLoader
|
||||
active: !isBarVertical
|
||||
anchors.centerIn: parent
|
||||
sourceComponent: ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: Settings.data.bar.showCapsule ? -5 : -3
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: I18n.locale.toString(now, formatHorizontal.trim()).split("\\n")
|
||||
NText {
|
||||
visible: text !== ""
|
||||
text: modelData
|
||||
family: useCustomFont && customFont ? customFont : Settings.data.ui.fontDefault
|
||||
Binding on pointSize {
|
||||
value: {
|
||||
if (repeater.model.length == 1) {
|
||||
// Single line: Full size
|
||||
return barFontSize;
|
||||
} else if (repeater.model.length == 2) {
|
||||
// Two lines: First line is bigger than the second
|
||||
return (index == 0) ? Math.round(barFontSize * 0.9) : Math.round(barFontSize * 0.75);
|
||||
} else {
|
||||
// More than two lines: Make it small!
|
||||
return Math.round(barFontSize * 0.75);
|
||||
}
|
||||
}
|
||||
}
|
||||
applyUiScale: false
|
||||
color: textColor
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
features: ({
|
||||
"tnum": 1
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Vertical
|
||||
Loader {
|
||||
id: verticalLoader
|
||||
active: isBarVertical
|
||||
anchors.centerIn: parent // Now this works without layout conflicts
|
||||
sourceComponent: ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: -2
|
||||
Repeater {
|
||||
model: I18n.locale.toString(now, formatVertical.trim()).split(" ")
|
||||
delegate: NText {
|
||||
visible: text !== ""
|
||||
text: modelData
|
||||
family: useCustomFont && customFont ? customFont : Settings.data.ui.fontDefault
|
||||
pointSize: barFontSize
|
||||
applyUiScale: false
|
||||
color: textColor
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
features: ({
|
||||
"tnum": 1
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NPopupContextMenu {
|
||||
id: contextMenu
|
||||
|
||||
model: [
|
||||
{
|
||||
"label": I18n.tr("actions.open-calendar"),
|
||||
"action": "open-calendar",
|
||||
"icon": "calendar"
|
||||
},
|
||||
{
|
||||
"label": I18n.tr("actions.widget-settings"),
|
||||
"action": "widget-settings",
|
||||
"icon": "settings"
|
||||
},
|
||||
]
|
||||
|
||||
onTriggered: action => {
|
||||
// Close the context menu
|
||||
contextMenu.close();
|
||||
PanelService.closeContextMenu(screen);
|
||||
|
||||
if (action === "open-calendar") {
|
||||
PanelService.getPanel("clockPanel", screen)?.toggle(root);
|
||||
} else if (action === "widget-settings") {
|
||||
BarService.openWidgetSettings(screen, section, sectionWidgetIndex, widgetId, widgetSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build tooltip text with formatted time/date
|
||||
function buildTooltipText() {
|
||||
if (tooltipFormat && tooltipFormat.trim() !== "") {
|
||||
return I18n.locale.toString(now, tooltipFormat.trim());
|
||||
}
|
||||
// Fallback to default if no format is set
|
||||
return I18n.tr("common.calendar"); // Defaults to "Calendar"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: clockMouseArea
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onEntered: {
|
||||
if (!PanelService.getPanel("clockPanel", screen)?.isPanelOpen) {
|
||||
TooltipService.show(root, buildTooltipText(), BarService.getTooltipDirection(root.screen?.name));
|
||||
tooltipRefreshTimer.start();
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
tooltipRefreshTimer.stop();
|
||||
TooltipService.hide();
|
||||
}
|
||||
onClicked: mouse => {
|
||||
TooltipService.hide();
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
PanelService.showContextMenu(contextMenu, root, screen);
|
||||
} else {
|
||||
PanelService.getPanel("clockPanel", screen)?.toggle(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: tooltipRefreshTimer
|
||||
interval: 1000
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
if (clockMouseArea.containsMouse && !PanelService.getPanel("clockPanel", screen)?.isPanelOpen) {
|
||||
TooltipService.updateText(buildTooltipText());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user