diff --git a/include/wx/private/uiaction.h b/include/wx/private/uiaction.h new file mode 100644 index 0000000000..ed6417ac3c --- /dev/null +++ b/include/wx/private/uiaction.h @@ -0,0 +1,44 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/private/uiaction.h +// Purpose: wxUIActionSimulatorImpl declaration +// Author: Vadim Zeitlin +// Created: 2016-05-21 +// Copyright: (c) 2016 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_PRIVATE_UIACTION_H_ +#define _WX_PRIVATE_UIACTION_H_ + +// ---------------------------------------------------------------------------- +// Platform-specific implementation of wxUIActionSimulator +// ---------------------------------------------------------------------------- + +class wxUIActionSimulatorImpl +{ +public: + wxUIActionSimulatorImpl() { } + virtual ~wxUIActionSimulatorImpl() { } + + // Low level mouse methods which must be implemented in the derived class. + virtual bool MouseMove(long x, long y) = 0; + virtual bool MouseDown(int button = wxMOUSE_BTN_LEFT) = 0; + virtual bool MouseUp(int button = wxMOUSE_BTN_LEFT) = 0; + + // Higher level mouse methods which have default implementation in the base + // class but can be overridden if necessary. + virtual bool MouseClick(int button = wxMOUSE_BTN_LEFT); + virtual bool MouseDblClick(int button = wxMOUSE_BTN_LEFT); + virtual bool MouseDragDrop(long x1, long y1, long x2, long y2, + int button = wxMOUSE_BTN_LEFT); + + // The low-level port-specific function which really generates the key + // presses. It should generate exactly one key event with the given + // parameters. + virtual bool DoKey(int keycode, int modifiers, bool isDown) = 0; + +private: + wxDECLARE_NO_COPY_CLASS(wxUIActionSimulatorImpl); +}; + +#endif // _WX_PRIVATE_UIACTION_H_ diff --git a/include/wx/uiaction.h b/include/wx/uiaction.h index 498da69821..9b8df1094f 100644 --- a/include/wx/uiaction.h +++ b/include/wx/uiaction.h @@ -2,11 +2,10 @@ // Name: wx/uiaction.h // Purpose: wxUIActionSimulator interface // Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin -// Modified by: // Created: 2010-03-06 -// Copyright: (c) Kevin Ollivier +// Copyright: (c) 2010 Kevin Ollivier // (c) 2010 Steven Lamerton -// (c) 2010 Vadim Zeitlin +// (c) 2010-2016 Vadim Zeitlin // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -22,11 +21,8 @@ class WXDLLIMPEXP_CORE wxUIActionSimulator { public: - wxUIActionSimulator() { } - - - // Default dtor, copy ctor and assignment operator are ok (even though the - // last two don't make much sense for this class). + wxUIActionSimulator(); + ~wxUIActionSimulator(); // Mouse simulation @@ -82,10 +78,12 @@ private: void SimulateModifiers(int modifier, bool isDown); - // The low-level port-specific function which really generates the key - // presses. It should generate exactly one key event with the given - // parameters. - bool DoKey(int keycode, int modifiers, bool isDown); + + // This pointer is allocated in the ctor and points to the + // platform-specific implementation. + class wxUIActionSimulatorImpl* const m_impl; + + wxDECLARE_NO_COPY_CLASS(wxUIActionSimulator); }; #endif // wxUSE_UIACTIONSIMULATOR diff --git a/src/common/uiactioncmn.cpp b/src/common/uiactioncmn.cpp index a74a0d10ec..3c9b41fadb 100644 --- a/src/common/uiactioncmn.cpp +++ b/src/common/uiactioncmn.cpp @@ -2,11 +2,10 @@ // Name: src/common/uiactioncmn.cpp // Purpose: wxUIActionSimulator common implementation // Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin -// Modified by: // Created: 2010-03-06 -// Copyright: (c) Kevin Ollivier +// Copyright: (c) 2010 Kevin Ollivier // (c) 2010 Steven Lamerton -// (c) 2010 Vadim Zeitlin +// (c) 2010-2016 Vadim Zeitlin // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -24,8 +23,48 @@ #include "wx/listbox.h" #endif // wxNO_RTTI +#include "wx/private/uiaction.h" + +// ---------------------------------------------------------------------------- +// Methods forwarded to wxUIActionSimulatorImpl +// ---------------------------------------------------------------------------- + +bool wxUIActionSimulator::MouseMove(long x, long y) +{ + return m_impl->MouseMove(x, y); +} + +bool wxUIActionSimulator::MouseDown(int button) +{ + return m_impl->MouseDown(button); +} + +bool wxUIActionSimulator::MouseUp(int button) +{ + return m_impl->MouseUp(button); +} bool wxUIActionSimulator::MouseClick(int button) +{ + return m_impl->MouseClick(button); +} + +bool wxUIActionSimulator::MouseDblClick(int button) +{ + return m_impl->MouseDblClick(button); +} + +bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2, + int button) +{ + return m_impl->MouseDragDrop(x1, y1, x2, y2, button); +} + +// ---------------------------------------------------------------------------- +// Methods implemented in wxUIActionSimulatorImpl itself +// ---------------------------------------------------------------------------- + +bool wxUIActionSimulatorImpl::MouseClick(int button) { MouseDown(button); MouseUp(button); @@ -33,9 +72,7 @@ bool wxUIActionSimulator::MouseClick(int button) return true; } -#ifndef __WXOSX__ - -bool wxUIActionSimulator::MouseDblClick(int button) +bool wxUIActionSimulatorImpl::MouseDblClick(int button) { MouseDown(button); MouseUp(button); @@ -45,7 +82,7 @@ bool wxUIActionSimulator::MouseDblClick(int button) return true; } -bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2, +bool wxUIActionSimulatorImpl::MouseDragDrop(long x1, long y1, long x2, long y2, int button) { MouseMove(x1, y1); @@ -56,8 +93,6 @@ bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2, return true; } -#endif - bool wxUIActionSimulator::Key(int keycode, int modifiers, bool isDown) { @@ -69,7 +104,7 @@ wxUIActionSimulator::Key(int keycode, int modifiers, bool isDown) if ( isDown ) SimulateModifiers(modifiers, true); - bool rc = DoKey(keycode, modifiers, isDown); + bool rc = m_impl->DoKey(keycode, modifiers, isDown); if ( !isDown ) SimulateModifiers(modifiers, false); @@ -80,11 +115,11 @@ wxUIActionSimulator::Key(int keycode, int modifiers, bool isDown) void wxUIActionSimulator::SimulateModifiers(int modifiers, bool isDown) { if ( modifiers & wxMOD_SHIFT ) - DoKey(WXK_SHIFT, modifiers, isDown); + m_impl->DoKey(WXK_SHIFT, modifiers, isDown); if ( modifiers & wxMOD_ALT ) - DoKey(WXK_ALT, modifiers, isDown); + m_impl->DoKey(WXK_ALT, modifiers, isDown); if ( modifiers & wxMOD_CONTROL ) - DoKey(WXK_CONTROL, modifiers, isDown); + m_impl->DoKey(WXK_CONTROL, modifiers, isDown); } bool wxUIActionSimulator::Char(int keycode, int modifiers) diff --git a/src/msw/uiaction.cpp b/src/msw/uiaction.cpp index 5308d9c0f1..9860d76b33 100644 --- a/src/msw/uiaction.cpp +++ b/src/msw/uiaction.cpp @@ -19,6 +19,8 @@ #endif #include "wx/uiaction.h" +#include "wx/private/uiaction.h" + #include "wx/msw/wrapwin.h" #include "wx/msw/private/keyboard.h" @@ -28,6 +30,31 @@ namespace { +class wxUIActionSimulatorMSWImpl : public wxUIActionSimulatorImpl +{ +public: + // Returns a pointer to the global simulator object: as it's stateless, we + // can reuse the same one without having to allocate it on the heap all the + // time. + static wxUIActionSimulatorMSWImpl* Get() + { + static wxUIActionSimulatorMSWImpl s_impl; + return &s_impl; + } + + virtual bool MouseMove(long x, long y) wxOVERRIDE; + virtual bool MouseDown(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE; + virtual bool MouseUp(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE; + + virtual bool DoKey(int keycode, int modifiers, bool isDown) wxOVERRIDE; + +private: + // This class has no public ctors, use Get() instead. + wxUIActionSimulatorMSWImpl() { } + + wxDECLARE_NO_COPY_CLASS(wxUIActionSimulatorMSWImpl); +}; + DWORD EventTypeForMouseButton(int button, bool isDown) { switch (button) @@ -49,7 +76,7 @@ DWORD EventTypeForMouseButton(int button, bool isDown) } // anonymous namespace -bool wxUIActionSimulator::MouseDown(int button) +bool wxUIActionSimulatorMSWImpl::MouseDown(int button) { POINT p; wxGetCursorPosMSW(&p); @@ -57,7 +84,7 @@ bool wxUIActionSimulator::MouseDown(int button) return true; } -bool wxUIActionSimulator::MouseMove(long x, long y) +bool wxUIActionSimulatorMSWImpl::MouseMove(long x, long y) { // Because MOUSEEVENTF_ABSOLUTE takes measurements scaled between 0 & 65535 // we need to scale our input too @@ -73,7 +100,7 @@ bool wxUIActionSimulator::MouseMove(long x, long y) return true; } -bool wxUIActionSimulator::MouseUp(int button) +bool wxUIActionSimulatorMSWImpl::MouseUp(int button) { POINT p; wxGetCursorPosMSW(&p); @@ -82,7 +109,7 @@ bool wxUIActionSimulator::MouseUp(int button) } bool -wxUIActionSimulator::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown) +wxUIActionSimulatorMSWImpl::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown) { bool isExtended; DWORD vkkeycode = wxMSWKeyboard::WXToVK(keycode, &isExtended); @@ -98,4 +125,15 @@ wxUIActionSimulator::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown) return true; } +wxUIActionSimulator::wxUIActionSimulator() + : m_impl(wxUIActionSimulatorMSWImpl::Get()) +{ +} + +wxUIActionSimulator::~wxUIActionSimulator() +{ + // We can use a static wxUIActionSimulatorMSWImpl object because it's + // stateless, so no need to delete it. +} + #endif // wxUSE_UIACTIONSIMULATOR diff --git a/src/osx/uiaction_osx.cpp b/src/osx/uiaction_osx.cpp index 78112ef07e..31b7d987ae 100644 --- a/src/osx/uiaction_osx.cpp +++ b/src/osx/uiaction_osx.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // Name: src/osx/uiaction_osx.cpp -// Purpose: wxUIActionSimulator implementation +// Purpose: wxUIActionSimulatorOSXImpl implementation // Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin // Modified by: // Created: 2010-03-06 @@ -19,6 +19,7 @@ #if wxUSE_UIACTIONSIMULATOR #include "wx/uiaction.h" +#include "wx/private/uiaction.h" #include "wx/log.h" @@ -111,9 +112,38 @@ CGPoint GetMousePosition() return pos; } +class wxUIActionSimulatorOSXImpl : public wxUIActionSimulatorImpl +{ +public: + // Returns a pointer to the global simulator object: as it's stateless, we + // can reuse the same one without having to allocate it on the heap all the + // time. + static wxUIActionSimulatorOSXImpl* Get() + { + static wxUIActionSimulatorOSXImpl s_impl; + return &s_impl; + } + + virtual bool MouseMove(long x, long y) wxOVERRIDE; + virtual bool MouseDown(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE; + virtual bool MouseUp(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE; + + virtual bool MouseDblClick(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE; + virtual bool MouseDragDrop(long x1, long y1, long x2, long y2, + int button = wxMOUSE_BTN_LEFT) wxOVERRIDE; + + virtual bool DoKey(int keycode, int modifiers, bool isDown) wxOVERRIDE; + +private: + // This class has no public ctors, use Get() instead. + wxUIActionSimulatorOSXImpl() { } + + wxDECLARE_NO_COPY_CLASS(wxUIActionSimulatorOSXImpl); +}; + } // anonymous namespace -bool wxUIActionSimulator::MouseDown(int button) +bool wxUIActionSimulatorOSXImpl::MouseDown(int button) { CGEventType type = CGEventTypeForMouseButton(button, true); wxCFRef event( @@ -131,7 +161,7 @@ bool wxUIActionSimulator::MouseDown(int button) return true; } -bool wxUIActionSimulator::MouseMove(long x, long y) +bool wxUIActionSimulatorOSXImpl::MouseMove(long x, long y) { CGPoint pos; pos.x = x; @@ -154,7 +184,7 @@ bool wxUIActionSimulator::MouseMove(long x, long y) return true; } -bool wxUIActionSimulator::MouseUp(int button) +bool wxUIActionSimulatorOSXImpl::MouseUp(int button) { CGEventType type = CGEventTypeForMouseButton(button, false); wxCFRef event( @@ -172,7 +202,7 @@ bool wxUIActionSimulator::MouseUp(int button) return true; } -bool wxUIActionSimulator::MouseDblClick(int button) +bool wxUIActionSimulatorOSXImpl::MouseDblClick(int button) { CGEventType downtype = CGEventTypeForMouseButton(button, true); CGEventType uptype = CGEventTypeForMouseButton(button, false); @@ -201,7 +231,7 @@ bool wxUIActionSimulator::MouseDblClick(int button) return true; } -bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2, +bool wxUIActionSimulatorOSXImpl::MouseDragDrop(long x1, long y1, long x2, long y2, int button) { CGPoint pos1,pos2; @@ -241,7 +271,7 @@ bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2, } bool -wxUIActionSimulator::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown) +wxUIActionSimulatorOSXImpl::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown) { CGKeyCode cgcode = wxCharCodeWXToOSX((wxKeyCode)keycode); @@ -258,5 +288,15 @@ wxUIActionSimulator::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown) return true; } -#endif // wxUSE_UIACTIONSIMULATOR +wxUIActionSimulator::wxUIActionSimulator() + : m_impl(wxUIActionSimulatorOSXImpl::Get()) +{ +} +wxUIActionSimulator::~wxUIActionSimulator() +{ + // We can use a static wxUIActionSimulatorOSXImpl object because it's + // stateless, so no need to delete it. +} + +#endif // wxUSE_UIACTIONSIMULATOR diff --git a/src/qt/uiaction.cpp b/src/qt/uiaction.cpp index 833d5c9f75..6490cf35d9 100644 --- a/src/qt/uiaction.cpp +++ b/src/qt/uiaction.cpp @@ -12,13 +12,15 @@ #pragma hdrstop #endif +#include "wx/uiaction.h" +#include "wx/private/uiaction.h" + #include #include #include #include "wx/qt/defs.h" #include "wx/qt/private/utils.h" -#include "wx/uiaction.h" #include "wx/qt/private/converter.h" @@ -37,6 +39,31 @@ inline QWindow* argForEvents(QWidget* w) { return w->windowHandle(); } inline QWidget* argForEvents(QWidget* w) { return w; } #endif +class wxUIActionSimulatorQtImpl : public wxUIActionSimulatorImpl +{ +public: + // Returns a pointer to the global simulator object: as it's stateless, we + // can reuse the same one without having to allocate it on the heap all the + // time. + static wxUIActionSimulatorQtImpl* Get() + { + static wxUIActionSimulatorQtImpl s_impl; + return &s_impl; + } + + virtual bool MouseMove(long x, long y) wxOVERRIDE; + virtual bool MouseDown(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE; + virtual bool MouseUp(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE; + + virtual bool DoKey(int keycode, int modifiers, bool isDown) wxOVERRIDE; + +private: + // This class has no public ctors, use Get() instead. + wxUIActionSimulatorQtImpl() { } + + wxDECLARE_NO_COPY_CLASS(wxUIActionSimulatorQtImpl); +}; + static MouseButton ConvertMouseButton( int button ) { MouseButton qtButton; @@ -95,24 +122,24 @@ static bool SimulateKeyboardKey( KeyAction keyAction, Key key ) return widget != NULL; } -bool wxUIActionSimulator::MouseDown( int button ) +bool wxUIActionSimulatorQtImpl::MouseDown( int button ) { return SimulateMouseButton( MousePress, ConvertMouseButton( button )); } -bool wxUIActionSimulator::MouseUp(int button) +bool wxUIActionSimulatorQtImpl::MouseUp(int button) { return SimulateMouseButton( MouseRelease, ConvertMouseButton( button )); } -bool wxUIActionSimulator::MouseMove(long x, long y) +bool wxUIActionSimulatorQtImpl::MouseMove(long x, long y) { QCursor::setPos( x, y ); return true; } -bool wxUIActionSimulator::DoKey(int keyCode, int modifiers, bool isDown) +bool wxUIActionSimulatorQtImpl::DoKey(int keyCode, int modifiers, bool isDown) { Qt::KeyboardModifiers qtmodifiers; enum Key key; @@ -124,5 +151,16 @@ bool wxUIActionSimulator::DoKey(int keyCode, int modifiers, bool isDown) return SimulateKeyboardKey( keyAction, key ); } -#endif // wxUSE_UIACTIONSIMULATOR +wxUIActionSimulator::wxUIActionSimulator() + : m_impl(wxUIActionSimulatorQtImpl::Get()) +{ +} + +wxUIActionSimulator::~wxUIActionSimulator() +{ + // We can use a static wxUIActionSimulatorQtImpl object because it's + // stateless, so no need to delete it. +} + +#endif // wxUSE_UIACTIONSIMULATOR diff --git a/src/unix/uiactionx11.cpp b/src/unix/uiactionx11.cpp index 4121eb4209..a0fe1cb2ee 100644 --- a/src/unix/uiactionx11.cpp +++ b/src/unix/uiactionx11.cpp @@ -2,11 +2,10 @@ // Name: src/unix/uiactionx11.cpp // Purpose: wxUIActionSimulator implementation // Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin -// Modified by: // Created: 2010-03-06 -// Copyright: (c) Kevin Ollivier +// Copyright: (c) 2010 Kevin Ollivier // (c) 2010 Steven Lamerton -// (c) 2010 Vadim Zeitlin +// (c) 2010-2016 Vadim Zeitlin // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -18,6 +17,8 @@ #include "wx/event.h" #include "wx/evtloop.h" +#include "wx/private/uiaction.h" + #include #include #if wxUSE_XTEST @@ -29,6 +30,31 @@ namespace { +class wxUIActionSimulatorX11Impl : public wxUIActionSimulatorImpl +{ +public: + // Returns a pointer to the global simulator object: as it's stateless, we + // can reuse the same one without having to allocate it on the heap all the + // time. + static wxUIActionSimulatorX11Impl* Get() + { + static wxUIActionSimulatorX11Impl s_impl; + return &s_impl; + } + + virtual bool MouseMove(long x, long y) wxOVERRIDE; + virtual bool MouseDown(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE; + virtual bool MouseUp(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE; + + virtual bool DoKey(int keycode, int modifiers, bool isDown) wxOVERRIDE; + +private: + // This class has no public ctors, use Get() instead. + wxUIActionSimulatorX11Impl() { } + + wxDECLARE_NO_COPY_CLASS(wxUIActionSimulatorX11Impl); +}; + void SendButtonEvent(int button, bool isDown) { int xbutton; @@ -83,13 +109,13 @@ void SendButtonEvent(int button, bool isDown) } // anonymous namespace -bool wxUIActionSimulator::MouseDown(int button) +bool wxUIActionSimulatorX11Impl::MouseDown(int button) { SendButtonEvent(button, true); return true; } -bool wxUIActionSimulator::MouseMove(long x, long y) +bool wxUIActionSimulatorX11Impl::MouseMove(long x, long y) { wxX11Display display; wxASSERT_MSG(display, "No display available!"); @@ -114,13 +140,13 @@ bool wxUIActionSimulator::MouseMove(long x, long y) return true; } -bool wxUIActionSimulator::MouseUp(int button) +bool wxUIActionSimulatorX11Impl::MouseUp(int button) { SendButtonEvent(button, false); return true; } -bool wxUIActionSimulator::DoKey(int keycode, int modifiers, bool isDown) +bool wxUIActionSimulatorX11Impl::DoKey(int keycode, int modifiers, bool isDown) { wxX11Display display; wxCHECK_MSG(display, false, "No display available!"); @@ -188,4 +214,15 @@ bool wxUIActionSimulator::DoKey(int keycode, int modifiers, bool isDown) #endif // !wxUSE_XTEST } +wxUIActionSimulator::wxUIActionSimulator() + : m_impl(wxUIActionSimulatorX11Impl::Get()) +{ +} + +wxUIActionSimulator::~wxUIActionSimulator() +{ + // We can use a static wxUIActionSimulatorX11Impl object because it's + // stateless, so no need to delete it. +} + #endif // wxUSE_UIACTIONSIMULATOR