Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ set(NEPDATE_WIDGET_SOURCES
main.cpp
mainwindow.cpp
calendarwindow.cpp
calendarlogic.cpp
calendartable.cpp
converter.cpp
panchanga.cpp
)

set(NEPDATE_WIDGET_HEADERS
Expand All @@ -63,6 +67,9 @@ set(NEPDATE_WIDGET_HEADERS
DayTithiWidget.h
panchanga.h
calendarwindow.h
calendarlogic.h
calendartable.h
converter.h
)

set(NEPDATE_WIDGET_FORMS
Expand All @@ -86,14 +93,21 @@ set(NEPDATE_CALENDAR_SOURCES
main_calendar.cpp
calendarwindow.cpp
mainwindow.cpp
calendarlogic.cpp
calendartable.cpp
converter.cpp
panchanga.cpp
)

set(NEPDATE_CALENDAR_HEADERS
calendarwindow.h
DayTithiWidget.h
bikram.h
panchanga.h
mainwindow.h
panchanga.h
calendarlogic.h
calendartable.h
converter.h
)

set(NEPDATE_CALENDAR_FORMS
Expand Down
251 changes: 193 additions & 58 deletions DayTithiWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,96 +4,233 @@
#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QIcon>
#include <QPixmap>
#include <QPainter>
#include <QResizeEvent>
#include <QFont>
#include <QFontDatabase>
#include <QtGlobal>
#include <QMouseEvent>
#include <QMessageBox>
#include <QStyleOption>
#include "panchanga.h"
#include "bikram.h"
#include <QDate>
#include "calendarlogic.h"

class DayTithiWidget : public QWidget {
Q_OBJECT

public:
explicit DayTithiWidget(const QString &day, const QString &tithi, const QString &englishDay, QWidget *parent = nullptr)
explicit DayTithiWidget(const QString &day = "", const QString &tithi = "", const QString &englishDay = "", QWidget *parent = nullptr)
: QWidget(parent), dayLabelText(day), tithiLabelText(tithi), englishDayLabelText(englishDay) {

// Day number (centered large text)
dayLabel = new QLabel(day, this);
dayLabel->setObjectName("dayLabel");
dayLabel->setAlignment(Qt::AlignCenter);
dayLabel->setStyleSheet("color: black; background-color: transparent;");
setAttribute(Qt::WA_Hover);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
setMinimumSize(60, 60);

QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(4, 4, 4, 4);
mainLayout->setSpacing(2);

QHBoxLayout *topLayout = new QHBoxLayout();
topLayout->setContentsMargins(0, 0, 0, 0);
topLayout->setSpacing(0);

// English day number (top-right, small, gray)
englishDayLabel = new QLabel(englishDay, this);
englishDayLabel->setObjectName("englishDayLabel");
englishDayLabel->setAlignment(Qt::AlignRight | Qt::AlignTop);
englishDayLabel->setStyleSheet("color:rgb(74, 32, 240); background-color: transparent;");
englishDayLabel->adjustSize();
englishDayLabel->setAlignment(Qt::AlignRight);
topLayout->addStretch();
topLayout->addWidget(englishDayLabel);

dayLabel = new QLabel(day, this);
dayLabel->setAlignment(Qt::AlignCenter);
dayLabel->setStyleSheet("color: black; background-color: transparent;");
dayLabel->setMinimumSize(1, 1);

// Tithi label (bottom left)
tithiLabel = new QLabel(tithi, this);
tithiLabel->setObjectName("tithiLabel");
tithiLabel->setStyleSheet("color: #2563eb; background-color: transparent;");
tithiLabel->setVisible(true);
tithiLabel->adjustSize();
tithiLabel->setAlignment(Qt::AlignLeft);

mainLayout->addLayout(topLayout);
mainLayout->addStretch();
mainLayout->addWidget(dayLabel);
mainLayout->addStretch();
mainLayout->addWidget(tithiLabel);

// Icon label (bottom right)
iconLabel = new QLabel(this);
iconLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
iconLabel->setStyleSheet("background-color: transparent;");
iconLabel->adjustSize();
iconLabel->setAttribute(Qt::WA_TransparentForMouseEvents);

applyResponsiveLayout();
}

void updateLabels(const QString &day, const QString &tithi, const QString &englishDay) {
dayLabel->setText(day);
tithiLabel->setText(tithi);
englishDayLabel->setText(englishDay);
applyResponsiveLayout();
}

void setTodayStyle() {
QFont font = dayLabel->font();
font.setBold(true);
dayLabel->setFont(font);
dayLabel->adjustSize();
int contentWidth = dayLabel->width();
int contentHeight = dayLabel->height();
int maxDimension = qMax(contentWidth, contentHeight);
int dynamicPadding = maxDimension / 3;
int finalPadding = qBound(10, dynamicPadding, 30);
int circleDiameter = maxDimension + (finalPadding * 2);
if (circleDiameter < 40) circleDiameter = 40;
dayLabel->setFixedSize(circleDiameter, circleDiameter);

QString styleSheet = QString(
"QLabel {"
" background-color:rgb(91, 240, 156);"
" color: white;"
" border-radius: %1px;" // Half of the diameter for a circle
" qproperty-alignment: AlignCenter;" // Center the text within the circular area
" border-radius: 50px;"
" qproperty-alignment: AlignCenter;"
"}"
).arg(circleDiameter / 2);

);
dayLabel->setStyleSheet(styleSheet);
applyResponsiveLayout();
}


void setSaturdayStyle() {
dayLabel->setStyleSheet("color: red;");
applyResponsiveLayout();
}

void setNormalStyle() {
dayLabel->setStyleSheet("color: black; background-color: transparent;");
QFont font = dayLabel->font();
font.setBold(false);
dayLabel->setFont(font);
applyResponsiveLayout();
}

void setIcon(const QIcon &icon, qreal opacity = 1.0) {
storedIcon = icon;
storedIconOpacity = opacity;
adjustIconSize();
}

void setSelected(bool selected) {
isSelected = selected;
update();
}

signals:
void dayCellClicked(DayTithiWidget *cell); // use to manage global selection

protected:
void resizeEvent(QResizeEvent *event) override {
QWidget::resizeEvent(event);
applyResponsiveLayout();
}

void mousePressEvent(QMouseEvent *event) override {
if (event->button() == Qt::LeftButton) {
isSelected = true;
update();
emit dayCellClicked(this);

int day = property("gDay").toInt();
int month = property("month").toInt();
int year = property("year").toInt();

QDate gdate(year, month, day);
Bikram bs;
bs.fromGregorian(year, month, day);

std::tm date = {};
date.tm_year = year - 1900;
date.tm_mon = month - 1;
date.tm_mday = day;

TithiResult tithi = calculateTithi(date);
YogaResult yoga = calculateYoga(date);
KaranResult karan = calculateKaran(date);
NakshatraResult nakshatra = calculateNakshatra(date);
RashiResult rashi = calculateRashi(date);
QString sunrise = QString::fromStdString(calculateSunriseOrSunset(date, true));
QString sunset = QString::fromStdString(calculateSunriseOrSunset(date, false));

QString details = QString(
"Gregorian: %1\n"
"Bikram: %2-%3-%4\n"
"Tithi: %5\n"
"Paksha: %6\n"
"Yoga: %7\n"
"Karana: %8\n"
"Nakshatra: %9\n"
"Rashi: %10\n"
"Sunrise: %11\n"
"Sunset: %12")
.arg(gdate.toString("yyyy-MM-dd"))
.arg(convertToNepaliNumerals(bs.getYear()))
.arg(convertToNepaliNumerals(bs.getMonth()))
.arg(convertToNepaliNumerals(bs.getDay()))
.arg(QString::fromStdString(tithi.tithiName))
.arg(QString::fromStdString(tithi.paksha))
.arg(QString::fromStdString(yoga.yogaName))
.arg(QString::fromStdString(karan.karanName))
.arg(QString::fromStdString(nakshatra.nakshatraName))
.arg(QString::fromStdString(rashi.rashiName))
.arg(sunrise)
.arg(sunset);

QMessageBox::information(this, tr("Day Details"), details);
}
QWidget::mousePressEvent(event);
}

bool event(QEvent *event) override {
if (event->type() == QEvent::Enter) {
isHovered = true;
update();
} else if (event->type() == QEvent::Leave) {
isHovered = false;
update();
}
return QWidget::event(event);
}

void paintEvent(QPaintEvent *event) override {
Q_UNUSED(event);
QPainter painter(this);
QColor bgColor = Qt::white;

if (isSelected) {
bgColor = QColor("#bfdbfe"); // light blue
} else if (isHovered) {
bgColor = QColor("#d1fae5"); // light green
}

painter.fillRect(rect(), bgColor);

QStyleOption opt;
opt.initFrom(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
}

private:
QLabel *dayLabel;
QLabel *tithiLabel;
QLabel *iconLabel;
QLabel *englishDayLabel;

QString dayLabelText;
QString tithiLabelText;
QString englishDayLabelText;

QSize iconSize = QSize(24, 24);
QIcon storedIcon;
qreal storedIconOpacity = 1.0;

bool isHovered = false;
bool isSelected = false;

void adjustIconSize() {
int minSize = qMin(width(), height()) / 4;
iconSize = QSize(minSize + 18, minSize + 18);
iconLabel->setFixedSize(iconSize);
iconLabel->setScaledContents(true);
iconLabel->move(width() - iconSize.width() - 4, height() - iconSize.height() - 4);
// Always re-render from original icon for sharpness
if (!storedIcon.isNull()) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QPixmap pixmap = storedIcon.pixmap(iconSize);
Expand All @@ -109,45 +246,43 @@ class DayTithiWidget : public QWidget {
iconLabel->setPixmap(transparentPixmap);
}
}
public:
void setIcon(const QIcon &icon, qreal opacity = 1.0) {
storedIcon = icon;
storedIconOpacity = opacity;
adjustIconSize();
}

protected:
void resizeEvent(QResizeEvent *event) override {
QWidget::resizeEvent(event);
void applyResponsiveLayout() {
int w = width();
int h = height();
int minDim = qMin(w, h);

int dayFontSize = std::max(12, static_cast<int>(minDim * 0.14));
int tithiFontSize = std::max(8, static_cast<int>(minDim * 0.05));
int englishDayFontSize = std::max(8, static_cast<int>(minDim * 0.05));
int fontId = QFontDatabase::addApplicationFont(":/resources/NotoSansDevanagari-VariableFont_wdth,wght.ttf");
QString fontFamily = QFontDatabase::applicationFontFamilies(fontId).at(0);
QFont dayFont = dayLabel->font();
dayFont.setPointSize(dayFontSize);

static QString fontFamily;
if (fontFamily.isEmpty()) {
int fontId = QFontDatabase::addApplicationFont(":/resources/NotoSansDevanagari-VariableFont_wdth,wght.ttf");
fontFamily = QFontDatabase::applicationFontFamilies(fontId).value(0, "Noto Sans");
}

QFont dayFont;
dayFont.setFamily(fontFamily);
dayFont.setBold(false);
dayFont.setPointSize(dayFontSize);
dayFont.setBold(dayLabel->font().bold());
dayLabel->setFont(dayFont);
QFont tithiFont = tithiLabel->font();

QFont tithiFont;
tithiFont.setPointSize(tithiFontSize);
tithiFont.setItalic(true);
tithiLabel->setFont(tithiFont);
QFont englishDayFont = englishDayLabel->font();
englishDayFont.setPointSize(englishDayFontSize);
englishDayLabel->setFont(englishDayFont);
// Position labels without adjustSize/repaint
int dayX = 20;
int dayY = (h / 3) - (dayLabel->height() / 2);
dayLabel->move(dayX, dayY);
englishDayLabel->move(width() - englishDayLabel->width() - 6, 6);
tithiLabel->move(6, h - tithiLabel->height() - 6);

QFont englishFont;
englishFont.setPointSize(englishDayFontSize);
englishDayLabel->setFont(englishFont);

dayLabel->adjustSize();
tithiLabel->adjustSize();
englishDayLabel->adjustSize();

adjustIconSize();
}

};

#endif // DAYTITHIWIDGET_H
Loading