Date chooser for month and year Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
maximand
Experienced Solver
Experienced Solver
Posts: 79
Joined: Fri Nov 11, 2011 5:44 pm
Location: Russia

Date chooser for month and year

Post by maximand »

Hi everybody,

I am looking something like wxCalendarCtrl but I need only header for month and year selection.
Examples:
[ << < February 2019 > >> ] or [ < February 2019 > ]
Please advice.
M$, VS2017, C++
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Date chooser for month and year

Post by doublemax »

I don't think there is any control that can do this out of the box. But it should be relatively easy to implement this yourself.
Use the source, Luke!
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7459
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Date chooser for month and year

Post by ONEEYEMAN »

Hi,
Just take a look at the generic version of calendar control.
maximand
Experienced Solver
Experienced Solver
Posts: 79
Joined: Fri Nov 11, 2011 5:44 pm
Location: Russia

Re: Date chooser for month and year

Post by maximand »

I am looking for a code that can be adopted for my purposes.
Unfortunately, I don't understand generic calendar code.
M$, VS2017, C++
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Date chooser for month and year

Post by doublemax »

How to create this control yourself:

- derive your own class from wxPanel
- add two member variables, one of the month and one for the year
- set reasonable default values for those
- create a horizontal boxsizer, add a wxButton, a wxStaticText and another wxButton
- add event handlers for the two buttons
- when the first button is clicked, decrease the "month" integer, if it goes below 1, wrap around and decrease the year
- do the same for the second button with month + 1
- have a method that updates the statictext based on the month and year values
- create a custom event that is sent to the parent each time the date changes (this is the hardest part of all)

Optional:
- have two extra buttons to increase/decrease the year directly
- have two wxChoice controls for the month and year
Use the source, Luke!
maximand
Experienced Solver
Experienced Solver
Posts: 79
Joined: Fri Nov 11, 2011 5:44 pm
Location: Russia

Re: Date chooser for month and year

Post by maximand »

@doublemax thank you for your step by step instruction.
I am afraid it would some issues with buttons and text box sizing but I'll try.
M$, VS2017, C++
maximand
Experienced Solver
Experienced Solver
Posts: 79
Joined: Fri Nov 11, 2011 5:44 pm
Location: Russia

Re: Date chooser for month and year

Post by maximand »

YearMonth.PNG
YearMonth.PNG (766 Bytes) Viewed 1376 times
I can't handle events.
I've created this:
Header:

Code: Select all

class mmDateYearMonth : public wxPanel
{
    //wxDECLARE_DYNAMIC_CLASS(mmDateYearMonth);
    //wxDECLARE_EVENT_TABLE();
public:
    mmDateYearMonth();
    mmDateYearMonth(wxWindow *parent);

private:
    bool Create(wxWindow* parent, wxWindowID id);
    void OnButtonPress(wxCommandEvent& event);
    int m_year;
    int m_month;
};
cpp:

Code: Select all

//wxIMPLEMENT_DYNAMIC_CLASS(mmDateYearMonth, wxDialog);

/*wxBEGIN_EVENT_TABLE(mmDateYearMonth, wxDialog)
    EVT_BUTTON(wxID_ANY, mmDateYearMonth::OnButtonPress)
wxEND_EVENT_TABLE()*/

mmDateYearMonth::mmDateYearMonth()
{
}

mmDateYearMonth::mmDateYearMonth(wxWindow *parent)
{
    m_year = wxDate::Today().GetYear();
    m_month = wxDate::Today().GetMonth();
    Create(parent, wxID_STATIC);
}

bool mmDateYearMonth::Create(wxWindow* parent, wxWindowID id)
{
    wxPanel::Create(parent, id);

    wxBoxSizer* box_sizer = new wxBoxSizer(wxHORIZONTAL);
    wxButton* buttonLeft = new wxButton(this, wxID_DOWN, "<");
    buttonLeft->SetMinSize(wxSize(16,16));
    wxStaticText* text = new wxStaticText(this, wxID_INFO, _("December 2019"));
    wxButton* buttonRight = new wxButton(this, wxID_UP, ">");
    buttonRight->SetMinSize(wxSize(16, 16));

    box_sizer->Add(buttonLeft);
    box_sizer->Add(text);
    box_sizer->Add(buttonRight);

    this->SetSizer(box_sizer);
    GetSizer()->Fit(this);
    GetSizer()->SetSizeHints(this);
    Centre();
    Fit();
    return TRUE;
}

void mmDateYearMonth::OnButtonPress(wxCommandEvent& event)
{
    wxDateTime d = wxDateTime::Today().SetDay(1).SetMonth((wxDateTime::Month)m_month).SetYear(m_year);
    int button_id = event.GetId();
    switch (button_id)
    {
    case wxID_DOWN:
        d.Subtract(wxDateSpan::Months(1));
        break;
    case wxID_UP:
        d.Add(wxDateSpan::Months(1));
        break;
    }

    const wxString l = wxGetTranslation(wxDateTime::GetEnglishMonthName(wxDateTime::Month(d.GetMonth())));
    wxStaticText* t = static_cast<wxStaticText*>(FindWindow(wxID_INFO));
    t->SetLabel(wxString::Format("%s %d", l, d.GetYear()));
}

PS I am calling it like this:

Code: Select all


    wxPanel* itemPanel3 = new wxPanel(this, wxID_ANY
        , wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
    wxBoxSizer* itemBoxSizerHeader = new wxBoxSizer(wxHORIZONTAL);
    itemPanel3->SetSizer(itemBoxSizerHeader);
            ....
                mmDateYearMonth* test = new mmDateYearMonth(itemPanel3);
        itemBoxSizerHeader->Add(test, 0, wxALL, 1);
        
        
M$, VS2017, C++
maximand
Experienced Solver
Experienced Solver
Posts: 79
Joined: Fri Nov 11, 2011 5:44 pm
Location: Russia

Re: Date chooser for month and year

Post by maximand »

I've changed wxPanel to wxWindow. Now it's working.

Code: Select all

wxIMPLEMENT_DYNAMIC_CLASS(mmDateYearMonth, wxWindow);

wxBEGIN_EVENT_TABLE(mmDateYearMonth, wxWindow)
    EVT_BUTTON(wxID_ANY, mmDateYearMonth::OnButtonPress)
wxEND_EVENT_TABLE()

mmDateYearMonth::mmDateYearMonth()
{
}

mmDateYearMonth::mmDateYearMonth(wxWindow *parent)
{
    m_year = wxDate::Today().GetYear();
    m_month = wxDate::Today().GetMonth();
    Create(parent, wxID_STATIC);
}

bool mmDateYearMonth::Create(wxWindow* parent, wxWindowID id)
{
    wxWindow::Create(parent, id);

    wxDateTime d = wxDateTime::Today().SetDay(1).SetMonth((wxDateTime::Month)m_month).SetYear(m_year);
    const wxString l = wxGetTranslation(wxDateTime::GetEnglishMonthName(wxDateTime::Month(d.GetMonth())));

    wxBoxSizer* box_sizer = new wxBoxSizer(wxHORIZONTAL);
    wxButton* buttonLeft = new wxButton(this, wxID_DOWN, "<");
    buttonLeft->SetMinSize(wxSize(16,16));
    wxStaticText* text = new wxStaticText(this, wxID_INFO, "");
    text->SetLabel(wxString::Format("%s %d", l, d.GetYear()));
    wxButton* buttonRight = new wxButton(this, wxID_UP, ">");
    buttonRight->SetMinSize(wxSize(16, 16));

    box_sizer->Add(buttonLeft);
    box_sizer->Add(text);
    box_sizer->Add(buttonRight);

    this->SetSizer(box_sizer);
    GetSizer()->Fit(this);
    GetSizer()->SetSizeHints(this);
    Centre();
    Fit();
    return TRUE;
}

void mmDateYearMonth::OnButtonPress(wxCommandEvent& event)
{
    wxDateTime d = wxDateTime::Today().SetDay(1).SetMonth((wxDateTime::Month)m_month).SetYear(m_year);
    int button_id = event.GetId();
    switch (button_id)
    {
    case wxID_DOWN:
        d.Subtract(wxDateSpan::Months(1));
        break;
    case wxID_UP:
        d.Add(wxDateSpan::Months(1));
        break;
    }

            m_month = d.GetMonth();
        m_year = d.GetYear();

    const wxString l = wxGetTranslation(wxDateTime::GetEnglishMonthName(wxDateTime::Month(d.GetMonth())));
    wxStaticText* t = static_cast<wxStaticText*>(FindWindow(wxID_INFO));
    t->SetLabel(wxString::Format("%s %d", l, d.GetYear()));
}


M$, VS2017, C++
Post Reply