]> git.saurik.com Git - wxWidgets.git/commitdiff
Preserve value when changing range of inverted wxSlider in wxMSW.
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 13 Dec 2010 18:10:02 +0000 (18:10 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 13 Dec 2010 18:10:02 +0000 (18:10 +0000)
The logical value of wxSlider was changed when its range was changed in wxMSW
if the slider had wxSL_INVERSE style because the logical value was actually
computed using the range and the actual physical control value and we forgot
to update the latter when changing the range.

Do update it now in SetRange() to fix this.

Also add unit tests checking for this and, more generally, for other
operations with inversed sliders.

Closes #12765.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66368 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/msw/slider.cpp
tests/controls/slidertest.cpp

index 4d08687349438ff6635d975f4ce31475440b750b..ffa5d3919aeed708dc0e415c54bbd75e1170d208 100644 (file)
@@ -712,6 +712,11 @@ void wxSlider::SetValue(int value)
 
 void wxSlider::SetRange(int minValue, int maxValue)
 {
+    // Remember the old logical value if we need to update the physical control
+    // value after changing its range in wxSL_INVERSE case (and avoid an
+    // unnecessary call to GetValue() otherwise as it's just not needed).
+    const int valueOld = HasFlag(wxSL_INVERSE) ? GetValue() : 0;
+
     m_rangeMin = minValue;
     m_rangeMax = maxValue;
 
@@ -725,6 +730,14 @@ void wxSlider::SetRange(int minValue, int maxValue)
         ::SetWindowText((*m_labels)[SliderLabel_Max],
                         Format(ValueInvertOrNot(m_rangeMax)).wx_str());
     }
+
+    // When emulating wxSL_INVERSE style in wxWidgets, we need to update the
+    // value after changing the range to ensure that the value seen by the user
+    // code, i.e. the one returned by GetValue(), does not change.
+    if ( HasFlag(wxSL_INVERSE) )
+    {
+        ::SendMessage(GetHwnd(), TBM_SETPOS, TRUE, ValueInvertOrNot(valueOld));
+    }
 }
 
 void wxSlider::SetTickFreq(int n, int pos)
index 536166c8fcfaa06bf28a8ed1e150f099b101d0b6..2712d4424a4ec7e555be2ff9bcfe85a71120b127 100644 (file)
@@ -39,6 +39,9 @@ private:
         CPPUNIT_TEST( Value );
         CPPUNIT_TEST( Range );
         WXUISIM_TEST( Thumb );
+        CPPUNIT_TEST( PseudoTest_Inversed );
+        CPPUNIT_TEST( Value );
+        CPPUNIT_TEST( Range );
     CPPUNIT_TEST_SUITE_END();
 
     void PageUpDown();
@@ -47,12 +50,17 @@ private:
     void Value();
     void Range();
     void Thumb();
+    void PseudoTest_Inversed() { ms_inversed = true; }
+
+    static bool ms_inversed;
 
     wxSlider* m_slider;
 
     DECLARE_NO_COPY_CLASS(SliderTestCase)
 };
 
+bool SliderTestCase::ms_inversed = false;
+
 // register in the unnamed registry so that these tests are run by default
 CPPUNIT_TEST_SUITE_REGISTRATION( SliderTestCase );
 
@@ -61,7 +69,14 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SliderTestCase, "SliderTestCase" );
 
 void SliderTestCase::setUp()
 {
-    m_slider = new wxSlider(wxTheApp->GetTopWindow(), wxID_ANY, 50, 0, 100);
+    long style = wxSL_HORIZONTAL;
+
+    if ( ms_inversed )
+        style |= wxSL_INVERSE;
+
+    m_slider = new wxSlider(wxTheApp->GetTopWindow(), wxID_ANY, 50, 0, 100,
+                            wxDefaultPosition, wxDefaultSize,
+                            style);
 }
 
 void SliderTestCase::tearDown()
@@ -163,6 +178,11 @@ void SliderTestCase::Range()
     CPPUNIT_ASSERT_EQUAL(0, m_slider->GetMin());
     CPPUNIT_ASSERT_EQUAL(100, m_slider->GetMax());
 
+    // Changing range shouldn't change the value.
+    m_slider->SetValue(17);
+    m_slider->SetRange(0, 200);
+    CPPUNIT_ASSERT_EQUAL(17, m_slider->GetValue());
+
     //Test negative ranges
     m_slider->SetRange(-50, 0);