implemented Mark() in the native MSW version of wxCalendarCtrl
[wxWidgets.git] / samples / calendar / calendar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: calendar.cpp
3 // Purpose: wxCalendarCtrl sample
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 02.01.00
7 // RCS-ID: $Id$
8 // Copyright: (c) Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 // for all others, include the necessary headers
28 #ifndef WX_PRECOMP
29 #include "wx/app.h"
30 #include "wx/log.h"
31 #include "wx/frame.h"
32 #include "wx/panel.h"
33 #include "wx/stattext.h"
34 #include "wx/menu.h"
35 #include "wx/layout.h"
36 #include "wx/msgdlg.h"
37 #include "wx/icon.h"
38 #include "wx/button.h"
39 #include "wx/sizer.h"
40 #include "wx/textctrl.h"
41 #include "wx/settings.h"
42 #endif
43
44 #include "wx/calctrl.h"
45 #include "wx/splitter.h"
46
47 #if wxUSE_DATEPICKCTRL
48 #include "wx/datectrl.h"
49 #if wxUSE_DATEPICKCTRL_GENERIC
50 #include "wx/generic/datectrl.h"
51 #endif // wxUSE_DATEPICKCTRL_GENERIC
52 #endif // wxUSE_DATEPICKCTRL
53
54 #include "../sample.xpm"
55
56 #ifdef wxHAS_NATIVE_CALENDARCTRL
57 #include "wx/generic/calctrlg.h"
58 #endif
59
60 // ----------------------------------------------------------------------------
61 // private classes
62 // ----------------------------------------------------------------------------
63
64 // Define a new application type, each program should derive a class from wxApp
65 class MyApp : public wxApp
66 {
67 public:
68 // override base class virtuals
69 // ----------------------------
70
71 // this one is called on application startup and is a good place for the app
72 // initialization (doing it here and not in the ctor allows to have an error
73 // return: if OnInit() returns false, the application terminates)
74 virtual bool OnInit();
75 };
76
77 class MyPanel : public wxPanel
78 {
79 public:
80 MyPanel(wxWindow *parent);
81
82 void OnCalendar(wxCalendarEvent& event);
83 void OnCalendarWeekDayClick(wxCalendarEvent& event);
84 void OnCalendarChange(wxCalendarEvent& event);
85 void OnCalMonthChange(wxCalendarEvent& event);
86
87 wxCalendarCtrlBase *GetCal() const { return m_calendar; }
88
89 // turn on/off the specified style bit on the calendar control
90 void ToggleCalStyle(bool on, int style);
91
92 bool IsUsingGeneric() const { return m_usingGeneric; }
93 void ToggleUseGeneric()
94 {
95 m_usingGeneric = !m_usingGeneric;
96 RecreateCalendar(m_calendar->GetWindowStyle());
97 }
98
99 void HighlightSpecial(bool on);
100
101 wxDateTime GetDate() const { return m_calendar->GetDate(); }
102 void SetDate(const wxDateTime& dt) { m_calendar->SetDate(dt); }
103
104 private:
105 wxCalendarCtrlBase *DoCreateCalendar(const wxDateTime& dt, long style);
106
107 void RecreateCalendar(long style);
108
109 wxCalendarCtrlBase *m_calendar;
110 wxStaticText *m_date;
111 wxSizer *m_sizer;
112
113 bool m_usingGeneric;
114
115
116 DECLARE_EVENT_TABLE()
117 };
118
119 // Define a new frame type: this is going to be our main frame
120 class MyFrame : public wxFrame
121 {
122 public:
123 // ctor(s)
124 MyFrame(const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize);
125
126 // event handlers (these functions should _not_ be virtual)
127 void OnAbout(wxCommandEvent& event);
128 void OnClearLog(wxCommandEvent& event);
129 void OnQuit(wxCommandEvent& event);
130
131 #if wxUSE_DATEPICKCTRL
132 void OnAskDate(wxCommandEvent& event);
133
134 void OnUpdateUIStartWithNone(wxUpdateUIEvent& event);
135 #endif // wxUSE_DATEPICKCTRL
136
137 #ifdef wxHAS_NATIVE_CALENDARCTRL
138 void OnCalGeneric(wxCommandEvent& WXUNUSED(event))
139 {
140 m_panel->ToggleUseGeneric();
141 }
142 #endif // wxHAS_NATIVE_CALENDARCTRL
143
144 void OnCalMonday(wxCommandEvent& event);
145 void OnCalHolidays(wxCommandEvent& event);
146 void OnCalSpecial(wxCommandEvent& event);
147
148 void OnCalAllowMonth(wxCommandEvent& event);
149
150 void OnCalSeqMonth(wxCommandEvent& event);
151 void OnCalShowSurroundingWeeks(wxCommandEvent& event);
152
153 void OnSetDate(wxCommandEvent& event);
154 void OnToday(wxCommandEvent& event);
155 void OnBeginDST(wxCommandEvent& event);
156
157 void OnCalToggleResizable(wxCommandEvent& event);
158
159 void OnUpdateUIGenericOnly(wxUpdateUIEvent& event)
160 {
161 event.Enable(m_panel->IsUsingGeneric());
162 }
163
164 void OnCalRClick(wxMouseEvent& event);
165
166 private:
167 MyPanel *m_panel;
168 wxTextCtrl *m_logWindow;
169
170 // any class wishing to process wxWidgets events must use this macro
171 DECLARE_EVENT_TABLE()
172 };
173
174 #if wxUSE_DATEPICKCTRL
175
176 // Define a simple modal dialog which asks the user for a date
177 class MyDialog : public wxDialog
178 {
179 public:
180 MyDialog(wxWindow *parent, const wxDateTime& dt, int dtpStyle);
181
182 wxDateTime GetDate() const { return m_datePicker->GetValue(); }
183
184 private:
185 void OnDateChange(wxDateEvent& event);
186
187
188 wxDatePickerCtrlBase *m_datePicker;
189 wxTextCtrl *m_text;
190
191
192 DECLARE_EVENT_TABLE()
193 };
194
195 #endif // wxUSE_DATEPICKCTRL
196
197 // ----------------------------------------------------------------------------
198 // constants
199 // ----------------------------------------------------------------------------
200
201 // IDs for the controls and the menu commands
202 enum
203 {
204 // menu items
205 Calendar_File_About = wxID_ABOUT,
206 Calendar_File_ClearLog = wxID_CLEAR,
207 Calendar_File_Quit = wxID_EXIT,
208 Calendar_Cal_Generic = 200,
209 Calendar_Cal_Monday,
210 Calendar_Cal_Holidays,
211 Calendar_Cal_Special,
212 Calendar_Cal_Month,
213 Calendar_Cal_SeqMonth,
214 Calendar_Cal_SurroundWeeks,
215 Calendar_Cal_SetDate,
216 Calendar_Cal_Today,
217 Calendar_Cal_BeginDST,
218 Calendar_Cal_Resizable,
219 #if wxUSE_DATEPICKCTRL
220 Calendar_DatePicker_AskDate = 300,
221 Calendar_DatePicker_ShowCentury,
222 Calendar_DatePicker_DropDown,
223 Calendar_DatePicker_AllowNone,
224 Calendar_DatePicker_StartWithNone,
225 #if wxUSE_DATEPICKCTRL_GENERIC
226 Calendar_DatePicker_Generic,
227 #endif // wxUSE_DATEPICKCTRL_GENERIC
228 #endif // wxUSE_DATEPICKCTRL
229 Calendar_CalCtrl = 1000
230 };
231
232 // ----------------------------------------------------------------------------
233 // event tables and other macros for wxWidgets
234 // ----------------------------------------------------------------------------
235
236 // the event tables connect the wxWidgets events with the functions (event
237 // handlers) which process them. It can be also done at run-time, but for the
238 // simple menu events like this the static method is much simpler.
239 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
240 EVT_MENU(Calendar_File_About, MyFrame::OnAbout)
241 EVT_MENU(Calendar_File_ClearLog, MyFrame::OnClearLog)
242 EVT_MENU(Calendar_File_Quit, MyFrame::OnQuit)
243
244 #if wxUSE_DATEPICKCTRL
245 EVT_MENU(Calendar_DatePicker_AskDate, MyFrame::OnAskDate)
246
247 EVT_UPDATE_UI(Calendar_DatePicker_StartWithNone,
248 MyFrame::OnUpdateUIStartWithNone)
249 #endif // wxUSE_DATEPICKCTRL
250
251 #ifdef wxHAS_NATIVE_CALENDARCTRL
252 EVT_MENU(Calendar_Cal_Generic, MyFrame::OnCalGeneric)
253 #endif // wxHAS_NATIVE_CALENDARCTRL
254
255 EVT_MENU(Calendar_Cal_Monday, MyFrame::OnCalMonday)
256 EVT_MENU(Calendar_Cal_Holidays, MyFrame::OnCalHolidays)
257 EVT_MENU(Calendar_Cal_Special, MyFrame::OnCalSpecial)
258
259 EVT_MENU(Calendar_Cal_Month, MyFrame::OnCalAllowMonth)
260
261 EVT_MENU(Calendar_Cal_SeqMonth, MyFrame::OnCalSeqMonth)
262 EVT_MENU(Calendar_Cal_SurroundWeeks, MyFrame::OnCalShowSurroundingWeeks)
263
264 EVT_MENU(Calendar_Cal_SetDate, MyFrame::OnSetDate)
265 EVT_MENU(Calendar_Cal_Today, MyFrame::OnToday)
266 EVT_MENU(Calendar_Cal_BeginDST, MyFrame::OnBeginDST)
267
268 EVT_MENU(Calendar_Cal_Resizable, MyFrame::OnCalToggleResizable)
269
270
271 EVT_UPDATE_UI(Calendar_Cal_SeqMonth, MyFrame::OnUpdateUIGenericOnly)
272 EVT_UPDATE_UI(Calendar_Cal_Monday, MyFrame::OnUpdateUIGenericOnly)
273 EVT_UPDATE_UI(Calendar_Cal_Holidays, MyFrame::OnUpdateUIGenericOnly)
274 EVT_UPDATE_UI(Calendar_Cal_Special, MyFrame::OnUpdateUIGenericOnly)
275 EVT_UPDATE_UI(Calendar_Cal_SurroundWeeks, MyFrame::OnUpdateUIGenericOnly)
276 END_EVENT_TABLE()
277
278 BEGIN_EVENT_TABLE(MyPanel, wxPanel)
279 EVT_CALENDAR(Calendar_CalCtrl, MyPanel::OnCalendar)
280 EVT_CALENDAR_PAGE_CHANGED(Calendar_CalCtrl, MyPanel::OnCalMonthChange)
281 EVT_CALENDAR_SEL_CHANGED(Calendar_CalCtrl, MyPanel::OnCalendarChange)
282 EVT_CALENDAR_WEEKDAY_CLICKED(Calendar_CalCtrl, MyPanel::OnCalendarWeekDayClick)
283 END_EVENT_TABLE()
284
285 #if wxUSE_DATEPICKCTRL
286
287 BEGIN_EVENT_TABLE(MyDialog, wxDialog)
288 EVT_DATE_CHANGED(wxID_ANY, MyDialog::OnDateChange)
289 END_EVENT_TABLE()
290
291 #endif // wxUSE_DATEPICKCTRL
292
293 // Create a new application object: this macro will allow wxWidgets to create
294 // the application object during program execution (it's better than using a
295 // static object for many reasons) and also declares the accessor function
296 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
297 // not wxApp)
298 IMPLEMENT_APP(MyApp)
299
300 // ============================================================================
301 // implementation
302 // ============================================================================
303
304 // ----------------------------------------------------------------------------
305 // the application class
306 // ----------------------------------------------------------------------------
307
308 // `Main program' equivalent: the program execution "starts" here
309 bool MyApp::OnInit()
310 {
311 if ( !wxApp::OnInit() )
312 return false;
313
314 // Create the main application window
315 MyFrame *frame = new MyFrame(_T("Calendar wxWidgets sample")
316 #ifndef __WXWINCE__
317 ,wxPoint(50, 50), wxSize(450, 340)
318 #endif
319 );
320
321 frame->Show(true);
322
323 // success: wxApp::OnRun() will be called which will enter the main message
324 // loop and the application will run. If we returned false here, the
325 // application would exit immediately.
326 return true;
327 }
328
329 // ----------------------------------------------------------------------------
330 // main frame
331 // ----------------------------------------------------------------------------
332
333 // frame constructor
334 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
335 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size)
336 {
337 // set the frame icon
338 SetIcon(wxIcon(sample_xpm));
339
340 // create a menu bar
341 wxMenu *menuFile = new wxMenu;
342 menuFile->Append(Calendar_File_About, _T("&About...\tCtrl-A"), _T("Show about dialog"));
343 menuFile->AppendSeparator();
344 menuFile->Append(Calendar_File_ClearLog, _T("&Clear log\tCtrl-L"));
345 menuFile->AppendSeparator();
346 menuFile->Append(Calendar_File_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
347
348 wxMenu *menuCal = new wxMenu;
349 #ifdef wxHAS_NATIVE_CALENDARCTRL
350 menuCal->AppendCheckItem(Calendar_Cal_Generic, "Use &generic version\tCtrl-G",
351 "Toggle between native and generic control");
352 menuCal->AppendSeparator();
353 #endif // wxHAS_NATIVE_CALENDARCTRL
354 menuCal->Append(Calendar_Cal_Monday,
355 _T("Monday &first weekday\tCtrl-F"),
356 _T("Toggle between Mon and Sun as the first week day"),
357 true);
358 menuCal->Append(Calendar_Cal_Holidays, _T("Show &holidays\tCtrl-H"),
359 _T("Toggle highlighting the holidays"),
360 true);
361 menuCal->Append(Calendar_Cal_Special, _T("Highlight &special dates\tCtrl-S"),
362 _T("Test custom highlighting"),
363 true);
364 menuCal->Append(Calendar_Cal_SurroundWeeks,
365 _T("Show s&urrounding weeks\tCtrl-W"),
366 _T("Show the neighbouring weeks in the prev/next month"),
367 true);
368 menuCal->AppendSeparator();
369 menuCal->Append(Calendar_Cal_SeqMonth,
370 _T("Toggle month selector st&yle\tCtrl-Y"),
371 _T("Use another style for the calendar controls"),
372 true);
373 menuCal->Append(Calendar_Cal_Month, _T("&Month can be changed\tCtrl-M"),
374 _T("Allow changing the month in the calendar"),
375 true);
376 menuCal->AppendSeparator();
377 menuCal->Append(Calendar_Cal_SetDate, _T("Call &SetDate(2005-12-24)"), _T("Set date to 2005-12-24."));
378 menuCal->Append(Calendar_Cal_Today, _T("Call &Today()"), _T("Set to the current date."));
379 menuCal->Append(Calendar_Cal_BeginDST, "Call SetDate(GetBeginDST())");
380 menuCal->AppendSeparator();
381 menuCal->AppendCheckItem(Calendar_Cal_Resizable, _T("Make &resizable\tCtrl-R"));
382
383 #if wxUSE_DATEPICKCTRL
384 wxMenu *menuDate = new wxMenu;
385 menuDate->AppendCheckItem(Calendar_DatePicker_ShowCentury,
386 _T("Al&ways show century"));
387 menuDate->AppendCheckItem(Calendar_DatePicker_DropDown,
388 _T("Use &drop down control"));
389 menuDate->AppendCheckItem(Calendar_DatePicker_AllowNone,
390 _T("Allow &no date"));
391 menuDate->AppendCheckItem(Calendar_DatePicker_StartWithNone,
392 _T("Start &with no date"));
393 #if wxUSE_DATEPICKCTRL_GENERIC
394 menuDate->AppendCheckItem(Calendar_DatePicker_Generic,
395 _T("Use &generic version of the control"));
396 #endif // wxUSE_DATEPICKCTRL_GENERIC
397 menuDate->AppendSeparator();
398 menuDate->Append(Calendar_DatePicker_AskDate, _T("&Choose date...\tCtrl-D"), _T("Show dialog with wxDatePickerCtrl"));
399 #endif // wxUSE_DATEPICKCTRL
400
401 // now append the freshly created menu to the menu bar...
402 wxMenuBar *menuBar = new wxMenuBar;
403 menuBar->Append(menuFile, _T("&File"));
404 menuBar->Append(menuCal, _T("&Calendar"));
405 #if wxUSE_DATEPICKCTRL
406 menuBar->Append(menuDate, _T("&Date picker"));
407 #endif // wxUSE_DATEPICKCTRL
408
409 menuBar->Check(Calendar_Cal_Monday, true);
410 menuBar->Check(Calendar_Cal_Holidays, true);
411 menuBar->Check(Calendar_Cal_Month, true);
412
413 #if wxUSE_DATEPICKCTRL
414 menuBar->Check(Calendar_DatePicker_ShowCentury, true);
415 #endif // wxUSE_DATEPICKCTRL
416
417 // ... and attach this menu bar to the frame
418 SetMenuBar(menuBar);
419
420 wxSplitterWindow *splitter = new wxSplitterWindow(this, wxID_ANY,
421 wxDefaultPosition, wxDefaultSize,
422 wxSP_NOBORDER);
423 m_panel = new MyPanel(splitter);
424 m_logWindow = new wxTextCtrl(splitter, wxID_ANY, wxEmptyString,
425 wxDefaultPosition, wxDefaultSize,
426 wxTE_READONLY | wxTE_MULTILINE);
427 splitter->SplitHorizontally(m_panel, m_logWindow);
428 splitter->SetMinimumPaneSize(20);
429 wxLog::SetActiveTarget(new wxLogTextCtrl(m_logWindow));
430 }
431
432 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
433 {
434 // true is to force the frame to close
435 Close(true);
436 }
437
438 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
439 {
440 wxMessageBox(_T("wxCalendarCtrl sample\n(c) 2000--2008 Vadim Zeitlin"),
441 _T("About Calendar"), wxOK | wxICON_INFORMATION, this);
442 }
443
444 void MyFrame::OnClearLog(wxCommandEvent& WXUNUSED(event))
445 {
446 m_logWindow->Clear();
447 }
448
449 void MyFrame::OnCalMonday(wxCommandEvent& event)
450 {
451 m_panel->ToggleCalStyle(event.IsChecked(), wxCAL_MONDAY_FIRST);
452 }
453
454 void MyFrame::OnCalHolidays(wxCommandEvent& event)
455 {
456 m_panel->GetCal()->EnableHolidayDisplay(event.IsChecked());
457 }
458
459 void MyFrame::OnCalSpecial(wxCommandEvent& event)
460 {
461 m_panel->HighlightSpecial(GetMenuBar()->IsChecked(event.GetId()));
462 }
463
464 void MyFrame::OnCalAllowMonth(wxCommandEvent& event)
465 {
466 m_panel->GetCal()->EnableMonthChange(event.IsChecked());
467 }
468
469 void MyFrame::OnCalSeqMonth(wxCommandEvent& event)
470 {
471 m_panel->ToggleCalStyle(event.IsChecked(),
472 wxCAL_SEQUENTIAL_MONTH_SELECTION);
473 }
474
475 void MyFrame::OnCalShowSurroundingWeeks(wxCommandEvent& event)
476 {
477 m_panel->ToggleCalStyle(event.IsChecked(), wxCAL_SHOW_SURROUNDING_WEEKS);
478 }
479
480 void MyFrame::OnSetDate(wxCommandEvent &WXUNUSED(event))
481 {
482 m_panel->SetDate(wxDateTime(24, wxDateTime::Dec, 2005, 22, 00, 00));
483 }
484
485 void MyFrame::OnToday(wxCommandEvent &WXUNUSED(event))
486 {
487 m_panel->SetDate(wxDateTime::Today());
488 }
489
490 void MyFrame::OnBeginDST(wxCommandEvent &WXUNUSED(event))
491 {
492 m_panel->SetDate(wxDateTime::GetBeginDST(m_panel->GetDate().GetYear()));
493 }
494
495 void MyFrame::OnCalToggleResizable(wxCommandEvent& event)
496 {
497 wxSizer * const sizer = m_panel->GetSizer();
498 wxSizerItem * const item = sizer->GetItem(m_panel->GetCal());
499 if ( event.IsChecked() )
500 {
501 item->SetProportion(1);
502 item->SetFlag(wxEXPAND);
503 }
504 else // not resizable
505 {
506 item->SetProportion(0);
507 item->SetFlag(wxALIGN_CENTER);
508 }
509
510 sizer->Layout();
511 }
512
513 void MyFrame::OnCalRClick(wxMouseEvent& event)
514 {
515 wxDateTime dt;
516 wxDateTime::WeekDay wd;
517
518 const wxPoint pt = event.GetPosition();
519 wxString msg = wxString::Format("Point (%d, %d) is ", pt.x, pt.y);
520
521 switch ( m_panel->GetCal()->HitTest(pt, &dt, &wd) )
522 {
523 default:
524 wxFAIL_MSG( "unexpected" );
525 // fall through
526
527 case wxCAL_HITTEST_NOWHERE:
528 msg += "nowhere";
529 break;
530
531 case wxCAL_HITTEST_HEADER:
532 msg += wxString::Format("over %s", wxDateTime::GetWeekDayName(wd));
533 break;
534
535 case wxCAL_HITTEST_DAY:
536 msg += wxString::Format("over %s", dt.FormatISODate());
537 break;
538
539 case wxCAL_HITTEST_INCMONTH:
540 msg += "over next month button";
541 break;
542
543 case wxCAL_HITTEST_DECMONTH:
544 msg += "over previous month button";
545 break;
546
547 case wxCAL_HITTEST_SURROUNDING_WEEK:
548 msg += "over a day from another month";
549 break;
550 }
551
552 wxLogMessage("%s", msg);
553 }
554
555 #if wxUSE_DATEPICKCTRL
556
557 void MyFrame::OnUpdateUIStartWithNone(wxUpdateUIEvent& event)
558 {
559 // it only makes sense to start with invalid date if we can have no date
560 event.Enable( GetMenuBar()->IsChecked(Calendar_DatePicker_AllowNone) );
561 }
562
563 void MyFrame::OnAskDate(wxCommandEvent& WXUNUSED(event))
564 {
565 wxDateTime dt = m_panel->GetCal()->GetDate();
566
567 int style = wxDP_DEFAULT;
568 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_ShowCentury) )
569 style |= wxDP_SHOWCENTURY;
570 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_DropDown) )
571 style |= wxDP_DROPDOWN;
572 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_AllowNone) )
573 {
574 style |= wxDP_ALLOWNONE;
575
576 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_StartWithNone) )
577 dt = wxDefaultDateTime;
578 }
579
580 MyDialog dlg(this, dt, style);
581 if ( dlg.ShowModal() == wxID_OK )
582 {
583 dt = dlg.GetDate();
584 if ( dt.IsValid() )
585 {
586 const wxDateTime today = wxDateTime::Today();
587
588 if ( dt.GetDay() == today.GetDay() &&
589 dt.GetMonth() == today.GetMonth() )
590 {
591 wxMessageBox(_T("Happy birthday!"), _T("Calendar Sample"));
592 }
593
594 m_panel->SetDate(dt);
595
596 wxLogStatus(_T("Changed the date to your input"));
597 }
598 else
599 {
600 wxLogStatus(_T("No date entered"));
601 }
602 }
603 }
604
605 #endif // wxUSE_DATEPICKCTRL
606
607 // ----------------------------------------------------------------------------
608 // MyPanel
609 // ----------------------------------------------------------------------------
610
611 MyPanel::MyPanel(wxWindow *parent)
612 : wxPanel(parent, wxID_ANY)
613 {
614 #ifdef wxHAS_NATIVE_CALENDARCTRL
615 m_usingGeneric = false;
616 #else
617 m_usingGeneric = true;
618 #endif
619
620 wxString date;
621 date.Printf(wxT("Selected date: %s"),
622 wxDateTime::Today().FormatISODate().c_str());
623 m_date = new wxStaticText(this, wxID_ANY, date);
624 m_calendar = DoCreateCalendar(wxDefaultDateTime,
625 wxCAL_MONDAY_FIRST | wxCAL_SHOW_HOLIDAYS);
626
627 // adjust to vertical/horizontal display, check mostly dedicated to WinCE
628 bool horizontal = ( wxSystemSettings::GetMetric(wxSYS_SCREEN_X) > wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) );
629 m_sizer = new wxBoxSizer( horizontal ? wxHORIZONTAL : wxVERTICAL );
630
631 m_sizer->Add(m_date, 0, wxALIGN_CENTER | wxALL, 10 );
632 m_sizer->Add(m_calendar, 0, wxALIGN_CENTER | wxALIGN_LEFT);
633
634 SetSizer( m_sizer );
635 m_sizer->SetSizeHints( this );
636 }
637
638 void MyPanel::OnCalendar(wxCalendarEvent& event)
639 {
640 // clicking the same date twice unmarks it (convenient for testing)
641 static wxDateTime s_dateLast;
642 const bool mark = !s_dateLast.IsValid() || event.GetDate() != s_dateLast;
643
644 s_dateLast = event.GetDate();
645
646 m_calendar->Mark(event.GetDate().GetDay(), mark);
647 wxLogMessage(wxT("Selected (and %smarked) %s from calendar."),
648 mark ? "" : "un", s_dateLast.FormatISODate().c_str());
649 }
650
651 void MyPanel::OnCalendarChange(wxCalendarEvent& event)
652 {
653 wxString s;
654 s.Printf(wxT("Selected date: %s"), event.GetDate().FormatISODate().c_str());
655
656 m_date->SetLabel(s);
657 wxLogStatus(s);
658 }
659
660 void MyPanel::OnCalMonthChange(wxCalendarEvent& event)
661 {
662 wxLogStatus(wxT("Calendar month changed to %s %d"),
663 wxDateTime::GetMonthName(event.GetDate().GetMonth()),
664 event.GetDate().GetYear());
665 }
666
667 void MyPanel::OnCalendarWeekDayClick(wxCalendarEvent& event)
668 {
669 wxLogMessage(wxT("Clicked on %s"),
670 wxDateTime::GetWeekDayName(event.GetWeekDay()).c_str());
671 }
672
673 wxCalendarCtrlBase *MyPanel::DoCreateCalendar(const wxDateTime& dt, long style)
674 {
675 wxCalendarCtrlBase *calendar;
676 #ifdef wxHAS_NATIVE_CALENDARCTRL
677 if ( m_usingGeneric )
678 calendar = new wxGenericCalendarCtrl(this, Calendar_CalCtrl,
679 dt,
680 wxDefaultPosition,
681 wxDefaultSize,
682 style);
683 else
684 #endif // wxHAS_NATIVE_CALENDARCTRL
685 calendar = new wxCalendarCtrl(this, Calendar_CalCtrl,
686 dt,
687 wxDefaultPosition,
688 wxDefaultSize,
689 style);
690
691 calendar->Connect(wxEVT_RIGHT_DOWN,
692 wxMouseEventHandler(MyFrame::OnCalRClick),
693 NULL,
694 wxGetTopLevelParent(this));
695
696 return calendar;
697 }
698
699 void MyPanel::RecreateCalendar(long style)
700 {
701 wxCalendarCtrlBase *calendar = DoCreateCalendar(m_calendar->GetDate(), style);
702
703 m_sizer->Replace(m_calendar, calendar);
704 delete m_calendar;
705 m_calendar = calendar;
706
707 m_sizer->Layout();
708 }
709
710 void MyPanel::ToggleCalStyle(bool on, int flag)
711 {
712 long style = m_calendar->GetWindowStyle();
713 if ( on )
714 style |= flag;
715 else
716 style &= ~flag;
717
718 if ( flag == wxCAL_SEQUENTIAL_MONTH_SELECTION )
719 {
720 // changing this style requires recreating the control
721 RecreateCalendar(style);
722 }
723 else // just changing the style is enough
724 {
725 m_calendar->SetWindowStyle(style);
726
727 m_calendar->Refresh();
728 }
729 }
730
731 void MyPanel::HighlightSpecial(bool on)
732 {
733 if ( on )
734 {
735 wxCalendarDateAttr
736 *attrRedCircle = new wxCalendarDateAttr(wxCAL_BORDER_ROUND, *wxRED),
737 *attrGreenSquare = new wxCalendarDateAttr(wxCAL_BORDER_SQUARE, *wxGREEN),
738 *attrHeaderLike = new wxCalendarDateAttr(*wxBLUE, *wxLIGHT_GREY);
739
740 m_calendar->SetAttr(17, attrRedCircle);
741 m_calendar->SetAttr(29, attrGreenSquare);
742 m_calendar->SetAttr(13, attrHeaderLike);
743 }
744 else // off
745 {
746 m_calendar->ResetAttr(17);
747 m_calendar->ResetAttr(29);
748 m_calendar->ResetAttr(13);
749 }
750
751 m_calendar->Refresh();
752 }
753
754
755 // ----------------------------------------------------------------------------
756 // MyDialog
757 // ----------------------------------------------------------------------------
758
759 #if wxUSE_DATEPICKCTRL
760
761 MyDialog::MyDialog(wxWindow *parent, const wxDateTime& dt, int dtpStyle)
762 : wxDialog(parent, wxID_ANY, wxString(_T("Calendar: Choose a date")))
763 {
764 wxStdDialogButtonSizer *sizerBtns = new wxStdDialogButtonSizer;
765 sizerBtns->AddButton(new wxButton(this, wxID_OK));
766 sizerBtns->AddButton(new wxButton(this, wxID_CANCEL));
767 sizerBtns->Realize();
768
769 wxSizer *sizerText = new wxBoxSizer(wxHORIZONTAL);
770 sizerText->Add(new wxStaticText(this, wxID_ANY, _T("Date in ISO format: ")),
771 wxSizerFlags().Border().Align(wxALIGN_CENTRE_VERTICAL));
772 m_text = new wxTextCtrl(this, wxID_ANY);
773 sizerText->Add(m_text, wxSizerFlags().
774 Expand().Border().Align(wxALIGN_CENTRE_VERTICAL));
775
776 wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
777 sizerTop->Add(new wxStaticText
778 (
779 this, wxID_ANY,
780 _T("Enter your birthday date (not before 20th century):")
781 ),
782 wxSizerFlags().Border());
783
784 #if wxUSE_DATEPICKCTRL_GENERIC
785 wxFrame *frame = (wxFrame *)wxGetTopLevelParent(parent);
786 if ( frame && frame->GetMenuBar()->IsChecked(Calendar_DatePicker_Generic) )
787 m_datePicker = new wxDatePickerCtrlGeneric(this, wxID_ANY, dt,
788 wxDefaultPosition,
789 wxDefaultSize,
790 dtpStyle);
791 else
792 #endif // wxUSE_DATEPICKCTRL_GENERIC
793 m_datePicker = new wxDatePickerCtrl(this, wxID_ANY, dt,
794 wxDefaultPosition, wxDefaultSize,
795 dtpStyle);
796 m_datePicker->SetRange(wxDateTime(1, wxDateTime::Jan, 1900),
797 wxDefaultDateTime);
798 sizerTop->Add(m_datePicker, wxSizerFlags().Expand().Border());
799
800 sizerTop->AddStretchSpacer(1);
801 sizerTop->Add(sizerText);
802
803 sizerTop->Add(sizerBtns, wxSizerFlags().Centre().Border());
804
805 SetSizerAndFit(sizerTop);
806 Layout();
807 }
808
809 void MyDialog::OnDateChange(wxDateEvent& event)
810 {
811 const wxDateTime dt = event.GetDate();
812 if ( dt.IsValid() )
813 m_text->SetValue(dt.FormatISODate());
814 else
815 m_text->SetValue(wxEmptyString);
816 }
817
818 #endif // wxUSE_DATEPICKCTRL