#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"
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
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 */
class WXDLLEXPORT wxCalendarCtrl : public wxControl
{
+friend class wxMonthComboBox;
+friend class wxYearSpinCtrl;
+
public:
// construction
wxCalendarCtrl() { Init(); }
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
// -------------------------------
virtual bool Enable(bool enable = TRUE);
virtual bool Show(bool show = TRUE);
+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);
-private:
- // common part of all ctors
- void Init();
-
// override some base class virtuals
virtual wxSize DoGetBestSize() const;
virtual void DoGetPosition(int *x, int *y) const;
// 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;
void OnEnableAll(wxCommandEvent& event);
void OnChangeColour(wxCommandEvent& event);
+ void OnCalendar(wxCalendarEvent& event);
+ void OnCalendarWeekDayClick(wxCalendarEvent& event);
void OnCalendarChange(wxCalendarEvent& event);
wxListBox *m_listbox,
#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 )
*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;
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;
EVT_CHAR(wxCalendarCtrl::OnChar)
EVT_LEFT_DOWN(wxCalendarCtrl::OnClick)
+ EVT_LEFT_DCLICK(wxCalendarCtrl::OnDClick)
END_EVENT_TABLE()
BEGIN_EVENT_TABLE(wxMonthComboBox, wxComboBox)
// 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_DOUBLECLICKED, FALSE);
+ }
+}
+
+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);
+ 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;
}
}
-bool wxCalendarCtrl::HitTest(const wxPoint& pos, wxDateTime *date)
+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;
+ }
+
+ *wd = (wxDateTime::WeekDay)wday;
+ }
- y -= m_heightRow;
- int week = y / m_heightRow,
- wday = pos.x / m_widthCol;
+ 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;
+ }
}
// ----------------------------------------------------------------------------
// 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)