Skip to content

Commit bd1331a

Browse files
authored
enhanced the day's details by adding key panchanga elements and refactored the code for improved efficiency. (#38)
* refactor and add panchanga components * cmake fix * adress build errors * Refactor(widget, calendar): Improve memory efficiency . #39 * Fix: day details on day cell click. improved panchanga calculations. #39 as per [comment](#39 (comment)) * compatibility fix
1 parent c0f42c7 commit bd1331a

19 files changed

+1221
-710
lines changed

CMakeLists.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ set(NEPDATE_WIDGET_SOURCES
5555
main.cpp
5656
mainwindow.cpp
5757
calendarwindow.cpp
58+
calendarlogic.cpp
59+
calendartable.cpp
60+
converter.cpp
61+
panchanga.cpp
5862
)
5963

6064
set(NEPDATE_WIDGET_HEADERS
@@ -63,6 +67,9 @@ set(NEPDATE_WIDGET_HEADERS
6367
DayTithiWidget.h
6468
panchanga.h
6569
calendarwindow.h
70+
calendarlogic.h
71+
calendartable.h
72+
converter.h
6673
)
6774

6875
set(NEPDATE_WIDGET_FORMS
@@ -86,14 +93,21 @@ set(NEPDATE_CALENDAR_SOURCES
8693
main_calendar.cpp
8794
calendarwindow.cpp
8895
mainwindow.cpp
96+
calendarlogic.cpp
97+
calendartable.cpp
98+
converter.cpp
99+
panchanga.cpp
89100
)
90101

91102
set(NEPDATE_CALENDAR_HEADERS
92103
calendarwindow.h
93104
DayTithiWidget.h
94105
bikram.h
95-
panchanga.h
96106
mainwindow.h
107+
panchanga.h
108+
calendarlogic.h
109+
calendartable.h
110+
converter.h
97111
)
98112

99113
set(NEPDATE_CALENDAR_FORMS

DayTithiWidget.h

Lines changed: 193 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,96 +4,233 @@
44
#include <QWidget>
55
#include <QLabel>
66
#include <QVBoxLayout>
7+
#include <QHBoxLayout>
78
#include <QIcon>
89
#include <QPixmap>
910
#include <QPainter>
1011
#include <QResizeEvent>
1112
#include <QFont>
1213
#include <QFontDatabase>
13-
#include <QtGlobal>
14+
#include <QMouseEvent>
15+
#include <QMessageBox>
16+
#include <QStyleOption>
17+
#include "panchanga.h"
18+
#include "bikram.h"
19+
#include <QDate>
20+
#include "calendarlogic.h"
1421

1522
class DayTithiWidget : public QWidget {
1623
Q_OBJECT
1724

1825
public:
19-
explicit DayTithiWidget(const QString &day, const QString &tithi, const QString &englishDay, QWidget *parent = nullptr)
26+
explicit DayTithiWidget(const QString &day = "", const QString &tithi = "", const QString &englishDay = "", QWidget *parent = nullptr)
2027
: QWidget(parent), dayLabelText(day), tithiLabelText(tithi), englishDayLabelText(englishDay) {
2128

22-
// Day number (centered large text)
23-
dayLabel = new QLabel(day, this);
24-
dayLabel->setObjectName("dayLabel");
25-
dayLabel->setAlignment(Qt::AlignCenter);
26-
dayLabel->setStyleSheet("color: black; background-color: transparent;");
29+
setAttribute(Qt::WA_Hover);
30+
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
31+
setMinimumSize(60, 60);
32+
33+
QVBoxLayout *mainLayout = new QVBoxLayout(this);
34+
mainLayout->setContentsMargins(4, 4, 4, 4);
35+
mainLayout->setSpacing(2);
36+
37+
QHBoxLayout *topLayout = new QHBoxLayout();
38+
topLayout->setContentsMargins(0, 0, 0, 0);
39+
topLayout->setSpacing(0);
2740

28-
// English day number (top-right, small, gray)
2941
englishDayLabel = new QLabel(englishDay, this);
30-
englishDayLabel->setObjectName("englishDayLabel");
31-
englishDayLabel->setAlignment(Qt::AlignRight | Qt::AlignTop);
3242
englishDayLabel->setStyleSheet("color:rgb(74, 32, 240); background-color: transparent;");
33-
englishDayLabel->adjustSize();
43+
englishDayLabel->setAlignment(Qt::AlignRight);
44+
topLayout->addStretch();
45+
topLayout->addWidget(englishDayLabel);
46+
47+
dayLabel = new QLabel(day, this);
48+
dayLabel->setAlignment(Qt::AlignCenter);
49+
dayLabel->setStyleSheet("color: black; background-color: transparent;");
50+
dayLabel->setMinimumSize(1, 1);
3451

35-
// Tithi label (bottom left)
3652
tithiLabel = new QLabel(tithi, this);
37-
tithiLabel->setObjectName("tithiLabel");
3853
tithiLabel->setStyleSheet("color: #2563eb; background-color: transparent;");
39-
tithiLabel->setVisible(true);
40-
tithiLabel->adjustSize();
54+
tithiLabel->setAlignment(Qt::AlignLeft);
55+
56+
mainLayout->addLayout(topLayout);
57+
mainLayout->addStretch();
58+
mainLayout->addWidget(dayLabel);
59+
mainLayout->addStretch();
60+
mainLayout->addWidget(tithiLabel);
4161

42-
// Icon label (bottom right)
4362
iconLabel = new QLabel(this);
44-
iconLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
4563
iconLabel->setStyleSheet("background-color: transparent;");
46-
iconLabel->adjustSize();
64+
iconLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
65+
66+
applyResponsiveLayout();
67+
}
68+
69+
void updateLabels(const QString &day, const QString &tithi, const QString &englishDay) {
70+
dayLabel->setText(day);
71+
tithiLabel->setText(tithi);
72+
englishDayLabel->setText(englishDay);
73+
applyResponsiveLayout();
4774
}
4875

4976
void setTodayStyle() {
5077
QFont font = dayLabel->font();
5178
font.setBold(true);
5279
dayLabel->setFont(font);
53-
dayLabel->adjustSize();
54-
int contentWidth = dayLabel->width();
55-
int contentHeight = dayLabel->height();
56-
int maxDimension = qMax(contentWidth, contentHeight);
57-
int dynamicPadding = maxDimension / 3;
58-
int finalPadding = qBound(10, dynamicPadding, 30);
59-
int circleDiameter = maxDimension + (finalPadding * 2);
60-
if (circleDiameter < 40) circleDiameter = 40;
61-
dayLabel->setFixedSize(circleDiameter, circleDiameter);
80+
6281
QString styleSheet = QString(
6382
"QLabel {"
6483
" background-color:rgb(91, 240, 156);"
6584
" color: white;"
66-
" border-radius: %1px;" // Half of the diameter for a circle
67-
" qproperty-alignment: AlignCenter;" // Center the text within the circular area
85+
" border-radius: 50px;"
86+
" qproperty-alignment: AlignCenter;"
6887
"}"
69-
).arg(circleDiameter / 2);
70-
88+
);
7189
dayLabel->setStyleSheet(styleSheet);
90+
applyResponsiveLayout();
7291
}
7392

74-
7593
void setSaturdayStyle() {
7694
dayLabel->setStyleSheet("color: red;");
95+
applyResponsiveLayout();
96+
}
97+
98+
void setNormalStyle() {
99+
dayLabel->setStyleSheet("color: black; background-color: transparent;");
100+
QFont font = dayLabel->font();
101+
font.setBold(false);
102+
dayLabel->setFont(font);
103+
applyResponsiveLayout();
104+
}
105+
106+
void setIcon(const QIcon &icon, qreal opacity = 1.0) {
107+
storedIcon = icon;
108+
storedIconOpacity = opacity;
109+
adjustIconSize();
110+
}
111+
112+
void setSelected(bool selected) {
113+
isSelected = selected;
114+
update();
115+
}
116+
117+
signals:
118+
void dayCellClicked(DayTithiWidget *cell); // use to manage global selection
119+
120+
protected:
121+
void resizeEvent(QResizeEvent *event) override {
122+
QWidget::resizeEvent(event);
123+
applyResponsiveLayout();
124+
}
125+
126+
void mousePressEvent(QMouseEvent *event) override {
127+
if (event->button() == Qt::LeftButton) {
128+
isSelected = true;
129+
update();
130+
emit dayCellClicked(this);
131+
132+
int day = property("gDay").toInt();
133+
int month = property("month").toInt();
134+
int year = property("year").toInt();
135+
136+
QDate gdate(year, month, day);
137+
Bikram bs;
138+
bs.fromGregorian(year, month, day);
139+
140+
std::tm date = {};
141+
date.tm_year = year - 1900;
142+
date.tm_mon = month - 1;
143+
date.tm_mday = day;
144+
145+
TithiResult tithi = calculateTithi(date);
146+
YogaResult yoga = calculateYoga(date);
147+
KaranResult karan = calculateKaran(date);
148+
NakshatraResult nakshatra = calculateNakshatra(date);
149+
RashiResult rashi = calculateRashi(date);
150+
QString sunrise = QString::fromStdString(calculateSunriseOrSunset(date, true));
151+
QString sunset = QString::fromStdString(calculateSunriseOrSunset(date, false));
152+
153+
QString details = QString(
154+
"Gregorian: %1\n"
155+
"Bikram: %2-%3-%4\n"
156+
"Tithi: %5\n"
157+
"Paksha: %6\n"
158+
"Yoga: %7\n"
159+
"Karana: %8\n"
160+
"Nakshatra: %9\n"
161+
"Rashi: %10\n"
162+
"Sunrise: %11\n"
163+
"Sunset: %12")
164+
.arg(gdate.toString("yyyy-MM-dd"))
165+
.arg(convertToNepaliNumerals(bs.getYear()))
166+
.arg(convertToNepaliNumerals(bs.getMonth()))
167+
.arg(convertToNepaliNumerals(bs.getDay()))
168+
.arg(QString::fromStdString(tithi.tithiName))
169+
.arg(QString::fromStdString(tithi.paksha))
170+
.arg(QString::fromStdString(yoga.yogaName))
171+
.arg(QString::fromStdString(karan.karanName))
172+
.arg(QString::fromStdString(nakshatra.nakshatraName))
173+
.arg(QString::fromStdString(rashi.rashiName))
174+
.arg(sunrise)
175+
.arg(sunset);
176+
177+
QMessageBox::information(this, tr("Day Details"), details);
178+
}
179+
QWidget::mousePressEvent(event);
180+
}
181+
182+
bool event(QEvent *event) override {
183+
if (event->type() == QEvent::Enter) {
184+
isHovered = true;
185+
update();
186+
} else if (event->type() == QEvent::Leave) {
187+
isHovered = false;
188+
update();
189+
}
190+
return QWidget::event(event);
191+
}
192+
193+
void paintEvent(QPaintEvent *event) override {
194+
Q_UNUSED(event);
195+
QPainter painter(this);
196+
QColor bgColor = Qt::white;
197+
198+
if (isSelected) {
199+
bgColor = QColor("#bfdbfe"); // light blue
200+
} else if (isHovered) {
201+
bgColor = QColor("#d1fae5"); // light green
202+
}
203+
204+
painter.fillRect(rect(), bgColor);
205+
206+
QStyleOption opt;
207+
opt.initFrom(this);
208+
style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
77209
}
78210

79211
private:
80212
QLabel *dayLabel;
81213
QLabel *tithiLabel;
82214
QLabel *iconLabel;
83215
QLabel *englishDayLabel;
216+
84217
QString dayLabelText;
85218
QString tithiLabelText;
86219
QString englishDayLabelText;
220+
87221
QSize iconSize = QSize(24, 24);
88222
QIcon storedIcon;
89223
qreal storedIconOpacity = 1.0;
224+
225+
bool isHovered = false;
226+
bool isSelected = false;
227+
90228
void adjustIconSize() {
91229
int minSize = qMin(width(), height()) / 4;
92230
iconSize = QSize(minSize + 18, minSize + 18);
93231
iconLabel->setFixedSize(iconSize);
94232
iconLabel->setScaledContents(true);
95233
iconLabel->move(width() - iconSize.width() - 4, height() - iconSize.height() - 4);
96-
// Always re-render from original icon for sharpness
97234
if (!storedIcon.isNull()) {
98235
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
99236
QPixmap pixmap = storedIcon.pixmap(iconSize);
@@ -109,45 +246,43 @@ class DayTithiWidget : public QWidget {
109246
iconLabel->setPixmap(transparentPixmap);
110247
}
111248
}
112-
public:
113-
void setIcon(const QIcon &icon, qreal opacity = 1.0) {
114-
storedIcon = icon;
115-
storedIconOpacity = opacity;
116-
adjustIconSize();
117-
}
118249

119-
protected:
120-
void resizeEvent(QResizeEvent *event) override {
121-
QWidget::resizeEvent(event);
250+
void applyResponsiveLayout() {
122251
int w = width();
123252
int h = height();
124253
int minDim = qMin(w, h);
254+
125255
int dayFontSize = std::max(12, static_cast<int>(minDim * 0.14));
126256
int tithiFontSize = std::max(8, static_cast<int>(minDim * 0.05));
127257
int englishDayFontSize = std::max(8, static_cast<int>(minDim * 0.05));
128-
int fontId = QFontDatabase::addApplicationFont(":/resources/NotoSansDevanagari-VariableFont_wdth,wght.ttf");
129-
QString fontFamily = QFontDatabase::applicationFontFamilies(fontId).at(0);
130-
QFont dayFont = dayLabel->font();
131-
dayFont.setPointSize(dayFontSize);
258+
259+
static QString fontFamily;
260+
if (fontFamily.isEmpty()) {
261+
int fontId = QFontDatabase::addApplicationFont(":/resources/NotoSansDevanagari-VariableFont_wdth,wght.ttf");
262+
fontFamily = QFontDatabase::applicationFontFamilies(fontId).value(0, "Noto Sans");
263+
}
264+
265+
QFont dayFont;
132266
dayFont.setFamily(fontFamily);
133-
dayFont.setBold(false);
267+
dayFont.setPointSize(dayFontSize);
268+
dayFont.setBold(dayLabel->font().bold());
134269
dayLabel->setFont(dayFont);
135-
QFont tithiFont = tithiLabel->font();
270+
271+
QFont tithiFont;
136272
tithiFont.setPointSize(tithiFontSize);
137273
tithiFont.setItalic(true);
138274
tithiLabel->setFont(tithiFont);
139-
QFont englishDayFont = englishDayLabel->font();
140-
englishDayFont.setPointSize(englishDayFontSize);
141-
englishDayLabel->setFont(englishDayFont);
142-
// Position labels without adjustSize/repaint
143-
int dayX = 20;
144-
int dayY = (h / 3) - (dayLabel->height() / 2);
145-
dayLabel->move(dayX, dayY);
146-
englishDayLabel->move(width() - englishDayLabel->width() - 6, 6);
147-
tithiLabel->move(6, h - tithiLabel->height() - 6);
275+
276+
QFont englishFont;
277+
englishFont.setPointSize(englishDayFontSize);
278+
englishDayLabel->setFont(englishFont);
279+
280+
dayLabel->adjustSize();
281+
tithiLabel->adjustSize();
282+
englishDayLabel->adjustSize();
283+
148284
adjustIconSize();
149285
}
150-
151286
};
152287

153288
#endif // DAYTITHIWIDGET_H

0 commit comments

Comments
 (0)