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: 72
Joined: Fri Nov 11, 2011 5:44 pm
Location: Russia

Date chooser for month and year

Post by maximand » Sun Feb 24, 2019 10:19 am

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: 14893
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Date chooser for month and year

Post by doublemax » Sun Feb 24, 2019 5:12 pm

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: 4170
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Date chooser for month and year

Post by ONEEYEMAN » Sun Feb 24, 2019 9:09 pm

Hi,
Just take a look at the generic version of calendar control.

maximand
Experienced Solver
Experienced Solver
Posts: 72
Joined: Fri Nov 11, 2011 5:44 pm
Location: Russia

Re: Date chooser for month and year

Post by maximand » Tue Feb 26, 2019 6:22 pm

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: 14893
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Date chooser for month and year

Post by doublemax » Tue Feb 26, 2019 7:56 pm

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: 72
Joined: Fri Nov 11, 2011 5:44 pm
Location: Russia

Re: Date chooser for month and year

Post by maximand » Sun Mar 03, 2019 12:12 pm

@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: 72
Joined: Fri Nov 11, 2011 5:44 pm
Location: Russia

Re: Date chooser for month and year

Post by maximand » Mon Mar 04, 2019 2:10 pm

YearMonth.PNG
YearMonth.PNG (766 Bytes) Viewed 535 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: 72
Joined: Fri Nov 11, 2011 5:44 pm
Location: Russia

Re: Date chooser for month and year

Post by maximand » Mon Mar 04, 2019 3:41 pm

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