1 /////////////////////////////////////////////////////////////////////////////// 2 // Name: generic/calctrl.h 3 // Purpose: generic implementation of date-picker control 4 // Author: Vadim Zeitlin 5 // Modified by: 6 // Created: 29.12.99 7 // RCS-ID: $Id: calctrl.h 61872 2009-09-09 22:37:05Z VZ $ 8 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> 9 // Licence: wxWindows licence 10 /////////////////////////////////////////////////////////////////////////////// 11 12 #ifndef _WX_GENERIC_CALCTRL_H 13 #define _WX_GENERIC_CALCTRL_H 14 15 #include "wx/control.h" // the base class 16 #include "wx/dcclient.h" // for wxPaintDC 17 18 class WXDLLIMPEXP_FWD_CORE wxComboBox; 19 class WXDLLIMPEXP_FWD_CORE wxStaticText; 20 class WXDLLIMPEXP_FWD_CORE wxSpinCtrl; 21 22 #define wxCalendarNameStr wxT("CalendarCtrl") 23 24 // ---------------------------------------------------------------------------- 25 // wxCalendarCtrl: a control allowing the user to pick a date interactively 26 // ---------------------------------------------------------------------------- 27 28 class WXDLLIMPEXP_ADV wxCalendarCtrl : public wxControl 29 { 30 public: 31 // construction wxCalendarCtrl()32 wxCalendarCtrl() { Init(); } 33 wxCalendarCtrl(wxWindow *parent, 34 wxWindowID id, 35 const wxDateTime& date = wxDefaultDateTime, 36 const wxPoint& pos = wxDefaultPosition, 37 const wxSize& size = wxDefaultSize, 38 long style = wxCAL_SHOW_HOLIDAYS | wxWANTS_CHARS, 39 const wxString& name = wxCalendarNameStr); 40 41 bool Create(wxWindow *parent, 42 wxWindowID id, 43 const wxDateTime& date = wxDefaultDateTime, 44 const wxPoint& pos = wxDefaultPosition, 45 const wxSize& size = wxDefaultSize, 46 long style = wxCAL_SHOW_HOLIDAYS | wxWANTS_CHARS, 47 const wxString& name = wxCalendarNameStr); 48 49 virtual ~wxCalendarCtrl(); 50 51 virtual bool Destroy(); 52 53 // set/get the current date 54 // ------------------------ 55 56 bool SetDate(const wxDateTime& date); // we need to be able to control if the event should be sent in SetDateAndNotify(...) GetDate()57 const wxDateTime& GetDate() const { return m_date; } 58 59 // set/get the range in which selection can occur 60 // --------------------------------------------- 61 62 bool SetLowerDateLimit(const wxDateTime& date = wxDefaultDateTime); GetLowerDateLimit()63 const wxDateTime& GetLowerDateLimit() const { return m_lowdate; } 64 bool SetUpperDateLimit(const wxDateTime& date = wxDefaultDateTime); GetUpperDateLimit()65 const wxDateTime& GetUpperDateLimit() const { return m_highdate; } 66 67 bool SetDateRange(const wxDateTime& lowerdate = wxDefaultDateTime, const wxDateTime& upperdate = wxDefaultDateTime); 68 69 // calendar mode 70 // ------------- 71 72 // some calendar styles can't be changed after the control creation by 73 // just using SetWindowStyle() and Refresh() and the functions below 74 // should be used instead for them 75 76 // corresponds to wxCAL_NO_YEAR_CHANGE bit 77 void EnableYearChange(bool enable = true); 78 79 // corresponds to wxCAL_NO_MONTH_CHANGE bit 80 void EnableMonthChange(bool enable = true); 81 82 // corresponds to wxCAL_SHOW_HOLIDAYS bit 83 void EnableHolidayDisplay(bool display = true); 84 85 // customization 86 // ------------- 87 88 // header colours are used for painting the weekdays at the top SetHeaderColours(const wxColour & colFg,const wxColour & colBg)89 void SetHeaderColours(const wxColour& colFg, const wxColour& colBg) 90 { 91 m_colHeaderFg = colFg; 92 m_colHeaderBg = colBg; 93 } 94 GetHeaderColourFg()95 const wxColour& GetHeaderColourFg() const { return m_colHeaderFg; } GetHeaderColourBg()96 const wxColour& GetHeaderColourBg() const { return m_colHeaderBg; } 97 98 // highlight colour is used for the currently selected date SetHighlightColours(const wxColour & colFg,const wxColour & colBg)99 void SetHighlightColours(const wxColour& colFg, const wxColour& colBg) 100 { 101 m_colHighlightFg = colFg; 102 m_colHighlightBg = colBg; 103 } 104 GetHighlightColourFg()105 const wxColour& GetHighlightColourFg() const { return m_colHighlightFg; } GetHighlightColourBg()106 const wxColour& GetHighlightColourBg() const { return m_colHighlightBg; } 107 108 // holiday colour is used for the holidays (if style & wxCAL_SHOW_HOLIDAYS) SetHolidayColours(const wxColour & colFg,const wxColour & colBg)109 void SetHolidayColours(const wxColour& colFg, const wxColour& colBg) 110 { 111 m_colHolidayFg = colFg; 112 m_colHolidayBg = colBg; 113 } 114 GetHolidayColourFg()115 const wxColour& GetHolidayColourFg() const { return m_colHolidayFg; } GetHolidayColourBg()116 const wxColour& GetHolidayColourBg() const { return m_colHolidayBg; } 117 118 // an item without custom attributes is drawn with the default colours and 119 // font and without border, setting custom attributes allows to modify this 120 // 121 // the day parameter should be in 1..31 range, for days 29, 30, 31 the 122 // corresponding attribute is just unused if there is no such day in the 123 // current month 124 GetAttr(size_t day)125 wxCalendarDateAttr *GetAttr(size_t day) const 126 { 127 wxCHECK_MSG( day > 0 && day < 32, NULL, wxT("invalid day") ); 128 129 return m_attrs[day - 1]; 130 } 131 SetAttr(size_t day,wxCalendarDateAttr * attr)132 void SetAttr(size_t day, wxCalendarDateAttr *attr) 133 { 134 wxCHECK_RET( day > 0 && day < 32, wxT("invalid day") ); 135 136 delete m_attrs[day - 1]; 137 m_attrs[day - 1] = attr; 138 } 139 140 void SetHoliday(size_t day); 141 ResetAttr(size_t day)142 void ResetAttr(size_t day) { SetAttr(day, (wxCalendarDateAttr *)NULL); } 143 144 // returns one of wxCAL_HITTEST_XXX constants and fills either date or wd 145 // with the corresponding value (none for NOWHERE, the date for DAY and wd 146 // for HEADER) 147 wxCalendarHitTestResult HitTest(const wxPoint& pos, 148 wxDateTime *date = NULL, 149 wxDateTime::WeekDay *wd = NULL); 150 151 // implementation only from now on 152 // ------------------------------- 153 154 // forward these functions to all subcontrols 155 virtual bool Enable(bool enable = true); 156 virtual bool Show(bool show = true); 157 158 virtual void SetWindowStyleFlag(long style); 159 GetDefaultAttributes()160 virtual wxVisualAttributes GetDefaultAttributes() const 161 { return GetClassDefaultAttributes(GetWindowVariant()); } 162 163 static wxVisualAttributes 164 GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); 165 166 void OnSysColourChanged(wxSysColourChangedEvent& event); 167 168 protected: 169 // override some base class virtuals 170 virtual wxSize DoGetBestSize() const; 171 virtual void DoGetPosition(int *x, int *y) const; 172 virtual void DoGetSize(int *width, int *height) const; 173 virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags); 174 virtual void DoMoveWindow(int x, int y, int width, int height); 175 176 private: 177 // common part of all ctors 178 void Init(); 179 180 // startup colours and reinitialization after colour changes in system 181 void InitColours(); 182 183 // event handlers 184 void OnPaint(wxPaintEvent& event); 185 void OnClick(wxMouseEvent& event); 186 void OnDClick(wxMouseEvent& event); 187 void OnChar(wxKeyEvent& event); 188 void OnMonthChange(wxCommandEvent& event); 189 void OnYearChange(wxCommandEvent& event); 190 void OnYearTextChange(wxCommandEvent& event); 191 192 // (re)calc m_widthCol and m_heightRow 193 void RecalcGeometry(); 194 195 // set the date and send the notification 196 void SetDateAndNotify(const wxDateTime& date); 197 198 // get the week (row, in range 1..6) for the given date 199 size_t GetWeek(const wxDateTime& date) const; 200 201 // get the date from which we start drawing days 202 wxDateTime GetStartDate() const; 203 204 // is this date shown? 205 bool IsDateShown(const wxDateTime& date) const; 206 207 // is this date in the given range? 208 bool IsDateInRange(const wxDateTime& date) const; 209 210 // range helpers 211 bool ChangeYear(wxDateTime* target) const; 212 bool ChangeMonth(wxDateTime* target) const; 213 214 // redraw the given date 215 void RefreshDate(const wxDateTime& date); 216 217 // change the date inside the same month/year 218 void ChangeDay(const wxDateTime& date); 219 220 // set the attributes for the holidays if needed 221 void SetHolidayAttrs(); 222 223 // reset all holidays 224 void ResetHolidayAttrs(); 225 226 // generate the given calendar event(s) GenerateEvent(wxEventType type)227 void GenerateEvent(wxEventType type) 228 { 229 wxCalendarEvent event(this, type); 230 (void)GetEventHandler()->ProcessEvent(event); 231 } 232 GenerateEvents(wxEventType type1,wxEventType type2)233 void GenerateEvents(wxEventType type1, wxEventType type2) 234 { 235 GenerateEvent(type1); 236 GenerateEvent(type2); 237 } 238 239 // do we allow changing the month/year? AllowMonthChange()240 bool AllowMonthChange() const 241 { 242 return (GetWindowStyle() & wxCAL_NO_MONTH_CHANGE) 243 != wxCAL_NO_MONTH_CHANGE; 244 } AllowYearChange()245 bool AllowYearChange() const 246 { 247 return !(GetWindowStyle() & wxCAL_NO_YEAR_CHANGE); 248 } 249 250 // show the correct controls 251 void ShowCurrentControls(); 252 253 // create the month combo and year spin controls 254 void CreateMonthComboBox(); 255 void CreateYearSpinCtrl(); 256 257 public: 258 // get the currently shown control for month/year 259 wxControl *GetMonthControl() const; 260 wxControl *GetYearControl() const; 261 262 private: 263 // OnPaint helper-methods 264 265 // Highlight the [fromdate : todate] range using pen and brush 266 void HighlightRange(wxPaintDC* dc, const wxDateTime& fromdate, const wxDateTime& todate, const wxPen* pen, const wxBrush* brush); 267 268 // Get the "coordinates" for the date relative to the month currently displayed. 269 // using (day, week): upper left coord is (1, 1), lower right coord is (7, 6) 270 // if the date isn't visible (-1, -1) is put in (day, week) and false is returned 271 bool GetDateCoord(const wxDateTime& date, int *day, int *week) const; 272 273 // Set the flag for SetDate(): otherwise it would overwrite the year 274 // typed in by the user SetUserChangedYear()275 void SetUserChangedYear() { m_userChangedYear = true; } 276 277 // the subcontrols 278 wxStaticText *m_staticMonth; 279 wxComboBox *m_comboMonth; 280 281 wxStaticText *m_staticYear; 282 wxSpinCtrl *m_spinYear; 283 284 // the current selection 285 wxDateTime m_date; 286 287 // the date-range 288 wxDateTime m_lowdate; 289 wxDateTime m_highdate; 290 291 // default attributes 292 wxColour m_colHighlightFg, 293 m_colHighlightBg, 294 m_colHolidayFg, 295 m_colHolidayBg, 296 m_colHeaderFg, 297 m_colHeaderBg, 298 m_colBackground, 299 m_colSorrounding; 300 301 // the attributes for each of the month days 302 wxCalendarDateAttr *m_attrs[31]; 303 304 // the width and height of one column/row in the calendar 305 wxCoord m_widthCol, 306 m_heightRow, 307 m_rowOffset; 308 309 wxRect m_leftArrowRect, 310 m_rightArrowRect; 311 312 // the week day names 313 wxString m_weekdays[7]; 314 315 // true if SetDate() is being called as the result of changing the year in 316 // the year control 317 bool m_userChangedYear; 318 319 DECLARE_DYNAMIC_CLASS(wxCalendarCtrl) 320 DECLARE_EVENT_TABLE() 321 DECLARE_NO_COPY_CLASS(wxCalendarCtrl) 322 }; 323 324 #endif // _WX_GENERIC_CALCTRL_H 325