diff --git a/docs/changes.txt b/docs/changes.txt index 25d36877e0..840417ab50 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -54,6 +54,12 @@ Changes in behaviour not resulting in compilation errors - wxEVT_AUINOTEBOOK_PAGE_CHANGED event is now sent after changing the page, as expected, and not before doing it. +- wxJoystickEvent::GetButtonChange() now returns "1 << N" for the events + generated by the button number N under all platforms, whereas it used to + return just "N" under Linux and macOS. Use the new GetButtonOrdinal() to + update the existing code if necessary. + + Changes in behaviour which may result in build errors ----------------------------------------------------- @@ -131,6 +137,7 @@ All (GUI): - Add wxGrid::SetCornerLabelValue() (Pavel Kalugin). - Add strikethrough support for fonts defined in XRC. - Add wxDisplay::GetPPI(). +- Add wxJoystickEvent::GetButtonOrdinal() (Mick Phillips). wxGTK: diff --git a/include/wx/event.h b/include/wx/event.h index d2b7a5d932..20f08b1ae2 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -15,6 +15,7 @@ #include "wx/cpp.h" #include "wx/object.h" #include "wx/clntdata.h" +#include "wx/math.h" #if wxUSE_GUI #include "wx/gdicmn.h" @@ -2760,6 +2761,7 @@ public: int GetZPosition() const { return m_zPosition; } int GetButtonState() const { return m_buttonState; } int GetButtonChange() const { return m_buttonChange; } + int GetButtonOrdinal() const { return wxCTZ(m_buttonChange); } int GetJoystick() const { return m_joyStick; } void SetJoystick(int stick) { m_joyStick = stick; } diff --git a/include/wx/math.h b/include/wx/math.h index 544b5c7d6e..261969d364 100644 --- a/include/wx/math.h +++ b/include/wx/math.h @@ -150,6 +150,9 @@ inline int wxRound(double x) inline double wxDegToRad(double deg) { return (deg * M_PI) / 180.0; } inline double wxRadToDeg(double rad) { return (rad * 180.0) / M_PI; } +// Count trailing zeros. +WXDLLIMPEXP_BASE unsigned int wxCTZ(wxUint32 x); + #endif /* __cplusplus */ diff --git a/interface/wx/event.h b/interface/wx/event.h index b58fdc4a3c..061ba76201 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -1741,10 +1741,24 @@ public: /** Returns the identifier of the button changing state. - This is a @c wxJOY_BUTTONn identifier, where @c n is one of 1, 2, 3, 4. + The return value is @code 1 << n @endcode where @c n is the index of the + button changing state, which can also be retrieved using GetButtonOrdinal(). + + Note that for @c n equal to 1, 2, 3 or 4 there are predefined @c wxJOY_BUTTONn + constants which can be used for more clarity, however these constants are not + defined for the buttons beyond the first four. */ int GetButtonChange() const; + /** + Returns the 0-indexed ordinal of the button changing state. + + @see GetButtonChange() + + @since 3.1.2. + */ + int GetButtonOrdinal() const; + /** Returns the down state of the buttons. diff --git a/interface/wx/math.h b/interface/wx/math.h index ca11a9fff2..b1486c270c 100644 --- a/interface/wx/math.h +++ b/interface/wx/math.h @@ -75,6 +75,19 @@ double wxDegToRad(double deg); */ double wxRadToDeg(double rad); +/** + Count the number of trailing zeros. + + This function returns the number of trailing zeros in the binary notation + of its argument @a x. E.g. for @a x equal to 4, or 0b100, the return value + is 2. + + @param x Strictly positive, i.e. non-zero, 32 bit number. + + @since 3.1.2 + */ +unsigned int wxCTZ(wxUint32 x); + /** Small wrapper around round(). */ diff --git a/samples/joytest/joytest.cpp b/samples/joytest/joytest.cpp index dd62713eec..c355d05fe6 100644 --- a/samples/joytest/joytest.cpp +++ b/samples/joytest/joytest.cpp @@ -159,7 +159,7 @@ void MyCanvas::OnJoystickEvent(wxJoystickEvent& event) #if wxUSE_STATUSBAR wxString buf; if (event.ButtonDown()) - buf.Printf("Joystick (%ld, %ld) #%i Fire!", xpos, ypos, event.GetButtonChange()); + buf.Printf("Joystick (%ld, %ld) #%i Fire!", xpos, ypos, event.GetButtonOrdinal()); else buf.Printf("Joystick (%ld, %ld) ", xpos, ypos); diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index f18f5f1fb2..456dc1b38a 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -19,6 +19,8 @@ // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" +#include "wx/debug.h" + #ifdef __BORLANDC__ #pragma hdrstop #endif @@ -1015,6 +1017,27 @@ unsigned int wxGCD(unsigned int u, unsigned int v) return u << shift; } +// ---------------------------------------------------------------------------- +// wxCTZ +// Count trailing zeros. Use optimised builtin where available. +// ---------------------------------------------------------------------------- +unsigned int wxCTZ(wxUint32 x) +{ + wxCHECK_MSG(x > 0, 0, "Undefined for x == 0."); +#ifdef __GNUC__ + return __builtin_ctz(x); +#else + int n; + n = 1; + if ((x & 0x0000FFFF) == 0) {n = n +16; x = x >>16;} + if ((x & 0x000000FF) == 0) {n = n + 8; x = x >> 8;} + if ((x & 0x0000000F) == 0) {n = n + 4; x = x >> 4;} + if ((x & 0x00000003) == 0) {n = n + 2; x = x >> 2;} + return n - (x & 1); +#endif +} + + #endif // wxUSE_BASE // ============================================================================ diff --git a/src/msw/joystick.cpp b/src/msw/joystick.cpp index 3290460ab6..b53aeb6d23 100644 --- a/src/msw/joystick.cpp +++ b/src/msw/joystick.cpp @@ -37,23 +37,6 @@ #include -// Use optimised count trailing zeros where available. -static int wxCtz(unsigned x) -{ - wxCHECK_MSG(x > 0, 0, "Undefined for x == 0."); -#ifdef __GNUC__ - return __builtin_ctz(x); -#else - int n; - n = 1; - if ((x & 0x0000FFFF) == 0) {n = n +16; x = x >>16;} - if ((x & 0x000000FF) == 0) {n = n + 8; x = x >> 8;} - if ((x & 0x0000000F) == 0) {n = n + 4; x = x >> 4;} - if ((x & 0x00000003) == 0) {n = n + 2; x = x >> 2;} - return n - (x & 1); -#endif -} - enum { wxJS_AXIS_X = 0, @@ -90,7 +73,7 @@ public: private: void SendEvent(wxEventType type, long ts, int change = 0); int m_joystick; - UINT m_buttons; + int m_buttons; wxWindow* m_catchwin; int m_polling; JOYINFO m_joyInfo; @@ -141,9 +124,9 @@ void* wxJoystickThread::Entry() // "Current button number that is pressed.", but it turns out // it is the *total* number of buttons pressed. if (deltaUp) - SendEvent(wxEVT_JOY_BUTTON_UP, ts, wxCtz(deltaUp)+1); + SendEvent(wxEVT_JOY_BUTTON_UP, ts, deltaUp); if (deltaDown) - SendEvent(wxEVT_JOY_BUTTON_DOWN, ts, wxCtz(deltaDown)+1); + SendEvent(wxEVT_JOY_BUTTON_DOWN, ts, deltaDown); if ((m_joyInfo.wXpos != m_lastJoyInfo.wXpos) || (m_joyInfo.wYpos != m_lastJoyInfo.wYpos) || diff --git a/src/osx/core/hidjoystick.cpp b/src/osx/core/hidjoystick.cpp index feace2517e..cf47209311 100644 --- a/src/osx/core/hidjoystick.cpp +++ b/src/osx/core/hidjoystick.cpp @@ -872,7 +872,7 @@ void* wxJoystickThread::Entry() wxevent.SetEventType(wxEVT_JOY_BUTTON_UP); } - wxevent.SetButtonChange(nIndex+1); + wxevent.SetButtonChange(1 << nIndex); } else if (nIndex == wxJS_AXIS_X) { diff --git a/src/unix/joystick.cpp b/src/unix/joystick.cpp index 928e9f6fc9..0e51fd5ca6 100644 --- a/src/unix/joystick.cpp +++ b/src/unix/joystick.cpp @@ -181,12 +181,12 @@ void* wxJoystickThread::Entry() if (j_evt.value) { m_buttons |= (1 << j_evt.number); - SendEvent(wxEVT_JOY_BUTTON_DOWN, j_evt.time, j_evt.number); + SendEvent(wxEVT_JOY_BUTTON_DOWN, j_evt.time, 1 << j_evt.number); } else { m_buttons &= ~(1 << j_evt.number); - SendEvent(wxEVT_JOY_BUTTON_UP, j_evt.time, j_evt.number); + SendEvent(wxEVT_JOY_BUTTON_UP, j_evt.time, 1 << j_evt.number); } } } diff --git a/tests/misc/misctests.cpp b/tests/misc/misctests.cpp index b6dd757513..c6f1a0f64b 100644 --- a/tests/misc/misctests.cpp +++ b/tests/misc/misctests.cpp @@ -19,6 +19,8 @@ #include "wx/defs.h" +#include "wx/math.h" + // just some classes using wxRTTI for wxStaticCast() test #include "wx/tarstrm.h" #include "wx/zipstrm.h" @@ -150,3 +152,12 @@ void MiscTestCase::StaticCast() #endif // wxUSE_TARSTREAM } +TEST_CASE("wxCTZ", "[math]") +{ + CHECK( wxCTZ(1) == 0 ); + CHECK( wxCTZ(4) == 2 ); + CHECK( wxCTZ(17) == 0 ); + CHECK( wxCTZ(0x80000000) == 31 ); + + WX_ASSERT_FAILS_WITH_ASSERT( wxCTZ(0) ); +}