calctrl.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,791 行 · 第 1/4 页

CPP
1,791
字号
///////////////////////////////////////////////////////////////////////////////
// Name:        src/generic/calctrl.cpp
// Purpose:     implementation fo the generic wxCalendarCtrl
// Author:      Vadim Zeitlin
// Modified by:
// Created:     29.12.99
// RCS-ID:      $Id: calctrl.cpp,v 1.70.2.3 2006/01/18 10:38:54 JS Exp $
// Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
// Licence:     wxWindows licence
///////////////////////////////////////////////////////////////////////////////

// ============================================================================
// declarations
// ============================================================================

// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------

#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
    #pragma implementation "calctrl.h"
#endif

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/dcclient.h"
    #include "wx/settings.h"
    #include "wx/brush.h"
    #include "wx/combobox.h"
    #include "wx/listbox.h"
    #include "wx/stattext.h"
    #include "wx/textctrl.h"
#endif //WX_PRECOMP

#if wxUSE_CALENDARCTRL

#include "wx/spinctrl.h"

// if wxDatePickerCtrl code doesn't define the date event, do it here as we
// need it as well
#if !wxUSE_DATEPICKCTRL
    #define _WX_DEFINE_DATE_EVENTS_
#endif

#include "wx/calctrl.h"

#define DEBUG_PAINT 0

// ----------------------------------------------------------------------------
// wxWin macros
// ----------------------------------------------------------------------------

BEGIN_EVENT_TABLE(wxCalendarCtrl, wxControl)
    EVT_PAINT(wxCalendarCtrl::OnPaint)

    EVT_CHAR(wxCalendarCtrl::OnChar)

    EVT_LEFT_DOWN(wxCalendarCtrl::OnClick)
    EVT_LEFT_DCLICK(wxCalendarCtrl::OnDClick)
END_EVENT_TABLE()

#if wxUSE_EXTENDED_RTTI
WX_DEFINE_FLAGS( wxCalendarCtrlStyle )

wxBEGIN_FLAGS( wxCalendarCtrlStyle )
    // new style border flags, we put them first to
    // use them for streaming out
    wxFLAGS_MEMBER(wxBORDER_SIMPLE)
    wxFLAGS_MEMBER(wxBORDER_SUNKEN)
    wxFLAGS_MEMBER(wxBORDER_DOUBLE)
    wxFLAGS_MEMBER(wxBORDER_RAISED)
    wxFLAGS_MEMBER(wxBORDER_STATIC)
    wxFLAGS_MEMBER(wxBORDER_NONE)

    // old style border flags
    wxFLAGS_MEMBER(wxSIMPLE_BORDER)
    wxFLAGS_MEMBER(wxSUNKEN_BORDER)
    wxFLAGS_MEMBER(wxDOUBLE_BORDER)
    wxFLAGS_MEMBER(wxRAISED_BORDER)
    wxFLAGS_MEMBER(wxSTATIC_BORDER)
    wxFLAGS_MEMBER(wxBORDER)

    // standard window styles
    wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
    wxFLAGS_MEMBER(wxCLIP_CHILDREN)
    wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
    wxFLAGS_MEMBER(wxWANTS_CHARS)
    wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
    wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
    wxFLAGS_MEMBER(wxVSCROLL)
    wxFLAGS_MEMBER(wxHSCROLL)

    wxFLAGS_MEMBER(wxCAL_SUNDAY_FIRST)
    wxFLAGS_MEMBER(wxCAL_MONDAY_FIRST)
    wxFLAGS_MEMBER(wxCAL_SHOW_HOLIDAYS)
    wxFLAGS_MEMBER(wxCAL_NO_YEAR_CHANGE)
    wxFLAGS_MEMBER(wxCAL_NO_MONTH_CHANGE)
    wxFLAGS_MEMBER(wxCAL_SEQUENTIAL_MONTH_SELECTION)
    wxFLAGS_MEMBER(wxCAL_SHOW_SURROUNDING_WEEKS)

wxEND_FLAGS( wxCalendarCtrlStyle )

IMPLEMENT_DYNAMIC_CLASS_XTI(wxCalendarCtrl, wxControl,"wx/calctrl.h")

wxBEGIN_PROPERTIES_TABLE(wxCalendarCtrl)
    wxEVENT_RANGE_PROPERTY( Updated , wxEVT_CALENDAR_SEL_CHANGED , wxEVT_CALENDAR_WEEKDAY_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
wxEND_PROPERTIES_TABLE()

wxBEGIN_HANDLERS_TABLE(wxCalendarCtrl)
wxEND_HANDLERS_TABLE()

wxCONSTRUCTOR_6( wxCalendarCtrl , wxWindow* , Parent , wxWindowID , Id , wxDateTime , Date , wxPoint , Position , wxSize , Size , long , WindowStyle )
#else
IMPLEMENT_DYNAMIC_CLASS(wxCalendarCtrl, wxControl)
#endif
IMPLEMENT_DYNAMIC_CLASS(wxCalendarEvent, wxDateEvent)

// ----------------------------------------------------------------------------
// events
// ----------------------------------------------------------------------------

DEFINE_EVENT_TYPE(wxEVT_CALENDAR_SEL_CHANGED)
DEFINE_EVENT_TYPE(wxEVT_CALENDAR_DAY_CHANGED)
DEFINE_EVENT_TYPE(wxEVT_CALENDAR_MONTH_CHANGED)
DEFINE_EVENT_TYPE(wxEVT_CALENDAR_YEAR_CHANGED)
DEFINE_EVENT_TYPE(wxEVT_CALENDAR_DOUBLECLICKED)
DEFINE_EVENT_TYPE(wxEVT_CALENDAR_WEEKDAY_CLICKED)

// ============================================================================
// implementation
// ============================================================================

// ----------------------------------------------------------------------------
// 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;

    wxDateTime::WeekDay wd;
    for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) )
    {
        m_weekdays[wd] = wxDateTime::GetWeekDayName(wd, wxDateTime::Name_Abbr);
    }

    for ( size_t n = 0; n < WXSIZEOF(m_attrs); n++ )
    {
        m_attrs[n] = NULL;
    }

    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

    m_colHeaderFg = *wxBLUE;
    m_colHeaderBg = *wxLIGHT_GREY;
}

bool wxCalendarCtrl::Create(wxWindow *parent,
                            wxWindowID id,
                            const wxDateTime& date,
                            const wxPoint& pos,
                            const wxSize& size,
                            long style,
                            const wxString& name)
{
    if ( !wxControl::Create(parent, id, pos, size,
                            style | wxCLIP_CHILDREN | wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE,
                            wxDefaultValidator, name) )
    {
        return false;
    }

    // needed to get the arrow keys normally used for the dialog navigation
    SetWindowStyle(style | wxWANTS_CHARS);

    m_date = date.IsValid() ? date : wxDateTime::Today();

    m_lowdate = wxDefaultDateTime;
    m_highdate = wxDefaultDateTime;

    if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) )
    {
        CreateYearSpinCtrl();
        m_staticYear = new wxStaticText(GetParent(), wxID_ANY, m_date.Format(_T("%Y")),
                                        wxDefaultPosition, wxDefaultSize,
                                        wxALIGN_CENTRE);

        CreateMonthComboBox();
        m_staticMonth = new wxStaticText(GetParent(), wxID_ANY, m_date.Format(_T("%B")),
                                         wxDefaultPosition, wxDefaultSize,
                                         wxALIGN_CENTRE);
    }

    ShowCurrentControls();

    // 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
    SetBestSize(size);
    SetPosition(pos);

    // Since we don't paint the whole background make sure that the platform
    // will use the right one.
    SetBackgroundColour(*wxWHITE);

    SetHolidayAttrs();

    return true;
}

wxCalendarCtrl::~wxCalendarCtrl()
{
    for ( size_t n = 0; n < WXSIZEOF(m_attrs); n++ )
    {
        delete m_attrs[n];
    }
}

// ----------------------------------------------------------------------------
// Create the wxComboBox and wxSpinCtrl
// ----------------------------------------------------------------------------

void wxCalendarCtrl::CreateMonthComboBox()
{
    m_comboMonth = new wxComboBox(GetParent(), wxID_ANY,
                                  wxEmptyString,
                                  wxDefaultPosition,
                                  wxDefaultSize,
                                  0, NULL,
                                  wxCB_READONLY | wxCLIP_SIBLINGS);

    wxDateTime::Month m;
    for ( m = wxDateTime::Jan; m < wxDateTime::Inv_Month; wxNextMonth(m) )
    {
        m_comboMonth->Append(wxDateTime::GetMonthName(m));
    }

    m_comboMonth->SetSelection(GetDate().GetMonth());
    m_comboMonth->SetSize(wxDefaultCoord,
                          wxDefaultCoord,
                          wxDefaultCoord,
                          wxDefaultCoord,
                          wxSIZE_AUTO_WIDTH|wxSIZE_AUTO_HEIGHT);

    m_comboMonth->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED,
                          wxCommandEventHandler(wxCalendarCtrl::OnMonthChange),
                          NULL, this);
}

void wxCalendarCtrl::CreateYearSpinCtrl()
{
    m_spinYear = new wxSpinCtrl(GetParent(), wxID_ANY,
                                GetDate().Format(_T("%Y")),
                                wxDefaultPosition,
                                wxDefaultSize,
                                wxSP_ARROW_KEYS | wxCLIP_SIBLINGS,
                                -4300, 10000, GetDate().GetYear());

    m_spinYear->Connect(wxEVT_COMMAND_TEXT_UPDATED,
                        wxCommandEventHandler(wxCalendarCtrl::OnYearTextChange),
                        NULL, this);

    m_spinYear->Connect(wxEVT_COMMAND_SPINCTRL_UPDATED,
                        wxCommandEventHandler(wxCalendarCtrl::OnYearChange),
                        NULL, this);
}

// ----------------------------------------------------------------------------
// 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) )
    {
        return false;
    }

    if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) )
    {
        if ( GetMonthControl() )
        {
            GetMonthControl()->Show(show);
            GetYearControl()->Show(show);
        }
    }

    return true;
}

bool wxCalendarCtrl::Enable(bool enable)
{
    if ( !wxControl::Enable(enable) )
    {
        return false;
    }

    if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) )
    {
        GetMonthControl()->Enable(enable);
        GetYearControl()->Enable(enable);
    }

    return true;
}

// ----------------------------------------------------------------------------
// enable/disable month/year controls
// ----------------------------------------------------------------------------

void wxCalendarCtrl::ShowCurrentControls()
{
    if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) )
    {
        if ( AllowMonthChange() )
        {
            m_comboMonth->Show();
            m_staticMonth->Hide();

            if ( AllowYearChange() )
            {
                m_spinYear->Show();
                m_staticYear->Hide();

                // skip the rest
                return;
            }
        }
        else
        {
            m_comboMonth->Hide();
            m_staticMonth->Show();
        }

        // year change not allowed here
        m_spinYear->Hide();
        m_staticYear->Show();
    }
}

wxControl *wxCalendarCtrl::GetMonthControl() const
{
    return AllowMonthChange() ? (wxControl *)m_comboMonth : (wxControl *)m_staticMonth;
}

wxControl *wxCalendarCtrl::GetYearControl() const
{
    return AllowYearChange() ? (wxControl *)m_spinYear : (wxControl *)m_staticYear;
}

void wxCalendarCtrl::EnableYearChange(bool enable)
{
    if ( enable != AllowYearChange() )
    {
        long style = GetWindowStyle();
        if ( enable )
            style &= ~wxCAL_NO_YEAR_CHANGE;
        else
            style |= wxCAL_NO_YEAR_CHANGE;
        SetWindowStyle(style);

        ShowCurrentControls();
        if ( GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION )
        {
            Refresh();
        }
    }
}

void wxCalendarCtrl::EnableMonthChange(bool enable)
{
    if ( enable != AllowMonthChange() )
    {
        long style = GetWindowStyle();
        if ( enable )
            style &= ~wxCAL_NO_MONTH_CHANGE;
        else
            style |= wxCAL_NO_MONTH_CHANGE;
        SetWindowStyle(style);

        ShowCurrentControls();
        if ( GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION )
        {
            Refresh();
        }
    }
}

// ----------------------------------------------------------------------------
// changing date
// ----------------------------------------------------------------------------

bool wxCalendarCtrl::SetDate(const wxDateTime& date)
{
    bool retval = true;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?