implemented toggling of wxCAL_MONDAY_FIRST 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 #ifdef __WXGTK20__
273 EVT_UPDATE_UI(Calendar_Cal_Monday, MyFrame::OnUpdateUIGenericOnly)
274 #endif
275 EVT_UPDATE_UI(Calendar_Cal_Holidays, MyFrame::OnUpdateUIGenericOnly)
276 EVT_UPDATE_UI(Calendar_Cal_Special, MyFrame::OnUpdateUIGenericOnly)
277 EVT_UPDATE_UI(Calendar_Cal_SurroundWeeks, MyFrame::OnUpdateUIGenericOnly)
278 END_EVENT_TABLE()
279
280 BEGIN_EVENT_TABLE(MyPanel, wxPanel)
281 EVT_CALENDAR(Calendar_CalCtrl, MyPanel::OnCalendar)
282 EVT_CALENDAR_PAGE_CHANGED(Calendar_CalCtrl, MyPanel::OnCalMonthChange)
283 EVT_CALENDAR_SEL_CHANGED(Calendar_CalCtrl, MyPanel::OnCalendarChange)
284 EVT_CALENDAR_WEEKDAY_CLICKED(Calendar_CalCtrl, MyPanel::OnCalendarWeekDayClick)
285 END_EVENT_TABLE()
286
287 #if wxUSE_DATEPICKCTRL
288
289 BEGIN_EVENT_TABLE(MyDialog, wxDialog)
290 EVT_DATE_CHANGED(wxID_ANY, MyDialog::OnDateChange)
291 END_EVENT_TABLE()
292
293 #endif // wxUSE_DATEPICKCTRL
294
295 // Create a new application object: this macro will allow wxWidgets to create
296 // the application object during program execution (it's better than using a
297 // static object for many reasons) and also declares the accessor function
298 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
299 // not wxApp)
300 IMPLEMENT_APP(MyApp)
301
302 // ============================================================================
303 // implementation
304 // ============================================================================
305
306 // ----------------------------------------------------------------------------
307 // the application class
308 // ----------------------------------------------------------------------------
309
310 // `Main program' equivalent: the program execution "starts" here
311 bool MyApp::OnInit()
312 {
313 if ( !wxApp::OnInit() )
314 return false;
315
316 // Create the main application window
317 MyFrame *frame = new MyFrame(_T("Calendar wxWidgets sample")
318 #ifndef __WXWINCE__
319 ,wxPoint(50, 50), wxSize(450, 340)
320 #endif
321 );
322
323 frame->Show(true);
324
325 // success: wxApp::OnRun() will be called which will enter the main message
326 // loop and the application will run. If we returned false here, the
327 // application would exit immediately.
328 return true;
329 }
330
331 // ----------------------------------------------------------------------------
332 // main frame
333 // ----------------------------------------------------------------------------
334
335 // frame constructor
336 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
337 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size)
338 {
339 // set the frame icon
340 SetIcon(wxIcon(sample_xpm));
341
342 // create a menu bar
343 wxMenu *menuFile = new wxMenu;
344 menuFile->Append(Calendar_File_About, _T("&About...\tCtrl-A"), _T("Show about dialog"));
345 menuFile->AppendSeparator();
346 menuFile->Append(Calendar_File_ClearLog, _T("&Clear log\tCtrl-L"));
347 menuFile->AppendSeparator();
348 menuFile->Append(Calendar_File_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
349
350 wxMenu *menuCal = new wxMenu;
351 #ifdef wxHAS_NATIVE_CALENDARCTRL
352 menuCal->AppendCheckItem(Calendar_Cal_Generic, "Use &generic version\tCtrl-G",
353 "Toggle between native and generic control");
354 menuCal->AppendSeparator();
355 #endif // wxHAS_NATIVE_CALENDARCTRL
356 menuCal->Append(Calendar_Cal_Monday,
357 _T("Monday &first weekday\tCtrl-F"),
358 _T("Toggle between Mon and Sun as the first week day"),
359 true);
360 menuCal->Append(Calendar_Cal_Holidays, _T("Show &holidays\tCtrl-H"),
361 _T("Toggle highlighting the holidays"),
362 true);
363 menuCal->Append(Calendar_Cal_Special, _T("Highlight &special dates\tCtrl-S"),
364 _T("Test custom highlighting"),
365 true);
366 menuCal->Append(Calendar_Cal_SurroundWeeks,
367 _T("Show s&urrounding weeks\tCtrl-W"),
368 _T("Show the neighbouring weeks in the prev/next month"),
369 true);
370 menuCal->AppendSeparator();
371 menuCal->Append(Calendar_Cal_SeqMonth,
372 _T("Toggle month selector st&yle\tCtrl-Y"),
373 _T("Use another style for the calendar controls"),
374 true);
375 menuCal->Append(Calendar_Cal_Month, _T("&Month can be changed\tCtrl-M"),
376 _T("Allow changing the month in the calendar"),
377 true);
378 menuCal->AppendSeparator();
379 menuCal->Append(Calendar_Cal_SetDate, _T("Call &SetDate(2005-12-24)"), _T("Set date to 2005-12-24."));
380 menuCal->Append(Calendar_Cal_Today, _T("Call &Today()"), _T("Set to the current date."));
381 menuCal->Append(Calendar_Cal_BeginDST, "Call SetDate(GetBeginDST())");
382 menuCal->AppendSeparator();
383 menuCal->AppendCheckItem(Calendar_Cal_Resizable, _T("Make &resizable\tCtrl-R"));
384
385 #if wxUSE_DATEPICKCTRL
386 wxMenu *menuDate = new wxMenu;
387 menuDate->AppendCheckItem(Calendar_DatePicker_ShowCentury,
388 _T("Al&ways show century"));
389 menuDate->AppendCheckItem(Calendar_DatePicker_DropDown,
390 _T("Use &drop down control"));
391 menuDate->AppendCheckItem(Calendar_DatePicker_AllowNone,
392 _T("Allow &no date"));
393 menuDate->AppendCheckItem(Calendar_DatePicker_StartWithNone,
394 _T("Start &with no date"));
395 #if wxUSE_DATEPICKCTRL_GENERIC
396 menuDate->AppendCheckItem(Calendar_DatePicker_Generic,
397 _T("Use &generic version of the control"));
398 #endif // wxUSE_DATEPICKCTRL_GENERIC
399 menuDate->AppendSeparator();
400 menuDate->Append(Calendar_DatePicker_AskDate, _T("&Choose date...\tCtrl-D"), _T("Show dialog with wxDatePickerCtrl"));
401 #endif // wxUSE_DATEPICKCTRL
402
403 // now append the freshly created menu to the menu bar...
404 wxMenuBar *menuBar = new wxMenuBar;
405 menuBar->Append(menuFile, _T("&File"));
406 menuBar->Append(menuCal, _T("&Calendar"));
407 #if wxUSE_DATEPICKCTRL
408 menuBar->Append(menuDate, _T("&Date picker"));
409 #endif // wxUSE_DATEPICKCTRL
410
411 menuBar->Check(Calendar_Cal_Monday, true);
412 menuBar->Check(Calendar_Cal_Holidays, true);
413 menuBar->Check(Calendar_Cal_Month, true);
414
415 #if wxUSE_DATEPICKCTRL
416 menuBar->Check(Calendar_DatePicker_ShowCentury, true);
417 #endif // wxUSE_DATEPICKCTRL
418
419 // ... and attach this menu bar to the frame
420 SetMenuBar(menuBar);
421
422 wxSplitterWindow *splitter = new wxSplitterWindow(this, wxID_ANY,
423 wxDefaultPosition, wxDefaultSize,
424 wxSP_NOBORDER);
425 m_panel = new MyPanel(splitter);
426 m_logWindow = new wxTextCtrl(splitter, wxID_ANY, wxEmptyString,
427 wxDefaultPosition, wxDefaultSize,
428 wxTE_READONLY | wxTE_MULTILINE);
429 splitter->SplitHorizontally(m_panel, m_logWindow);
430 splitter->SetMinimumPaneSize(20);
431 wxLog::SetActiveTarget(new wxLogTextCtrl(m_logWindow));
432 }
433
434 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
435 {
436 // true is to force the frame to close
437 Close(true);
438 }
439
440 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
441 {
442 wxMessageBox(_T("wxCalendarCtrl sample\n(c) 2000--2008 Vadim Zeitlin"),
443 _T("About Calendar"), wxOK | wxICON_INFORMATION, this);
444 }
445
446 void MyFrame::OnClearLog(wxCommandEvent& WXUNUSED(event))
447 {
448 m_logWindow->Clear();
449 }
450
451 void MyFrame::OnCalMonday(wxCommandEvent& event)
452 {
453 m_panel->ToggleCalStyle(event.IsChecked(), wxCAL_MONDAY_FIRST);
454 }
455
456 void MyFrame::OnCalHolidays(wxCommandEvent& event)
457 {
458 m_panel->GetCal()->EnableHolidayDisplay(event.IsChecked());
459 }
460
461 void MyFrame::OnCalSpecial(wxCommandEvent& event)
462 {
463 m_panel->HighlightSpecial(GetMenuBar()->IsChecked(event.GetId()));
464 }
465
466 void MyFrame::OnCalAllowMonth(wxCommandEvent& event)
467 {
468 m_panel->GetCal()->EnableMonthChange(event.IsChecked());
469 }
470
471 void MyFrame::OnCalSeqMonth(wxCommandEvent& event)
472 {
473 m_panel->ToggleCalStyle(event.IsChecked(),
474 wxCAL_SEQUENTIAL_MONTH_SELECTION);
475 }
476
477 void MyFrame::OnCalShowSurroundingWeeks(wxCommandEvent& event)
478 {
479 m_panel->ToggleCalStyle(event.IsChecked(), wxCAL_SHOW_SURROUNDING_WEEKS);
480 }
481
482 void MyFrame::OnSetDate(wxCommandEvent &WXUNUSED(event))
483 {
484 m_panel->SetDate(wxDateTime(24, wxDateTime::Dec, 2005, 22, 00, 00));
485 }
486
487 void MyFrame::OnToday(wxCommandEvent &WXUNUSED(event))
488 {
489 m_panel->SetDate(wxDateTime::Today());
490 }
491
492 void MyFrame::OnBeginDST(wxCommandEvent &WXUNUSED(event))
493 {
494 m_panel->SetDate(wxDateTime::GetBeginDST(m_panel->GetDate().GetYear()));
495 }
496
497 void MyFrame::OnCalToggleResizable(wxCommandEvent& event)
498 {
499 wxSizer * const sizer = m_panel->GetSizer();
500 wxSizerItem * const item = sizer->GetItem(m_panel->GetCal());
501 if ( event.IsChecked() )
502 {
503 item->SetProportion(1);
504 item->SetFlag(wxEXPAND);
505 }
506 else // not resizable
507 {
508 item->SetProportion(0);
509 item->SetFlag(wxALIGN_CENTER);
510 }
511
512 sizer->Layout();
513 }
514
515 void MyFrame::OnCalRClick(wxMouseEvent& event)
516 {
517 wxDateTime dt;
518 wxDateTime::WeekDay wd;
519
520 const wxPoint pt = event.GetPosition();
521 wxString msg = wxString::Format("Point (%d, %d) is ", pt.x, pt.y);
522
523 switch ( m_panel->GetCal()->HitTest(pt, &dt, &wd) )
524 {
525 default:
526 wxFAIL_MSG( "unexpected" );
527 // fall through
528
529 case wxCAL_HITTEST_NOWHERE:
530 msg += "nowhere";
531 break;
532
533 case wxCAL_HITTEST_HEADER:
534 msg += wxString::Format("over %s", wxDateTime::GetWeekDayName(wd));
535 break;
536
537 case wxCAL_HITTEST_DAY:
538 msg += wxString::Format("over %s", dt.FormatISODate());
539 break;
540
541 case wxCAL_HITTEST_INCMONTH:
542 msg += "over next month button";
543 break;
544
545 case wxCAL_HITTEST_DECMONTH:
546 msg += "over previous month button";
547 break;
548
549 case wxCAL_HITTEST_SURROUNDING_WEEK:
550 msg += "over a day from another month";
551 break;
552 }
553
554 wxLogMessage("%s", msg);
555 }
556
557 #if wxUSE_DATEPICKCTRL
558
559 void MyFrame::OnUpdateUIStartWithNone(wxUpdateUIEvent& event)
560 {
561 // it only makes sense to start with invalid date if we can have no date
562 event.Enable( GetMenuBar()->IsChecked(Calendar_DatePicker_AllowNone) );
563 }
564
565 void MyFrame::OnAskDate(wxCommandEvent& WXUNUSED(event))
566 {
567 wxDateTime dt = m_panel->GetCal()->GetDate();
568
569 int style = wxDP_DEFAULT;
570 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_ShowCentury) )
571 style |= wxDP_SHOWCENTURY;
572 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_DropDown) )
573 style |= wxDP_DROPDOWN;
574 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_AllowNone) )
575 {
576 style |= wxDP_ALLOWNONE;
577
578 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_StartWithNone) )
579 dt = wxDefaultDateTime;
580 }
581
582 MyDialog dlg(this, dt, style);
583 if ( dlg.ShowModal() == wxID_OK )
584 {
585 dt = dlg.GetDate();
586 if ( dt.IsValid() )
587 {
588 const wxDateTime today = wxDateTime::Today();
589
590 if ( dt.GetDay() == today.GetDay() &&
591 dt.GetMonth() == today.GetMonth() )
592 {
593 wxMessageBox(_T("Happy birthday!"), _T("Calendar Sample"));
594 }
595
596 m_panel->SetDate(dt);
597
598 wxLogStatus(_T("Changed the date to your input"));
599 }
600 else
601 {
602 wxLogStatus(_T("No date entered"));
603 }
604 }
605 }
606
607 #endif // wxUSE_DATEPICKCTRL
608
609 // ----------------------------------------------------------------------------
610 // MyPanel
611 // ----------------------------------------------------------------------------
612
613 MyPanel::MyPanel(wxWindow *parent)
614 : wxPanel(parent, wxID_ANY)
615 {
616 #ifdef wxHAS_NATIVE_CALENDARCTRL
617 m_usingGeneric = false;
618 #else
619 m_usingGeneric = true;
620 #endif
621
622 wxString date;
623 date.Printf(wxT("Selected date: %s"),
624 wxDateTime::Today().FormatISODate().c_str());
625 m_date = new wxStaticText(this, wxID_ANY, date);
626 m_calendar = DoCreateCalendar(wxDefaultDateTime,
627 wxCAL_MONDAY_FIRST | wxCAL_SHOW_HOLIDAYS);
628
629 // adjust to vertical/horizontal display, check mostly dedicated to WinCE
630 bool horizontal = ( wxSystemSettings::GetMetric(wxSYS_SCREEN_X) > wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) );
631 m_sizer = new wxBoxSizer( horizontal ? wxHORIZONTAL : wxVERTICAL );
632
633 m_sizer->Add(m_date, 0, wxALIGN_CENTER | wxALL, 10 );
634 m_sizer->Add(m_calendar, 0, wxALIGN_CENTER | wxALIGN_LEFT);
635
636 SetSizer( m_sizer );
637 m_sizer->SetSizeHints( this );
638 }
639
640 void MyPanel::OnCalendar(wxCalendarEvent& event)
641 {
642 // clicking the same date twice unmarks it (convenient for testing)
643 static wxDateTime s_dateLast;
644 const bool mark = !s_dateLast.IsValid() || event.GetDate() != s_dateLast;
645
646 s_dateLast = event.GetDate();
647
648 m_calendar->Mark(event.GetDate().GetDay(), mark);
649 wxLogMessage(wxT("Selected (and %smarked) %s from calendar."),
650 mark ? "" : "un", s_dateLast.FormatISODate().c_str());
651 }
652
653 void MyPanel::OnCalendarChange(wxCalendarEvent& event)
654 {
655 wxString s;
656 s.Printf(wxT("Selected date: %s"), event.GetDate().FormatISODate().c_str());
657
658 m_date->SetLabel(s);
659 wxLogStatus(s);
660 }
661
662 void MyPanel::OnCalMonthChange(wxCalendarEvent& event)
663 {
664 wxLogStatus(wxT("Calendar month changed to %s %d"),
665 wxDateTime::GetMonthName(event.GetDate().GetMonth()),
666 event.GetDate().GetYear());
667 }
668
669 void MyPanel::OnCalendarWeekDayClick(wxCalendarEvent& event)
670 {
671 wxLogMessage(wxT("Clicked on %s"),
672 wxDateTime::GetWeekDayName(event.GetWeekDay()).c_str());
673 }
674
675 wxCalendarCtrlBase *MyPanel::DoCreateCalendar(const wxDateTime& dt, long style)
676 {
677 wxCalendarCtrlBase *calendar;
678 #ifdef wxHAS_NATIVE_CALENDARCTRL
679 if ( m_usingGeneric )
680 calendar = new wxGenericCalendarCtrl(this, Calendar_CalCtrl,
681 dt,
682 wxDefaultPosition,
683 wxDefaultSize,
684 style);
685 else
686 #endif // wxHAS_NATIVE_CALENDARCTRL
687 calendar = new wxCalendarCtrl(this, Calendar_CalCtrl,
688 dt,
689 wxDefaultPosition,
690 wxDefaultSize,
691 style);
692
693 calendar->Connect(wxEVT_RIGHT_DOWN,
694 wxMouseEventHandler(MyFrame::OnCalRClick),
695 NULL,
696 wxGetTopLevelParent(this));
697
698 return calendar;
699 }
700
701 void MyPanel::RecreateCalendar(long style)
702 {
703 wxCalendarCtrlBase *calendar = DoCreateCalendar(m_calendar->GetDate(), style);
704
705 m_sizer->Replace(m_calendar, calendar);
706 delete m_calendar;
707 m_calendar = calendar;
708
709 m_sizer->Layout();
710 }
711
712 void MyPanel::ToggleCalStyle(bool on, int flag)
713 {
714 long style = m_calendar->GetWindowStyle();
715 if ( on )
716 style |= flag;
717 else
718 style &= ~flag;
719
720 if ( flag == wxCAL_SEQUENTIAL_MONTH_SELECTION )
721 {
722 // changing this style requires recreating the control
723 RecreateCalendar(style);
724 }
725 else // just changing the style is enough
726 {
727 m_calendar->SetWindowStyle(style);
728
729 m_calendar->Refresh();
730 }
731 }
732
733 void MyPanel::HighlightSpecial(bool on)
734 {
735 if ( on )
736 {
737 wxCalendarDateAttr
738 *attrRedCircle = new wxCalendarDateAttr(wxCAL_BORDER_ROUND, *wxRED),
739 *attrGreenSquare = new wxCalendarDateAttr(wxCAL_BORDER_SQUARE, *wxGREEN),
740 *attrHeaderLike = new wxCalendarDateAttr(*wxBLUE, *wxLIGHT_GREY);
741
742 m_calendar->SetAttr(17, attrRedCircle);
743 m_calendar->SetAttr(29, attrGreenSquare);
744 m_calendar->SetAttr(13, attrHeaderLike);
745 }
746 else // off
747 {
748 m_calendar->ResetAttr(17);
749 m_calendar->ResetAttr(29);
750 m_calendar->ResetAttr(13);
751 }
752
753 m_calendar->Refresh();
754 }
755
756
757 // ----------------------------------------------------------------------------
758 // MyDialog
759 // ----------------------------------------------------------------------------
760
761 #if wxUSE_DATEPICKCTRL
762
763 MyDialog::MyDialog(wxWindow *parent, const wxDateTime& dt, int dtpStyle)
764 : wxDialog(parent, wxID_ANY, wxString(_T("Calendar: Choose a date")))
765 {
766 wxStdDialogButtonSizer *sizerBtns = new wxStdDialogButtonSizer;
767 sizerBtns->AddButton(new wxButton(this, wxID_OK));
768 sizerBtns->AddButton(new wxButton(this, wxID_CANCEL));
769 sizerBtns->Realize();
770
771 wxSizer *sizerText = new wxBoxSizer(wxHORIZONTAL);
772 sizerText->Add(new wxStaticText(this, wxID_ANY, _T("Date in ISO format: ")),
773 wxSizerFlags().Border().Align(wxALIGN_CENTRE_VERTICAL));
774 m_text = new wxTextCtrl(this, wxID_ANY);
775 sizerText->Add(m_text, wxSizerFlags().
776 Expand().Border().Align(wxALIGN_CENTRE_VERTICAL));
777
778 wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
779 sizerTop->Add(new wxStaticText
780 (
781 this, wxID_ANY,
782 _T("Enter your birthday date (not before 20th century):")
783 ),
784 wxSizerFlags().Border());
785
786 #if wxUSE_DATEPICKCTRL_GENERIC
787 wxFrame *frame = (wxFrame *)wxGetTopLevelParent(parent);
788 if ( frame && frame->GetMenuBar()->IsChecked(Calendar_DatePicker_Generic) )
789 m_datePicker = new wxDatePickerCtrlGeneric(this, wxID_ANY, dt,
790 wxDefaultPosition,
791 wxDefaultSize,
792 dtpStyle);
793 else
794 #endif // wxUSE_DATEPICKCTRL_GENERIC
795 m_datePicker = new wxDatePickerCtrl(this, wxID_ANY, dt,
796 wxDefaultPosition, wxDefaultSize,
797 dtpStyle);
798 m_datePicker->SetRange(wxDateTime(1, wxDateTime::Jan, 1900),
799 wxDefaultDateTime);
800 sizerTop->Add(m_datePicker, wxSizerFlags().Expand().Border());
801
802 sizerTop->AddStretchSpacer(1);
803 sizerTop->Add(sizerText);
804
805 sizerTop->Add(sizerBtns, wxSizerFlags().Centre().Border());
806
807 SetSizerAndFit(sizerTop);
808 Layout();
809 }
810
811 void MyDialog::OnDateChange(wxDateEvent& event)
812 {
813 const wxDateTime dt = event.GetDate();
814 if ( dt.IsValid() )
815 m_text->SetValue(dt.FormatISODate());
816 else
817 m_text->SetValue(wxEmptyString);
818 }
819
820 #endif // wxUSE_DATEPICKCTRL