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> 
1414#include  < QMouseEvent> 
1515#include  < QMessageBox> 
16+ #include  < QStyleOption> 
17+ #include  " panchanga.h" 
1618#include  " bikram.h" 
1719#include  < QDate> 
1820#include  " calendarlogic.h" 
19- #include  " panchanga.h" 
2021
2122class  DayTithiWidget  : public  QWidget  {
2223    Q_OBJECT
2324
2425public: 
25-     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 =  " " nullptr )
2627        : QWidget(parent), dayLabelText(day), tithiLabelText(tithi), englishDayLabelText(englishDay) {
2728
28-         //  Day number (centered large text)
29-         dayLabel = new  QLabel (day, this );
30-         dayLabel->setObjectName (" dayLabel" 
31-         dayLabel->setAlignment (Qt::AlignCenter);
32-         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 );
3340
34-         //  English day number (top-right, small, gray)
3541        englishDayLabel = new  QLabel (englishDay, this );
36-         englishDayLabel->setObjectName (" englishDayLabel" 
37-         englishDayLabel->setAlignment (Qt::AlignRight | Qt::AlignTop);
3842        englishDayLabel->setStyleSheet (" color:rgb(74, 32, 240); background-color: transparent;" 
39-         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 );
4051
41-         //  Tithi label (bottom left)
4252        tithiLabel = new  QLabel (tithi, this );
43-         tithiLabel->setObjectName (" tithiLabel" 
4453        tithiLabel->setStyleSheet (" color: #2563eb; background-color: transparent;" 
45-         tithiLabel->setVisible (true );
46-         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);
4761
48-         //  Icon label (bottom right)
4962        iconLabel = new  QLabel (this );
50-         iconLabel->setAttribute (Qt::WA_TransparentForMouseEvents);
5163        iconLabel->setStyleSheet (" background-color: transparent;" 
52-         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 ();
5374    }
5475
5576    void  setTodayStyle () {
5677        QFont font = dayLabel->font ();
5778        font.setBold (true );
5879        dayLabel->setFont (font);
59-         dayLabel->adjustSize ();
60-         int  contentWidth = dayLabel->width ();
61-         int  contentHeight = dayLabel->height ();
62-         int  maxDimension = qMax (contentWidth, contentHeight);
63-         int  dynamicPadding = maxDimension / 3 ;
64-         int  finalPadding = qBound (10 , dynamicPadding, 30 );
65-         int  circleDiameter = maxDimension + (finalPadding * 2 );
66-         if  (circleDiameter < 40 ) circleDiameter = 40 ;
67-         dayLabel->setFixedSize (circleDiameter, circleDiameter);
80+ 
6881        QString styleSheet = QString (
6982            " QLabel {" 
7083            "    background-color:rgb(91, 240, 156);" 
7184            "    color: white;" 
72-             "    border-radius: %1px; "   //  Half of the diameter for a circle 
73-             "    qproperty-alignment: AlignCenter;"   //  Center the text within the circular area 
85+             "    border-radius: 50px; " 
86+             "    qproperty-alignment: AlignCenter;" 
7487            " }" 
75-         ).arg (circleDiameter / 2 );
76- 
88+         );
7789        dayLabel->setStyleSheet (styleSheet);
90+         applyResponsiveLayout ();
7891    }
7992
80- 
8193    void  setSaturdayStyle () {
8294        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" 
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.init (this );
208+         style ()->drawPrimitive (QStyle::PE_Widget, &opt, &painter, this );
83209    }
84210
85211private: 
86212    QLabel *dayLabel;
87213    QLabel *tithiLabel;
88214    QLabel *iconLabel;
89215    QLabel *englishDayLabel;
216+ 
90217    QString dayLabelText;
91218    QString tithiLabelText;
92219    QString englishDayLabelText;
220+ 
93221    QSize iconSize = QSize(24 , 24 );
94222    QIcon storedIcon;
95223    qreal storedIconOpacity = 1.0 ;
224+ 
225+     bool  isHovered = false ;
226+     bool  isSelected = false ;
227+ 
96228    void  adjustIconSize () {
97229        int  minSize = qMin (width (), height ()) / 4 ;
98230        iconSize = QSize (minSize + 18 , minSize + 18 );
99231        iconLabel->setFixedSize (iconSize);
100232        iconLabel->setScaledContents (true );
101233        iconLabel->move (width () - iconSize.width () - 4 , height () - iconSize.height () - 4 );
102-         //  Always re-render from original icon for sharpness
103234        if  (!storedIcon.isNull ()) {
104235#if  QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
105236            QPixmap pixmap = storedIcon.pixmap (iconSize);
@@ -115,95 +246,43 @@ class DayTithiWidget : public QWidget {
115246            iconLabel->setPixmap (transparentPixmap);
116247        }
117248    }
118- public: 
119-     void  setIcon (const  QIcon &icon, qreal opacity = 1.0 ) {
120-         storedIcon = icon;
121-         storedIconOpacity = opacity;
122-         adjustIconSize ();
123-     }
124249
125- protected: 
126-     void  resizeEvent (QResizeEvent *event) override  {
127-         QWidget::resizeEvent (event);
250+     void  applyResponsiveLayout () {
128251        int  w = width ();
129252        int  h = height ();
130253        int  minDim = qMin (w, h);
254+ 
131255        int  dayFontSize = std::max (12 , static_cast <int >(minDim * 0.14 ));
132256        int  tithiFontSize = std::max (8 , static_cast <int >(minDim * 0.05 ));
133257        int  englishDayFontSize = std::max (8 , static_cast <int >(minDim * 0.05 ));
134-         QString notoFamily = " Noto Sans Devanagari" 
135258
136-         //  Register font if it's not available
137-         if  (!QFontDatabase ().families ().contains (notoFamily)) {
138-             QFontDatabase::addApplicationFont (" :/resources/NotoSansDevanagari-VariableFont_wdth,wght.ttf" 
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" 
139263        }
140264
141-         //  Set label font
142-         QFont labelFont = dayLabel->font ();
143-         labelFont.setPointSize (dayFontSize);
144-         labelFont.setFamily (notoFamily);
145-         labelFont.setBold (false );
146-         dayLabel->setFont (labelFont);
265+         QFont dayFont;
266+         dayFont.setFamily (fontFamily);
267+         dayFont.setPointSize (dayFontSize);
268+         dayFont.setBold (dayLabel->font ().bold ());
269+         dayLabel->setFont (dayFont);
147270
148-         QFont tithiFont = tithiLabel-> font () ;
271+         QFont tithiFont;
149272        tithiFont.setPointSize (tithiFontSize);
150273        tithiFont.setItalic (true );
151274        tithiLabel->setFont (tithiFont);
152-         QFont englishDayFont = englishDayLabel-> font (); 
153-         englishDayFont. setPointSize (englishDayFontSize) ;
154-         englishDayLabel-> setFont (englishDayFont );
155-         //  Position labels without adjustSize/repaint 
156-          int  dayX =  20 ; 
157-         int  dayY = (h /  3 ) - ( dayLabel->height () /  2 );
158-         dayLabel-> move (dayX, dayY );
159-         englishDayLabel->move ( width () - englishDayLabel-> width () -  6 ,  6 );
160-         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+ 
161284        adjustIconSize ();
162285    }
163-     void  mousePressEvent (QMouseEvent *event) override  {
164-         if  (event->button () == Qt::LeftButton) {
165-             int  day = property (" gDay" toInt (); //  Use actual Gregorian day
166-             int  month = property (" month" toInt ();
167-             int  year = property (" year" toInt ();
168-             //  Gregorian date
169-             QDate gdate (year, month, day);
170-             //  Bikram date
171-             Bikram bs;
172-             bs.fromGregorian (year, month, day);
173-             int  bsYear = bs.getYear ();
174-             int  bsMonth = bs.getMonth ();
175-             int  bsDay = bs.getDay ();
176-             //  Panchanga details
177-             std::tm date = {};
178-             date.tm_year  = year - 1900 ;
179-             date.tm_mon  = month - 1 ;
180-             date.tm_mday  = day;
181-             TithiResult tithi = calculateTithi (date);
182-             YogaResult yoga = calculateYoga (date);
183-             KaranResult karan = calculateKaran (date);
184-             NakshatraResult nakshatra = calculateNakshatra (date);
185-             RashiResult rashi = calculateRashi (date);
186-             QString sunrise = QString::fromStdString (calculateSunriseOrSunset (date, true ));
187-             QString sunset = QString::fromStdString (calculateSunriseOrSunset (date, false ));
188-             //  Show details dialog
189-             QString details = QString (
190-                 " 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" 
191-                 .arg (QString::number (gdate.year ()) + " -" QString::number (gdate.month ()).rightJustified (2 , ' 0' " -" QString::number (gdate.day ()).rightJustified (2 , ' 0' 
192-                 .arg (convertToNepaliNumerals (bsYear)).arg (convertToNepaliNumerals (bsMonth)).arg (convertToNepaliNumerals (bsDay))
193-                 .arg (QString::fromStdString (tithi.tithiName ))
194-                 .arg (QString::fromStdString (tithi.paksha ))
195-                 .arg (QString::fromStdString (yoga.yogaName ))
196-                 .arg (QString::fromStdString (karan.karanName ))
197-                 .arg (QString::fromStdString (nakshatra.nakshatraName ))
198-                 .arg (QString::fromStdString (rashi.rashiName ))
199-                 .arg (sunrise)
200-                 .arg (sunset);
201-             QWidget *topLevel = this ->window ();
202-             QMessageBox::information (topLevel, tr (" Day Details" 
203-         }
204-         QWidget::mousePressEvent (event);
205-     }
206- 
207286};
208287
209288#endif  //  DAYTITHIWIDGET_H
0 commit comments