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