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