/////////////////////////////////////////////////////////////////////////////// // Name: generic/calctrl.h // Purpose: generic implementation of date-picker control // Author: Vadim Zeitlin // Modified by: // Created: 29.12.99 // RCS-ID: $Id$ // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// #ifndef _WX_GENERIC_CALCTRL_H #define _WX_GENERIC_CALCTRL_H #include "wx/control.h" // the base class #include "wx/dcclient.h" // for wxPaintDC class WXDLLIMPEXP_FWD_CORE wxComboBox; class WXDLLIMPEXP_FWD_CORE wxStaticText; class WXDLLIMPEXP_FWD_CORE wxSpinCtrl; #define wxCalendarNameStr _T("CalendarCtrl") // ---------------------------------------------------------------------------- // wxCalendarCtrl: a control allowing the user to pick a date interactively // ---------------------------------------------------------------------------- class WXDLLIMPEXP_ADV wxCalendarCtrl : public wxControl { public: // construction wxCalendarCtrl() { Init(); } wxCalendarCtrl(wxWindow *parent, wxWindowID id, const wxDateTime& date = wxDefaultDateTime, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCAL_SHOW_HOLIDAYS | wxWANTS_CHARS, const wxString& name = wxCalendarNameStr); bool Create(wxWindow *parent, wxWindowID id, const wxDateTime& date = wxDefaultDateTime, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCAL_SHOW_HOLIDAYS | wxWANTS_CHARS, const wxString& name = wxCalendarNameStr); virtual ~wxCalendarCtrl(); virtual bool Destroy(); // set/get the current date // ------------------------ bool SetDate(const wxDateTime& date); // we need to be able to control if the event should be sent in SetDateAndNotify(...) const wxDateTime& GetDate() const { return m_date; } // set/get the range in which selection can occur // --------------------------------------------- bool SetLowerDateLimit(const wxDateTime& date = wxDefaultDateTime); const wxDateTime& GetLowerDateLimit() const { return m_lowdate; } bool SetUpperDateLimit(const wxDateTime& date = wxDefaultDateTime); const wxDateTime& GetUpperDateLimit() const { return m_highdate; } bool SetDateRange(const wxDateTime& lowerdate = wxDefaultDateTime, const wxDateTime& upperdate = wxDefaultDateTime); // calendar mode // ------------- // some calendar styles can't be changed after the control creation by // just using SetWindowStyle() and Refresh() and the functions below // should be used instead for them // corresponds to wxCAL_NO_YEAR_CHANGE bit void EnableYearChange(bool enable = true); // corresponds to wxCAL_NO_MONTH_CHANGE bit void EnableMonthChange(bool enable = true); // corresponds to wxCAL_SHOW_HOLIDAYS bit void EnableHolidayDisplay(bool display = true); // customization // ------------- // header colours are used for painting the weekdays at the top void SetHeaderColours(const wxColour& colFg, const wxColour& colBg) { m_colHeaderFg = colFg; m_colHeaderBg = colBg; } const wxColour& GetHeaderColourFg() const { return m_colHeaderFg; } const wxColour& GetHeaderColourBg() const { return m_colHeaderBg; } // highlight colour is used for the currently selected date void SetHighlightColours(const wxColour& colFg, const wxColour& colBg) { m_colHighlightFg = colFg; m_colHighlightBg = colBg; } const wxColour& GetHighlightColourFg() const { return m_colHighlightFg; } const wxColour& GetHighlightColourBg() const { return m_colHighlightBg; } // holiday colour is used for the holidays (if style & wxCAL_SHOW_HOLIDAYS) void SetHolidayColours(const wxColour& colFg, const wxColour& colBg) { m_colHolidayFg = colFg; m_colHolidayBg = colBg; } const wxColour& GetHolidayColourFg() const { return m_colHolidayFg; } const wxColour& GetHolidayColourBg() const { return m_colHolidayBg; } // an item without custom attributes is drawn with the default colours and // font and without border, setting custom attributes allows to modify this // // the day parameter should be in 1..31 range, for days 29, 30, 31 the // corresponding attribute is just unused if there is no such day in the // current month wxCalendarDateAttr *GetAttr(size_t day) const { wxCHECK_MSG( day > 0 && day < 32, NULL, _T("invalid day") ); return m_attrs[day - 1]; } void SetAttr(size_t day, wxCalendarDateAttr *attr) { wxCHECK_RET( day > 0 && day < 32, _T("invalid day") ); delete m_attrs[day - 1]; m_attrs[day - 1] = attr; } void SetHoliday(size_t day); void ResetAttr(size_t day) { SetAttr(day, (wxCalendarDateAttr *)NULL); } // 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 // ------------------------------- // forward these functions to all subcontrols virtual bool Enable(bool enable = true); virtual bool Show(bool show = true); virtual void SetWindowStyleFlag(long style); virtual wxVisualAttributes GetDefaultAttributes() const { return GetClassDefaultAttributes(GetWindowVariant()); } static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); void OnSysColourChanged(wxSysColourChangedEvent& event); protected: // override some base class virtuals virtual wxSize DoGetBestSize() const; virtual void DoGetPosition(int *x, int *y) const; virtual void DoGetSize(int *width, int *height) const; virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags); virtual void DoMoveWindow(int x, int y, int width, int height); private: // common part of all ctors void Init(); // startup colours and reinitialization after colour changes in system void InitColours(); // event handlers void OnPaint(wxPaintEvent& event); void OnClick(wxMouseEvent& event); void OnDClick(wxMouseEvent& event); void OnChar(wxKeyEvent& event); void OnMonthChange(wxCommandEvent& event); void OnYearChange(wxCommandEvent& event); void OnYearTextChange(wxCommandEvent& event); // (re)calc m_widthCol and m_heightRow void RecalcGeometry(); // set the date and send the notification void SetDateAndNotify(const wxDateTime& date); // get the week (row, in range 1..6) for the given date size_t GetWeek(const wxDateTime& date) const; // get the date from which we start drawing days wxDateTime GetStartDate() const; // is this date shown? bool IsDateShown(const wxDateTime& date) const; // is this date in the given range? bool IsDateInRange(const wxDateTime& date) const; // range helpers bool ChangeYear(wxDateTime* target) const; bool ChangeMonth(wxDateTime* target) const; // redraw the given date void RefreshDate(const wxDateTime& date); // change the date inside the same month/year void ChangeDay(const wxDateTime& date); // set the attributes for the holidays if needed void SetHolidayAttrs(); // reset all holidays void ResetHolidayAttrs(); // generate the given calendar event(s) void GenerateEvent(wxEventType type) { wxCalendarEvent event(this, type); (void)GetEventHandler()->ProcessEvent(event); } void GenerateEvents(wxEventType type1, wxEventType type2) { GenerateEvent(type1); GenerateEvent(type2); } // do we allow changing the month/year? bool AllowMonthChange() const { return (GetWindowStyle() & wxCAL_NO_MONTH_CHANGE) != wxCAL_NO_MONTH_CHANGE; } bool AllowYearChange() const { return !(GetWindowStyle() & wxCAL_NO_YEAR_CHANGE); } // show the correct controls void ShowCurrentControls(); // create the month combo and year spin controls void CreateMonthComboBox(); void CreateYearSpinCtrl(); public: // get the currently shown control for month/year wxControl *GetMonthControl() const; wxControl *GetYearControl() const; private: // OnPaint helper-methods // Highlight the [fromdate : todate] range using pen and brush void HighlightRange(wxPaintDC* dc, const wxDateTime& fromdate, const wxDateTime& todate, const wxPen* pen, const wxBrush* brush); // Get the "coordinates" for the date relative to the month currently displayed. // using (day, week): upper left coord is (1, 1), lower right coord is (7, 6) // if the date isn't visible (-1, -1) is put in (day, week) and false is returned bool GetDateCoord(const wxDateTime& date, int *day, int *week) const; // Set the flag for SetDate(): otherwise it would overwrite the year // typed in by the user void SetUserChangedYear() { m_userChangedYear = true; } // the subcontrols wxStaticText *m_staticMonth; wxComboBox *m_comboMonth; wxStaticText *m_staticYear; wxSpinCtrl *m_spinYear; // the current selection wxDateTime m_date; // the date-range wxDateTime m_lowdate; wxDateTime m_highdate; // default attributes wxColour m_colHighlightFg, m_colHighlightBg, m_colHolidayFg, m_colHolidayBg, m_colHeaderFg, m_colHeaderBg, m_colBackground, m_colSorrounding; // the attributes for each of the month days wxCalendarDateAttr *m_attrs[31]; // the width and height of one column/row in the calendar wxCoord m_widthCol, m_heightRow, m_rowOffset; wxRect m_leftArrowRect, m_rightArrowRect; // the week day names wxString m_weekdays[7]; // true if SetDate() is being called as the result of changing the year in // the year control bool m_userChangedYear; DECLARE_DYNAMIC_CLASS(wxCalendarCtrl) DECLARE_EVENT_TABLE() DECLARE_NO_COPY_CLASS(wxCalendarCtrl) }; #endif // _WX_GENERIC_CALCTRL_H