Merge branch 'spinctrl-value'

Consistently return minimum value from wxSpinCtrl with invalid text
value.

See https://github.com/wxWidgets/wxWidgets/pull/2345
This commit is contained in:
Vadim Zeitlin
2021-04-24 11:20:31 +02:00
7 changed files with 38 additions and 33 deletions

View File

@@ -114,6 +114,12 @@ Changes in behaviour not resulting in compilation errors
- wxChoice::GetString() now consistently asserts when passed an invalid index. - wxChoice::GetString() now consistently asserts when passed an invalid index.
- wxSpinCtrlDouble now always resets its value to GetMin() if an invalid text
string is passed to its SetValue(wxString) overload after its creation.
- wxSpinCtrl::SetValue(wxString) overload doesn't generate any events with
wxMSW, which was already the documented behaviour.
Changes in behaviour which may result in build errors Changes in behaviour which may result in build errors
----------------------------------------------------- -----------------------------------------------------

View File

@@ -197,10 +197,10 @@ public:
Sets the value of the spin control. Sets the value of the spin control.
It is recommended to use the overload taking an integer value instead. It is recommended to use the overload taking an integer value instead.
The behaviour of this function when @a text doesn't represent a valid If @a text doesn't represent a valid number, it may not be shown in the
number currently differs between the platforms, however passing an text part of the control at all (only empty string is guaranteed to be
empty string does clear the text part contents, without affecting the supported under all platforms) and the numeric value will be changed to
value returned by GetValue(), under all of them. GetMin().
Notice that, unlike wxTextCtrl::SetValue(), but like most of the other Notice that, unlike wxTextCtrl::SetValue(), but like most of the other
setter methods in wxWidgets, calling this method does not generate any setter methods in wxWidgets, calling this method does not generate any

View File

@@ -522,6 +522,8 @@ void wxSpinCtrlGenericBase::SetValue(const wxString& text)
} }
else // not a number at all or out of range else // not a number at all or out of range
{ {
m_value = m_min;
m_textCtrl->ChangeValue(text); m_textCtrl->ChangeValue(text);
m_textCtrl->SelectAll(); m_textCtrl->SelectAll();
} }

View File

@@ -130,13 +130,9 @@ private:
class wxSpinCtrlGTKTextOverride class wxSpinCtrlGTKTextOverride
{ {
public: public:
wxSpinCtrlGTKTextOverride() // Text value used instead of the text representation of the actual numeric
: m_value(0.0) // value. Notice that this string may be empty.
{
}
wxString m_text; wxString m_text;
double m_value;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -160,19 +156,8 @@ wxSpinCtrlGTKBase::~wxSpinCtrlGTKBase()
void wxSpinCtrlGTKBase::GTKSetTextOverride(const wxString& text) void wxSpinCtrlGTKBase::GTKSetTextOverride(const wxString& text)
{ {
if ( !m_textOverride ) if ( !m_textOverride )
{
// Remember the original numeric value, that we're going to keep using
// it while this override is valid, and do it before initializing
// m_textOverride as our own "input" handler called from GTKGetValue()
// would use it if it were non-null.
const double value = GTKGetValue();
m_textOverride = new wxSpinCtrlGTKTextOverride(); m_textOverride = new wxSpinCtrlGTKTextOverride();
m_textOverride->m_value = value;
}
//else: No need to change the value, it stays the same anyhow.
// Update the text in any case.
m_textOverride->m_text = text; m_textOverride->m_text = text;
} }
@@ -258,10 +243,8 @@ bool wxSpinCtrlGTKBase::Create(wxWindow *parent, wxWindowID id,
double wxSpinCtrlGTKBase::DoGetValue() const double wxSpinCtrlGTKBase::DoGetValue() const
{ {
// While using a text override, the text value is fixed by the program and // While using a text override, the text value is fixed by the program and
// shouldn't be used, just return the numeric value we had had before, as // shouldn't be used, just return the minimum value (which is 0 by default).
// the text override is reset whenever it changes, so it must not have return m_textOverride ? DoGetMin() : GTKGetValue();
// changed yet.
return m_textOverride ? m_textOverride->m_value : GTKGetValue();
} }
double wxSpinCtrlGTKBase::GTKGetValue() const double wxSpinCtrlGTKBase::GTKGetValue() const
@@ -512,7 +495,7 @@ wxSpinCtrlGTKBase::GTKInputResult wxSpinCtrlGTKBase::GTKInput(double* value) con
{ {
if ( m_textOverride ) if ( m_textOverride )
{ {
*value = m_textOverride->m_value; *value = DoGetMin();
return GTKInput_Converted; return GTKInput_Converted;
} }

View File

@@ -37,6 +37,8 @@
#include "wx/msw/private.h" #include "wx/msw/private.h"
#include "wx/msw/private/winstyle.h" #include "wx/msw/private/winstyle.h"
#include "wx/scopeguard.h"
#if wxUSE_TOOLTIPS #if wxUSE_TOOLTIPS
#include "wx/tooltip.h" #include "wx/tooltip.h"
#endif // wxUSE_TOOLTIPS #endif // wxUSE_TOOLTIPS
@@ -359,12 +361,9 @@ bool wxSpinCtrl::Create(wxWindow *parent,
SetRange(min, max); SetRange(min, max);
SetValue(initial); SetValue(initial);
// Also set the text part of the control if it was specified independently // Also set the text part of the control if it was specified independently.
// but don't generate an event for this, it would be unexpected.
m_blockEvent = true;
if ( !value.empty() ) if ( !value.empty() )
SetValue(value); SetValue(value);
m_blockEvent = false;
// Finally deal with the size: notice that this can only be done now both // Finally deal with the size: notice that this can only be done now both
// windows are created and the text one is set up as buddy because // windows are created and the text one is set up as buddy because
@@ -449,6 +448,9 @@ wxString wxSpinCtrl::GetTextValue() const
void wxSpinCtrl::SetValue(const wxString& text) void wxSpinCtrl::SetValue(const wxString& text)
{ {
m_blockEvent = true;
wxON_BLOCK_EXIT_SET(m_blockEvent, false);
if ( !::SetWindowText(GetBuddyHwnd(), text.c_str()) ) if ( !::SetWindowText(GetBuddyHwnd(), text.c_str()) )
{ {
wxLogLastError(wxT("SetWindowText(buddy)")); wxLogLastError(wxT("SetWindowText(buddy)"));
@@ -458,6 +460,7 @@ void wxSpinCtrl::SetValue(const wxString& text)
void wxSpinCtrl::SetValue(int val) void wxSpinCtrl::SetValue(int val)
{ {
m_blockEvent = true; m_blockEvent = true;
wxON_BLOCK_EXIT_SET(m_blockEvent, false);
wxSpinButton::SetValue(val); wxSpinButton::SetValue(val);
@@ -486,8 +489,6 @@ void wxSpinCtrl::SetValue(int val)
} }
m_oldValue = GetValue(); m_oldValue = GetValue();
m_blockEvent = false;
} }
int wxSpinCtrl::GetValue() const int wxSpinCtrl::GetValue() const

View File

@@ -177,9 +177,15 @@ TEST_CASE_METHOD(SpinCtrlDoubleTestCase,
CHECK( m_spin->GetTextValue() == "57.30" ); CHECK( m_spin->GetTextValue() == "57.30" );
CHECK( m_spin->GetValue() == 57.3 ); CHECK( m_spin->GetValue() == 57.3 );
CHECK( updatedSpin.GetCount() == 0 );
CHECK( updatedText.GetCount() == 0 );
m_spin->SetValue(""); m_spin->SetValue("");
CHECK( m_spin->GetTextValue() == "" ); CHECK( m_spin->GetTextValue() == "" );
CHECK( m_spin->GetValue() == 57.3 ); CHECK( m_spin->GetValue() == 0 );
CHECK( updatedSpin.GetCount() == 0 );
CHECK( updatedText.GetCount() == 0 );
} }
#if wxUSE_UIACTIONSIMULATOR #if wxUSE_UIACTIONSIMULATOR

View File

@@ -276,8 +276,15 @@ TEST_CASE_METHOD(SpinCtrlTestCase2, "SpinCtrl::Value", "[spinctrl]")
CHECK( m_spin->GetTextValue() == "57" ); CHECK( m_spin->GetTextValue() == "57" );
CHECK( m_spin->GetValue() == 57 ); CHECK( m_spin->GetValue() == 57 );
CHECK(updatedSpin.GetCount() == 0);
CHECK(updatedText.GetCount() == 0);
m_spin->SetValue(""); m_spin->SetValue("");
CHECK( m_spin->GetTextValue() == "" ); CHECK( m_spin->GetTextValue() == "" );
CHECK( m_spin->GetValue() == 0 );
CHECK(updatedSpin.GetCount() == 0);
CHECK(updatedText.GetCount() == 0);
} }
TEST_CASE_METHOD(SpinCtrlTestCase2, "SpinCtrl::Base", "[spinctrl]") TEST_CASE_METHOD(SpinCtrlTestCase2, "SpinCtrl::Base", "[spinctrl]")