]> git.saurik.com Git - wxWidgets.git/commitdiff
implemented Mark() in the native MSW version of wxCalendarCtrl
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 4 Apr 2008 16:26:39 +0000 (16:26 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 4 Apr 2008 16:26:39 +0000 (16:26 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@53009 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/calctrl.h
samples/calendar/calendar.cpp
src/msw/calctrl.cpp

index 3f527182f1c70efb661c2703d1b1f7c73a88bd02..d750d54728c7647ae664f9da35c94f79c24819e2 100644 (file)
@@ -13,7 +13,7 @@
 class WXDLLIMPEXP_ADV wxCalendarCtrl : public wxCalendarCtrlBase
 {
 public:
 class WXDLLIMPEXP_ADV wxCalendarCtrl : public wxCalendarCtrlBase
 {
 public:
-    wxCalendarCtrl() { }
+    wxCalendarCtrl() { Init(); }
     wxCalendarCtrl(wxWindow *parent,
                    wxWindowID id,
                    const wxDateTime& date = wxDefaultDateTime,
     wxCalendarCtrl(wxWindow *parent,
                    wxWindowID id,
                    const wxDateTime& date = wxDefaultDateTime,
@@ -22,6 +22,8 @@ public:
                    long style = wxCAL_SHOW_HOLIDAYS,
                    const wxString& name = wxCalendarNameStr)
     {
                    long style = wxCAL_SHOW_HOLIDAYS,
                    const wxString& name = wxCalendarNameStr)
     {
+        Init();
+
         Create(parent, id, date, pos, size, style, name);
     }
 
         Create(parent, id, date, pos, size, style, name);
     }
 
@@ -58,8 +60,20 @@ protected:
     void MSWOnDoubleClick(wxMouseEvent& event);
 
 private:
     void MSWOnDoubleClick(wxMouseEvent& event);
 
 private:
+    void Init() { m_marks = 0; }
+
+    void UpdateMarks();
+
+
+    // current date, we need to store it instead of simply retrieving it from
+    // the control as needed in order to be able to generate the correct events
+    // from MSWOnNotify()
     wxDateTime m_date;
 
     wxDateTime m_date;
 
+    // bit field containing the state (marked or not) of all days in the month
+    wxUint32 m_marks;
+
+
     DECLARE_DYNAMIC_CLASS(wxCalendarCtrl)
     DECLARE_NO_COPY_CLASS(wxCalendarCtrl)
 };
     DECLARE_DYNAMIC_CLASS(wxCalendarCtrl)
     DECLARE_NO_COPY_CLASS(wxCalendarCtrl)
 };
index 0c9a7892bbc5f79a450f02f610acb54ce61db044..6b93a7eb4e082c904e23cbc0eae3dada761bf841 100644 (file)
@@ -637,9 +637,15 @@ MyPanel::MyPanel(wxWindow *parent)
 
 void MyPanel::OnCalendar(wxCalendarEvent& event)
 {
 
 void MyPanel::OnCalendar(wxCalendarEvent& event)
 {
-    m_calendar->Mark(event.GetDate().GetDay(), true);
-    wxLogMessage(wxT("Selected (and marked) %s from calendar."),
-                 event.GetDate().FormatISODate().c_str());
+    // clicking the same date twice unmarks it (convenient for testing)
+    static wxDateTime s_dateLast;
+    const bool mark = !s_dateLast.IsValid() || event.GetDate() != s_dateLast;
+
+    s_dateLast = event.GetDate();
+
+    m_calendar->Mark(event.GetDate().GetDay(), mark);
+    wxLogMessage(wxT("Selected (and %smarked) %s from calendar."),
+                 mark ? "" : "un", s_dateLast.FormatISODate().c_str());
 }
 
 void MyPanel::OnCalendarChange(wxCalendarEvent& event)
 }
 
 void MyPanel::OnCalendarChange(wxCalendarEvent& event)
index 53e802a82765744a6a76ce43422d6b0f850c70e2..69c5abeb6b858d51e3b59d4ab9a6bd765a822660 100644 (file)
@@ -89,7 +89,9 @@ wxCalendarCtrl::Create(wxWindow *parent,
 
     SetDate(dt.IsValid() ? dt : wxDateTime::Today());
 
 
     SetDate(dt.IsValid() ? dt : wxDateTime::Today());
 
-    Connect(wxEVT_LEFT_DOWN,
+    UpdateMarks();
+
+    Connect(wxEVT_LEFT_DCLICK,
             wxMouseEventHandler(wxCalendarCtrl::MSWOnDoubleClick));
 
     return true;
             wxMouseEventHandler(wxCalendarCtrl::MSWOnDoubleClick));
 
     return true;
@@ -107,6 +109,9 @@ WXDWORD wxCalendarCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
     // unconditionally for now
     styleMSW |= MCS_NOTODAY;
 
     // unconditionally for now
     styleMSW |= MCS_NOTODAY;
 
+    // we also need this style for Mark() to work
+    styleMSW |= MCS_DAYSTATE;
+
     return styleMSW;
 }
 
     return styleMSW;
 }
 
@@ -292,7 +297,31 @@ bool wxCalendarCtrl::EnableMonthChange(bool enable)
 
 void wxCalendarCtrl::Mark(size_t day, bool mark)
 {
 
 void wxCalendarCtrl::Mark(size_t day, bool mark)
 {
-    wxFAIL_MSG( "not implemented" );
+    wxCHECK_RET( day > 0 && day < 32, "invalid day" );
+
+    int mask = 1 << (day - 1);
+    if ( mark )
+        m_marks |= mask;
+    else
+        m_marks &= ~mask;
+
+    // calling Refresh() here is not enough to change the day appearance
+    UpdateMarks();
+}
+
+void wxCalendarCtrl::UpdateMarks()
+{
+    MONTHDAYSTATE states[3];
+    const int nMonths = MonthCal_GetMonthRange(GetHwnd(), GMR_DAYSTATE, NULL);
+    wxCHECK_RET( nMonths <= WXSIZEOF(states), "unexpected months range" );
+
+    for ( int i = 0; i < nMonths; i++ )
+        states[i] = m_marks;
+
+    if ( !MonthCal_SetDayState(GetHwnd(), nMonths, states) )
+    {
+        wxLogLastError(_T("MonthCal_SetDayState"));
+    }
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -305,25 +334,39 @@ bool wxCalendarCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
     switch ( hdr->code )
     {
         case MCN_SELCHANGE:
     switch ( hdr->code )
     {
         case MCN_SELCHANGE:
-            // we need to update m_date first, before calling the user code
-            // which expects GetDate() to return the new date
-            const wxDateTime dateOld = m_date;
-            const NMSELCHANGE * const sch = (NMSELCHANGE *)lParam;
-            wxMSWDateControls::FromSystemTime(&m_date, sch->stSelStart);
-
-            // changing the year or the month results in a second dummy
-            // MCN_SELCHANGE event on this system which doesn't really change
-            // anything -- filter it out
-            if ( m_date != dateOld )
             {
             {
-                GenerateAllChangeEvents(dateOld);
+                // we need to update m_date first, before calling the user code
+                // which expects GetDate() to return the new date
+                const wxDateTime dateOld = m_date;
+                const NMSELCHANGE * const sch = (NMSELCHANGE *)lParam;
+                wxMSWDateControls::FromSystemTime(&m_date, sch->stSelStart);
+
+                // changing the year or the month results in a second dummy
+                // MCN_SELCHANGE event on this system which doesn't really
+                // change anything -- filter it out
+                if ( m_date != dateOld )
+                {
+                    GenerateAllChangeEvents(dateOld);
+                }
+            }
+            break;
 
 
-                *result = 0;
-                return true;
+        case MCN_GETDAYSTATE:
+            {
+                const NMDAYSTATE * const ds = (NMDAYSTATE *)lParam;
+                for ( int i = 0; i < ds->cDayState; i++ )
+                {
+                    ds->prgDayState[i] = m_marks;
+                }
             }
             }
+            break;
+
+        default:
+            return wxCalendarCtrlBase::MSWOnNotify(idCtrl, lParam, result);
     }
 
     }
 
-    return wxCalendarCtrlBase::MSWOnNotify(idCtrl, lParam, result);
+    *result = 0;
+    return true;
 }
 
 void wxCalendarCtrl::MSWOnDoubleClick(wxMouseEvent& event)
 }
 
 void wxCalendarCtrl::MSWOnDoubleClick(wxMouseEvent& event)