From f8ce8a84cd43c9a4842f4efc06d2979e29e8ffb5 Mon Sep 17 00:00:00 2001 From: Roland Winklmeier Date: Wed, 5 Mar 2014 15:12:22 +0100 Subject: [PATCH] IKeyboard interface This is the main interface for platform specific implementations. It is a singleton design, since we need one object per process. refs #83 --- src/blackcore/keyboard.cpp | 44 +++++++++ src/blackcore/keyboard.h | 184 +++++++++++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+) create mode 100644 src/blackcore/keyboard.cpp create mode 100644 src/blackcore/keyboard.h diff --git a/src/blackcore/keyboard.cpp b/src/blackcore/keyboard.cpp new file mode 100644 index 000000000..e8b764ae8 --- /dev/null +++ b/src/blackcore/keyboard.cpp @@ -0,0 +1,44 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "keyboard.h" + +#if defined(Q_OS_WIN) + #include "blackcore/win/keyboard_windows.h" +#endif + +namespace BlackCore +{ + IKeyboard *IKeyboard::m_instance = nullptr; + + IKeyboard::IKeyboard(QObject *parent) : + QObject(parent) + { + } + + IKeyboard *IKeyboard::getInstance() + { + if (!m_instance) + { +#if defined(Q_OS_WIN) + m_instance = new CKeyboardWindows; +#elif defined(Q_OS_OSX) +#elif defined(Q_OS_LINUX) +#endif + Q_ASSERT_X(m_instance, "IKeyboard::getInstance", "Pointer to IKeyboard is NULL!"); + m_instance->init(); + } + return m_instance; + } + + bool operator==(IKeyboard::RegistrationHandle const &lhs, IKeyboard::RegistrationHandle const &rhs) + { + if ((lhs.m_key == rhs.m_key) && (lhs.m_receiver == rhs.m_receiver)) + return true; + else + return false; + } + +} // BlackCore diff --git a/src/blackcore/keyboard.h b/src/blackcore/keyboard.h new file mode 100644 index 000000000..281f973d7 --- /dev/null +++ b/src/blackcore/keyboard.h @@ -0,0 +1,184 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*! + \file +*/ + +#ifndef BLACKCORE_KEYBOARD_H +#define BLACKCORE_KEYBOARD_H + +#include "../blackmisc/hwkeyboardkey.h" +#include +#include +#include +#include + +namespace BlackCore +{ + /*! + * \brief Abstract interface for native keyboard handling. + * \todo Add implementation for Linux and OSX. + */ + class IKeyboard : public QObject + { + Q_OBJECT + public: + + //! \brief Handle to a registered hotkey function + struct RegistrationHandle + { + //! \brief Constructor + RegistrationHandle() {} + + BlackMisc::Hardware::CKeyboardKey m_key; //!< Registered key set + QPointer m_receiver; //!< Registered receiver + std::function function; //!< Registered function + }; + + //! Operation mode + enum Mode + { + Mode_Nominal, + Mode_Capture + }; + + //! Constructor + IKeyboard(QObject *parent = nullptr); + + //! Destructor + virtual ~IKeyboard() {} + + //! Creates a native keyboard handler object + static IKeyboard *getInstance(); + + /*! + * \brief Register a invokable slot as hotkey target + * \param key + * \param receiver + * \param slotName + * \return RegistrationHandle + */ + IKeyboard::RegistrationHandle registerHotkey(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, const QByteArray &slotName) + { + auto function = [=](bool isPressed){ QMetaObject::invokeMethod(receiver, slotName, Q_ARG(bool, isPressed)); }; + return registerHotkeyImpl(key, receiver, function); + } + + /*! + * \brief Register a member function as hotkey target + * \param key + * \param receiver + * \param slotPointer + * \return RegistrationHandle + */ + template + IKeyboard::RegistrationHandle registerHotkey(BlackMisc::Hardware::CKeyboardKey key, T *receiver, void (T:: *slotPointer)(bool)) + { + using namespace std::placeholders; + auto function = std::bind(slotPointer, receiver, _1); + return registerHotkeyImpl(key, receiver, function); + } + + /*! + * \brief Register a function object as hotkey target + * \param key + * \param receiver + * \param functionObject + * \return RegistrationHandle + */ + template + IKeyboard::RegistrationHandle registerHotkey(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, F functionObject) + { + return registerHotkeyImpl(key, receiver, functionObject); + } + + /*! + * \brief Unregister hotkey target + * \param handle + */ + void unregisterHotkey(const IKeyboard::RegistrationHandle &handle) + { + unregisterHotkeyImpl(handle); + } + + //! \brief Unregister all hotkeys + void unregisterAllHotkeys() + { + unregisterAllHotkeysImpl(); + } + + /*! + * \brief Select a key combination as hotkey. This method returns immediatly. + * Listen for signals keySelectionChanged and keySelectionFinished + * to retrieve the user input. + * \param ignoreNextKey + * Set to true, if you want to ignore the first key, + * e.g. [ENTER] in case you are running from command line. + */ + virtual void startCapture(bool ignoreNextKey) = 0; + + /*! + * \brief Returns the amount of registered hotkey functions + * \return Size + */ + virtual int sizeOfRegisteredFunctions() const = 0; + + /*! + * \brief Triggers a key event manually and calls the registered functions. + * \param key + * \param isPressed + */ + virtual void triggerKey(const BlackMisc::Hardware::CKeyboardKey key, bool isPressed) = 0; + + signals: + + /*! + * \brief Key selection has changed, but is not finished yet. + * \param key + */ + void keySelectionChanged(BlackMisc::Hardware::CKeyboardKey key); + + /*! + * \brief Key selection has finished. + * \param key + */ + void keySelectionFinished(BlackMisc::Hardware::CKeyboardKey key); + + protected: + + /*! + * \brief Initializes the platform keyboard device + */ + virtual bool init() = 0; + + /*! + * \brief Register implementation + */ + virtual IKeyboard::RegistrationHandle registerHotkeyImpl(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, std::function function) = 0; + + /*! + * \brief Unregister implementation + */ + virtual void unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle) = 0; + + //! \brief Unregister implementation + virtual void unregisterAllHotkeysImpl() = 0; + + private: + + static IKeyboard *m_instance; + }; + + /*! + * \brief Equal operator == + * \param lhs + * \param rhs + * \return + */ + bool operator==(IKeyboard::RegistrationHandle const &lhs, IKeyboard::RegistrationHandle const &rhs); +} + +#endif // BLACKCORE_KEYBOARD_H