calctrl.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,791 行 · 第 1/4 页
CPP
1,791 行
wxLogDebug(" +++ LDOM +++");
#endif
GetDateCoord(ldcm.SetToLastMonthDay(m_date.GetMonth(), m_date.GetYear()), &lastday, &lastweek);
#if DEBUG_PAINT
wxLogDebug(" --- LDOM ---");
#endif
wxTimeSpan span = date - ldcm;
int daysfromlast = span.GetDays();
#if DEBUG_PAINT
wxLogDebug("daysfromlast: %i", daysfromlast);
#endif
if ( daysfromlast + lastday > 7 ) // past week boundary
{
int wholeweeks = (daysfromlast / 7);
*week = wholeweeks + lastweek;
if ( (daysfromlast - (7 * wholeweeks) + lastday) > 7 )
{
*week += 1;
}
}
else
{
*week = lastweek;
}
}
}
}
else
{
*day = -1;
*week = -1;
retval = false;
}
#if DEBUG_PAINT
wxLogDebug("--- GetDateCoord: (%s) = (%i, %i) ---", date.Format("%d %m %Y"), *day, *week);
#endif
return retval;
}
// ----------------------------------------------------------------------------
// mouse handling
// ----------------------------------------------------------------------------
void wxCalendarCtrl::OnDClick(wxMouseEvent& event)
{
if ( HitTest(event.GetPosition()) != wxCAL_HITTEST_DAY )
{
event.Skip();
}
else
{
GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED);
}
}
void wxCalendarCtrl::OnClick(wxMouseEvent& event)
{
wxDateTime date;
wxDateTime::WeekDay wday;
switch ( HitTest(event.GetPosition(), &date, &wday) )
{
case wxCAL_HITTEST_DAY:
if ( IsDateInRange(date) )
{
ChangeDay(date);
GenerateEvents(wxEVT_CALENDAR_DAY_CHANGED,
wxEVT_CALENDAR_SEL_CHANGED);
}
break;
case wxCAL_HITTEST_HEADER:
{
wxCalendarEvent eventWd(this, wxEVT_CALENDAR_WEEKDAY_CLICKED);
eventWd.m_wday = wday;
(void)GetEventHandler()->ProcessEvent(eventWd);
}
break;
case wxCAL_HITTEST_DECMONTH:
case wxCAL_HITTEST_INCMONTH:
case wxCAL_HITTEST_SURROUNDING_WEEK:
SetDateAndNotify(date); // we probably only want to refresh the control. No notification.. (maybe as an option?)
break;
default:
wxFAIL_MSG(_T("unknown hittest code"));
// fall through
case wxCAL_HITTEST_NOWHERE:
event.Skip();
break;
}
}
wxCalendarHitTestResult wxCalendarCtrl::HitTest(const wxPoint& pos,
wxDateTime *date,
wxDateTime::WeekDay *wd)
{
RecalcGeometry();
// use the correct x-pos
wxCoord x0 = wxMax((GetSize().x - m_widthCol*7) /2, 0);
wxPoint pos_corr = pos;
pos_corr.x -= x0;
wxCoord y = pos_corr.y;
///////////////////////////////////////////////////////////////////////////////////////////////////////
if ( (GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) )
{
// Header: month
// we need to find out if the hit is on left arrow, on month or on right arrow
// left arrow?
if ( wxRegion(m_leftArrowRect).Contains(pos_corr) == wxInRegion )
{
if ( date )
{
if ( IsDateInRange(m_date - wxDateSpan::Month()) )
{
*date = m_date - wxDateSpan::Month();
}
else
{
*date = GetLowerDateLimit();
}
}
return wxCAL_HITTEST_DECMONTH;
}
if ( wxRegion(m_rightArrowRect).Contains(pos_corr) == wxInRegion )
{
if ( date )
{
if ( IsDateInRange(m_date + wxDateSpan::Month()) )
{
*date = m_date + wxDateSpan::Month();
}
else
{
*date = GetUpperDateLimit();
}
}
return wxCAL_HITTEST_INCMONTH;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Header: Days
int wday = pos_corr.x / m_widthCol;
// if ( y < m_heightRow )
if ( y < (m_heightRow + m_rowOffset) )
{
if ( y > m_rowOffset )
{
if ( wd )
{
if ( GetWindowStyle() & wxCAL_MONDAY_FIRST )
{
wday = wday == 6 ? 0 : wday + 1;
}
*wd = (wxDateTime::WeekDay)wday;
}
return wxCAL_HITTEST_HEADER;
}
else
{
return wxCAL_HITTEST_NOWHERE;
}
}
// int week = (y - m_heightRow) / m_heightRow;
int week = (y - (m_heightRow + m_rowOffset)) / m_heightRow;
if ( week >= 6 || wday >= 7 )
{
return wxCAL_HITTEST_NOWHERE;
}
wxDateTime dt = GetStartDate() + wxDateSpan::Days(7*week + wday);
if ( IsDateShown(dt) )
{
if ( date )
*date = dt;
if ( dt.GetMonth() == m_date.GetMonth() )
{
return wxCAL_HITTEST_DAY;
}
else
{
return wxCAL_HITTEST_SURROUNDING_WEEK;
}
}
else
{
return wxCAL_HITTEST_NOWHERE;
}
}
// ----------------------------------------------------------------------------
// subcontrols events handling
// ----------------------------------------------------------------------------
void wxCalendarCtrl::OnMonthChange(wxCommandEvent& event)
{
wxDateTime::Tm tm = m_date.GetTm();
wxDateTime::Month mon = (wxDateTime::Month)event.GetInt();
if ( tm.mday > wxDateTime::GetNumberOfDays(mon, tm.year) )
{
tm.mday = wxDateTime::GetNumberOfDays(mon, tm.year);
}
wxDateTime target = wxDateTime(tm.mday, mon, tm.year);
ChangeMonth(&target);
SetDateAndNotify(target);
}
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();
if ( tm.mday > wxDateTime::GetNumberOfDays(tm.mon, year) )
{
tm.mday = wxDateTime::GetNumberOfDays(tm.mon, year);
}
wxDateTime target = wxDateTime(tm.mday, tm.mon, year);
if ( ChangeYear(&target) )
{
SetDateAndNotify(target);
}
else
{
// In this case we don't want to change the date. That would put us
// inside the same year but a strange number of months forward/back..
m_spinYear->SetValue(target.GetYear());
}
}
void wxCalendarCtrl::OnYearTextChange(wxCommandEvent& event)
{
SetUserChangedYear();
OnYearChange(event);
}
// ----------------------------------------------------------------------------
// keyboard interface
// ----------------------------------------------------------------------------
void wxCalendarCtrl::OnChar(wxKeyEvent& event)
{
wxDateTime target;
switch ( event.GetKeyCode() )
{
case _T('+'):
case WXK_ADD:
target = m_date + wxDateSpan::Year();
if ( ChangeYear(&target) )
{
SetDateAndNotify(target);
}
break;
case _T('-'):
case WXK_SUBTRACT:
target = m_date - wxDateSpan::Year();
if ( ChangeYear(&target) )
{
SetDateAndNotify(target);
}
break;
case WXK_PRIOR:
target = m_date - wxDateSpan::Month();
ChangeMonth(&target);
SetDateAndNotify(target); // always
break;
case WXK_NEXT:
target = m_date + wxDateSpan::Month();
ChangeMonth(&target);
SetDateAndNotify(target); // always
break;
case WXK_RIGHT:
if ( event.ControlDown() )
{
target = wxDateTime(m_date).SetToNextWeekDay(
GetWindowStyle() & wxCAL_MONDAY_FIRST
? wxDateTime::Sun : wxDateTime::Sat);
if ( !IsDateInRange(target) )
{
target = GetUpperDateLimit();
}
SetDateAndNotify(target);
}
else
SetDateAndNotify(m_date + wxDateSpan::Day());
break;
case WXK_LEFT:
if ( event.ControlDown() )
{
target = wxDateTime(m_date).SetToPrevWeekDay(
GetWindowStyle() & wxCAL_MONDAY_FIRST
? wxDateTime::Mon : wxDateTime::Sun);
if ( !IsDateInRange(target) )
{
target = GetLowerDateLimit();
}
SetDateAndNotify(target);
}
else
SetDateAndNotify(m_date - wxDateSpan::Day());
break;
case WXK_UP:
SetDateAndNotify(m_date - wxDateSpan::Week());
break;
case WXK_DOWN:
SetDateAndNotify(m_date + wxDateSpan::Week());
break;
case WXK_HOME:
if ( event.ControlDown() )
SetDateAndNotify(wxDateTime::Today());
else
SetDateAndNotify(wxDateTime(1, m_date.GetMonth(), m_date.GetYear()));
break;
case WXK_END:
SetDateAndNotify(wxDateTime(m_date).SetToLastMonthDay());
break;
case WXK_RETURN:
GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED);
break;
default:
event.Skip();
}
}
// ----------------------------------------------------------------------------
// holidays handling
// ----------------------------------------------------------------------------
void wxCalendarCtrl::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 wxCalendarCtrl::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 wxCalendarCtrl::SetHoliday(size_t day)
{
wxCHECK_RET( day > 0 && day < 32, _T("invalid day in SetHoliday") );
wxCalendarDateAttr *attr = GetAttr(day);
if ( !attr )
{
attr = new wxCalendarDateAttr;
}
attr->SetHoliday(true);
// can't use SetAttr() because it would delete this pointer
m_attrs[day - 1] = attr;
}
void wxCalendarCtrl::ResetHolidayAttrs()
{
for ( size_t day = 0; day < 31; day++ )
{
if ( m_attrs[day] )
{
m_attrs[day]->SetHoliday(false);
}
}
}
//static
wxVisualAttributes
wxCalendarCtrl::GetClassDefaultAttributes(wxWindowVariant variant)
{
// Use the same color scheme as wxListBox
return wxListBox::GetClassDefaultAttributes(variant);
}
#endif // wxUSE_CALENDARCTRL
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?