diff --git a/toonz/sources/include/tools/inputmanager.h b/toonz/sources/include/tools/inputmanager.h new file mode 100644 index 0000000..63d3560 --- /dev/null +++ b/toonz/sources/include/tools/inputmanager.h @@ -0,0 +1,356 @@ +#ifndef INPUTMANAGER_INCLUDED +#define INPUTMANAGER_INCLUDED + +// TnzTools includes +#include +#include +#include + +// TnzCore includes +#include +#include + +// Qt includes +#include +#include + +// std includes +#include +#include + + +#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 + + +//==================================================== + +// Forward declarations + +class TInputModifier; +class TInputManager; + +typedef TSmartPointerT TInputModifierP; +typedef TSmartPointerT TInputManagerP; + +//=================================================================== + + +//***************************************************************************************** +// TInputSavePoint definition +//***************************************************************************************** + +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 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 (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 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 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_refCount; } + inline void unlock() + { if ((--m_refCount) <= 0) delete this; } + +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)); } +}; + + +//***************************************************************************************** +// TInputModifier definition +//***************************************************************************************** + +class TInputModifier: public TSmartObject { +private: + TInputManager *m_manager; + +public: + typedef std::vector List; + + TInputManager* getManager() const + { return m_manager; } + void setManager(TInputManager *manager); + virtual void onSetManager() { } + + virtual void activate() { } + + virtual void modifyTrack( + const TTrackP &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 void drawHover(const TPointD &hover) { } + virtual void drawTrack(const TTrackP &track) { } + virtual void draw(const TTrackList &tracks, const THoverList &hovers); + + virtual void deactivate() { } +}; + + +//***************************************************************************************** +// TInputHandler definition +//***************************************************************************************** + +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); + + /*! paint single track-point at the top painting level */ + virtual void inputPaintTrackPoint(const TTrackPoint &point, const TTrack &track, bool firstTrack); + + /*! create new painting level and return true, or do nothing and return false + was: ------O-------O------ + become: ------O-------O------O */ + virtual bool inputPaintPush() { return false; } + /*! paint several track-points at the top painting level + was: ------O-------O------ + become: ------O-------O------------ */ + virtual void inputPaintTracks(const TTrackList &tracks); + /*! try to merge N top painting levels and return count of levels that actually merged + was: ------O-------O------O------ + become (N = 2): ------O--------------------- */ + virtual int inputPaintApply(int count) { return 0; } + /*! reset top level to initial state + was: ------O-------O------O------ + become: ------O-------O------O */ + virtual void inputPaintCancel() { } + /*! cancel and pop N painting levels + was: ------O-------O------O------ + become (N = 2): ------O------- */ + virtual void inputPaintPop(int count) { } +}; + + +//***************************************************************************************** +// TInputManager definition +//***************************************************************************************** + +class TInputManager: public TSmartObject { +public: + class TrackHandler: public TTrackHandler { + public: + std::vector saves; + TrackHandler(TTrack &original, int keysCount = 0): + TTrackHandler(original), saves(keysCount, 0) + { } + }; + +private: + TInputHandler *m_handler; + TInputModifier::List m_modifiers; + std::vector m_tracks; + std::vector m_hovers; + TInputSavePoint::List m_savePoints; + int m_savePointsSent; + + static TInputState::TouchId m_lastTouchId; + + +public: + TInputState state; + + +public: + TInputManager(); + +private: + 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 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); + + void draw(); + + static TInputState::TouchId genTouchId(); +}; + + +#endif diff --git a/toonz/sources/include/tools/inputstate.h b/toonz/sources/include/tools/inputstate.h index 5fd2109..faab530 100644 --- a/toonz/sources/include/tools/inputstate.h +++ b/toonz/sources/include/tools/inputstate.h @@ -10,12 +10,14 @@ // TnzCore includes #include #include +#include // Qt includes #include // std includes #include +#include #undef DVAPI @@ -29,10 +31,57 @@ #endif +//==================================================== + +// Forward declarations + +typedef std::vector THoverList; + //=================================================================== //***************************************************************************************** +// TKey definition +//***************************************************************************************** + +class TKey { +public: + Qt::Key key; + bool generic; + bool numPad; + + static const TKey shift; + static const TKey control; + static const TKey alt; + static const TKey meta; + + inline explicit TKey(Qt::Key key = Qt::Key(), bool generic = true, bool numPad = false): + key(key), + generic(generic), + numPad(numPad) + { } + + inline bool operator== (const TKey &other) const { + if (generic || other.generic) + return is(other.key); + return key == other.key && numPad == other.numPad; + } + + inline bool is(Qt::Key key) const + { return mapKey(this->key) == mapKey(key); } + + inline bool isModifier() const + { return isModifier(key); } + inline bool isNumber() const + { return isNumber(key); } + + static Qt::Key mapKey(Qt::Key key); + static bool isNumber(Qt::Key key); + static bool isModifier(Qt::Key key); +}; + + +//***************************************************************************************** // TInputState definition //***************************************************************************************** @@ -41,7 +90,7 @@ public: typedef qint64 DeviceId; typedef long long TouchId; - typedef Qt::Key Key; + typedef TKey Key; typedef TKeyHistoryT KeyHistory; typedef KeyHistory::State KeyState; @@ -51,23 +100,25 @@ public: typedef std::map ButtonHistoryMap; private: - TTimerTicks ticks; - KeyHistory::Pointer keyHistory_; - mutable ButtonHistoryMap buttonHistories_; - - void touch(TTimerTicks ticks); + TTimerTicks m_ticks; + KeyHistory::Pointer m_keyHistory; + mutable ButtonHistoryMap m_buttonHistories; public: TInputState(); ~TInputState(); - inline KeyHistory::Pointer keyHistory() const - { return keyHistory(); } + TTimerTicks ticks() const + { return m_ticks; } + void touch(TTimerTicks ticks); + + inline const KeyHistory::Pointer& keyHistory() const + { return m_keyHistory; } inline KeyState::Pointer keyState() const { return keyHistory()->current(); } inline void keyEvent(bool press, Key key, TTimerTicks ticks) - { touch(ticks); keyHistory()->change(press, key, this->ticks); } + { touch(ticks); keyHistory()->change(press, key, m_ticks); } inline void keyPress(Key key, TTimerTicks ticks) { keyEvent(true, key, ticks); } inline void keyRelease(Key key, TTimerTicks ticks) @@ -80,21 +131,30 @@ public: inline double howLongKeyPressed(Key key, TTimerTicks ticks, double timeOffset = 0.0) { return KeyState::Holder::howLongPressed(keyFind(key), ticks, timeOffset); } inline double howLongKeyPressed(Key key) - { return howLongKeyPressed(key, ticks); } + { return howLongKeyPressed(key, m_ticks); } - ButtonHistory::Pointer buttonHistory(DeviceId device) const; + inline KeyState::Holder keyStateHolder(TTimerTicks ticks, double timeOffset = 0.0) const + { return KeyState::Holder(keyState(), ticks, timeOffset); } + inline KeyState::Holder keyStateHolder() const + { return keyStateHolder(m_ticks); } + inline KeyHistory::Holder keyHistoryHolder(TTimerTicks ticks, double timeOffset = 0.0) const + { return KeyHistory::Holder(keyHistory(), ticks, timeOffset); } + inline KeyHistory::Holder keyHistoryHolder() const + { return keyHistoryHolder(m_ticks); } + + ButtonHistory::Pointer buttonHistory(DeviceId deviceId) const; inline const ButtonHistoryMap buttonHistories() const - { return buttonHistories_; } - inline ButtonState::Pointer buttonState(DeviceId device) const - { return buttonHistory(device)->current(); } - - inline void buttonEvent(bool press, DeviceId device, Button button, TTimerTicks ticks) - { touch(ticks); buttonHistory(device)->change(press, button, this->ticks); } - inline void buttonPress(DeviceId device, Button button, TTimerTicks ticks) - { buttonEvent(true, device, button, ticks); } - inline void buttonRelease(DeviceId device, Button button, TTimerTicks ticks) - { buttonEvent(false, device, button, ticks); } + { return m_buttonHistories; } + inline ButtonState::Pointer buttonState(DeviceId deviceId) const + { return buttonHistory(deviceId)->current(); } + + inline void buttonEvent(bool press, DeviceId deviceId, Button button, TTimerTicks ticks) + { touch(ticks); buttonHistory(deviceId)->change(press, button, m_ticks); } + inline void buttonPress(DeviceId deviceId, Button button, TTimerTicks ticks) + { buttonEvent(true, deviceId, button, ticks); } + inline void buttonRelease(DeviceId deviceId, Button button, TTimerTicks ticks) + { buttonEvent(false, deviceId, button, ticks); } inline void buttonEvent(bool press, Button button, TTimerTicks ticks) { buttonEvent(press, 0, button, ticks); } inline void buttonPress(Button button, TTimerTicks ticks) @@ -102,14 +162,14 @@ public: inline void buttonRelease(Button button, TTimerTicks ticks) { buttonEvent(false, button, ticks); } - inline ButtonState::Pointer buttonFind(DeviceId device, Button button) - { return buttonState(device)->find(button); } - inline bool isButtonPressed(DeviceId device, Button button) - { return buttonFind(device, button); } - inline double howLongButtonPressed(DeviceId device, Button button, TTimerTicks ticks, double timeOffset = 0.0) - { return ButtonState::Holder::howLongPressed(buttonFind(device, button), ticks, timeOffset); } - inline double howLongButtonPressed(DeviceId device, Button button) - { return howLongButtonPressed(device, button, ticks); } + inline ButtonState::Pointer buttonFind(DeviceId deviceId, Button button) + { return buttonState(deviceId)->find(button); } + inline bool isButtonPressed(DeviceId deviceId, Button button) + { return buttonFind(deviceId, button); } + inline double howLongButtonPressed(DeviceId deviceId, Button button, TTimerTicks ticks, double timeOffset = 0.0) + { return ButtonState::Holder::howLongPressed(buttonFind(deviceId, button), ticks, timeOffset); } + inline double howLongButtonPressed(DeviceId deviceId, Button button) + { return howLongButtonPressed(deviceId, button, m_ticks); } inline ButtonState::Pointer buttonFindDefault(Button button) { return buttonFind(DeviceId(), button); } @@ -118,36 +178,27 @@ public: inline double howLongButtonPressedDefault(Button button, TTimerTicks ticks, double timeOffset = 0.0) { return howLongButtonPressed(DeviceId(), button, ticks, timeOffset); } inline double howLongButtonPressedDefault(Button button) - { return howLongButtonPressedDefault(button, ticks); } + { return howLongButtonPressedDefault(button, m_ticks); } ButtonState::Pointer buttonFindAny(Button button, DeviceId &outDevice); inline ButtonState::Pointer buttonFindAny(Button button) - { DeviceId device; return buttonFindAny(button, device); } + { DeviceId deviceId; return buttonFindAny(button, deviceId); } inline bool isButtonPressedAny(Button button) { return buttonFindAny(button); } inline double howLongButtonPressedAny(Button button, TTimerTicks ticks, double timeOffset = 0.0) { return ButtonState::Holder::howLongPressed(buttonFindAny(button), ticks, timeOffset); } inline double howLongButtonPressedAny(Button button) - { return howLongButtonPressedAny(button, ticks); } - - inline KeyState::Holder keyStateHolder(TTimerTicks ticks, double timeOffset = 0.0) const - { return KeyState::Holder(keyState(), ticks, timeOffset); } - inline KeyState::Holder keyStateHolder() - { return keyStateHolder(ticks); } - inline KeyHistory::Holder keyHistoryHolder(TTimerTicks ticks, double timeOffset = 0.0) - { return KeyHistory::Holder(keyHistory(), ticks, timeOffset); } - inline KeyHistory::Holder keyHistoryHolder() - { return keyHistoryHolder(ticks); } - - inline ButtonState::Holder buttonStateHolder(DeviceId device, TTimerTicks ticks, double timeOffset = 0.0) - { return ButtonState::Holder(buttonState(device), ticks, timeOffset); } - inline ButtonState::Holder buttonStateHolder(DeviceId device) - { return buttonStateHolder(device, ticks); } - inline ButtonHistory::Holder buttonHistoryHolder(DeviceId device, long ticks, double timeOffset = 0.0) - { return ButtonHistory::Holder(buttonHistory(device), ticks, timeOffset); } - inline ButtonHistory::Holder buttonHistoryHolder(DeviceId device) - { return buttonHistoryHolder(device, ticks); } + { return howLongButtonPressedAny(button, m_ticks); } + + inline ButtonState::Holder buttonStateHolder(DeviceId deviceId, TTimerTicks ticks, double timeOffset = 0.0) + { return ButtonState::Holder(buttonState(deviceId), ticks, timeOffset); } + inline ButtonState::Holder buttonStateHolder(DeviceId deviceId) + { return buttonStateHolder(deviceId, m_ticks); } + inline ButtonHistory::Holder buttonHistoryHolder(DeviceId deviceId, long ticks, double timeOffset = 0.0) + { return ButtonHistory::Holder(buttonHistory(deviceId), ticks, timeOffset); } + inline ButtonHistory::Holder buttonHistoryHolder(DeviceId deviceId) + { return buttonHistoryHolder(deviceId, m_ticks); } }; diff --git a/toonz/sources/include/tools/keyhistory.h b/toonz/sources/include/tools/keyhistory.h index 79537fb..6bf4d27 100644 --- a/toonz/sources/include/tools/keyhistory.h +++ b/toonz/sources/include/tools/keyhistory.h @@ -30,26 +30,12 @@ //=================================================================== -// Base Classee Declarations - - -class DVAPI TKeyStateBase : public TSmartObject { - DECLARE_CLASS_CODE -}; - -class DVAPI TKeyHistoryBase : public TSmartObject { - DECLARE_CLASS_CODE -}; - -//=================================================================== - - //***************************************************************************************** // TKeyState definition //***************************************************************************************** template -class TKeyStateT : public TKeyStateBase { +class TKeyStateT : public TSmartObject { public: typedef T Type; typedef TSmartPointerT Pointer; @@ -59,7 +45,7 @@ public: TTimerTicks ticks; double timeOffset; - explicit Holder(const Pointer &state, TTimerTicks ticks = 0, double timeOffset = 0.0): + explicit Holder(const Pointer &state = Pointer(), TTimerTicks ticks = 0, double timeOffset = 0.0): state(state), ticks(ticks), timeOffset(timeOffset) { } Pointer find(const Type &value) const @@ -145,7 +131,7 @@ const typename TKeyStateT::Pointer TKeyStateT::empty = new TKeyStateT() //***************************************************************************************** template -class TKeyHistoryT : public TKeyHistoryBase { +class TKeyHistoryT : public TSmartObject { public: typedef T Type; typedef TSmartPointerT Pointer; @@ -155,19 +141,19 @@ public: class Holder { private: - Pointer history_; - TTimerTicks ticks_; - double timeOffset_; - TTimerTicks heldTicks; + Pointer m_history; + TTimerTicks m_ticks; + double m_timeOffset; + TTimerTicks m_heldTicks; public: Holder(): - ticks_(), timeOffset_(), heldTicks() { } + m_ticks(), m_timeOffset(), m_heldTicks() { } Holder(const Pointer &history, TTimerTicks ticks, double timeOffset = 0.0): - ticks_(), timeOffset_(), heldTicks() + m_ticks(), m_timeOffset(), m_heldTicks() { set(history, ticks, timeOffset); } Holder(const Holder &other): - ticks_(), timeOffset_(), heldTicks() + m_ticks(), m_timeOffset(), m_heldTicks() { set(other); } ~Holder() { reset(); } @@ -176,11 +162,11 @@ public: { set(other); return *this; } void set(const Pointer &history, TTimerTicks ticks, double timeOffset = 0.0) { - if (history_) history_->releaseTicks(heldTicks); - history_ = history; - ticks_ = ticks; - timeOffset_ = timeOffset; - heldTicks = (history_ ? history_->holdTicks(ticks_) : 0); + if (m_history) m_history->releaseTicks(m_heldTicks); + m_history = history; + m_ticks = ticks; + m_timeOffset = timeOffset; + m_heldTicks = (m_history ? m_history->holdTicks(m_ticks) : 0); } void set(const Holder &other) { set(other.history(), other.ticks(), other.timeOffset()); } @@ -188,11 +174,11 @@ public: { set(Pointer(), 0); } Pointer history() const - { return history_; } + { return m_history; } TTimerTicks ticks() const - { return ticks_; } + { return m_ticks; } double timeOffset() const - { return timeOffset_; } + { return m_timeOffset; } Holder offset(double timeOffset) const { return fabs(timeOffset) < TToolTimer::epsilon ? *this @@ -200,49 +186,49 @@ public: } StateHolder get(double time) const { - TTimerTicks dticks = (TTimerTicks)ceil(TToolTimer::frequency*(time + timeOffset)); - StatePointer state = history_->get(ticks + dticks); - return StateHolder(state, ticks, timeOffset + time); + TTimerTicks dticks = (TTimerTicks)ceil(TToolTimer::frequency*(time + m_timeOffset)); + StatePointer state = m_history->get(m_ticks + dticks); + return StateHolder(state, m_ticks, m_timeOffset + time); } }; private: - std::map states; - std::multiset locks; + std::map m_states; + std::multiset m_locks; void autoRemove() { - TTimerTicks ticks = locks.empty() - ? states.rbegin()->first - : *locks.begin(); + TTimerTicks ticks = m_locks.empty() + ? m_states.rbegin()->first + : *m_locks.begin(); while(true) { - typename std::map::iterator i = states.begin(); + typename std::map::iterator i = m_states.begin(); ++i; - if (i == states.end() || (!i->second->isEmpty() && i->first >= ticks)) break; - states.erase(i); + if (i == m_states.end() || (!i->second->isEmpty() && i->first >= ticks)) break; + m_states.erase(i); } } TTimerTicks holdTicks(TTimerTicks ticks) - { return *locks.insert(std::max(ticks, states.begin()->first)); } + { return *m_locks.insert(std::max(ticks, m_states.begin()->first)); } void releaseTicks(TTimerTicks heldTicks) - { locks.erase(heldTicks); autoRemove(); } + { m_locks.erase(heldTicks); autoRemove(); } StatePointer get(TTimerTicks ticks) { - typename std::map::iterator i = states.upper_bound(ticks); - return i == states.begin() ? i->second : (--i)->second; + typename std::map::iterator i = m_states.upper_bound(ticks); + return i == m_states.begin() ? i->second : (--i)->second; } public: TKeyHistoryT() - { states[TTimerTicks()] = StatePointer(new State()); } + { m_states[TTimerTicks()] = StatePointer(new State()); } StatePointer current() const - { return states.rbegin()->second; } + { return m_states.rbegin()->second; } StatePointer change(bool press, Type value, TTimerTicks ticks) { StatePointer state = current()->change(press, value, ticks); - if (state != current() && state->ticks > states.rbegin()->first) - states[state->ticks] = state; + if (state != current() && state->ticks > m_states.rbegin()->first) + m_states[state->ticks] = state; autoRemove(); return current(); } diff --git a/toonz/sources/include/tools/tool.h b/toonz/sources/include/tools/tool.h index ab30f5a..4aed87a 100644 --- a/toonz/sources/include/tools/tool.h +++ b/toonz/sources/include/tools/tool.h @@ -391,7 +391,7 @@ return true if the method execution can have changed the current tool virtual void rightButtonDown(const TPointD &, const TMouseEvent &) {} virtual bool keyDown(QKeyEvent *) { return false; } - virtual void onInputText(std::wstring, std::wstring, int, int){}; + virtual void onInputText(const std::wstring&, const std::wstring&, int, int){}; virtual void onSetViewer() {} diff --git a/toonz/sources/include/tools/tooltimer.h b/toonz/sources/include/tools/tooltimer.h index ec73471..60f6df5 100644 --- a/toonz/sources/include/tools/tooltimer.h +++ b/toonz/sources/include/tools/tooltimer.h @@ -30,8 +30,8 @@ typedef qint64 TTimerTicks; class DVAPI TToolTimer { private: - static TToolTimer instance; - QElapsedTimer timer; + static TToolTimer m_instance; + QElapsedTimer m_timer; TToolTimer(); public: @@ -40,7 +40,7 @@ public: static const double epsilon; static inline TTimerTicks ticks() - { return instance.timer.nsecsElapsed(); } + { return m_instance.m_timer.nsecsElapsed(); } }; diff --git a/toonz/sources/include/tools/track.h b/toonz/sources/include/tools/track.h index 84fa7a4..2883a19 100644 --- a/toonz/sources/include/tools/track.h +++ b/toonz/sources/include/tools/track.h @@ -34,11 +34,15 @@ // Forward Declarations class TTrack; +class TTrackPoint; class TTrackHandler; class TTrackModifier; + typedef TSmartPointerT TTrackP; typedef TSmartPointerT TTrackHandlerP; typedef TSmartPointerT TTrackModifierP; + +typedef std::vector TTrackPointList; typedef std::vector TTrackList; //=================================================================== @@ -48,7 +52,7 @@ typedef std::vector TTrackList; // TTrackPoint definition //***************************************************************************************** -struct TTrackPoint { +class TTrackPoint { public: TPointD position; double pressure; @@ -85,7 +89,6 @@ public: //***************************************************************************************** class DVAPI TTrackHandler : public TSmartObject { - DECLARE_CLASS_CODE public: TTrack &original; std::vector tracks; @@ -99,7 +102,6 @@ public: //***************************************************************************************** class DVAPI TTrackModifier : public TSmartObject { - DECLARE_CLASS_CODE public: TTrackHandler &handler; TTrack &original; @@ -116,15 +118,13 @@ public: //***************************************************************************************** class DVAPI TTrack : public TSmartObject { - DECLARE_CLASS_CODE - public: typedef long long Id; static const double epsilon; private: - static Id lastId; + static Id m_lastId; public: const Id id; @@ -132,15 +132,17 @@ public: const TInputState::TouchId touchId; const TInputState::KeyHistory::Holder keyHistory; const TInputState::ButtonHistory::Holder buttonHistory; + const bool hasPressure; + const bool hasTilt; const TTrackModifierP modifier; TTrackHandlerP handler; - int wayPointsRemoved; - int wayPointsAdded; + int pointsRemoved; + int pointsAdded; private: - std::vector points_; - const TTrackPoint none; + TTrackPointList m_points; + const TTrackPoint m_none; public: @@ -148,7 +150,9 @@ public: TInputState::DeviceId deviceId = TInputState::DeviceId(), TInputState::TouchId touchId = TInputState::TouchId(), const TInputState::KeyHistory::Holder &keyHistory = TInputState::KeyHistory::Holder(), - const TInputState::ButtonHistory::Holder &buttonHistory = TInputState::ButtonHistory::Holder() + const TInputState::ButtonHistory::Holder &buttonHistory = TInputState::ButtonHistory::Holder(), + bool hasPressure = false, + bool hasTilt = false ); explicit TTrack(const TTrackModifierP &modifier); @@ -160,7 +164,7 @@ public: inline TTimerTicks ticks() const { return keyHistory.ticks(); } inline bool changed() const - { return wayPointsAdded != 0 || wayPointsRemoved != 0; } + { return pointsAdded != 0 || pointsRemoved != 0; } const TTrack* root() const; TTrack* root(); @@ -187,22 +191,22 @@ public: { return point(ceilIndex(index)); } inline const TTrackPoint& point(int index) const - { return empty() ? none : points_[clampIndex(index)]; } + { return empty() ? m_none : m_points[clampIndex(index)]; } inline int size() const - { return (int)points_.size(); } + { return (int)m_points.size(); } inline bool empty() const - { return points_.empty(); } + { return m_points.empty(); } inline const TTrackPoint& front() const { return point(0); } inline const TTrackPoint& back() const { return point(size() - 1); } inline bool finished() const - { return !points_.empty() && back().final; } + { return !m_points.empty() && back().final; } inline const TTrackPoint& operator[] (int index) const { return point(index); } - inline const std::vector& points() const - { return points_; } + inline const TTrackPointList& points() const + { return m_points; } void push_back(const TTrackPoint &point); void pop_back(int count = 1); @@ -210,22 +214,32 @@ public: inline void truncate(int count) { pop_back(size() - count); } + inline const TTrackPoint& current() const + { return point(size() - pointsAdded); } + inline TInputState::KeyState::Holder getKeyState(double time) const + { return keyHistory.get(time); } + inline TInputState::KeyState::Holder getCurrentKeyState() const + { return getKeyState(current().time); } + inline TInputState::ButtonState::Holder getButtonState(double time) const + { return buttonHistory.get(time); } + inline TInputState::ButtonState::Holder getCurrentButtonState() const + { return getButtonState(current().time); } private: template double binarySearch(double value) const { // points_[a].value <= value < points_[b].value - if (points_.empty()) return 0.0; + if (m_points.empty()) return 0.0; int a = 0; - double aa = points_[a].*Field; + double aa = m_points[a].*Field; if (value - aa <= 0.5*epsilon) return (double)a; - int b = (int)points_.size() - 1; - double bb = points_[b].*Field; + int b = (int)m_points.size() - 1; + double bb = m_points[b].*Field; if (bb - value <= 0.5*epsilon) return (double)b; while(true) { int c = (a + b)/2; if (a == c) break; - double cc = points_[c].*Field; + double cc = m_points[c].*Field; if (cc - value > 0.5*epsilon) { b = c; bb = cc; } else { a = c; aa = cc; } } @@ -261,6 +275,8 @@ public: TTrackPoint calcPoint(double index) const; TPointD calcTangent(double index, double distance = 0.1) const; + double rootIndexByIndex(double index) const; + TTrackPoint calcRootPoint(double index) const; inline TTrackPoint interpolateLinear(double index) const { double frac; diff --git a/toonz/sources/tnztools/CMakeLists.txt b/toonz/sources/tnztools/CMakeLists.txt index cfaa257..113061e 100644 --- a/toonz/sources/tnztools/CMakeLists.txt +++ b/toonz/sources/tnztools/CMakeLists.txt @@ -47,6 +47,7 @@ set(HEADERS ../include/tools/keyhistory.h ../include/tools/inputstate.h ../include/tools/track.h + ../include/tools/inputmanager.h ) set(SOURCES @@ -111,9 +112,9 @@ set(SOURCES toonzrasterbrushtool.cpp toonzvectorbrushtool.cpp tooltimer.cpp - keyhistory.cpp inputstate.cpp track.cpp + inputmanager.cpp ) set(RESOURCES tnztools.qrc) diff --git a/toonz/sources/tnztools/inputmanager.cpp b/toonz/sources/tnztools/inputmanager.cpp new file mode 100644 index 0000000..13069a7 --- /dev/null +++ b/toonz/sources/tnztools/inputmanager.cpp @@ -0,0 +1,592 @@ + + +#include + + +//***************************************************************************************** +// static members +//***************************************************************************************** + +TInputState::TouchId TInputManager::m_lastTouchId = 0; + + +//***************************************************************************************** +// TInputModifier implementation +//***************************************************************************************** + + +void +TInputModifier::setManager(TInputManager *manager) { + if (m_manager != manager) + { m_manager = manager; onSetManager(); } +} + + +void +TInputModifier::modifyTracks( + const TTrackList &tracks, + const TInputSavePoint::Holder &savePoint, + TTrackList &outTracks ) +{ + for(TTrackList::const_iterator i = tracks.begin(); i != tracks.end(); ++i) + modifyTrack(*i, savePoint, outTracks); +} + + +void +TInputModifier::modifyHovers( + const THoverList &hovers, + THoverList &outHovers ) +{ + for(THoverList::const_iterator i = hovers.begin(); i != hovers.end(); ++i) + modifyHover(*i, outHovers); +} + + +void +TInputModifier::draw(const TTrackList &tracks, const THoverList &hovers) { + for(TTrackList::const_iterator i = tracks.begin(); i != tracks.end(); ++i) + drawTrack(*i); + for(THoverList::const_iterator i = hovers.begin(); i != hovers.end(); ++i) + drawHover(*i); +} + + +//***************************************************************************************** +// TInputHandler implementation +//***************************************************************************************** + + +bool +TInputHandler::inputKeyEvent( + bool press, + TInputState::Key key, + QKeyEvent *event, + const TInputManager &manager ) +{ + return press && inputKeyDown(event); +} + + +void +TInputHandler::inputButtonEvent( + bool press, + TInputState::DeviceId device, + TInputState::Button button, + const TInputManager &manager ) +{ + if (press && button == Qt::RightButton && !manager.getOutputHovers().empty()) + inputRightButtonDown(manager.getOutputHovers().front(), manager.state); +} + + +void +TInputHandler::inputHoverEvent(const TInputManager &manager) { + if (!manager.getOutputHovers().empty()) + inputMouseMove(manager.getOutputHovers().front(), manager.state); +} + + +void +TInputHandler::inputPaintTrackPoint(const TTrackPoint &point, const TTrack &track, bool firstTrack) { + if (firstTrack) { + if (track.pointsAdded == track.size()) + inputLeftButtonDown(point, track); + else + if (point.final) + inputLeftButtonUp(point, track); + else + inputLeftButtonDrag(point, track); + } +} + + +void +TInputHandler::inputPaintTracks(const TTrackList &tracks) { + // paint track points in chronological order + while(true) { + TTrackP track; + TTimerTicks minTicks = 0; + double minTimeOffset = 0.0; + for(TTrackList::const_iterator i = tracks.begin(); i != tracks.end(); ++i) { + const TTrack &t = **i; + if (t.pointsAdded > 0) { + TTimerTicks ticks = t.ticks(); + double timeOffset = t.timeOffset() + t.current().time; + if (!track || (ticks - minTicks)*TToolTimer::frequency + timeOffset - minTimeOffset < 0.0) { + track = *i; + minTicks = ticks; + minTimeOffset = timeOffset; + } + } + } + if (!track) break; + inputPaintTrackPoint(track->current(), *track, track == tracks.front()); + --track->pointsAdded; + } +} + + +//***************************************************************************************** +// TInputManager implementation +//***************************************************************************************** + + +TInputManager::TInputManager(): + m_handler(), + m_tracks(1), + m_hovers(1), + m_savePointsSent() +{ } + + +void +TInputManager::paintRollbackTo(int saveIndex, TTrackList &subTracks) { + if (saveIndex >= (int)m_savePoints.size()) + return; + + int level = saveIndex + 1; + if (level <= m_savePointsSent) { + if (m_handler) { + if (level < m_savePointsSent) + m_handler->inputPaintPop(m_savePointsSent - level); + m_handler->inputPaintCancel(); + } + m_savePointsSent = level; + } + + for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) { + TTrack &track = **i; + if (TrackHandler *handler = dynamic_cast(track.handler.getPointer())) { + handler->saves.erase(handler->saves.begin() + level, handler->saves.end()); + int cnt = handler->saves[saveIndex]; + track.pointsRemoved = 0; + track.pointsAdded = track.size() - cnt; + } + } + for(int i = level; i < (int)m_savePoints.size(); ++i) + m_savePoints[i].savePoint()->available = false; + m_savePoints.erase(m_savePoints.begin() + level, m_savePoints.end()); +} + + +void +TInputManager::paintApply(int count, TTrackList &subTracks) { + if (count <= 0) + return; + + int level = (int)m_savePoints.size() - count; + bool resend = true; + + if (level < m_savePointsSent) { + // apply + int applied = m_handler ? m_handler->inputPaintApply(m_savePointsSent - level) : false; + applied = std::max(0, std::min(m_savePointsSent - level, applied)); + m_savePointsSent -= applied; + if (m_savePointsSent == level) resend = false; + } + + if (level < m_savePointsSent) { + // rollback + if (m_handler) m_handler->inputPaintPop(m_savePointsSent - level); + m_savePointsSent = level; + } + + // remove keypoints + for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) { + TTrack &track = **i; + if (TrackHandler *handler = dynamic_cast(track.handler.getPointer())) { + if (resend) { + track.pointsRemoved = 0; + track.pointsAdded = track.size() - handler->saves[m_savePointsSent]; + } + handler->saves.erase(handler->saves.begin() + level, handler->saves.end()); + } + } + for(int i = level; i < (int)m_savePoints.size(); ++i) + m_savePoints[i].savePoint()->available = false; + m_savePoints.erase(m_savePoints.begin() + level, m_savePoints.end()); +} + + +void +TInputManager::paintTracks() { + bool allFinished = true; + for(TTrackList::const_iterator i = m_tracks.front().begin(); i != m_tracks.front().end(); ++i) + if (!(*i)->finished()) + { allFinished = false; break; } + + while(true) { + // run modifiers + TInputSavePoint::Holder newSavePoint = TInputSavePoint::create(true); + for(int i = 0; i < (int)m_modifiers.size(); ++i) { + m_tracks[i+1].clear(); + m_modifiers[i]->modifyTracks(m_tracks[i], newSavePoint, m_tracks[i+1]); + } + TTrackList &subTracks = m_tracks.back(); + + // create handlers + for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) + if (!(*i)->handler) + (*i)->handler = new TrackHandler(**i, (int)m_savePoints.size()); + + if (!m_savePoints.empty()) { + // rollback + int rollbackIndex = (int)m_savePoints.size(); + for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) { + TTrack &track = **i; + if (track.pointsRemoved > 0) { + int count = track.size() - track.pointsAdded; + if (TrackHandler *handler = dynamic_cast(track.handler.getPointer())) + while(rollbackIndex > 0 && (rollbackIndex >= (int)m_savePoints.size() || handler->saves[rollbackIndex] > count)) + --rollbackIndex; + } + } + paintRollbackTo(rollbackIndex, subTracks); + + // apply + int applyCount = 0; + while(applyCount < (int)m_savePoints.size() && m_savePoints[(int)m_savePoints.size() - applyCount - 1].isFree()) + ++applyCount; + paintApply(applyCount, subTracks); + } + + // send to handler + if (m_savePointsSent == (int)m_savePoints.size() && !subTracks.empty() && m_handler) + m_handler->inputPaintTracks(subTracks); + for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) { + TTrack &track = **i; + track.pointsRemoved = 0; + track.pointsAdded = 0; + } + + // is paint finished? + if (newSavePoint.isFree()) { + newSavePoint.savePoint()->available = false; + if (allFinished) { + paintApply((int)m_savePoints.size(), subTracks); + for(std::vector::iterator i = m_tracks.begin(); i != m_tracks.end(); ++i) + i->clear(); + if (m_handler) m_handler->inputSetBusy(false); + } + break; + } + + // create save point + if (m_handler && m_handler->inputPaintPush()) ++m_savePointsSent; + m_savePoints.push_back(newSavePoint); + for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) + if (TrackHandler *handler = dynamic_cast((*i)->handler.getPointer())) + handler->saves.push_back((*i)->size()); + } +} + + +int +TInputManager::trackCompare( + const TTrack &track, + TInputState::DeviceId deviceId, + TInputState::TouchId touchId ) +{ + if (track.deviceId < deviceId) return -1; + if (deviceId < track.deviceId) return 1; + if (track.touchId < touchId) return -1; + if (touchId < track.touchId) return 1; + return 0; +} + + +const TTrackP& +TInputManager::createTrack( + int index, + TInputState::DeviceId deviceId, + TInputState::TouchId touchId, + TTimerTicks ticks, + bool hasPressure, + bool hasTilt ) +{ + TTrackP track = new TTrack( + deviceId, + touchId, + state.keyHistoryHolder(ticks), + state.buttonHistoryHolder(deviceId, ticks), + hasPressure, + hasTilt ); + return *m_tracks.front().insert(m_tracks[0].begin() + index, track); +} + + +const TTrackP& +TInputManager::getTrack( + TInputState::DeviceId deviceId, + TInputState::TouchId touchId, + TTimerTicks ticks, + bool hasPressure, + bool hasTilt ) +{ + TTrackList &origTracks = m_tracks.front(); + if (origTracks.empty()) + return createTrack(0, deviceId, touchId, ticks, hasPressure, hasTilt); + int cmp; + + int a = 0; + cmp = trackCompare(*origTracks[a], deviceId, touchId); + if (cmp == 0) return origTracks[a]; + if (cmp < 0) return createTrack(a, deviceId, touchId, ticks, hasPressure, hasTilt); + + int b = (int)origTracks.size() - 1; + cmp = trackCompare(*origTracks[b], deviceId, touchId); + if (cmp == 0) return origTracks[b]; + if (cmp > 0) return createTrack(b+1, deviceId, touchId, ticks, hasPressure, hasTilt); + + // binary search: tracks[a] < tracks[c] < tracks[b] + while(true) { + int c = (a + b)/2; + if (a == c) break; + cmp = trackCompare(*origTracks[c], deviceId, touchId); + if (cmp < 0) b = c; else + if (cmp > 0) a = c; else + return origTracks[c]; + } + return createTrack(b, deviceId, touchId, ticks, hasPressure, hasTilt); +} + + +void +TInputManager::addTrackPoint( + const TTrackP& track, + const TPointD &position, + double pressure, + const TPointD &tilt, + double time, + bool final ) +{ + track->push_back( TTrackPoint( + position, + pressure, + tilt, + (double)track->size(), + time, + 0.0, // length will calculated inside of TTrack::push_back + final )); + ++track->pointsAdded; +} + + +void +TInputManager::touchTracks(bool finish) { + for(TTrackList::const_iterator i = m_tracks.front().begin(); i != m_tracks.front().end(); ++i) { + if (!(*i)->finished() && (*i)->size() > 0) { + const TTrackPoint &p = (*i)->back(); + addTrackPoint(*i, p.position, p.pressure, p.tilt, p.time, finish); + } + } +} + + +void +TInputManager::modifierActivate(const TInputModifierP &modifier) { + modifier->setManager(this); + modifier->activate(); +} + + +void +TInputManager::modifierDeactivate(const TInputModifierP &modifier) { + modifier->deactivate(); + modifier->setManager(NULL); +} + + +void +TInputManager::processTracks() + { paintTracks(); } + + +void +TInputManager::finishTracks() { + touchTracks(true); + processTracks(); +} + + +void +TInputManager::reset() { + // forget about handler paint stack + // assuime it was already reset by outside + m_savePointsSent = 0; + + // reset save point + for(int i = 0; i < (int)m_savePoints.size(); ++i) + m_savePoints[i].savePoint()->available = false; + m_savePoints.clear(); + + // reset tracks + for(int i = 0; i < (int)m_tracks.size(); ++i) + m_tracks[i].clear(); +} + + +void +TInputManager::setHandler(TInputHandler *handler) { + if (m_handler == handler) + return; + reset(); + m_handler = handler; +} + + +int +TInputManager::findModifier(const TInputModifierP &modifier) const { + for(int i = 0; i < getModifiersCount(); ++i) + if (getModifier(i) == modifier) + return i; + return -1; +} + + +void +TInputManager::insertModifier(int index, const TInputModifierP &modifier) { + if (findModifier(modifier) >= 0) return; + finishTracks(); + m_modifiers.insert(m_modifiers.begin() + index, modifier); + m_tracks.insert(m_tracks.begin() + index + 1, TTrackList()); + m_hovers.insert(m_hovers.begin() + index + 1, THoverList()); + modifierActivate(modifier); +} + + +void +TInputManager::removeModifier(int index) { + if (index >= 0 && index < getModifiersCount()) { + finishTracks(); + modifierDeactivate(m_modifiers[index]); + m_modifiers.erase(m_modifiers.begin() + index); + m_tracks.erase(m_tracks.begin() + index + 1); + m_hovers.erase(m_hovers.begin() + index + 1); + } +} + + +void +TInputManager::clearModifiers() { + while(getModifiersCount() > 0) + removeModifier(getModifiersCount() - 1); +} + + +void +TInputManager::trackEvent( + TInputState::DeviceId deviceId, + TInputState::TouchId touchId, + const TPointD &position, + const double *pressure, + const TPointD *tilt, + bool final, + TTimerTicks ticks ) +{ + if (getInputTracks().empty() && m_handler) + m_handler->inputSetBusy(true); + + TTrackP track = getTrack(deviceId, touchId, ticks, (bool)pressure, (bool)tilt); + if (!track->finished()) { + double time = (double)(ticks - track->ticks())*TToolTimer::step - track->timeOffset(); + addTrackPoint( + track, + position, + pressure ? *pressure : 0.5, + tilt ? *tilt : TPointD(), + time, + final ); + } +} + + +bool +TInputManager::keyEvent( + bool press, + TInputState::Key key, + TTimerTicks ticks, + QKeyEvent *event ) +{ + state.keyEvent(press, key, ticks); + processTracks(); + bool result = m_handler && m_handler->inputKeyEvent(press, key, event, *this); + touchTracks(); + processTracks(); + //hoverEvent(getInputHovers()); + return result; +} + + +void +TInputManager::buttonEvent( + bool press, + TInputState::DeviceId deviceId, + TInputState::Button button, + TTimerTicks ticks ) +{ + state.buttonEvent(press, deviceId, button, ticks); + processTracks(); + if (m_handler) m_handler->inputButtonEvent(press, deviceId, button, *this); + touchTracks(); + processTracks(); +} + + +void +TInputManager::hoverEvent(const THoverList &hovers) { + if (&m_hovers[0] != &hovers) + m_hovers[0] = hovers; + for(int i = 0; i < (int)m_modifiers.size(); ++i) { + m_hovers[i+1].clear(); + m_modifiers[i]->modifyHovers(m_hovers[i], m_hovers[i+1]); + } + if (m_handler) m_handler->inputHoverEvent(*this); +} + + +void +TInputManager::draw() { + // TODO: paint + + // paint not sent sub-tracks + if (m_savePointsSent < (int)m_savePoints.size()) { + //context.Save(); + //penPreview.apply(context); + for(TTrackList::const_iterator i = getOutputTracks().begin(); i != getOutputTracks().end(); ++i) { + TTrack &track = **i; + if (TrackHandler *handler = dynamic_cast(track.handler.getPointer())) { + int start = handler->saves[m_savePointsSent] - 1; + if (start < 0) start = 0; + if (start < track.size()) { + //Drawing.Color color = penPreview.color; + int level = m_savePointsSent; + + //color.apply(context); + //context.MoveTo(track[start].position.x, track.points[start].position.y); + for(int i = start + 1; i < track.size(); ++i) { + while(level < (int)handler->saves.size() && handler->saves[level] <= i) { + //context.Stroke(); + //context.MoveTo(track[i-1].position.x, track[i-1].position.y); + //color.a *= levelAlpha; + //color.apply(context); + ++level; + } + //context.LineTo(track[i].position.x, track[i].position.y); + } + } + } + } + //context.Stroke(); + //context.Restore(); + } + + // paint modifiers + for(int i = 0; i < (int)m_modifiers.size(); ++i) + m_modifiers[i]->draw(m_tracks[i], m_hovers[i]); +} + +TInputState::TouchId +TInputManager::genTouchId() + { return ++m_lastTouchId; } diff --git a/toonz/sources/tnztools/inputstate.cpp b/toonz/sources/tnztools/inputstate.cpp index db414e0..5251d1e 100644 --- a/toonz/sources/tnztools/inputstate.cpp +++ b/toonz/sources/tnztools/inputstate.cpp @@ -4,12 +4,50 @@ //***************************************************************************************** -// TInputState static members +// TKey static members +//***************************************************************************************** + +const TKey TKey::shift ( Qt::Key_Shift , true ); +const TKey TKey::control ( Qt::Key_Control , true ); +const TKey TKey::alt ( Qt::Key_Alt , true ); +const TKey TKey::meta ( Qt::Key_Meta , true ); + + +Qt::Key +TKey::mapKey(Qt::Key key) { + switch(key) { + case Qt::Key_AltGr: return Qt::Key_Alt; + default: break; + } + return key; +} + + +bool +TKey::isModifier(Qt::Key key) { + key = mapKey(key); + return key == Qt::Key_Shift + || key == Qt::Key_Control + || key == Qt::Key_Alt + || key == Qt::Key_AltGr + || key == Qt::Key_Meta; +} + + +bool +TKey::isNumber(Qt::Key key) { + key = mapKey(key); + return key >= Qt::Key_0 && key <= Qt::Key_9; +} + + +//***************************************************************************************** +// TInputState implementation //***************************************************************************************** TInputState::TInputState(): - ticks(), - keyHistory_(new KeyHistory()) + m_ticks(), + m_keyHistory(new KeyHistory()) { } TInputState::~TInputState() @@ -17,22 +55,22 @@ TInputState::~TInputState() void TInputState::touch(TTimerTicks ticks) { - if (this->ticks < ticks) - this->ticks = ticks; + if (m_ticks < ticks) + m_ticks = ticks; else - ++this->ticks; + ++m_ticks; } TInputState::ButtonHistory::Pointer TInputState::buttonHistory(DeviceId device) const { - ButtonHistory::Pointer &history = buttonHistories_[device]; + ButtonHistory::Pointer &history = m_buttonHistories[device]; if (!history) history = new ButtonHistory(); return history; } TInputState::ButtonState::Pointer TInputState::buttonFindAny(Button button, DeviceId &outDevice) { - for(ButtonHistoryMap::const_iterator i = buttonHistories_.begin(); i != buttonHistories_.end(); ++i) { + for(ButtonHistoryMap::const_iterator i = m_buttonHistories.begin(); i != m_buttonHistories.end(); ++i) { ButtonState::Pointer state = i->second->current()->find(button); if (state) { outDevice = i->first; diff --git a/toonz/sources/tnztools/keyhistory.cpp b/toonz/sources/tnztools/keyhistory.cpp deleted file mode 100644 index 121ac56..0000000 --- a/toonz/sources/tnztools/keyhistory.cpp +++ /dev/null @@ -1,12 +0,0 @@ - - -#include - - -//***************************************************************************************** -// TKeyStateBase static members -//***************************************************************************************** - -DEFINE_CLASS_CODE(TKeyStateBase, 125) -DEFINE_CLASS_CODE(TKeyHistoryBase, 126) - diff --git a/toonz/sources/tnztools/tooltimer.cpp b/toonz/sources/tnztools/tooltimer.cpp index 45bd778..5dfdc15 100644 --- a/toonz/sources/tnztools/tooltimer.cpp +++ b/toonz/sources/tnztools/tooltimer.cpp @@ -10,7 +10,7 @@ const TTimerTicks TToolTimer::frequency = 1000000000; const double TToolTimer::step = 1e-9; const double TToolTimer::epsilon = 1e-10; -TToolTimer TToolTimer::instance; +TToolTimer TToolTimer::m_instance; //***************************************************************************************** @@ -18,4 +18,4 @@ TToolTimer TToolTimer::instance; //***************************************************************************************** TToolTimer::TToolTimer() - { timer.start(); } + { m_timer.start(); } diff --git a/toonz/sources/tnztools/track.cpp b/toonz/sources/tnztools/track.cpp index b603517..27d8b1e 100644 --- a/toonz/sources/tnztools/track.cpp +++ b/toonz/sources/tnztools/track.cpp @@ -4,15 +4,11 @@ //***************************************************************************************** -// Class definitions +// Static fields //***************************************************************************************** const double TTrack::epsilon = 1e-9; -TTrack::Id TTrack::lastId = 0; - -DEFINE_CLASS_CODE(TTrackHandler, 130) -DEFINE_CLASS_CODE(TTrackModifier, 131) -DEFINE_CLASS_CODE(TTrack, 132) +TTrack::Id TTrack::m_lastId = 0; //***************************************************************************************** @@ -35,25 +31,31 @@ TTrack::TTrack( TInputState::DeviceId deviceId, TInputState::TouchId touchId, const TInputState::KeyHistory::Holder &keyHistory, - const TInputState::ButtonHistory::Holder &buttonHistory + const TInputState::ButtonHistory::Holder &buttonHistory, + bool hasPressure, + bool hasTilt ): - id(++lastId), + id(++m_lastId), deviceId(deviceId), touchId(touchId), keyHistory(keyHistory), buttonHistory(buttonHistory), - wayPointsRemoved(), - wayPointsAdded() + hasPressure(hasPressure), + hasTilt(hasTilt), + pointsRemoved(), + pointsAdded() { } TTrack::TTrack(const TTrackModifierP &modifier): - id(++lastId), + id(++m_lastId), deviceId(modifier->original.deviceId), touchId(modifier->original.touchId), keyHistory(modifier->original.keyHistory), buttonHistory(modifier->original.buttonHistory), - wayPointsRemoved(), - wayPointsAdded() + hasPressure(modifier->original.hasPressure), + hasTilt(modifier->original.hasTilt), + pointsRemoved(), + pointsAdded() { } const TTrack* @@ -81,11 +83,11 @@ TTrack::floorIndex(double index, double &outFrac) const { void TTrack::push_back(const TTrackPoint &point) { - points_.push_back(point); + m_points.push_back(point); if (size() == 1) return; - const TTrackPoint &prev = *(points_.rbegin() + 1); - TTrackPoint &p = points_.back(); + const TTrackPoint &prev = *(m_points.rbegin() + 1); + TTrackPoint &p = m_points.back(); // fix originalIndex if (p.originalIndex < prev.originalIndex) @@ -103,7 +105,7 @@ void TTrack::pop_back(int count) { if (count > (int)size()) count = size(); if (count <= 0) return; - points_.erase(points_.end() - count, points_.end()); + m_points.erase(m_points.end() - count, m_points.end()); } @@ -124,3 +126,17 @@ TTrack::calcTangent(double index, double distance) const { double lenSqr = dp.x*dp.x + dp.y*dp.y; return lenSqr > epsilon*epsilon ? dp*sqrt(1.0/lenSqr) : TPointD(); } + +double +TTrack::rootIndexByIndex(double index) const { + return modifier + ? modifier->original.rootIndexByIndex( originalIndexByIndex(index) ) + : index; +} + +TTrackPoint +TTrack::calcRootPoint(double index) const { + return modifier + ? modifier->original.calcRootPoint( originalIndexByIndex(index) ) + : calcPoint(index); +} diff --git a/toonz/sources/tnztools/typetool.cpp b/toonz/sources/tnztools/typetool.cpp index 1c3ca6d..a2a3b72 100644 --- a/toonz/sources/tnztools/typetool.cpp +++ b/toonz/sources/tnztools/typetool.cpp @@ -363,7 +363,7 @@ public: void rightButtonDown(const TPointD &pos, const TMouseEvent &) override; bool keyDown(QKeyEvent *event) override; - void onInputText(std::wstring preedit, std::wstring commit, + void onInputText(const std::wstring &preedit, const std::wstring &commit, int replacementStart, int replacementLen) override; // cancella gli StrokeChar fra from e to-1 e inserisce nuovi StrokeChar @@ -1665,7 +1665,7 @@ bool TypeTool::keyDown(QKeyEvent *event) { //----------------------------------------------------------------------------- -void TypeTool::onInputText(std::wstring preedit, std::wstring commit, +void TypeTool::onInputText(const std::wstring &preedit, const std::wstring &commit, int replacementStart, int replacementLen) { // butto la vecchia preedit string m_preeditRange.first = std::max(0, m_preeditRange.first);