]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/calctrl.cpp
Store pointer to owning wxWindow in wxPizza widget
[wxWidgets.git] / src / msw / calctrl.cpp
index 90faa55f4736a7e3ca6cf250d7797b862c20a41e..dc18f88615b44f778c05ca9f143953a958d3aa9c 100644 (file)
@@ -44,6 +44,12 @@ IMPLEMENT_DYNAMIC_CLASS(wxCalendarCtrl, wxControl)
 // wxCalendarCtrl creation
 // ----------------------------------------------------------------------------
 
+void wxCalendarCtrl::Init()
+{
+    m_marks =
+    m_holidays = 0;
+}
+
 bool
 wxCalendarCtrl::Create(wxWindow *parent,
                        wxWindowID id,
@@ -95,7 +101,8 @@ wxCalendarCtrl::Create(wxWindow *parent,
 
     SetDate(dt.IsValid() ? dt : wxDateTime::Today());
 
-    UpdateMarks();
+    if ( SetHolidayAttrs() )
+        UpdateMarks();
 
     Connect(wxEVT_LEFT_DOWN,
             wxMouseEventHandler(wxCalendarCtrl::MSWOnClick));
@@ -183,7 +190,7 @@ wxCalendarCtrl::HitTest(const wxPoint& pos,
         case MCHT_CALENDARDAY:
             if ( wd )
             {
-                *wd = wx_static_cast(wxDateTime::WeekDay, hti.st.wDayOfWeek);
+                *wd = static_cast<wxDateTime::WeekDay>(hti.st.wDayOfWeek);
             }
             return wxCAL_HITTEST_HEADER;
 
@@ -327,14 +334,30 @@ void wxCalendarCtrl::Mark(size_t day, bool mark)
     UpdateMarks();
 }
 
+void wxCalendarCtrl::SetHoliday(size_t day)
+{
+    wxCHECK_RET( day > 0 && day < 32, "invalid day" );
+
+    m_holidays |= 1 << (day - 1);
+}
+
 void wxCalendarCtrl::UpdateMarks()
 {
-    MONTHDAYSTATE states[3];
+    // we show only one full month but there can be some days from the month
+    // before it and from the one after it so days from 3 different months can
+    // be partially shown
+    MONTHDAYSTATE states[3] = { 0 };
     const int nMonths = MonthCal_GetMonthRange(GetHwnd(), GMR_DAYSTATE, NULL);
-    wxCHECK_RET( nMonths <= (int)WXSIZEOF(states), "unexpected months range" );
 
-    for ( int i = 0; i < nMonths; i++ )
-        states[i] = m_marks;
+    // although in principle the calendar might not show any days from the
+    // preceding months, it seems like it always does, consider e.g. Feb 2010
+    // which starts on Monday and ends on Sunday and so could fit on 4 lines
+    // without showing any subsequent months -- the standard control still
+    // shows it on 6 lines and the number of visible months is still 3
+    wxCHECK_RET( nMonths == (int)WXSIZEOF(states), "unexpected months range" );
+
+    // the fully visible month is the one in the middle
+    states[1] = m_marks | m_holidays;
 
     if ( !MonthCal_SetDayState(GetHwnd(), nMonths, states) )
     {
@@ -369,7 +392,13 @@ bool wxCalendarCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 // change anything -- filter it out
                 if ( m_date != dateOld )
                 {
-                    GenerateAllChangeEvents(dateOld);
+                    if ( GenerateAllChangeEvents(dateOld) )
+                    {
+                        // month changed, need to update the holidays if we use
+                        // them
+                        if ( SetHolidayAttrs() )
+                            UpdateMarks();
+                    }
                 }
             }
             break;
@@ -379,7 +408,7 @@ bool wxCalendarCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 const NMDAYSTATE * const ds = (NMDAYSTATE *)lParam;
                 for ( int i = 0; i < ds->cDayState; i++ )
                 {
-                    ds->prgDayState[i] = m_marks;
+                    ds->prgDayState[i] = m_marks | m_holidays;
                 }
             }
             break;