X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/50d0b061eeeb4f87594ccea7508a7c5975fb36dd..1b9a0df6794997ac17e866eeb9ea6ea91b6a803b:/src/generic/calctrl.cpp diff --git a/src/generic/calctrl.cpp b/src/generic/calctrl.cpp index 8813954b64..8a4b397da2 100644 --- a/src/generic/calctrl.cpp +++ b/src/generic/calctrl.cpp @@ -6,7 +6,7 @@ // Created: 29.12.99 // RCS-ID: $Id$ // Copyright: (c) 1999 Vadim Zeitlin -// Licence: wxWindows license +// Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -17,7 +17,7 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "calctrl.h" #endif @@ -34,10 +34,13 @@ #include "wx/brush.h" #include "wx/combobox.h" #include "wx/stattext.h" + #include "wx/textctrl.h" #endif //WX_PRECOMP #if wxUSE_CALENDARCTRL +#include "wx/spinctrl.h" + #include "wx/calctrl.h" #define DEBUG_PAINT 0 @@ -57,6 +60,7 @@ private: wxCalendarCtrl *m_cal; DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxMonthComboBox) }; class wxYearSpinCtrl : public wxSpinCtrl @@ -64,12 +68,18 @@ class wxYearSpinCtrl : public wxSpinCtrl public: wxYearSpinCtrl(wxCalendarCtrl *cal); + void OnYearTextChange(wxCommandEvent& event) + { + m_cal->SetUserChangedYear(); + m_cal->OnYearChange(event); + } void OnYearChange(wxSpinEvent& event) { m_cal->OnYearChange(event); } private: wxCalendarCtrl *m_cal; DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxYearSpinCtrl) }; // ---------------------------------------------------------------------------- @@ -90,6 +100,7 @@ BEGIN_EVENT_TABLE(wxMonthComboBox, wxComboBox) END_EVENT_TABLE() BEGIN_EVENT_TABLE(wxYearSpinCtrl, wxSpinCtrl) + EVT_TEXT(-1, wxYearSpinCtrl::OnYearTextChange) EVT_SPINCTRL(-1, wxYearSpinCtrl::OnYearChange) END_EVENT_TABLE() @@ -121,7 +132,7 @@ wxMonthComboBox::wxMonthComboBox(wxCalendarCtrl *cal) wxDefaultPosition, wxDefaultSize, 0, NULL, - wxCB_READONLY) + wxCB_READONLY | wxCLIP_SIBLINGS) { m_cal = cal; @@ -140,8 +151,9 @@ wxYearSpinCtrl::wxYearSpinCtrl(wxCalendarCtrl *cal) cal->GetDate().Format(_T("%Y")), wxDefaultPosition, wxDefaultSize, - wxSP_ARROW_KEYS, + wxSP_ARROW_KEYS | wxCLIP_SIBLINGS, -4300, 10000, cal->GetDate().GetYear()) + { m_cal = cal; } @@ -150,10 +162,27 @@ wxYearSpinCtrl::wxYearSpinCtrl(wxCalendarCtrl *cal) // wxCalendarCtrl // ---------------------------------------------------------------------------- +wxCalendarCtrl::wxCalendarCtrl(wxWindow *parent, + wxWindowID id, + const wxDateTime& date, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) +{ + Init(); + + (void)Create(parent, id, date, pos, size, style, name); +} + void wxCalendarCtrl::Init() { m_comboMonth = NULL; m_spinYear = NULL; + m_staticYear = NULL; + m_staticMonth = NULL; + + m_userChangedYear = FALSE; m_widthCol = m_heightRow = 0; @@ -169,9 +198,8 @@ void wxCalendarCtrl::Init() m_attrs[n] = NULL; } - wxSystemSettings ss; - m_colHighlightFg = ss.GetSystemColour(wxSYS_COLOUR_HIGHLIGHTTEXT); - m_colHighlightBg = ss.GetSystemColour(wxSYS_COLOUR_HIGHLIGHT); + m_colHighlightFg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); + m_colHighlightBg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT); m_colHolidayFg = *wxRED; // don't set m_colHolidayBg - by default, same as our bg colour @@ -189,7 +217,8 @@ bool wxCalendarCtrl::Create(wxWindow *parent, const wxString& name) { if ( !wxControl::Create(parent, id, pos, size, - style | wxWANTS_CHARS, wxDefaultValidator, name) ) + style | wxCLIP_CHILDREN | wxWANTS_CHARS, + wxDefaultValidator, name) ) { return FALSE; } @@ -202,7 +231,7 @@ bool wxCalendarCtrl::Create(wxWindow *parent, m_lowdate = wxDefaultDateTime; m_highdate = wxDefaultDateTime; - if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) ) + if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { m_spinYear = new wxYearSpinCtrl(this); m_staticYear = new wxStaticText(GetParent(), -1, m_date.Format(_T("%Y")), @@ -231,7 +260,10 @@ bool wxCalendarCtrl::Create(wxWindow *parent, sizeReal = size; } - SetSize(sizeReal); + // we need to set the position as well because the main control position + // is not the same as the one specified in pos if we have the controls + // above it + SetSize(pos.x, pos.y, sizeReal.x, sizeReal.y); SetBackgroundColour(*wxWHITE); SetFont(*wxSWISS_FONT); @@ -253,6 +285,25 @@ wxCalendarCtrl::~wxCalendarCtrl() // forward wxWin functions to subcontrols // ---------------------------------------------------------------------------- +bool wxCalendarCtrl::Destroy() +{ + if ( m_staticYear ) + m_staticYear->Destroy(); + if ( m_spinYear ) + m_spinYear->Destroy(); + if ( m_comboMonth ) + m_comboMonth->Destroy(); + if ( m_staticMonth ) + m_staticMonth->Destroy(); + + m_staticYear = NULL; + m_spinYear = NULL; + m_comboMonth = NULL; + m_staticMonth = NULL; + + return wxControl::Destroy(); +} + bool wxCalendarCtrl::Show(bool show) { if ( !wxControl::Show(show) ) @@ -294,7 +345,7 @@ bool wxCalendarCtrl::Enable(bool enable) void wxCalendarCtrl::ShowCurrentControls() { - if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) ) + if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { if ( AllowMonthChange() ) { @@ -376,7 +427,7 @@ void wxCalendarCtrl::EnableMonthChange(bool enable) bool wxCalendarCtrl::SetDate(const wxDateTime& date) { - bool retval = FALSE; + bool retval = TRUE; bool sameMonth = m_date.GetMonth() == date.GetMonth(), sameYear = m_date.GetYear() == date.GetYear(); @@ -386,40 +437,43 @@ bool wxCalendarCtrl::SetDate(const wxDateTime& date) if ( sameMonth && sameYear ) { // just change the day - retval = TRUE; ChangeDay(date); } else { - if ( !AllowMonthChange() || (!AllowYearChange() && !sameYear) ) - { - // forbidden - return retval; - } - - // change everything - retval = TRUE; - m_date = date; - - if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) ) + if ( AllowMonthChange() && (AllowYearChange() || sameYear) ) { - // update the controls - m_comboMonth->SetSelection(m_date.GetMonth()); + // change everything + m_date = date; - if ( AllowYearChange() ) + if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { - m_spinYear->SetValue(m_date.Format(_T("%Y"))); + // update the controls + m_comboMonth->SetSelection(m_date.GetMonth()); + + if ( AllowYearChange() ) + { + if ( !m_userChangedYear ) + m_spinYear->SetValue(m_date.Format(_T("%Y"))); + } } - } - // as the month changed, holidays did too - SetHolidayAttrs(); + // as the month changed, holidays did too + SetHolidayAttrs(); - // update the calendar - Refresh(); + // update the calendar + Refresh(); + } + else + { + // forbidden + retval = FALSE; + } } } + m_userChangedYear = FALSE; + return retval; } @@ -665,30 +719,27 @@ size_t wxCalendarCtrl::GetWeek(const wxDateTime& date) const // the constants used for the layout #define VERT_MARGIN 5 // distance between combo and calendar +#ifdef __WXMAC__ +#define HORZ_MARGIN 5 // spin +#else #define HORZ_MARGIN 15 // spin - +#endif wxSize wxCalendarCtrl::DoGetBestSize() const { // calc the size of the calendar ((wxCalendarCtrl *)this)->RecalcGeometry(); // const_cast wxCoord width = 7*m_widthCol, - height = 7*m_heightRow + m_rowOffset; - - // the combobox doesn't report its height correctly (it returns the - // height including the drop down list) so don't use it + height = 7*m_heightRow + m_rowOffset + VERT_MARGIN; - if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) ) - { - height += VERT_MARGIN + m_spinYear->GetBestSize().y; - } - else + if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { - height += VERT_MARGIN; + // the combobox doesn't report its height correctly (it returns the + // height including the drop down list) so don't use it + height += m_spinYear->GetBestSize().y; } -// if ( GetWindowStyle() & (wxRAISED_BORDER | wxSUNKEN_BORDER) ) // This doesn't work. Default is wxBORDER_DEFAULT (0) - if ( !(GetWindowStyle() & wxBORDER_NONE) ) + if ( !HasFlag(wxBORDER_NONE) ) { // the border would clip the last line otherwise height += 6; @@ -707,27 +758,59 @@ void wxCalendarCtrl::DoSetSize(int x, int y, void wxCalendarCtrl::DoMoveWindow(int x, int y, int width, int height) { - int xDiff = 0; - int yDiff = 0; + int yDiff; - if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) ) + if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { wxSize sizeCombo = m_comboMonth->GetSize(); wxSize sizeStatic = m_staticMonth->GetSize(); - + wxSize sizeSpin = m_spinYear->GetSize(); int dy = (sizeCombo.y - sizeStatic.y) / 2; - +/* +In the calender the size of the combobox for the year +is just defined by a margin from the month combobox to +the left border. While in wxUniv the year control can't +show all 4 digits, in wxMsw it show almost twice as +much. Instead the year should use it's best size and be +left aligned to the calendar. Just in case the month in +any language is longer than it has space in the +calendar it is shortend.This way the year always can +show the 4 digits. + +This patch relies on the fact that a combobox has a +good best size implementation. This is not the case +with wxMSW but I don't know why. + +Otto Wyss +*/ + +#ifdef __WXUNIVERSAL__ + if (sizeCombo.x + HORZ_MARGIN - sizeSpin.x > width) + { + m_comboMonth->SetSize(x, y, width - HORZ_MARGIN - sizeSpin.x, sizeCombo.y); + } + else + { + m_comboMonth->Move(x, y); + } + m_staticMonth->Move(x, y + dy); + m_spinYear->Move(x + width - sizeSpin.x, y); + m_staticYear->Move(x + width - sizeSpin.x, y + dy); +#else m_comboMonth->Move(x, y); m_staticMonth->SetSize(x, y + dy, sizeCombo.x, sizeStatic.y); - xDiff = sizeCombo.x + HORZ_MARGIN; + int xDiff = sizeCombo.x + HORZ_MARGIN; m_spinYear->SetSize(x + xDiff, y, width - xDiff, sizeCombo.y); m_staticYear->SetSize(x + xDiff, y + dy, width - xDiff, sizeStatic.y); - - wxSize sizeSpin = m_spinYear->GetSize(); +#endif yDiff = wxMax(sizeSpin.y, sizeCombo.y) + VERT_MARGIN; } + else // no controls on the top + { + yDiff = 0; + } wxControl::DoMoveWindow(x, y + yDiff, width, height - yDiff); } @@ -753,7 +836,7 @@ void wxCalendarCtrl::DoGetSize(int *width, int *height) const if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { // our real height is bigger - if ( height ) + if ( height && GetMonthControl()) { *height += GetMonthControl()->GetSize().y + VERT_MARGIN; } @@ -810,9 +893,7 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) wxCoord y = 0; -///////////////////////////////////////////////////////////////////////////////////////// - - if ( (GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) ) + if ( HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { // draw the sequential month-selector @@ -820,7 +901,7 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) dc.SetTextForeground(*wxBLACK); dc.SetBrush(wxBrush(m_colHeaderBg, wxSOLID)); dc.SetPen(wxPen(m_colHeaderBg, 1, wxSOLID)); - dc.DrawRectangle(0, y, 7*m_widthCol, m_heightRow); + dc.DrawRectangle(0, y, GetClientSize().x, m_heightRow); // Get extent of month-name + year wxCoord monthw, monthh; @@ -882,8 +963,6 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) y += m_heightRow; } -///////////////////////////////////////////////////////////////////////////////////////// - // first draw the week days if ( IsExposed(0, y, 7*m_widthCol, m_heightRow) ) { @@ -895,7 +974,7 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) dc.SetTextForeground(m_colHeaderFg); dc.SetBrush(wxBrush(m_colHeaderBg, wxSOLID)); dc.SetPen(wxPen(m_colHeaderBg, 1, wxSOLID)); - dc.DrawRectangle(0, y, 7*m_widthCol, m_heightRow); + dc.DrawRectangle(0, y, GetClientSize().x, m_heightRow); bool startOnMonday = (GetWindowStyle() & wxCAL_MONDAY_FIRST) != 0; for ( size_t wd = 0; wd < 7; wd++ ) @@ -907,7 +986,6 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) n = wd; wxCoord dayw, dayh; dc.GetTextExtent(m_weekdays[n], &dayw, &dayh); -// dc.DrawText(m_weekdays[n], wd*m_widthCol + 1, y); dc.DrawText(m_weekdays[n], (wd*m_widthCol) + ((m_widthCol- dayw) / 2), y); // center the day-name } } @@ -1488,11 +1566,17 @@ void wxCalendarCtrl::OnMonthChange(wxCommandEvent& event) SetDateAndNotify(target); } -void wxCalendarCtrl::OnYearChange(wxSpinEvent& event) +void wxCalendarCtrl::OnYearChange(wxCommandEvent& event) { + int year = (int)event.GetInt(); + if ( year == INT_MIN ) + { + // invalid year in the spin control, ignore it + return; + } + wxDateTime::Tm tm = m_date.GetTm(); - int year = (int)event.GetInt(); if ( tm.mday > wxDateTime::GetNumberOfDays(tm.mon, year) ) { tm.mday = wxDateTime::GetNumberOfDays(tm.mon, year); @@ -1510,7 +1594,6 @@ void wxCalendarCtrl::OnYearChange(wxSpinEvent& event) // inside the same year but a strange number of months forward/back.. m_spinYear->SetValue(target.GetYear()); } - } // ---------------------------------------------------------------------------- @@ -1520,7 +1603,7 @@ void wxCalendarCtrl::OnYearChange(wxSpinEvent& event) void wxCalendarCtrl::OnChar(wxKeyEvent& event) { wxDateTime target; - switch ( event.KeyCode() ) + switch ( event.GetKeyCode() ) { case _T('+'): case WXK_ADD: