diff --git a/qml/CalendarGrid.qml b/qml/CalendarGrid.qml index 75c19f9..6d9cbc1 100644 --- a/qml/CalendarGrid.qml +++ b/qml/CalendarGrid.qml @@ -7,8 +7,8 @@ import "qrc:/qml/" GridLayout { id: calendarGrid columns: 7 - rowSpacing: 8 - columnSpacing: 8 + rowSpacing: 0 + columnSpacing: 0 Layout.fillWidth: true Layout.fillHeight: true Layout.margins: 20 @@ -26,13 +26,10 @@ GridLayout { Layout.fillHeight: modelData.type === "day" || modelData.type === "empty" Layout.preferredHeight: modelData.type === "header" ? 35 : -1 - // Use a Loader to conditionally instantiate the correct component. - // This is the key to fixing the "Unable to assign [undefined]" errors. Loader { id: delegateLoader anchors.fill: parent - // Set the source component based on the model data type sourceComponent: { if (modelData.type === "header") { return headerComponent; @@ -43,7 +40,6 @@ GridLayout { } } - // After the correct component is loaded, set its specific properties. onLoaded: { if (modelData.type === "day") { item.bsDay = modelData.bsDay; @@ -52,53 +48,104 @@ GridLayout { item.isToday = modelData.isToday; item.isSaturday = modelData.isSaturday; item.theme = calendarGrid.theme; - // Connect the signal from the loaded DayCell to the CalendarGrid's signal item.clicked.connect(function() { calendarGrid.dayClicked(modelData.panchanga) }); } else if (modelData.type === "header") { item.text = modelData.text; item.theme = calendarGrid.theme; + item.cellIndex = index; } } } } } - // --- Component Definitions for the Loader --- Component { id: headerComponent - Rectangle { - // These properties are set by the Loader + Item { + id: headerItemContainer property string text property var theme + property int cellIndex: -1 + + Rectangle { + id: headerBackground + anchors.fill: parent + radius: (cellIndex === 0 || cellIndex === 6) ? 6 : 0 + color: theme ? theme.secondaryBg : "#FFFFFF" + border.color: theme.borderColor + } - radius: 8 - color: theme && theme.isDark ? theme.secondaryBg : (theme ? theme.tertiaryBg : "lightgrey") - border.width: 0 + Rectangle { + visible: cellIndex === 0 + width: headerBackground.radius + height: headerBackground.radius + color: headerBackground.color + anchors.top: parent.top + anchors.right: parent.right + } + Rectangle { + visible: cellIndex === 0 + width: headerBackground.radius + height: headerBackground.radius + color: headerBackground.color + anchors.bottom: parent.bottom + anchors.left: parent.left + } + Rectangle { + visible: cellIndex === 6 + width: headerBackground.radius + height: headerBackground.radius + color: headerBackground.color + anchors.top: parent.top + anchors.left: parent.left + } + Rectangle { + visible: cellIndex === 6 + width: headerBackground.radius + height: headerBackground.radius + color: headerBackground.color + anchors.bottom: parent.bottom + anchors.left: parent.left + } + Rectangle { + visible: cellIndex === 0 || cellIndex === 6 + width: headerBackground.radius + height: headerBackground.radius + color: headerBackground.color + anchors.bottom: parent.bottom + anchors.right: parent.right + } Label { - text: parent.text - color: theme && theme.isDark ? theme.secondaryText : (theme ? theme.accentText : "blue") + text: headerItemContainer.text + color: { + if (cellIndex === 6) { + return "#E4080A" + } else { + return theme.accentText; + } + } font.bold: true - font.pixelSize: 12 - anchors.fill: parent - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter + font.pixelSize: 14 + anchors.centerIn: parent } } } Component { id: dayComponent - // The DayCell itself. Its properties will be set by the Loader's onLoaded handler. DayCell {} } Component { id: emptyComponent - // An empty item for the blank days at the start of the month. - Item {} + Rectangle { + border.color: theme ? theme.borderColor : "grey" + border.width: 1 + color: "transparent" + } } } diff --git a/qml/DayCell.qml b/qml/DayCell.qml index 7e808ea..af2e323 100644 --- a/qml/DayCell.qml +++ b/qml/DayCell.qml @@ -6,13 +6,7 @@ import "qrc:/qml/" // DayCell.qml Rectangle { id: dayCell - radius: 12 - scale: cellMouseArea.containsMouse ? 1.2 : 1.0 - z: cellMouseArea.containsMouse ? 1 : 0 - Behavior on scale { - NumberAnimation { duration: 150; easing.type: Easing.InOutQuad } - } - + radius: 5 property int bsDay: 0 property int adDay: 0 property string tithi: "" @@ -42,6 +36,11 @@ Rectangle { text: Panchanga.toDevanagari(bsDay || 0) font.bold: true font.pixelSize: cellMouseArea.containsMouse ? 28 : 25 + scale: cellMouseArea.containsMouse ? 1.2 : 1.0 + z: cellMouseArea.containsMouse ? 1 : 0 + Behavior on scale { + NumberAnimation { duration: 150; easing.type: Easing.InOutQuad } + } color: { if (!theme) return "black"; if (isToday) return theme.accentText; diff --git a/qml/PanchangaDetailDialog.qml b/qml/PanchangaDetailDialog.qml index b53fe0c..9573ea6 100644 --- a/qml/PanchangaDetailDialog.qml +++ b/qml/PanchangaDetailDialog.qml @@ -212,6 +212,7 @@ Dialog { onClosed: { clearPanchangaDetails(); + Panchanga.clearCache(); debugVisible = false; } diff --git a/qml/Settings.qml b/qml/Settings.qml index 3d85343..87e85a7 100644 --- a/qml/Settings.qml +++ b/qml/Settings.qml @@ -275,26 +275,6 @@ ApplicationWindow { } } - // New Calendar Button (visible only on Wayland) - Button { - id: calendarButton - Layout.fillWidth: true - text: "Open Calendar" - // Access the global 'platformName' context property directly - visible: platformName === "wayland" - - onClicked: { - openCalendar(); - } - - background: Rectangle { color: "#555"; radius: 3; } - contentItem: Text { - text: parent.text; color: "lightgreen"; font.pointSize: 12 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - } - } - Button { text: "Exit Widget" Layout.fillWidth: true @@ -352,31 +332,6 @@ ApplicationWindow { resetTimer.start(); } - // Function to show the calendar - function openCalendar() { - if (calendarWindow) { - calendarWindow.show(); - calendarWindow.raise(); - calendarWindow.requestActivate(); - return; - } - if (!calendarComponent) { - calendarComponent = Qt.createComponent("main.qml"); - } - if (calendarComponent.status === Component.Ready) { - calendarWindow = calendarComponent.createObject(widgetWindow); - if (calendarWindow) { - calendarWindow.closing.connect(() => { - Panchanga.clearCache(); - calendarWindow.destroy(); - calendarWindow = null; - }); - calendarWindow.show(); - } else { console.error("Failed to create calendar window."); } - } else { console.error("Error loading component:", calendarComponent.errorString()); } - } - - // Window Closing Handler onClosing: { resetTimer.stop(); diff --git a/qml/Theme.qml b/qml/Theme.qml index 2d7e30c..f480933 100644 --- a/qml/Theme.qml +++ b/qml/Theme.qml @@ -34,11 +34,11 @@ QtObject { // === Borders === readonly property color borderColor: isDark ? "#334155" : "#e2e8f0" readonly property color todayBorder: isDark ? "#0ea5e9" : "#0284c7" - readonly property color saturdayBorder: isDark ? "#fb7185" : "#fda4af" + readonly property color saturdayBorder: isDark ? "#334155" : "#fda4af" // === Highlighted Days === readonly property color todayBg: isDark ? "#082f49" : "#f0f9ff" - readonly property color saturdayBg: isDark ? "#831843" : "#FEDDDF" + readonly property color saturdayBg: isDark ? "#6E3233" : "#FEDDDF" readonly property color adDayText: isDark ? "#BBCFFA" : "#6E9BFD" // === Modal / Dialogs === diff --git a/qml/widget.qml b/qml/widget.qml index 8079155..ba4df6e 100644 --- a/qml/widget.qml +++ b/qml/widget.qml @@ -100,69 +100,95 @@ ApplicationWindow { acceptedButtons: Qt.LeftButton | Qt.RightButton hoverEnabled: true + // Drag state + property bool isPressed: false + property bool dragStarted: false + property bool wasDragged: false + property point pressPos: Qt.point(0, 0) property int dragStartX: 0 property int dragStartY: 0 property int windowStartX: 0 property int windowStartY: 0 - property bool wasDragged: false - - Timer { - id: resetDragTimer - interval: 300 - repeat: false - onTriggered: dragArea.wasDragged = false - } + property int dragThreshold: 8 // pixels + // Tooltip logic Timer { id: tooltipTimer interval: 500 repeat: false onTriggered: showTooltip() } - - onEntered: tooltipTimer.start() - onExited: { + // Ignore wayland for tooltip now. (REASON: tooltip position is over widget in buttom side of screen) + onEntered: if (platformName !== "wayland") { + tooltipTimer.start() + } + onExited: { if (platformName !== "wayland") { tooltipTimer.stop() hideTooltip() + } + } + + // Drag reset timer + Timer { + id: resetDragTimer + interval: 300 + repeat: false + onTriggered: dragArea.wasDragged = false } Item { id: globalMapper; anchors.fill: parent; visible: false } onPressed: function(mouse) { if (mouse.button === Qt.LeftButton) { - wasDragged = false; - if (platformName === "wayland") { - widgetWindow.startSystemMove() - wasDragged = true; // Assume a drag will happen - } else { // X11 and other platforms - // Use the direct screen coordinates from the mouse event for reliability. - var globalPos = globalMapper.mapToGlobal(Qt.point(mouse.x, mouse.y)) - dragStartX = globalPos.x - dragStartY = globalPos.y - windowStartX = widgetWindow.x - windowStartY = widgetWindow.y - + isPressed = true + dragStarted = false + wasDragged = false + pressPos = Qt.point(mouse.x, mouse.y) + + if (platformName !== "wayland") { + var globalPos = globalMapper.mapToGlobal(pressPos) + dragStartX = globalPos.x + dragStartY = globalPos.y + windowStartX = widgetWindow.x + windowStartY = widgetWindow.y } } } onPositionChanged: function(mouse) { - if (platformName !== "wayland" && (mouse.buttons & Qt.LeftButton)) { - var globalPos = globalMapper.mapToGlobal(Qt.point(mouse.x, mouse.y)) - widgetWindow.x = windowStartX + (globalPos.x - dragStartX) - widgetWindow.y = windowStartY + (globalPos.y - dragStartY) + if (!isPressed) + return + var dx = mouse.x - pressPos.x + var dy = mouse.y - pressPos.y + var distance = Math.sqrt(dx * dx + dy * dy) + + if (!dragStarted && distance > dragThreshold) { + dragStarted = true wasDragged = true + + if (platformName === "wayland") { + widgetWindow.startSystemMove() + } + } + + if (dragStarted && platformName !== "wayland") { + var globalPos = globalMapper.mapToGlobal(Qt.point(mouse.x, mouse.y)) + widgetWindow.x = windowStartX + (globalPos.x - dragStartX) + widgetWindow.y = windowStartY + (globalPos.y - dragStartY) resetDragTimer.stop() } } onReleased: function(mouse) { - if (mouse.button === Qt.LeftButton && wasDragged) { - if (mouse.button === Qt.LeftButton && wasDragged) { - appSettings.setValue("widgetPositionX", widgetWindow.x) - appSettings.setValue("widgetPositionY", widgetWindow.y) - resetDragTimer.start() + if (mouse.button === Qt.LeftButton) { + isPressed = false + dragStarted = false + + if (wasDragged) { + appSettings.setValue("widgetPositionX", widgetWindow.x) + appSettings.setValue("widgetPositionY", widgetWindow.y) + resetDragTimer.start() } } } diff --git a/tooltipmanager.cpp b/tooltipmanager.cpp index 98a9e12..21f84c3 100644 --- a/tooltipmanager.cpp +++ b/tooltipmanager.cpp @@ -1,15 +1,31 @@ #include "tooltipmanager.h" #include #include -#include +#include #include #include +#include +#include TooltipManager::TooltipManager(QObject *parent) : QObject(parent) {} void TooltipManager::showText(const QPoint &pos, const QString &text) { - QToolTip::showText(pos, text); + QQuickWindow *window = qobject_cast(QGuiApplication::focusWindow()); + if (!window) return; + QQuickItem *tooltipItem = new QQuickItem(window->contentItem()); + tooltipItem->setParentItem(window->contentItem()); + tooltipItem->setWidth(200); + tooltipItem->setHeight(50); + + QQuickItem *textItem = new QQuickItem(tooltipItem); + textItem->setParentItem(tooltipItem); + textItem->setWidth(tooltipItem->width()); + textItem->setHeight(tooltipItem->height()); + textItem->setProperty("text", text); + tooltipItem->setPosition(pos); + tooltipItem->setParentItem(window->contentItem()); + tooltipItem->setProperty("transientParent", QVariant::fromValue(window)); } void TooltipManager::hide()