| #pragma once |
| |
| #ifndef INPUTMANAGER_INCLUDED |
| #define INPUTMANAGER_INCLUDED |
| |
| |
| #include <tools/tooltimer.h> |
| #include <tools/inputstate.h> |
| #include <tools/track.h> |
| |
| |
| #include <tcommon.h> |
| #include <tsmartpointer.h> |
| |
| |
| #include <QObject> |
| #include <QKeyEvent> |
| |
| |
| #include <vector> |
| #include <algorithm> |
| |
| |
| #undef DVAPI |
| #undef DVVAR |
| #ifdef TNZTOOLS_EXPORTS |
| #define DVAPI DV_EXPORT_API |
| #define DVVAR DV_EXPORT_VAR |
| #else |
| #define DVAPI DV_IMPORT_API |
| #define DVVAR DV_IMPORT_VAR |
| #endif |
| |
| |
| |
| |
| |
| |
| class TInputModifier; |
| class TInputManager; |
| |
| typedef TSmartPointerT<TInputModifier> TInputModifierP; |
| |
| |
| |
| |
| |
| |
| |
| |
| class TInputSavePoint { |
| public: |
| class Holder { |
| private: |
| TInputSavePoint *m_savePoint; |
| bool m_lock = false; |
| |
| public: |
| inline explicit Holder(TInputSavePoint *savePoint = NULL, bool lock = true): |
| m_savePoint(), m_lock() |
| { set(savePoint, lock); } |
| inline Holder(const Holder &other): |
| m_savePoint(), m_lock() |
| { *this = other; } |
| inline ~Holder() |
| { reset(); } |
| |
| inline Holder& operator= (const Holder &other) |
| { set(other.m_savePoint, other.m_lock); return *this; } |
| |
| inline operator bool () const |
| { return assigned(); } |
| |
| inline void set(TInputSavePoint *savePoint, bool lock) { |
| if (m_savePoint != savePoint) { |
| if (m_savePoint) { |
| if (m_lock) m_savePoint->unlock(); |
| m_savePoint->release(); |
| } |
| m_savePoint = savePoint; |
| m_lock = lock; |
| if (m_savePoint) { |
| m_savePoint->hold(); |
| if (m_lock) savePoint->lock(); |
| } |
| } else |
| if (m_lock != lock) { |
| if (m_savePoint) { |
| if (lock) m_savePoint->lock(); |
| else m_savePoint->unlock(); |
| } |
| m_lock = lock; |
| } |
| } |
| |
| inline void reset() |
| { set(NULL, false); } |
| inline void lock() |
| { set(m_savePoint, true); } |
| inline void unlock() |
| { set(m_savePoint, false); } |
| |
| inline TInputSavePoint* savePoint() const |
| { return m_savePoint; } |
| inline bool assigned() const |
| { return savePoint(); } |
| inline bool locked() const |
| { return m_savePoint && m_lock; } |
| inline bool available() const |
| { return m_savePoint && m_savePoint->available; } |
| inline bool isFree() const |
| { return !m_savePoint || m_savePoint->isFree(); } |
| }; |
| |
| typedef std::vector<Holder> List; |
| |
| private: |
| int m_refCount; |
| int m_lockCount; |
| |
| inline void hold() |
| { ++m_refCount; } |
| inline void release() |
| { if ((--m_refCount) <= 0) delete this; } |
| inline void lock() |
| { ++m_lockCount; } |
| inline void unlock() |
| { --m_lockCount; } |
| |
| public: |
| bool available; |
| |
| inline explicit TInputSavePoint(bool available = false): |
| m_refCount(), m_lockCount(), available(available) { } |
| inline bool isFree() const |
| { return m_lockCount <= 0; } |
| |
| static inline Holder create(bool available = false) |
| { return Holder(new TInputSavePoint(available)); } |
| }; |
| |
| |
| |
| |
| |
| |
| class TInputModifier: public TSmartObject { |
| private: |
| TInputManager *m_manager; |
| |
| public: |
| typedef std::vector<TInputModifierP> List; |
| |
| TInputManager* getManager() const |
| { return m_manager; } |
| void setManager(TInputManager *manager); |
| virtual void onSetManager() { } |
| |
| virtual void activate() { } |
| |
| virtual void modifyTrack( |
| const TTrack &track, |
| const TInputSavePoint::Holder &savePoint, |
| TTrackList &outTracks ); |
| virtual void modifyTracks( |
| const TTrackList &tracks, |
| const TInputSavePoint::Holder &savePoint, |
| TTrackList &outTracks ); |
| |
| virtual void modifyHover( |
| const TPointD &hover, |
| THoverList &outHovers ); |
| virtual void modifyHovers( |
| const THoverList &hovers, |
| THoverList &outHovers ); |
| |
| virtual TRectD calcDrawBoundsHover(const TPointD &hover) { return TRectD(); } |
| virtual TRectD calcDrawBoundsTrack(const TTrack &track) { return TRectD(); } |
| virtual TRectD calcDrawBounds(const TTrackList &tracks, const THoverList &hovers); |
| |
| virtual void drawHover(const TPointD &hover) { } |
| virtual void drawTrack(const TTrack &track) { } |
| virtual void draw(const TTrackList &tracks, const THoverList &hovers); |
| |
| virtual void deactivate() { } |
| }; |
| |
| |
| |
| |
| |
| |
| class TInputHandler { |
| public: |
| virtual void inputLeftButtonDown(const TTrackPoint&, const TTrack&) { } |
| virtual void inputLeftButtonDrag(const TTrackPoint&, const TTrack&) { } |
| virtual void inputLeftButtonUp(const TTrackPoint&, const TTrack&) { } |
| virtual void inputMouseMove(const TPointD&, const TInputState&) { } |
| virtual void inputRightButtonDown(const TPointD&, const TInputState&) { } |
| virtual bool inputKeyDown(QKeyEvent *) { return false; } |
| |
| virtual void inputSetBusy(bool) { } |
| |
| virtual bool inputKeyEvent( |
| bool press, |
| TInputState::Key key, |
| QKeyEvent *event, |
| const TInputManager &manager ); |
| |
| virtual void inputButtonEvent( |
| bool press, |
| TInputState::DeviceId device, |
| TInputState::Button button, |
| const TInputManager &manager ); |
| |
| virtual void inputHoverEvent(const TInputManager &manager); |
| |
| |
| virtual void inputPaintTrackPoint(const TTrackPoint &point, const TTrack &track, bool firstTrack); |
| |
| |
| |
| |
| virtual bool inputPaintPush() { return false; } |
| |
| |
| |
| virtual void inputPaintTracks(const TTrackList &tracks); |
| |
| |
| |
| virtual int inputPaintApply(int count) { return 0; } |
| |
| |
| |
| virtual void inputPaintCancel() { } |
| |
| |
| |
| virtual void inputPaintPop(int count) { } |
| |
| virtual void inputInvalidateRect(const TRectD &bounds) { } |
| }; |
| |
| |
| |
| |
| |
| |
| class TInputManager { |
| public: |
| class TrackHandler: public TTrackHandler { |
| public: |
| std::vector<int> saves; |
| TrackHandler(TTrack &original, int keysCount = 0): |
| TTrackHandler(original), saves(keysCount, 0) |
| { } |
| }; |
| |
| private: |
| TTimerTicks m_lastTicks; |
| TInputHandler *m_handler; |
| TInputModifier::List m_modifiers; |
| std::vector<TTrackList> m_tracks; |
| std::vector<THoverList> m_hovers; |
| TInputSavePoint::List m_savePoints; |
| int m_savePointsSent; |
| |
| static TInputState::TouchId m_lastTouchId; |
| |
| |
| public: |
| TInputState state; |
| |
| |
| public: |
| TInputManager(); |
| |
| private: |
| inline TTimerTicks fixTicks(TTimerTicks ticks) { |
| if (ticks <= m_lastTicks) ticks = m_lastTicks + 1; |
| return m_lastTicks = ticks; |
| } |
| |
| void paintRollbackTo(int saveIndex, TTrackList &subTracks); |
| void paintApply(int count, TTrackList &subTracks); |
| void paintTracks(); |
| |
| int trackCompare( |
| const TTrack &track, |
| TInputState::DeviceId deviceId, |
| TInputState::TouchId touchId ) const; |
| const TTrackP& createTrack( |
| int index, |
| TInputState::DeviceId deviceId, |
| TInputState::TouchId touchId, |
| TTimerTicks ticks, |
| bool hasPressure, |
| bool hasTilt ); |
| const TTrackP& getTrack( |
| TInputState::DeviceId deviceId, |
| TInputState::TouchId touchId, |
| TTimerTicks ticks, |
| bool hasPressure, |
| bool hasTilt ); |
| void addTrackPoint( |
| const TTrackP& track, |
| const TPointD &position, |
| double pressure, |
| const TPointD &tilt, |
| double time, |
| bool final ); |
| void touchTracks(bool finish = false); |
| |
| void modifierActivate(const TInputModifierP &modifier); |
| void modifierDeactivate(const TInputModifierP &modifier); |
| |
| public: |
| inline const TTrackList& getInputTracks() const |
| { return m_tracks.front(); } |
| inline const TTrackList& getOutputTracks() const |
| { return m_tracks.back(); } |
| |
| inline const THoverList& getInputHovers() const |
| { return m_hovers.front(); } |
| inline const THoverList& getOutputHovers() const |
| { return m_hovers.back(); } |
| |
| void processTracks(); |
| void finishTracks(); |
| void reset(); |
| |
| TInputHandler* getHandler() const |
| { return m_handler; } |
| void setHandler(TInputHandler *handler); |
| |
| int getModifiersCount() const |
| { return (int)m_modifiers.size(); } |
| const TInputModifierP& getModifier(int index) const |
| { return m_modifiers[index]; } |
| int findModifier(const TInputModifierP &modifier) const; |
| void insertModifier(int index, const TInputModifierP &modifier); |
| void addModifier(const TInputModifierP &modifier) |
| { insertModifier(getModifiersCount(), modifier); } |
| void removeModifier(int index); |
| void removeModifier(const TInputModifierP &modifier) |
| { removeModifier(findModifier(modifier)); } |
| void clearModifiers(); |
| |
| void trackEvent( |
| TInputState::DeviceId deviceId, |
| TInputState::TouchId touchId, |
| const TPointD &position, |
| const double *pressure, |
| const TPointD *tilt, |
| bool final, |
| TTimerTicks ticks ); |
| bool keyEvent( |
| bool press, |
| TInputState::Key key, |
| TTimerTicks ticks, |
| QKeyEvent *event ); |
| void buttonEvent( |
| bool press, |
| TInputState::DeviceId deviceId, |
| TInputState::Button button, |
| TTimerTicks ticks); |
| void hoverEvent(const THoverList &hovers); |
| |
| TRectD calcDrawBounds(); |
| void draw(); |
| |
| static TInputState::TouchId genTouchId(); |
| }; |
| |
| |
| #endif |