]> git.saurik.com Git - wxWidgets.git/blame - src/generic/datectlg.cpp
Fix bug [ 1170089 ] wxGenericDirCtrl doesn't show files
[wxWidgets.git] / src / generic / datectlg.cpp
CommitLineData
39df3acd 1/////////////////////////////////////////////////////////////////////////////
d5ae99f5 2// Name: generic/datectlg.cpp
7ae712f5 3// Purpose: generic wxDatePickerCtrlGeneric implementation
39df3acd
VZ
4// Author: Andreas Pflug
5// Modified by:
6// Created: 2005-01-19
7// RCS-ID: $Id$
8// Copyright: (c) 2005 Andreas Pflug <pgadmin@pse-consulting.de>
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
7ae712f5
VZ
26#if wxUSE_DATEPICKCTRL
27
15c86b39 28#include "wx/datectrl.h"
7ae712f5
VZ
29
30// use this version if we're explicitly requested to do it or if it's the only
31// one we have
15c86b39 32#if wxUSE_DATEPICKCTRL_GENERIC || !defined(wxHAS_NATIVE_DATEPICKCTRL)
7ae712f5 33
a962d4e0
KH
34#ifndef WX_PRECOMP
35 #include "wx/bmpbuttn.h"
36 #include "wx/dialog.h"
37 #include "wx/dcmemory.h"
38 #include "wx/panel.h"
39 #include "wx/textctrl.h"
40 #include "wx/valtext.h"
41#endif
42
1721a8c0
VZ
43#ifdef wxHAS_NATIVE_DATEPICKCTRL
44 // this header is not included from wx/datectrl.h if we have a native
45 // version, but we do need it here
46 #include "wx/generic/datectrl.h"
930fb29e
VZ
47#else
48 // we need to define _WX_DEFINE_DATE_EVENTS_ before including wx/dateevt.h to
49 // define the event types we use if we're the only date picker control version
50 // being compiled -- otherwise it's defined in the native version implementation
7ae712f5
VZ
51 #define _WX_DEFINE_DATE_EVENTS_
52#endif
53
91edf16c
VZ
54#include "wx/dateevt.h"
55
4b134bb2 56#include "wx/calctrl.h"
4221a0e5 57#include "wx/renderer.h"
39df3acd
VZ
58
59// ----------------------------------------------------------------------------
60// constants
61// ----------------------------------------------------------------------------
62
63enum
64{
65 CTRLID_TXT = 101,
4b134bb2
VZ
66 CTRLID_CAL,
67 CTRLID_BTN,
39df3acd
VZ
68 CTRLID_PAN
69};
70
71#ifndef DEFAULT_ITEM_WIDTH
72 #define DEFAULT_ITEM_WIDTH 100
73#endif
74
930fb29e
VZ
75#ifdef __WXMSW__
76 #undef wxUSE_POPUPWIN
77 #define wxUSE_POPUPWIN 0 // Popup not working
78 #define TXTCTRL_FLAGS wxNO_BORDER
79 #define BTN_FLAGS wxNO_BORDER
80 #define CALBORDER 0
7e24348e 81 #define RIGHTBUTTONBORDER 4
930fb29e 82 #define TOPBUTTONBORDER 0
7e24348e 83 #define BUTTONBORDER 4
930fb29e
VZ
84 #define TXTPOSY 1
85#else
86 #define TXTCTRL_FLAGS 0
87 #define BTN_FLAGS wxBU_AUTODRAW
88 #define CALBORDER 4
89 #define RIGHTBUTTONBORDER 0
90 #define TOPBUTTONBORDER 0
91 #define BUTTONBORDER 0
92 #define TXTPOSY 0
93#endif
94
95
1721a8c0
VZ
96// ----------------------------------------------------------------------------
97// local classes
98// ----------------------------------------------------------------------------
99
38511687
VZ
100
101class wxDropdownButton : public wxBitmapButton
102{
103public:
104 wxDropdownButton() { Init(); }
105 wxDropdownButton(wxWindow *parent,
106 wxWindowID id,
107 const wxPoint& pos = wxDefaultPosition,
108 const wxSize& size = wxDefaultSize,
109 long style=0,
110 const wxValidator& validator = wxDefaultValidator);
111
112 void Init()
113 {
114 m_borderX = -1;
115 m_borderY = -1;
116 }
94ab4d92 117 bool Create(wxWindow *parent,
38511687
VZ
118 wxWindowID id,
119 const wxPoint& pos = wxDefaultPosition,
120 const wxSize& size = wxDefaultSize,
930fb29e 121 long style = 0,
38511687
VZ
122 const wxValidator& validator = wxDefaultValidator);
123
124 void DoMoveWindow(int x, int y, int w, int h);
125
126protected:
127 int m_borderX, m_borderY;
128};
129
130
131wxDropdownButton::wxDropdownButton(wxWindow *parent,
132 wxWindowID id,
133 const wxPoint& pos,
134 const wxSize& size,
135 long style,
136 const wxValidator& validator)
137{
138 Init();
139 Create(parent, id, pos, size, style, validator);
140}
141
142
94ab4d92 143bool wxDropdownButton::Create(wxWindow *parent,
38511687
VZ
144 wxWindowID id,
145 const wxPoint& pos,
146 const wxSize& size,
94ab4d92 147 long WXUNUSED(style),
38511687
VZ
148 const wxValidator& validator)
149{
930fb29e
VZ
150 m_marginX = 0;
151 m_marginY = 0;
152
38511687 153 wxBitmap chkBmp(15,15); // arbitrary
94ab4d92 154 if ( !wxBitmapButton::Create(parent, id, chkBmp,
930fb29e 155 pos, wxDefaultSize, BTN_FLAGS, validator) )
94ab4d92 156 return false;
38511687 157
94ab4d92
VZ
158 const wxSize sz = GetSize();
159 int w = chkBmp.GetWidth(),
160 h = chkBmp.GetHeight();
161 m_borderX = sz.x - m_marginX - w;
162 m_borderY = sz.y - m_marginY - h;
38511687 163
94ab4d92
VZ
164 w = size.x > 0 ? size.x : sz.x;
165 h = size.y > 0 ? size.y : sz.y;
38511687
VZ
166
167 DoMoveWindow(pos.x, pos.y, w, h);
94ab4d92
VZ
168
169 return true;
38511687
VZ
170}
171
172
173void wxDropdownButton::DoMoveWindow(int x, int y, int w, int h)
174{
175 if (m_borderX >= 0 && m_borderY >= 0 && (w >= 0 || h >= 0))
176 {
177 wxMemoryDC dc;
178 if (w < 0)
179 w = GetSize().x;
180#ifdef __WXGTK__
181 else
182 w = m_marginX + m_borderX + 15; // GTK magic size
183#endif
184 if (h < 0)
185 h = GetSize().y;
186
7e24348e
RD
187 int borderX = m_marginX + m_borderX;
188 int borderY = m_marginY + m_borderY;
189 int bw = w - borderX;
190 int bh = h - borderY;
38511687
VZ
191 if (bh < 11) bh=11;
192 if (bw < 9) bw=9;
193
194 wxBitmap bmp(bw, bh);
195 dc.SelectObject(bmp);
196
89448b5d 197 wxRendererNative& renderer = wxRendererNative::Get();
f5c479cc 198
83dc6964 199#ifdef __WXGTK__
7e24348e 200 wxRect r(-(borderX/2),-(borderY/2),w,h);
83dc6964
RR
201 wxColour magic(255,0,255);
202 dc.SetBrush( wxBrush( magic ) );
203 dc.SetPen( *wxTRANSPARENT_PEN );
204 dc.DrawRectangle(0,0,bw,bh);
7e24348e 205 renderer.DrawDropArrow(this, dc, r);
83dc6964
RR
206 wxMask *mask = new wxMask( bmp, magic );
207 bmp.SetMask( mask );
208#else
7e24348e 209 wxRect r(0,0,bw,bh);
89448b5d 210 renderer.DrawComboBoxDropButton(this, dc, r);
83dc6964 211#endif
38511687 212 SetBitmapLabel(bmp);
89448b5d
VZ
213
214 wxBitmap bmpSel(bw, bh);
215 dc.SelectObject(bmpSel);
f5c479cc 216
83dc6964
RR
217#ifdef __WXGTK__
218 dc.SetBrush( wxBrush( magic ) );
219 dc.SetPen( *wxTRANSPARENT_PEN );
220 dc.DrawRectangle(0,0,bw,bh);
7e24348e 221 renderer.DrawDropArrow(this, dc, r, wxCONTROL_PRESSED);
83dc6964
RR
222 mask = new wxMask( bmpSel, magic );
223 bmpSel.SetMask( mask );
224#else
89448b5d 225 renderer.DrawComboBoxDropButton(this, dc, r, wxCONTROL_PRESSED);
f5c479cc 226#endif
89448b5d 227 SetBitmapSelected(bmpSel);
38511687
VZ
228 }
229
230 wxBitmapButton::DoMoveWindow(x, y, w, h);
231}
232
233
1721a8c0
VZ
234#if wxUSE_POPUPWIN
235
236#include "wx/popupwin.h"
237
238class wxDatePopupInternal : public wxPopupTransientWindow
239{
240public:
241 wxDatePopupInternal(wxWindow *parent) : wxPopupTransientWindow(parent) { }
242
243 void ShowAt(int x, int y)
244 {
245 Position(wxPoint(x, y), wxSize(0, 0));
246 Popup();
247 }
248
249 void Hide()
250 {
251 Dismiss();
252 }
253};
254
255#else // !wxUSE_POPUPWIN
256
257class wxDatePopupInternal : public wxDialog
258{
259public:
260 wxDatePopupInternal(wxWindow *parent)
261 : wxDialog(parent,
262 wxID_ANY,
263 wxEmptyString,
264 wxDefaultPosition,
265 wxDefaultSize,
266 wxSIMPLE_BORDER)
267 {
268 }
269
270 void ShowAt(int x, int y)
271 {
272 Show();
273 Move(x, y);
274 }
275
276 void Hide()
277 {
278 wxDialog::Hide();
279 }
280};
281
282#endif // wxUSE_POPUPWIN/!wxUSE_POPUPWIN
283
39df3acd 284// ============================================================================
7ae712f5 285// wxDatePickerCtrlGeneric implementation
39df3acd
VZ
286// ============================================================================
287
7ae712f5
VZ
288BEGIN_EVENT_TABLE(wxDatePickerCtrlGeneric, wxDatePickerCtrlBase)
289 EVT_BUTTON(CTRLID_BTN, wxDatePickerCtrlGeneric::OnClick)
290 EVT_TEXT(CTRLID_TXT, wxDatePickerCtrlGeneric::OnText)
291 EVT_CHILD_FOCUS(wxDatePickerCtrlGeneric::OnChildSetFocus)
39df3acd
VZ
292END_EVENT_TABLE()
293
b6292ff0 294#ifndef wxHAS_NATIVE_DATEPICKCTRL
94ab4d92 295 IMPLEMENT_DYNAMIC_CLASS(wxDatePickerCtrl, wxControl)
b6292ff0 296#endif
39df3acd
VZ
297
298// ----------------------------------------------------------------------------
299// creation
300// ----------------------------------------------------------------------------
301
7ae712f5
VZ
302bool wxDatePickerCtrlGeneric::Create(wxWindow *parent,
303 wxWindowID id,
304 const wxDateTime& date,
305 const wxPoint& pos,
306 const wxSize& size,
307 long style,
807f5038 308 const wxValidator& validator,
7ae712f5 309 const wxString& name)
39df3acd 310{
29c86948
VZ
311 wxASSERT_MSG( !(style & wxDP_SPIN),
312 _T("wxDP_SPIN style not supported, use wxDP_DEFAULT") );
313
39df3acd
VZ
314 if ( !wxControl::Create(parent, id, pos, size,
315 style | wxCLIP_CHILDREN | wxWANTS_CHARS,
807f5038 316 validator, name) )
39df3acd
VZ
317
318 {
319 return false;
320 }
321
39df3acd
VZ
322 InheritAttributes();
323
930fb29e 324 m_txt = new wxTextCtrl(this, CTRLID_TXT, wxEmptyString, wxDefaultPosition, wxDefaultSize, TXTCTRL_FLAGS);
38511687 325
b6261304
VZ
326 m_txt->Connect(wxEVT_KEY_DOWN,
327 wxKeyEventHandler(wxDatePickerCtrlGeneric::OnEditKey),
328 NULL, this);
329 m_txt->Connect(wxEVT_KILL_FOCUS,
330 wxFocusEventHandler(wxDatePickerCtrlGeneric::OnKillFocus),
331 NULL, this);
39df3acd 332
930fb29e 333 const int height = m_txt->GetBestSize().y - BUTTONBORDER;
39df3acd 334
38511687 335 m_btn = new wxDropdownButton(this, CTRLID_BTN, wxDefaultPosition, wxSize(height, height));
930fb29e 336
1721a8c0 337 m_popup = new wxDatePopupInternal(this);
d5ae99f5 338 m_popup->SetFont(GetFont());
39df3acd 339
d5ae99f5 340 wxPanel *panel=new wxPanel(m_popup, CTRLID_PAN,
1721a8c0 341 wxPoint(0, 0), wxDefaultSize,
4b134bb2
VZ
342 wxSUNKEN_BORDER);
343 m_cal = new wxCalendarCtrl(panel, CTRLID_CAL, wxDefaultDateTime,
1721a8c0 344 wxPoint(0, 0), wxDefaultSize,
4b134bb2 345 wxCAL_SHOW_HOLIDAYS | wxSUNKEN_BORDER);
b6261304
VZ
346 m_cal->Connect(wxEVT_CALENDAR_SEL_CHANGED,
347 wxCalendarEventHandler(wxDatePickerCtrlGeneric::OnSelChange),
348 NULL, this);
349 m_cal->Connect(wxEVT_KEY_DOWN,
350 wxKeyEventHandler(wxDatePickerCtrlGeneric::OnCalKey),
351 NULL, this);
352 m_cal->Connect(wxEVT_CALENDAR_DOUBLECLICKED,
353 wxCalendarEventHandler(wxDatePickerCtrlGeneric::OnSelChange),
354 NULL, this);
355 m_cal->Connect(wxEVT_CALENDAR_DAY_CHANGED,
356 wxCalendarEventHandler(wxDatePickerCtrlGeneric::OnSelChange),
357 NULL, this);
358 m_cal->Connect(wxEVT_CALENDAR_MONTH_CHANGED,
359 wxCalendarEventHandler(wxDatePickerCtrlGeneric::OnSelChange),
360 NULL, this);
361 m_cal->Connect(wxEVT_CALENDAR_YEAR_CHANGED,
362 wxCalendarEventHandler(wxDatePickerCtrlGeneric::OnSelChange),
363 NULL, this);
39df3acd
VZ
364
365 wxWindow *yearControl = m_cal->GetYearControl();
366
b6261304
VZ
367 Connect(wxEVT_SET_FOCUS,
368 wxFocusEventHandler(wxDatePickerCtrlGeneric::OnSetFocus));
39df3acd
VZ
369
370 wxClientDC dc(yearControl);
9d9e32a0 371 dc.SetFont(yearControl->GetFont());
39df3acd
VZ
372 wxCoord width, dummy;
373 dc.GetTextExtent(wxT("2000"), &width, &dummy);
1721a8c0 374 width += ConvertDialogToPixels(wxSize(20, 0)).x;
39df3acd
VZ
375
376 wxSize calSize = m_cal->GetBestSize();
377 wxSize yearSize = yearControl->GetSize();
378 yearSize.x = width;
379
380 wxPoint yearPosition = yearControl->GetPosition();
381
d5ae99f5
VZ
382 SetFormat(wxT("%x"));
383
39df3acd
VZ
384 width = yearPosition.x + yearSize.x+2+CALBORDER/2;
385 if (width < calSize.x-4)
386 width = calSize.x-4;
387
388 int calPos = (width-calSize.x)/2;
389 if (calPos == -1)
390 {
391 calPos = 0;
392 width += 2;
393 }
394 m_cal->SetSize(calPos, 0, calSize.x, calSize.y);
4b134bb2
VZ
395 yearControl->SetSize(width-yearSize.x-CALBORDER/2, yearPosition.y,
396 yearSize.x, yearSize.y);
39df3acd
VZ
397 m_cal->GetMonthControl()->Move(0, 0);
398
399
400
401 panel->SetClientSize(width+CALBORDER/2, calSize.y-2+CALBORDER);
d5ae99f5
VZ
402 m_popup->SetClientSize(panel->GetSize());
403 m_popup->Hide();
39df3acd 404
964f23b7 405 SetValue(date.IsValid() ? date : wxDateTime::Today());
1721a8c0 406
d8b49350 407 SetBestFittingSize(size);
930fb29e 408
3a0c6181 409 return true;
39df3acd
VZ
410}
411
412
7ae712f5 413void wxDatePickerCtrlGeneric::Init()
39df3acd 414{
d5ae99f5 415 m_popup = NULL;
39df3acd
VZ
416 m_txt = NULL;
417 m_cal = NULL;
418 m_btn = NULL;
419
420 m_dropped = false;
421 m_ignoreDrop = false;
422}
423
424
7ae712f5 425bool wxDatePickerCtrlGeneric::Destroy()
39df3acd
VZ
426{
427 if (m_cal)
428 m_cal->Destroy();
d5ae99f5
VZ
429 if (m_popup)
430 m_popup->Destroy();
39df3acd
VZ
431 if (m_txt)
432 m_txt->Destroy();
433 if (m_btn)
434 m_btn->Destroy();
435
d5ae99f5 436 m_popup = NULL;
39df3acd
VZ
437 m_txt = NULL;
438 m_cal = NULL;
439 m_btn = NULL;
440
441 return wxControl::Destroy();
442}
443
444// ----------------------------------------------------------------------------
445// overridden base class methods
446// ----------------------------------------------------------------------------
447
7ae712f5 448void wxDatePickerCtrlGeneric::DoMoveWindow(int x, int y, int w, int h)
39df3acd
VZ
449{
450 wxControl::DoMoveWindow(x, y, w, h);
451 wxSize bs=m_btn->GetBestSize();
452 int eh=m_txt->GetBestSize().y;
453
930fb29e 454 m_txt->SetSize(0, TXTPOSY, w-bs.x-RIGHTBUTTONBORDER, h > eh ? eh-TXTPOSY : h-TXTPOSY);
1721a8c0 455 m_btn->SetSize(w - bs.x-RIGHTBUTTONBORDER, TOPBUTTONBORDER, bs.x, h > bs.y ? bs.y : h);
39df3acd
VZ
456
457 if (m_dropped)
1721a8c0 458 DropDown(true);
39df3acd
VZ
459}
460
7ae712f5 461wxSize wxDatePickerCtrlGeneric::DoGetBestSize() const
39df3acd
VZ
462{
463 int bh=m_btn->GetBestSize().y;
464 int eh=m_txt->GetBestSize().y;
465 return wxSize(DEFAULT_ITEM_WIDTH, bh > eh ? bh : eh);
466}
467
468
7ae712f5 469bool wxDatePickerCtrlGeneric::Show(bool show)
39df3acd
VZ
470{
471 if ( !wxControl::Show(show) )
472 {
3a0c6181 473 return false;
39df3acd
VZ
474 }
475
1721a8c0 476 if ( !show )
39df3acd 477 {
1721a8c0 478 if ( m_popup )
39df3acd 479 {
d5ae99f5 480 m_popup->Hide();
39df3acd
VZ
481 m_dropped = false;
482 }
483 }
484
3a0c6181 485 return true;
39df3acd
VZ
486}
487
488
7ae712f5 489bool wxDatePickerCtrlGeneric::Enable(bool enable)
39df3acd
VZ
490{
491 if ( !wxControl::Enable(enable) )
492 {
3a0c6181 493 return false;
39df3acd
VZ
494 }
495
1721a8c0 496 if ( !enable )
39df3acd 497 {
2eda91db
VZ
498 if ( m_popup )
499 m_popup->Hide();
39df3acd 500 }
1721a8c0
VZ
501
502 if ( m_btn )
39df3acd 503 m_btn->Enable(enable);
1721a8c0 504
3a0c6181 505 return true;
39df3acd
VZ
506}
507
508// ----------------------------------------------------------------------------
7ae712f5 509// wxDatePickerCtrlGeneric API
39df3acd
VZ
510// ----------------------------------------------------------------------------
511
4b134bb2 512bool
7ae712f5
VZ
513wxDatePickerCtrlGeneric::SetDateRange(const wxDateTime& lowerdate,
514 const wxDateTime& upperdate)
4b134bb2
VZ
515{
516 return m_cal->SetDateRange(lowerdate, upperdate);
517}
518
7ae712f5 519bool wxDatePickerCtrlGeneric::SetFormat(const wxChar *fmt)
39df3acd
VZ
520{
521 wxDateTime dt;
522 dt.ParseFormat(wxT("2003-10-13"), wxT("%Y-%m-%d"));
523 wxString str=dt.Format(fmt);
524 wxChar *p=(wxChar*)str.c_str();
525
526 m_format=wxEmptyString;
527
528 while (*p)
529 {
530 int n=wxAtoi(p);
531 if (n == dt.GetDay())
532 {
533 m_format.Append(wxT("%d"));
534 p += 2;
535 }
536 else if (n == (int)dt.GetMonth()+1)
537 {
538 m_format.Append(wxT("%m"));
539 p += 2;
540 }
541 else if (n == dt.GetYear())
542 {
543 m_format.Append(wxT("%Y"));
544 p += 4;
545 }
d5ae99f5
VZ
546 else if (n == (dt.GetYear() % 100))
547 {
1721a8c0
VZ
548 if (GetWindowStyle() & wxDP_SHOWCENTURY)
549 m_format.Append(wxT("%Y"));
550 else
551 m_format.Append(wxT("%y"));
d5ae99f5
VZ
552 p += 2;
553 }
39df3acd
VZ
554 else
555 m_format.Append(*p++);
556 }
557
558 if (m_txt)
559 {
1721a8c0
VZ
560 wxArrayString allowedChars;
561 for ( wxChar c = _T('0'); c <= _T('9'); c++ )
562 allowedChars.Add(wxString(c, 1));
563
564 const wxChar *p = m_format.c_str();
39df3acd
VZ
565 while (*p)
566 {
567 if (*p == '%')
568 p += 2;
569 else
1721a8c0 570 allowedChars.Add(wxString(*p++, 1));
39df3acd 571 }
1721a8c0 572
f5c479cc 573#if wxUSE_VALIDATORS
39df3acd 574 wxTextValidator tv(wxFILTER_INCLUDE_CHAR_LIST);
1721a8c0 575 tv.SetIncludes(allowedChars);
39df3acd 576 m_txt->SetValidator(tv);
f5c479cc 577#endif
d5ae99f5 578
1721a8c0
VZ
579 if (m_currentDate.IsValid())
580 m_txt->SetValue(m_currentDate.Format(m_format));
39df3acd 581 }
1721a8c0 582
39df3acd
VZ
583 return true;
584}
585
586
7ae712f5 587wxDateTime wxDatePickerCtrlGeneric::GetValue() const
39df3acd 588{
1721a8c0 589 return m_currentDate;
39df3acd
VZ
590}
591
592
7ae712f5 593void wxDatePickerCtrlGeneric::SetValue(const wxDateTime& date)
39df3acd
VZ
594{
595 if (m_cal)
596 {
597 if (date.IsValid())
d5ae99f5 598 m_txt->SetValue(date.Format(m_format));
39df3acd 599 else
1721a8c0
VZ
600 {
601 wxASSERT_MSG( HasFlag(wxDP_ALLOWNONE),
602 _T("this control must have a valid date") );
603
39df3acd 604 m_txt->SetValue(wxEmptyString);
1721a8c0
VZ
605 }
606
607 m_currentDate = date;
39df3acd
VZ
608 }
609}
610
611
7ae712f5 612bool wxDatePickerCtrlGeneric::GetRange(wxDateTime *dt1, wxDateTime *dt2) const
39df3acd
VZ
613{
614 if (dt1)
4b134bb2 615 *dt1 = m_cal->GetLowerDateLimit();
39df3acd 616 if (dt1)
4b134bb2 617 *dt2 = m_cal->GetUpperDateLimit();
39df3acd
VZ
618 return true;
619}
620
621
7ae712f5
VZ
622void
623wxDatePickerCtrlGeneric::SetRange(const wxDateTime &dt1, const wxDateTime &dt2)
39df3acd 624{
4b134bb2 625 m_cal->SetDateRange(dt1, dt2);
39df3acd
VZ
626}
627
628// ----------------------------------------------------------------------------
629// event handlers
630// ----------------------------------------------------------------------------
631
7ae712f5 632void wxDatePickerCtrlGeneric::DropDown(bool down)
39df3acd 633{
d5ae99f5 634 if (m_popup)
39df3acd
VZ
635 {
636 if (down)
637 {
d5ae99f5 638 wxDateTime dt;
a7c58211 639 if (!m_txt->GetValue().empty())
39df3acd 640 dt.ParseFormat(m_txt->GetValue(), m_format);
d5ae99f5
VZ
641
642 if (dt.IsValid())
39df3acd 643 m_cal->SetDate(dt);
d5ae99f5
VZ
644 else
645 m_cal->SetDate(wxDateTime::Today());
39df3acd 646
d5ae99f5 647 wxPoint pos=GetParent()->ClientToScreen(GetPosition());
1721a8c0 648 m_popup->ShowAt(pos.x, pos.y + GetSize().y);
39df3acd 649 m_dropped = true;
1721a8c0 650 m_cal->SetFocus();
39df3acd
VZ
651 }
652 else
653 {
654 if (m_dropped)
d5ae99f5 655 m_popup->Hide();
39df3acd
VZ
656 m_dropped = false;
657 }
658 }
659}
660
661
7ae712f5 662void wxDatePickerCtrlGeneric::OnChildSetFocus(wxChildFocusEvent &ev)
39df3acd
VZ
663{
664 ev.Skip();
665 m_ignoreDrop = false;
666
667 wxWindow *w=(wxWindow*)ev.GetEventObject();
668 while (w)
669 {
d5ae99f5 670 if (w == m_popup)
39df3acd
VZ
671 return;
672 w = w->GetParent();
673 }
674
675 if (m_dropped)
676 {
677 DropDown(false);
678 if (ev.GetEventObject() == m_btn)
679 m_ignoreDrop = true;
680 }
681}
682
683
b6292ff0 684void wxDatePickerCtrlGeneric::OnClick(wxCommandEvent& WXUNUSED(event))
39df3acd
VZ
685{
686 if (m_ignoreDrop)
687 {
688 m_ignoreDrop = false;
689 m_txt->SetFocus();
690 }
691 else
692 {
693 DropDown();
694 m_cal->SetFocus();
695 }
696}
697
698
b6292ff0 699void wxDatePickerCtrlGeneric::OnSetFocus(wxFocusEvent& WXUNUSED(ev))
39df3acd
VZ
700{
701 if (m_txt)
702 {
703 m_txt->SetFocus();
1721a8c0 704 m_txt->SetSelection(-1, -1); // select everything
39df3acd
VZ
705 }
706}
707
708
7ae712f5 709void wxDatePickerCtrlGeneric::OnKillFocus(wxFocusEvent &ev)
39df3acd
VZ
710{
711 ev.Skip();
712
713 wxDateTime dt;
714 dt.ParseFormat(m_txt->GetValue(), m_format);
2436cac7 715 if ( !dt.IsValid() )
1721a8c0
VZ
716 {
717 if ( !HasFlag(wxDP_ALLOWNONE) )
718 dt = m_currentDate;
719 }
720
a7c58211
WS
721 if(dt.IsValid())
722 m_txt->SetValue(dt.Format(m_format));
723 else
724 m_txt->SetValue(wxEmptyString);
1721a8c0
VZ
725
726 // notify that we had to change the date after validation
2436cac7
VZ
727 if ( (dt.IsValid() && m_currentDate != dt) ||
728 (!dt.IsValid() && m_currentDate.IsValid()) )
1721a8c0
VZ
729 {
730 m_currentDate = dt;
731 wxDateEvent event(this, dt, wxEVT_DATE_CHANGED);
732 GetEventHandler()->ProcessEvent(event);
733 }
39df3acd
VZ
734}
735
736
7ae712f5 737void wxDatePickerCtrlGeneric::OnSelChange(wxCalendarEvent &ev)
39df3acd
VZ
738{
739 if (m_cal)
740 {
1721a8c0
VZ
741 m_currentDate = m_cal->GetDate();
742 m_txt->SetValue(m_currentDate.Format(m_format));
39df3acd
VZ
743 if (ev.GetEventType() == wxEVT_CALENDAR_DOUBLECLICKED)
744 {
745 DropDown(false);
746 m_txt->SetFocus();
747 }
748 }
749 ev.SetEventObject(this);
750 ev.SetId(GetId());
751 GetParent()->ProcessEvent(ev);
1721a8c0
VZ
752
753 wxDateEvent dev(this, ev.GetDate(), wxEVT_DATE_CHANGED);
754 GetParent()->ProcessEvent(dev);
39df3acd
VZ
755}
756
757
7ae712f5 758void wxDatePickerCtrlGeneric::OnText(wxCommandEvent &ev)
39df3acd
VZ
759{
760 ev.SetEventObject(this);
761 ev.SetId(GetId());
762 GetParent()->ProcessEvent(ev);
763
764 // We'll create an additional event if the date is valid.
1721a8c0 765 // If the date isn't valid, the user's probably in the middle of typing
a7c58211 766 wxString txt = m_txt->GetValue();
39df3acd 767 wxDateTime dt;
a7c58211 768 if (!txt.empty())
39df3acd
VZ
769 {
770 dt.ParseFormat(txt, m_format);
771 if (!dt.IsValid())
772 return;
773 }
774
775 wxCalendarEvent cev(m_cal, wxEVT_CALENDAR_SEL_CHANGED);
776 cev.SetEventObject(this);
777 cev.SetId(GetId());
778 cev.SetDate(dt);
779
780 GetParent()->ProcessEvent(cev);
1721a8c0
VZ
781
782 wxDateEvent dev(this, dt, wxEVT_DATE_CHANGED);
783 GetParent()->ProcessEvent(dev);
39df3acd
VZ
784}
785
786
7ae712f5 787void wxDatePickerCtrlGeneric::OnEditKey(wxKeyEvent & ev)
39df3acd
VZ
788{
789 if (ev.GetKeyCode() == WXK_DOWN && !ev.HasModifiers())
1721a8c0 790 DropDown(true);
39df3acd
VZ
791 else
792 ev.Skip();
793}
794
795
7ae712f5 796void wxDatePickerCtrlGeneric::OnCalKey(wxKeyEvent & ev)
39df3acd
VZ
797{
798 if (ev.GetKeyCode() == WXK_ESCAPE && !ev.HasModifiers())
799 DropDown(false);
800 else
801 ev.Skip();
802}
803
7ae712f5
VZ
804#endif // wxUSE_DATEPICKCTRL_GENERIC
805
806#endif // wxUSE_DATEPICKCTRL
807