7e9eb1
#pragma once
7e9eb1
49945e
#ifndef INPUTMANAGER_INCLUDED
49945e
#define INPUTMANAGER_INCLUDED
49945e
49945e
// TnzTools includes
49945e
#include <tools tooltimer.h=""></tools>
49945e
#include <tools inputstate.h=""></tools>
49945e
#include <tools track.h=""></tools>
49945e
49945e
// TnzCore includes
49945e
#include <tcommon.h></tcommon.h>
49945e
#include <tsmartpointer.h></tsmartpointer.h>
49945e
49945e
// Qt includes
49945e
#include <qobject></qobject>
49945e
#include <qkeyevent></qkeyevent>
49945e
49945e
// std includes
49945e
#include <vector></vector>
49945e
#include <algorithm></algorithm>
49945e
49945e
49945e
#undef DVAPI
49945e
#undef DVVAR
49945e
#ifdef TNZTOOLS_EXPORTS
49945e
#define DVAPI DV_EXPORT_API
49945e
#define DVVAR DV_EXPORT_VAR
49945e
#else
49945e
#define DVAPI DV_IMPORT_API
49945e
#define DVVAR DV_IMPORT_VAR
49945e
#endif
49945e
49945e
49945e
//====================================================
49945e
49945e
//  Forward declarations
49945e
49945e
class TInputModifier;
49945e
class TInputManager;
49945e
49945e
typedef TSmartPointerT<tinputmodifier> TInputModifierP;</tinputmodifier>
49945e
typedef TSmartPointerT<tinputmanager> TInputManagerP;</tinputmanager>
49945e
49945e
//===================================================================
49945e
49945e
49945e
//*****************************************************************************************
49945e
//    TInputSavePoint definition
49945e
//*****************************************************************************************
49945e
49945e
class TInputSavePoint {
49945e
public:
49945e
  class Holder {
49945e
  private:
49945e
    TInputSavePoint *m_savePoint;
49945e
    bool m_lock = false;
49945e
49945e
  public:
49945e
    inline explicit Holder(TInputSavePoint *savePoint = NULL, bool lock = true):
49945e
      m_savePoint(), m_lock()
49945e
      { set(savePoint, lock); }
49945e
    inline Holder(const Holder &other):
49945e
      m_savePoint(), m_lock()
49945e
      { *this = other; }
49945e
    inline ~Holder()
49945e
      { reset(); }
49945e
49945e
    inline Holder& operator= (const Holder &other)
49945e
      { set(other.m_savePoint, other.m_lock); return *this; }
49945e
49945e
    inline void set(TInputSavePoint *savePoint, bool lock) {
49945e
      if (m_savePoint != savePoint) {
49945e
        if (m_savePoint) {
49945e
          if (m_lock) m_savePoint->unlock();
49945e
          m_savePoint->release();
49945e
        }
49945e
        m_savePoint = savePoint;
49945e
        m_lock = lock;
49945e
        if (m_savePoint) {
49945e
          m_savePoint->hold();
49945e
           if (m_lock) savePoint->lock();
49945e
        }
49945e
      } else
49945e
      if (m_lock != lock) {
49945e
        if (lock) m_savePoint->lock();
49945e
             else m_savePoint->unlock();
49945e
        m_lock = lock;
49945e
      }
49945e
    }
49945e
49945e
    inline void reset()
49945e
      { set(NULL, false); }
49945e
    inline void lock()
49945e
      { set(m_savePoint, true); }
49945e
    inline void unlock()
49945e
      { set(m_savePoint, false); }
49945e
49945e
    inline TInputSavePoint* savePoint() const
49945e
      { return m_savePoint; }
49945e
    inline bool locked() const
49945e
      { return m_savePoint && m_lock; }
49945e
    inline bool available() const
49945e
      { return m_savePoint && m_savePoint->available; }
49945e
    inline bool isFree() const
49945e
      { return !m_savePoint || m_savePoint->isFree(); }
49945e
  };
49945e
49945e
  typedef std::vector<holder> List;</holder>
49945e
49945e
private:
49945e
  int m_refCount;
49945e
  int m_lockCount;
49945e
49945e
  inline void hold()
49945e
    { ++m_refCount; }
49945e
  inline void release()
49945e
    { if ((--m_refCount) <= 0) delete this; }
49945e
  inline void lock()
49945e
    { ++m_refCount; }
49945e
  inline void unlock()
49945e
    { if ((--m_refCount) <= 0) delete this; }
49945e
49945e
public:
49945e
  bool available;
49945e
49945e
  inline explicit TInputSavePoint(bool available = false):
49945e
    m_refCount(), m_lockCount(), available(available) { }
49945e
  inline bool isFree() const
49945e
    { return m_lockCount <= 0; }
49945e
49945e
  static inline Holder create(bool available = false)
49945e
    { return Holder(new TInputSavePoint(available)); }
49945e
};
49945e
49945e
49945e
//*****************************************************************************************
49945e
//    TInputModifier definition
49945e
//*****************************************************************************************
49945e
49945e
class TInputModifier: public TSmartObject {
49945e
private:
49945e
  TInputManager *m_manager;
49945e
49945e
public:
49945e
  typedef std::vector<tinputmodifierp> List;</tinputmodifierp>
49945e
49945e
  TInputManager* getManager() const
49945e
    { return m_manager; }
49945e
  void setManager(TInputManager *manager);
49945e
  virtual void onSetManager() { }
49945e
49945e
  virtual void activate() { }
49945e
49945e
  virtual void modifyTrack(
49945e
    const TTrackP &track,
49945e
    const TInputSavePoint::Holder &savePoint,
7e9eb1
    TTrackList &outTracks );
49945e
  virtual void modifyTracks(
49945e
    const TTrackList &tracks,
49945e
    const TInputSavePoint::Holder &savePoint,
49945e
    TTrackList &outTracks );
49945e
49945e
  virtual void modifyHover(
49945e
    const TPointD &hover,
7e9eb1
    THoverList &outHovers );
49945e
  virtual void modifyHovers(
49945e
    const THoverList &hovers,
49945e
    THoverList &outHovers );
49945e
49945e
  virtual void drawHover(const TPointD &hover) { }
49945e
  virtual void drawTrack(const TTrackP &track) { }
49945e
  virtual void draw(const TTrackList &tracks, const THoverList &hovers);
49945e
49945e
  virtual void deactivate() { }
49945e
};
49945e
49945e
49945e
//*****************************************************************************************
49945e
//    TInputHandler definition
49945e
//*****************************************************************************************
49945e
49945e
class TInputHandler {
49945e
public:
49945e
  virtual void inputLeftButtonDown(const TTrackPoint&, const TTrack&) { }
49945e
  virtual void inputLeftButtonDrag(const TTrackPoint&, const TTrack&) { }
49945e
  virtual void inputLeftButtonUp(const TTrackPoint&, const TTrack&) { }
49945e
  virtual void inputMouseMove(const TPointD&, const TInputState&) { }
49945e
  virtual void inputRightButtonDown(const TPointD&, const TInputState&) { }
49945e
  virtual bool inputKeyDown(QKeyEvent *) { return false; }
49945e
49945e
  virtual void inputSetBusy(bool) { }
49945e
  
49945e
  virtual bool inputKeyEvent(
49945e
    bool press,
49945e
    TInputState::Key key,
49945e
    QKeyEvent *event,
49945e
    const TInputManager &manager );
49945e
  
49945e
  virtual void inputButtonEvent(
49945e
    bool press,
49945e
    TInputState::DeviceId device,
49945e
    TInputState::Button button,
49945e
    const TInputManager &manager );
49945e
  
49945e
  virtual void inputHoverEvent(const TInputManager &manager);
49945e
49945e
  /*! paint single track-point at the top painting level */
49945e
  virtual void inputPaintTrackPoint(const TTrackPoint &point, const TTrack &track, bool firstTrack);
49945e
49945e
  /*! create new painting level and return true, or do nothing and return false
49945e
      was:            ------O-------O------
49945e
      become:         ------O-------O------O */
49945e
  virtual bool inputPaintPush() { return false; }
49945e
  /*! paint several track-points at the top painting level
49945e
      was:            ------O-------O------
49945e
      become:         ------O-------O------------ */
49945e
  virtual void inputPaintTracks(const TTrackList &tracks);
49945e
  /*! try to merge N top painting levels and return count of levels that actually merged
49945e
      was:            ------O-------O------O------
49945e
      become (N = 2): ------O--------------------- */
49945e
  virtual int inputPaintApply(int count) { return 0; }
49945e
  /*! reset top level to initial state
49945e
      was:            ------O-------O------O------
49945e
      become:         ------O-------O------O */
49945e
  virtual void inputPaintCancel() { }
49945e
  /*! cancel and pop N painting levels
49945e
      was:            ------O-------O------O------
49945e
      become (N = 2): ------O------- */
49945e
  virtual void inputPaintPop(int count) { }
49945e
};
49945e
49945e
49945e
//*****************************************************************************************
49945e
//    TInputManager definition
49945e
//*****************************************************************************************
49945e
49945e
class TInputManager: public TSmartObject {
49945e
public:
49945e
  class TrackHandler: public TTrackHandler {
49945e
  public:
49945e
    std::vector<int> saves;</int>
49945e
    TrackHandler(TTrack &original, int keysCount = 0):
49945e
      TTrackHandler(original), saves(keysCount, 0)
49945e
      { }
49945e
  };
49945e
49945e
private:
49945e
  TInputHandler *m_handler;
49945e
  TInputModifier::List m_modifiers;
49945e
  std::vector<ttracklist> m_tracks;</ttracklist>
49945e
  std::vector<thoverlist> m_hovers;</thoverlist>
49945e
  TInputSavePoint::List m_savePoints;
49945e
  int m_savePointsSent;
49945e
49945e
  static TInputState::TouchId m_lastTouchId;
49945e
49945e
49945e
public:
49945e
  TInputState state;
49945e
49945e
49945e
public:
49945e
  TInputManager();
49945e
49945e
private:
49945e
  void paintRollbackTo(int saveIndex, TTrackList &subTracks);
49945e
  void paintApply(int count, TTrackList &subTracks);
49945e
  void paintTracks();
49945e
49945e
  int trackCompare(
49945e
    const TTrack &track,
49945e
    TInputState::DeviceId deviceId,
49945e
    TInputState::TouchId touchId );
49945e
  const TTrackP& createTrack(
49945e
    int index,
49945e
    TInputState::DeviceId deviceId,
49945e
    TInputState::TouchId touchId,
49945e
    TTimerTicks ticks,
49945e
    bool hasPressure,
49945e
    bool hasTilt );
49945e
  const TTrackP& getTrack(
49945e
    TInputState::DeviceId deviceId,
49945e
    TInputState::TouchId touchId,
49945e
    TTimerTicks ticks,
49945e
    bool hasPressure,
49945e
    bool hasTilt );
49945e
  void addTrackPoint(
49945e
    const TTrackP& track,
49945e
    const TPointD &position,
49945e
    double pressure,
49945e
    const TPointD &tilt,
49945e
    double time,
49945e
    bool final );
49945e
  void touchTracks(bool finish = false);
49945e
49945e
  void modifierActivate(const TInputModifierP &modifier);
49945e
  void modifierDeactivate(const TInputModifierP &modifier);
49945e
49945e
public:
49945e
  inline const TTrackList& getInputTracks() const
49945e
    { return m_tracks.front(); }
49945e
  inline const TTrackList& getOutputTracks() const
49945e
    { return m_tracks.back(); }
49945e
49945e
  inline const THoverList& getInputHovers() const
49945e
    { return m_hovers.front(); }
49945e
  inline const THoverList& getOutputHovers() const
49945e
    { return m_hovers.back(); }
49945e
49945e
  void processTracks();
49945e
  void finishTracks();
49945e
  void reset();
49945e
49945e
  TInputHandler* getHandler() const
49945e
    { return m_handler; }
49945e
  void setHandler(TInputHandler *handler);
49945e
49945e
  int getModifiersCount() const
49945e
    { return (int)m_modifiers.size(); }
49945e
  const TInputModifierP& getModifier(int index) const
49945e
    { return m_modifiers[index]; }
49945e
  int findModifier(const TInputModifierP &modifier) const;
49945e
  void insertModifier(int index, const TInputModifierP &modifier);
49945e
  void addModifier(const TInputModifierP &modifier)
49945e
    { insertModifier(getModifiersCount(), modifier); }
49945e
  void removeModifier(int index);
49945e
  void removeModifier(const TInputModifierP &modifier)
49945e
    { removeModifier(findModifier(modifier)); }
49945e
  void clearModifiers();
49945e
49945e
  void trackEvent(
49945e
    TInputState::DeviceId deviceId,
49945e
    TInputState::TouchId touchId,
49945e
    const TPointD &position,
49945e
    const double *pressure,
49945e
    const TPointD *tilt,
49945e
    bool final,
49945e
    TTimerTicks ticks );
49945e
  bool keyEvent(
49945e
    bool press,
49945e
    TInputState::Key key,
49945e
    TTimerTicks ticks,
49945e
    QKeyEvent *event );
49945e
  void buttonEvent(
49945e
    bool press,
49945e
    TInputState::DeviceId deviceId,
49945e
    TInputState::Button button,
49945e
    TTimerTicks ticks);
49945e
  void hoverEvent(const THoverList &hovers);
49945e
49945e
  void draw();
49945e
49945e
  static TInputState::TouchId genTouchId();
49945e
};
49945e
49945e
49945e
#endif