From 0185cd097844887c308a81fbd137676086ae8580 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 30 Dec 1999 18:21:42 +0000 Subject: [PATCH] added support for several new events in wxCalendarCtrl: clicking on week days in the header, double clicking git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5153 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/calctrl.h | 28 +++++++++- include/wx/event.h | 4 +- include/wx/generic/calctrl.h | 32 +++++++---- samples/controls/controls.cpp | 21 ++++++- src/generic/calctrl.cpp | 101 ++++++++++++++++++++++++++-------- 5 files changed, 148 insertions(+), 38 deletions(-) diff --git a/include/wx/calctrl.h b/include/wx/calctrl.h index 1017e4e182..3fe059bea3 100644 --- a/include/wx/calctrl.h +++ b/include/wx/calctrl.h @@ -12,6 +12,22 @@ #ifndef _WX_CALCTRL_H #define _WX_CALCTRL_H +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + +// return values for the HitTest() method +enum wxCalendarHitTestResult +{ + wxCAL_HITTEST_NOWHERE, // outside of anything + wxCAL_HITTEST_HEADER, // on the header (weekdays) + wxCAL_HITTEST_DAY // on a day in the calendar +}; + +// ---------------------------------------------------------------------------- +// wxCalendarCtrl +// ---------------------------------------------------------------------------- + // so far we only have a generic version, so keep it simple #include "wx/generic/calctrl.h" @@ -21,19 +37,27 @@ class WXDLLEXPORT wxCalendarEvent : public wxCommandEvent { +friend class wxCalendarCtrl; public: - wxCalendarEvent() { } + wxCalendarEvent() { Init(); } wxCalendarEvent(wxCalendarCtrl *cal, wxEventType type); const wxDateTime& GetDate() const { return m_date; } + wxDateTime::WeekDay GetWeekDay() const { return m_wday; } + +protected: + void Init(); private: wxDateTime m_date; + wxDateTime::WeekDay m_wday; }; -#define EVT_CALENDAR(id, fn) { wxEVT_CALENDAR_SEL_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL }, +#define EVT_CALENDAR(id, fn) { wxEVT_CALENDAR_DOUBLECLICKED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL }, +#define EVT_CALENDAR_SEL_CHANGED(id, fn) { wxEVT_CALENDAR_SEL_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL }, #define EVT_CALENDAR_DAY(id, fn) { wxEVT_CALENDAR_DAY_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL }, #define EVT_CALENDAR_MONTH(id, fn) { wxEVT_CALENDAR_MONTH_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL }, #define EVT_CALENDAR_YEAR(id, fn) { wxEVT_CALENDAR_YEAR_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL }, +#define EVT_CALENDAR_WEEKDAY_CLICKED(id, fn) { wxEVT_CALENDAR_WEEKDAY_CLICKED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL }, #endif // _WX_CALCTRL_H diff --git a/include/wx/event.h b/include/wx/event.h index d125990a06..1d97b842f8 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -255,8 +255,10 @@ const wxEventType wxEVT_CALENDAR_SEL_CHANGED = wxEVT_FIRST + 950; const wxEventType wxEVT_CALENDAR_DAY_CHANGED = wxEVT_FIRST + 951; const wxEventType wxEVT_CALENDAR_MONTH_CHANGED = wxEVT_FIRST + 952; const wxEventType wxEVT_CALENDAR_YEAR_CHANGED = wxEVT_FIRST + 953; +const wxEventType wxEVT_CALENDAR_DOUBLECLICKED = wxEVT_FIRST + 954; +const wxEventType wxEVT_CALENDAR_WEEKDAY_CLICKED = wxEVT_FIRST + 955; -const wxEventType wxEVT_USER_FIRST = wxEVT_FIRST + 2000; +const wxEventType wxEVT_USER_FIRST = wxEVT_FIRST + 2000; /* Compatibility */ diff --git a/include/wx/generic/calctrl.h b/include/wx/generic/calctrl.h index c685deeb48..a3c4617964 100644 --- a/include/wx/generic/calctrl.h +++ b/include/wx/generic/calctrl.h @@ -30,6 +30,9 @@ class WXDLLEXPORT wxCalendarCtrl : public wxControl { +friend class wxMonthComboBox; +friend class wxYearSpinCtrl; + public: // construction wxCalendarCtrl() { Init(); } @@ -62,9 +65,12 @@ public: void SetDate(const wxDateTime& date); const wxDateTime& GetDate() const { return m_date; } - // returns TRUE if the given point is on a day and fills date with its - // value - bool HitTest(const wxPoint& pos, wxDateTime *date); + // returns one of wxCAL_HITTEST_XXX constants and fills either date or wd + // with the corresponding value (none for NOWHERE, the date for DAY and wd + // for HEADER) + wxCalendarHitTestResult HitTest(const wxPoint& pos, + wxDateTime *date = NULL, + wxDateTime::WeekDay *wd = NULL); // implementation only from now on // ------------------------------- @@ -73,17 +79,18 @@ public: virtual bool Enable(bool enable = TRUE); virtual bool Show(bool show = TRUE); - // event handlers - void OnPaint(wxPaintEvent& event); - void OnClick(wxMouseEvent& event); - void OnChar(wxKeyEvent& event); - void OnMonthChange(wxCommandEvent& event); - void OnYearChange(wxSpinEvent& event); - private: // common part of all ctors void Init(); + // event handlers + void OnPaint(wxPaintEvent& event); + void OnClick(wxMouseEvent& event); + void OnDClick(wxMouseEvent& event); + void OnChar(wxKeyEvent& event); + void OnMonthChange(wxCommandEvent& event); + void OnYearChange(wxSpinEvent& event); + // override some base class virtuals virtual wxSize DoGetBestSize() const; virtual void DoGetPosition(int *x, int *y) const; @@ -112,8 +119,9 @@ private: // change the date inside the same month/year void ChangeDay(const wxDateTime& date); - // generate a calendar event - void GenerateEvent(wxEventType type); + // generate the given calendar event and a "selection changed" one if + // selChanged is TRUE + void GenerateEvent(wxEventType type, bool selChanged = TRUE); // the subcontrols wxComboBox *m_comboMonth; diff --git a/samples/controls/controls.cpp b/samples/controls/controls.cpp index aedd9ae761..ac99563156 100644 --- a/samples/controls/controls.cpp +++ b/samples/controls/controls.cpp @@ -113,6 +113,8 @@ public: void OnEnableAll(wxCommandEvent& event); void OnChangeColour(wxCommandEvent& event); + void OnCalendar(wxCalendarEvent& event); + void OnCalendarWeekDayClick(wxCalendarEvent& event); void OnCalendarChange(wxCalendarEvent& event); wxListBox *m_listbox, @@ -380,7 +382,11 @@ EVT_SPINCTRL (ID_SPINCTRL, MyPanel::OnSpinCtrl) #endif // wxUSE_SPINCTRL EVT_BUTTON (ID_BUTTON_LABEL, MyPanel::OnUpdateLabel) EVT_CHECKBOX (ID_CHANGE_COLOUR, MyPanel::OnChangeColour) -EVT_CALENDAR (ID_CALENDAR, MyPanel::OnCalendarChange) + +EVT_CALENDAR (ID_CALENDAR, MyPanel::OnCalendar) +EVT_CALENDAR_SEL_CHANGED(ID_CALENDAR, MyPanel::OnCalendarChange) +EVT_CALENDAR_WEEKDAY_CLICKED(ID_CALENDAR, MyPanel::OnCalendarWeekDayClick) + END_EVENT_TABLE() MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h ) @@ -758,6 +764,12 @@ void MyPanel::OnPageChanged( wxNotebookEvent &event ) *m_text << "Notebook selection is " << event.GetSelection() << "\n"; } +void MyPanel::OnCalendar(wxCalendarEvent& event) +{ + *m_text << "Selected " << event.GetDate().FormatISODate() << + " from calendar\n"; +} + void MyPanel::OnCalendarChange(wxCalendarEvent& event) { wxString s; @@ -766,6 +778,13 @@ void MyPanel::OnCalendarChange(wxCalendarEvent& event) m_date->SetLabel(s); } +void MyPanel::OnCalendarWeekDayClick(wxCalendarEvent& event) +{ + *m_text << "Clicked on " + << wxDateTime::GetWeekDayName(event.GetWeekDay()) + << "\n"; +} + void MyPanel::OnChangeColour(wxCommandEvent& WXUNUSED(event)) { static wxColour s_colOld; diff --git a/src/generic/calctrl.cpp b/src/generic/calctrl.cpp index a3f7cbd455..78b6c57f49 100644 --- a/src/generic/calctrl.cpp +++ b/src/generic/calctrl.cpp @@ -78,6 +78,7 @@ BEGIN_EVENT_TABLE(wxCalendarCtrl, wxControl) EVT_CHAR(wxCalendarCtrl::OnChar) EVT_LEFT_DOWN(wxCalendarCtrl::OnClick) + EVT_LEFT_DCLICK(wxCalendarCtrl::OnDClick) END_EVENT_TABLE() BEGIN_EVENT_TABLE(wxMonthComboBox, wxComboBox) @@ -551,44 +552,91 @@ void wxCalendarCtrl::RefreshDate(const wxDateTime& date) // mouse handling // ---------------------------------------------------------------------------- -void wxCalendarCtrl::OnClick(wxMouseEvent& event) +void wxCalendarCtrl::OnDClick(wxMouseEvent& event) { - RecalcGeometry(); - - wxDateTime date; - if ( !HitTest(event.GetPosition(), &date) ) + if ( HitTest(event.GetPosition()) != wxCAL_HITTEST_DAY ) { event.Skip(); } else { - ChangeDay(date); - - GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED); + GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED, FALSE); } } -bool wxCalendarCtrl::HitTest(const wxPoint& pos, wxDateTime *date) +void wxCalendarCtrl::OnClick(wxMouseEvent& event) +{ + wxDateTime date; + wxDateTime::WeekDay wday; + switch ( HitTest(event.GetPosition(), &date, &wday) ) + { + case wxCAL_HITTEST_DAY: + ChangeDay(date); + + GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED); + break; + + case wxCAL_HITTEST_HEADER: + { + wxCalendarEvent event(this, wxEVT_CALENDAR_WEEKDAY_CLICKED); + event.m_wday = wday; + (void)GetEventHandler()->ProcessEvent(event); + } + break; + + default: + wxFAIL_MSG(_T("unknown hittest code")); + // fall through + + case wxCAL_HITTEST_NOWHERE: + event.Skip(); + break; + } +} + +wxCalendarHitTestResult wxCalendarCtrl::HitTest(const wxPoint& pos, + wxDateTime *date, + wxDateTime::WeekDay *wd) { RecalcGeometry(); + int wday = pos.x / m_widthCol; + wxCoord y = pos.y; if ( y < m_heightRow ) - return FALSE; + { + if ( wd ) + { + if ( GetWindowStyle() & wxCAL_MONDAY_FIRST ) + { + wday = wday == 6 ? 0 : wday + 1; + } - y -= m_heightRow; - int week = y / m_heightRow, - wday = pos.x / m_widthCol; + *wd = (wxDateTime::WeekDay)wday; + } + return wxCAL_HITTEST_HEADER; + } + + int week = (y - m_heightRow) / m_heightRow; if ( week >= 6 || wday >= 7 ) - return FALSE; + { + return wxCAL_HITTEST_NOWHERE; + } - wxCHECK_MSG( date, FALSE, _T("bad pointer in wxCalendarCtrl::HitTest") ); + wxDateTime dt = GetStartDate() + wxDateSpan::Days(7*week + wday); - *date = GetStartDate(); - *date += wxDateSpan::Days(7*week + wday); + if ( IsDateShown(dt) ) + { + if ( date ) + *date = dt; - return IsDateShown(*date); + return wxCAL_HITTEST_DAY; + } + else + { + return wxCAL_HITTEST_NOWHERE; + } } // ---------------------------------------------------------------------------- @@ -697,15 +745,24 @@ void wxCalendarCtrl::OnChar(wxKeyEvent& event) // wxCalendarEvent // ---------------------------------------------------------------------------- -void wxCalendarCtrl::GenerateEvent(wxEventType type) +void wxCalendarCtrl::GenerateEvent(wxEventType type, bool selChanged) { // we're called for a change in some particular date field but we always // also generate a generic "changed" event wxCalendarEvent event(this, type); - wxCalendarEvent event2(this, wxEVT_CALENDAR_SEL_CHANGED); - (void)GetEventHandler()->ProcessEvent(event); - (void)GetEventHandler()->ProcessEvent(event2); + + if ( selChanged ) + { + wxCalendarEvent event2(this, wxEVT_CALENDAR_SEL_CHANGED); + + (void)GetEventHandler()->ProcessEvent(event2); + } +} + +void wxCalendarEvent::Init() +{ + m_wday = wxDateTime::Inv_WeekDay; } wxCalendarEvent::wxCalendarEvent(wxCalendarCtrl *cal, wxEventType type)