X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c3a899dd9210a348a9dc5904f08d489eea0b6b34..c02f03d563e895258dcac98a2ade423a1acbf7f9:/src/generic/calctrlg.cpp diff --git a/src/generic/calctrlg.cpp b/src/generic/calctrlg.cpp index cb153cce28..1129f56c54 100644 --- a/src/generic/calctrlg.cpp +++ b/src/generic/calctrlg.cpp @@ -96,13 +96,14 @@ wxBEGIN_FLAGS( wxCalendarCtrlStyle ) wxFLAGS_MEMBER(wxCAL_NO_MONTH_CHANGE) wxFLAGS_MEMBER(wxCAL_SEQUENTIAL_MONTH_SELECTION) wxFLAGS_MEMBER(wxCAL_SHOW_SURROUNDING_WEEKS) + wxFLAGS_MEMBER(wxCAL_SHOW_WEEK_NUMBERS) wxEND_FLAGS( wxCalendarCtrlStyle ) IMPLEMENT_DYNAMIC_CLASS_XTI(wxGenericCalendarCtrl, wxControl,"wx/calctrl.h") wxBEGIN_PROPERTIES_TABLE(wxGenericCalendarCtrl) - wxEVENT_RANGE_PROPERTY( Updated , wxEVT_CALENDAR_SEL_CHANGED , wxEVT_CALENDAR_WEEKDAY_CLICKED , wxCalendarEvent ) + wxEVENT_RANGE_PROPERTY( Updated , wxEVT_CALENDAR_SEL_CHANGED , wxEVT_CALENDAR_WEEK_CLICKED , wxCalendarEvent ) wxHIDE_PROPERTY( Children ) wxPROPERTY( Date,wxDateTime, SetDate , GetDate, , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) wxPROPERTY_FLAGS( WindowStyle , wxCalendarCtrlStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style @@ -190,7 +191,8 @@ void wxGenericCalendarCtrl::Init() m_userChangedYear = false; m_widthCol = - m_heightRow = 0; + m_heightRow = + m_calendarWeekWidth = 0; wxDateTime::WeekDay wd; for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) ) @@ -246,12 +248,11 @@ bool wxGenericCalendarCtrl::Create(wxWindow *parent, if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { CreateYearSpinCtrl(); - m_staticYear = new wxStaticText(GetParent(), wxID_ANY, m_date.Format(_T("%Y")), + m_staticYear = new wxStaticText(GetParent(), wxID_ANY, m_date.Format(wxT("%Y")), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); - CreateMonthComboBox(); - m_staticMonth = new wxStaticText(GetParent(), wxID_ANY, m_date.Format(_T("%B")), + m_staticMonth = new wxStaticText(GetParent(), wxID_ANY, m_date.Format(wxT("%B")), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); } @@ -295,7 +296,7 @@ void wxGenericCalendarCtrl::SetWindowStyleFlag(long style) // created/shown/hidden accordingly wxASSERT_MSG( (style & wxCAL_SEQUENTIAL_MONTH_SELECTION) == (m_windowStyle & wxCAL_SEQUENTIAL_MONTH_SELECTION), - _T("wxCAL_SEQUENTIAL_MONTH_SELECTION can't be changed after creation") ); + wxT("wxCAL_SEQUENTIAL_MONTH_SELECTION can't be changed after creation") ); wxControl::SetWindowStyleFlag(style); } @@ -334,18 +335,21 @@ void wxGenericCalendarCtrl::CreateMonthComboBox() void wxGenericCalendarCtrl::CreateYearSpinCtrl() { m_spinYear = new wxSpinCtrl(GetParent(), wxID_ANY, - GetDate().Format(_T("%Y")), + GetDate().Format(wxT("%Y")), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS | wxCLIP_SIBLINGS, -4300, 10000, GetDate().GetYear()); +#ifdef __WXMAC__ + m_spinYear->SetSize( 90, -1 ); +#endif m_spinYear->Connect(m_spinYear->GetId(), wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(wxGenericCalendarCtrl::OnYearTextChange), NULL, this); m_spinYear->Connect(m_spinYear->GetId(), wxEVT_COMMAND_SPINCTRL_UPDATED, - wxCommandEventHandler(wxGenericCalendarCtrl::OnYearChange), + wxSpinEventHandler(wxGenericCalendarCtrl::OnYearChange), NULL, this); } @@ -516,7 +520,7 @@ bool wxGenericCalendarCtrl::SetDate(const wxDateTime& date) if ( AllowYearChange() ) { if ( !m_userChangedYear ) - m_spinYear->SetValue(m_date.Format(_T("%Y"))); + m_spinYear->SetValue(m_date.Format(wxT("%Y"))); } } @@ -770,26 +774,23 @@ size_t wxGenericCalendarCtrl::GetWeek(const wxDateTime& date) const // this is a composite control and it must arrange its parts each time its // size or position changes: the combobox and spinctrl are along the top of -// the available area and the calendar takes up therest of the space +// the available area and the calendar takes up the rest of the space // the static controls are supposed to be always smaller than combo/spin so we // always use the latter for size calculations and position the static to take // the same space // the constants used for the layout -#define VERT_MARGIN 5 // distance between combo and calendar -#ifdef __WXMAC__ +#define VERT_MARGIN 5 // distance between combo and calendar #define HORZ_MARGIN 5 // spin -#else -#define HORZ_MARGIN 15 // spin -#endif + wxSize wxGenericCalendarCtrl::DoGetBestSize() const { // calc the size of the calendar - wx_const_cast(wxGenericCalendarCtrl *, this)->RecalcGeometry(); + const_cast(this)->RecalcGeometry(); - wxCoord width = 7*m_widthCol, - height = 7*m_heightRow + m_rowOffset; + wxCoord width = 7*m_widthCol + m_calendarWeekWidth, + height = 7*m_heightRow + m_rowOffset + VERT_MARGIN; if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { @@ -797,6 +798,10 @@ wxSize wxGenericCalendarCtrl::DoGetBestSize() const height += wxMax(bestSizeCombo.y, m_spinYear->GetBestSize().y) + VERT_MARGIN; +#ifdef __WXMAC__ + // the spin control get clipped otherwise + width += 25; +#endif wxCoord w2 = bestSizeCombo.x + HORZ_MARGIN + GetCharWidth()*6; if ( width < w2 ) @@ -810,6 +815,7 @@ wxSize wxGenericCalendarCtrl::DoGetBestSize() const } CacheBestSize(best); + return best; } @@ -825,12 +831,16 @@ void wxGenericCalendarCtrl::DoMoveWindow(int x, int y, int width, int height) int maxHeight = wxMax(sizeSpin.y, sizeCombo.y); int dy = (maxHeight - sizeStatic.y) / 2; - m_comboMonth->Move(x, y); +#ifdef __WXMAC__ + m_comboMonth->Move(x, y + (maxHeight - sizeCombo.y)/2 + 2); // FIXME, something is reporting the wrong size.. +#else + m_comboMonth->Move(x, y + (maxHeight - sizeCombo.y)/2); +#endif m_staticMonth->SetSize(x, y + dy, sizeCombo.x, -1, sizeStatic.y); int xDiff = sizeCombo.x + HORZ_MARGIN; - m_spinYear->SetSize(x + xDiff, y, width - xDiff, maxHeight); + m_spinYear->SetSize(x + xDiff, y + (maxHeight - sizeSpin.y)/2, width - xDiff, maxHeight); m_staticYear->SetSize(x + xDiff, y + dy, width - xDiff, sizeStatic.y); yDiff = maxHeight + VERT_MARGIN; @@ -843,6 +853,24 @@ void wxGenericCalendarCtrl::DoMoveWindow(int x, int y, int width, int height) wxControl::DoMoveWindow(x, y + yDiff, width, height - yDiff); } +void wxGenericCalendarCtrl::DoGetSize(int *width, int *height) const +{ +#ifdef __WXMAC__ + wxControl::DoGetSize( width, height ); + + if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) && m_staticMonth && height ) + { + wxSize sizeCombo = m_comboMonth->GetEffectiveMinSize(); + wxSize sizeSpin = m_spinYear->GetSize(); + + int maxHeight = wxMax(sizeSpin.y, sizeCombo.y); + *height += maxHeight + VERT_MARGIN; + } +#else + wxControl::DoGetSize( width, height ); +#endif +} + void wxGenericCalendarCtrl::RecalcGeometry() { wxClientDC dc(this); @@ -874,6 +902,9 @@ void wxGenericCalendarCtrl::RecalcGeometry() } } + m_calendarWeekWidth = HasFlag( wxCAL_SHOW_WEEK_NUMBERS ) + ? dc.GetTextExtent( wxString::Format( wxT( "%d" ), 42 )).GetWidth() + 4 : 0; + // leave some margins m_widthCol += 2; m_heightRow += 2; @@ -900,7 +931,7 @@ void wxGenericCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) #endif wxCoord y = 0; - wxCoord x0 = wxMax( (GetSize().x - m_widthCol*7) /2 , 0 ); + wxCoord x0 = m_calendarWeekWidth; if ( HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { @@ -1003,6 +1034,24 @@ void wxGenericCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) //dc.SetFont(*wxNORMAL_FONT); y += m_heightRow; + + // draw column with calendar week nr + if ( HasFlag( wxCAL_SHOW_WEEK_NUMBERS ) && IsExposed( 0, y, m_calendarWeekWidth, m_heightRow * 6 )) + { + dc.SetBackgroundMode(wxTRANSPARENT); + dc.SetBrush(wxBrush(m_colHeaderBg, wxSOLID)); + dc.SetPen(wxPen(m_colHeaderBg, 1, wxSOLID)); + dc.DrawRectangle( 0, y, m_calendarWeekWidth, m_heightRow * 6 ); + wxDateTime date = GetStartDate(); + for ( size_t i = 0; i < 6; ++i ) + { + const int weekNr = date.GetWeekOfYear(); + wxString text = wxString::Format( wxT( "%d" ), weekNr ); + dc.DrawText( text, m_calendarWeekWidth - dc.GetTextExtent( text ).GetWidth() - 2, y + m_heightRow * i ); + date += wxDateSpan::Week(); + } + } + wxDateTime date = GetStartDate(); #if DEBUG_PAINT @@ -1032,9 +1081,9 @@ void wxGenericCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) { // don't use wxDate::Format() which prepends 0s unsigned int day = date.GetDay(); - wxString dayStr = wxString::Format(_T("%u"), day); + wxString dayStr = wxString::Format(wxT("%u"), day); wxCoord width; - dc.GetTextExtent(dayStr, &width, (wxCoord *)NULL); + dc.GetTextExtent(dayStr, &width, NULL); bool changedColours = false, changedFont = false; @@ -1127,7 +1176,7 @@ void wxGenericCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) break; default: - wxFAIL_MSG(_T("unknown border type")); + wxFAIL_MSG(wxT("unknown border type")); } } @@ -1185,9 +1234,9 @@ void wxGenericCalendarCtrl::RefreshDate(const wxDateTime& date) wxRect rect; // always refresh the whole row at once because our OnPaint() will draw - // the whole row anyhow - and this allows the small optimisation in + // the whole row anyhow - and this allows the small optimization in // OnClick() below to work - rect.x = wxMax( (GetSize().x - m_widthCol*7) /2 , 0 ); + rect.x = m_calendarWeekWidth; rect.y = (m_heightRow * GetWeek(date)) + m_rowOffset; @@ -1253,7 +1302,7 @@ void wxGenericCalendarCtrl::HighlightRange(wxPaintDC* pDC, const wxDateTime& fro { int numpoints; wxPoint corners[8]; // potentially 8 corners in polygon - wxCoord x0 = wxMax( (GetSize().x - m_widthCol*7) /2 , 0 ); + wxCoord x0 = m_calendarWeekWidth; if ( fw == tw ) { @@ -1426,7 +1475,14 @@ void wxGenericCalendarCtrl::OnClick(wxMouseEvent& event) // GenerateAllChangeEvents() here, we know which event to send GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED); } - break; + break; + + case wxCAL_HITTEST_WEEK: + { + wxCalendarEvent send( this, date, wxEVT_CALENDAR_WEEK_CLICKED ); + HandleWindowEvent( send ); + } + break; case wxCAL_HITTEST_HEADER: { @@ -1444,7 +1500,7 @@ void wxGenericCalendarCtrl::OnClick(wxMouseEvent& event) break; default: - wxFAIL_MSG(_T("unknown hittest code")); + wxFAIL_MSG(wxT("unknown hittest code")); // fall through case wxCAL_HITTEST_NOWHERE: @@ -1464,7 +1520,7 @@ wxCalendarHitTestResult wxGenericCalendarCtrl::HitTest(const wxPoint& pos, RecalcGeometry(); // the position where the calendar really begins - wxCoord x0 = wxMax((GetSize().x - m_widthCol*7)/2, 0); + wxCoord x0 = m_calendarWeekWidth; if ( HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { @@ -1505,12 +1561,30 @@ wxCalendarHitTestResult wxGenericCalendarCtrl::HitTest(const wxPoint& pos, return wxCAL_HITTEST_INCMONTH; } + } + if ( pos.x - x0 < 0 ) + { + if ( pos.x >= 0 && pos.y > m_rowOffset + m_heightRow && pos.y <= m_rowOffset + m_heightRow * 7 ) + { + if ( date ) + { + *date = GetStartDate(); + *date += wxDateSpan::Week() * (( pos.y - m_rowOffset ) / m_heightRow - 1 ); + } + if ( wd ) + *wd = ( GetWindowStyle() & wxCAL_MONDAY_FIRST ) ? wxDateTime::Mon : wxDateTime::Sun; + return wxCAL_HITTEST_WEEK; + } + else // early exit -> the rest of the function checks for clicks on days + return wxCAL_HITTEST_NOWHERE; } // header: week days int wday = (pos.x - x0) / m_widthCol; - if ( pos.y < (m_heightRow + m_rowOffset) ) + if ( wday > 6 ) + return wxCAL_HITTEST_NOWHERE; + if ( pos.y < (m_heightRow + m_rowOffset)) { if ( pos.y > m_rowOffset ) { @@ -1581,7 +1655,7 @@ void wxGenericCalendarCtrl::OnMonthChange(wxCommandEvent& event) SetDateAndNotify(target); } -void wxGenericCalendarCtrl::OnYearChange(wxCommandEvent& event) +void wxGenericCalendarCtrl::HandleYearChange(wxCommandEvent& event) { int year = (int)event.GetInt(); if ( year == INT_MIN ) @@ -1611,10 +1685,15 @@ void wxGenericCalendarCtrl::OnYearChange(wxCommandEvent& event) } } +void wxGenericCalendarCtrl::OnYearChange(wxSpinEvent& event) +{ + HandleYearChange( event ); +} + void wxGenericCalendarCtrl::OnYearTextChange(wxCommandEvent& event) { SetUserChangedYear(); - OnYearChange(event); + HandleYearChange(event); } // Responds to colour changes, and passes event on to children. @@ -1640,7 +1719,7 @@ void wxGenericCalendarCtrl::OnChar(wxKeyEvent& event) wxDateTime target; switch ( event.GetKeyCode() ) { - case _T('+'): + case wxT('+'): case WXK_ADD: target = m_date + wxDateSpan::Year(); if ( ChangeYear(&target) ) @@ -1649,7 +1728,7 @@ void wxGenericCalendarCtrl::OnChar(wxKeyEvent& event) } break; - case _T('-'): + case wxT('-'): case WXK_SUBTRACT: target = m_date - wxDateSpan::Year(); if ( ChangeYear(&target) ) @@ -1734,48 +1813,9 @@ void wxGenericCalendarCtrl::OnChar(wxKeyEvent& event) // holidays handling // ---------------------------------------------------------------------------- -void wxGenericCalendarCtrl::EnableHolidayDisplay(bool display) -{ - long style = GetWindowStyle(); - if ( display ) - style |= wxCAL_SHOW_HOLIDAYS; - else - style &= ~wxCAL_SHOW_HOLIDAYS; - - SetWindowStyle(style); - - if ( display ) - SetHolidayAttrs(); - else - ResetHolidayAttrs(); - - Refresh(); -} - -void wxGenericCalendarCtrl::SetHolidayAttrs() -{ - if ( GetWindowStyle() & wxCAL_SHOW_HOLIDAYS ) - { - ResetHolidayAttrs(); - - wxDateTime::Tm tm = m_date.GetTm(); - wxDateTime dtStart(1, tm.mon, tm.year), - dtEnd = dtStart.GetLastMonthDay(); - - wxDateTimeArray hol; - wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol); - - size_t count = hol.GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - SetHoliday(hol[n].GetDay()); - } - } -} - void wxGenericCalendarCtrl::SetHoliday(size_t day) { - wxCHECK_RET( day > 0 && day < 32, _T("invalid day in SetHoliday") ); + wxCHECK_RET( day > 0 && day < 32, wxT("invalid day in SetHoliday") ); wxCalendarDateAttr *attr = GetAttr(day); if ( !attr ) @@ -1802,7 +1842,7 @@ void wxGenericCalendarCtrl::ResetHolidayAttrs() void wxGenericCalendarCtrl::Mark(size_t day, bool mark) { - wxCHECK_RET( day > 0 && day < 32, _T("invalid day in Mark") ); + wxCHECK_RET( day > 0 && day < 32, wxT("invalid day in Mark") ); const wxCalendarDateAttr& m = wxCalendarDateAttr::GetMark(); if (mark) {