Page 1 of 1

wxTimePickerCtrl Format

Posted: Sat Feb 08, 2020 5:19 pm
by Rob'
Is it possible the change the format of wxTimePickerCtrl? I would like to suppress the seconds.

Thanks in advance.
Rob'

Re: wxTimePickerCtrl Format

Posted: Sun Feb 09, 2020 12:16 pm
by Martin Silenus
I have been struggling with wxDatePickerCtrl and wxTimePickerCtrl a bit myself too.

Both have a data exchange format using wxDateTime, however
- in case of wxDatePickerCtrl, the time part is "ignored"
- in case of wxTimePickerCtrl, the date part is "ignored"
however the "unused" parts are still there since it is inherently linked to the time model underlying wxDateTime.

The only way I found to correctly suppress the unused parts is to manually copy the useful parts, e.g. (in simplified code)

Code: Select all

// from my GUI, interfacing with wxDatePickerCtrl
void MessageDialog::OnDatePickerFilterTimeFromChange(wxDateEvent& event)
{
    MessageRetriever->SetStartDate(event.GetDate());
}

// in my object code 
void MessageRetriever::SetStartDate(wxDateTime NewStartDate) // only date portion is used
{
    StartDateTime.SetYear(NewStartDate.GetYear());
    StartDateTime.SetMonth(NewStartDate.GetMonth());
    StartDateTime.SetDay(NewStartDate.GetDay());
}
or similarly for time

Code: Select all

void MessageDialog::OnTimePickerFilterTimeFromChange(wxDateEvent& event)
{
    MessageRetriever->SetStartTime(event.GetDate());
}

void MessageRetriever::SetStartTime(wxDateTime NewStartTime) // only time portion is used
{
    StartDateTime.SetHour(NewStartTime.GetHour());
    StartDateTime.SetMinute(NewStartTime.GetMinute());
    StartDateTime.SetSecond(NewStartTime.GetSecond());
}
Note that in my application, StartDateTime is still a wxDateTime element which uses both date and time components. It is however the GUI interface that is split up in two widgets, one for date and another for time.

Hope it helps with your problem

Re: wxTimePickerCtrl Format

Posted: Mon Feb 10, 2020 7:16 pm
by Rob'
Thank you for your reply. But it does not cover my problem. What I want to accomplish is the user should not see the seconds in the input field and it also shouldn't be necessary to enter a complete time with hours, minutes and seconds. I'm looking for something similar to a format string that I can pass to the control, i.e. "HH:mm". Any ideas?

Rob'

Re: wxTimePickerCtrl Format

Posted: Mon Feb 10, 2020 8:06 pm
by doublemax
I don't see an easy way to do this. I think your best chance is to copy the code of the generic implementation of wxTimePickerCtrl and modify it. It's in <wxdir>/src/generic/timectrlg.cpp

Re: wxTimePickerCtrl Format

Posted: Mon Feb 10, 2020 8:07 pm
by PB
The MSW native control wxTimePickerCtrl wraps should be capable of that but I have no idea about other OSes.

EDIT
FWIW, it seems to work just fine on MSW (in a real app the time format string must be built for the user locale) but obviously if one needs to use the app outside of Windows, it is not of much use.
custom_timepicker.png
custom_timepicker.png (2.83 KiB) Viewed 182 times

Code: Select all

#include <wx/wx.h>
#include <wx/timectrl.h>

#ifdef __WXMSW__
    #include <wx/msw/wrapcctl.h>
#endif

class MyDialog : public wxDialog
{
public:
    MyDialog() : wxDialog(nullptr, wxID_ANY, "Test")
    {
        wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
                
        wxTimePickerCtrl* timePickerDefault = new wxTimePickerCtrl(this, wxID_ANY);
        mainSizer->Add(timePickerDefault, wxSizerFlags().Border());

        wxTimePickerCtrl* timePickerCustom = new wxTimePickerCtrl(this, wxID_ANY);
#ifdef __WXMSW__
        //::SendMessageW(timePickerCustom->GetHWND(), DTM_SETFORMAT, 0, LPARAM(L"h:m"));
        DateTime_SetFormat(timePickerCustom->GetHWND(), L"h:m");
#endif
        mainSizer->Add(timePickerCustom, wxSizerFlags().Border());
        
        mainSizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), wxSizerFlags().Expand().Border());

        SetSizerAndFit(mainSizer);
    }
};

class MyApp : public wxApp
{
public:
    bool OnInit() override
    {
        MyDialog().ShowModal();
        return false;
    }
}; wxIMPLEMENT_APP(MyApp);

Re: wxTimePickerCtrl Format

Posted: Tue Feb 11, 2020 11:16 am
by sw
Another potential idea is that you could hook into the kill focus event of a control and always set the seconds component to '00'.

I had a similar scenario to yours wherein I did not want to allow a user to enter seconds. I eventually just opted to set the seconds to whenever a user clicks out of the control.

Code: Select all

// binding
myTimeCtrl->Bind(
    wxEVT_KILL_FOCUS,
    &MyDialog::OnTimeFocusLost,
    this
);

void MyDialog::OnTimeFocusLost(wxFocusEvent& event)
{
    wxDateTime secondsInitializedToZero = wxDateTime::Now();
    secondsInitializedToZero.SetSecond(0);
    myTimeCtrl->SetValue(secondsInitializedToZero);
    
    event.Skip();
}

Re: wxTimePickerCtrl Format

Posted: Fri Feb 14, 2020 9:47 am
by Rob'
Thanks to all! I'm going to try PB's approach.

Rob'