diff --git a/toonz/sources/include/tools/inputstate.h b/toonz/sources/include/tools/inputstate.h new file mode 100644 index 0000000..5fd2109 --- /dev/null +++ b/toonz/sources/include/tools/inputstate.h @@ -0,0 +1,154 @@ +#pragma once + +#ifndef INPUTSTATE_INCLUDED +#define INPUTSTATE_INCLUDED + +// TnzTools includes +#include <tools/tooltimer.h> +#include <tools/keyhistory.h> + +// TnzCore includes +#include <tcommon.h> +#include <tsmartpointer.h> + +// Qt includes +#include <Qt> + +// std includes +#include <map> + + +#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 + + +//=================================================================== + + +//***************************************************************************************** +// TInputState definition +//***************************************************************************************** + +class TInputState { +public: + typedef qint64 DeviceId; + typedef long long TouchId; + + typedef Qt::Key Key; + typedef TKeyHistoryT<Key> KeyHistory; + typedef KeyHistory::State KeyState; + + typedef Qt::MouseButton Button; + typedef TKeyHistoryT<Button> ButtonHistory; + typedef ButtonHistory::State ButtonState; + typedef std::map<DeviceId, ButtonHistory::Pointer> ButtonHistoryMap; + +private: + TTimerTicks ticks; + KeyHistory::Pointer keyHistory_; + mutable ButtonHistoryMap buttonHistories_; + + void touch(TTimerTicks ticks); + +public: + TInputState(); + ~TInputState(); + + inline KeyHistory::Pointer keyHistory() const + { return 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); } + inline void keyPress(Key key, TTimerTicks ticks) + { keyEvent(true, key, ticks); } + inline void keyRelease(Key key, TTimerTicks ticks) + { keyEvent(false, key, ticks); } + + inline KeyState::Pointer keyFind(Key key) const + { return keyState()->find(key); } + inline bool isKeyPressed(Key key) const + { return keyFind(key); } + 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); } + + ButtonHistory::Pointer buttonHistory(DeviceId device) 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); } + inline void buttonEvent(bool press, Button button, TTimerTicks ticks) + { buttonEvent(press, 0, button, ticks); } + inline void buttonPress(Button button, TTimerTicks ticks) + { buttonEvent(true, button, ticks); } + 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 buttonFindDefault(Button button) + { return buttonFind(DeviceId(), button); } + inline bool isButtonPressedDefault(Button button) + { return isButtonPressed(DeviceId(), button); } + 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); } + + ButtonState::Pointer buttonFindAny(Button button, DeviceId &outDevice); + + inline ButtonState::Pointer buttonFindAny(Button button) + { DeviceId device; return buttonFindAny(button, device); } + 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); } +}; + + +#endif diff --git a/toonz/sources/include/tools/keyhistory.h b/toonz/sources/include/tools/keyhistory.h index c49a662..79537fb 100644 --- a/toonz/sources/include/tools/keyhistory.h +++ b/toonz/sources/include/tools/keyhistory.h @@ -72,7 +72,9 @@ public: { return howLongPressed(find(value), ticks, timeOffset); } static double howLongPressed(const Pointer &state, long ticks, double timeOffset) { - return state ? std::max(TToolTimer::step, (ticks - state.ticks)*TToolTimer::step + timeOffset) : 0.0; + return state + ? std::max(TToolTimer::step, (ticks - state->ticks)*TToolTimer::step + timeOffset) + : 0.0; } }; @@ -232,15 +234,15 @@ private: public: TKeyHistoryT() - { states.insert(StatePointer(new State())); } + { states[TTimerTicks()] = StatePointer(new State()); } StatePointer current() const - { return states.back(); } + { return 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.insert(state.ticks, state); + if (state != current() && state->ticks > states.rbegin()->first) + states[state->ticks] = state; autoRemove(); return current(); } diff --git a/toonz/sources/include/tools/track.h b/toonz/sources/include/tools/track.h index dbb38ef..84fa7a4 100644 --- a/toonz/sources/include/tools/track.h +++ b/toonz/sources/include/tools/track.h @@ -4,8 +4,9 @@ #define TRACK_INCLUDED // TnzTools includes -#include <tools/keyhistory.h> -#include <tools/tooltimer.h> +#include <tools/inputstate.h> + +// TnzCore includes #include <tcommon.h> #include <tgeometry.h> @@ -38,6 +39,7 @@ class TTrackModifier; typedef TSmartPointerT<TTrack> TTrackP; typedef TSmartPointerT<TTrackHandler> TTrackHandlerP; typedef TSmartPointerT<TTrackModifier> TTrackModifierP; +typedef std::vector<TTrackP> TTrackList; //=================================================================== @@ -85,11 +87,10 @@ public: class DVAPI TTrackHandler : public TSmartObject { DECLARE_CLASS_CODE public: - TSmartObject &owner; TTrack &original; std::vector<TTrackP> tracks; - TTrackHandler(TSmartObject &owner, TTrack &original): - owner(owner), original(original) { } + TTrackHandler(TTrack &original): + original(original) { } }; @@ -119,8 +120,6 @@ class DVAPI TTrack : public TSmartObject { public: typedef long long Id; - typedef long long TouchId; - typedef qint64 DeviceId; static const double epsilon; @@ -129,10 +128,10 @@ private: public: const Id id; - const DeviceId deviceId; - const TouchId touchId; - const TKeyHistoryT<Qt::Key>::Holder keyHistory; - const TKeyHistoryT<Qt::MouseButton>::Holder buttonHistory; + const TInputState::DeviceId deviceId; + const TInputState::TouchId touchId; + const TInputState::KeyHistory::Holder keyHistory; + const TInputState::ButtonHistory::Holder buttonHistory; const TTrackModifierP modifier; TTrackHandlerP handler; @@ -146,10 +145,10 @@ private: public: explicit TTrack( - DeviceId deviceId = 0, - TouchId touchId = 0, - const TKeyHistoryT<Qt::Key>::Holder &keyHistory = TKeyHistoryT<Qt::Key>::Holder(), - const TKeyHistoryT<Qt::MouseButton>::Holder &buttonHistory = TKeyHistoryT<Qt::MouseButton>::Holder() + 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() ); explicit TTrack(const TTrackModifierP &modifier); diff --git a/toonz/sources/tnztools/CMakeLists.txt b/toonz/sources/tnztools/CMakeLists.txt index a56b0e5..cfaa257 100644 --- a/toonz/sources/tnztools/CMakeLists.txt +++ b/toonz/sources/tnztools/CMakeLists.txt @@ -45,6 +45,7 @@ set(HEADERS ../include/tools/toolutils.h ../include/tools/tooltimer.h ../include/tools/keyhistory.h + ../include/tools/inputstate.h ../include/tools/track.h ) @@ -111,6 +112,7 @@ set(SOURCES toonzvectorbrushtool.cpp tooltimer.cpp keyhistory.cpp + inputstate.cpp track.cpp ) diff --git a/toonz/sources/tnztools/inputstate.cpp b/toonz/sources/tnztools/inputstate.cpp new file mode 100644 index 0000000..db414e0 --- /dev/null +++ b/toonz/sources/tnztools/inputstate.cpp @@ -0,0 +1,44 @@ + + +#include <tools/inputstate.h> + + +//***************************************************************************************** +// TInputState static members +//***************************************************************************************** + +TInputState::TInputState(): + ticks(), + keyHistory_(new KeyHistory()) + { } + +TInputState::~TInputState() + { } + +void +TInputState::touch(TTimerTicks ticks) { + if (this->ticks < ticks) + this->ticks = ticks; + else + ++this->ticks; +} + +TInputState::ButtonHistory::Pointer +TInputState::buttonHistory(DeviceId device) const { + ButtonHistory::Pointer &history = 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) { + ButtonState::Pointer state = i->second->current()->find(button); + if (state) { + outDevice = i->first; + return state; + } + } + outDevice = DeviceId(); + return ButtonState::Pointer(); +} diff --git a/toonz/sources/tnztools/track.cpp b/toonz/sources/tnztools/track.cpp index c949044..b603517 100644 --- a/toonz/sources/tnztools/track.cpp +++ b/toonz/sources/tnztools/track.cpp @@ -32,10 +32,10 @@ TTrackModifier::calcPoint(double originalIndex) { //***************************************************************************************** TTrack::TTrack( - DeviceId deviceId, - TouchId touchId, - const TKeyHistoryT<Qt::Key>::Holder &keyHistory, - const TKeyHistoryT<Qt::MouseButton>::Holder &buttonHistory + TInputState::DeviceId deviceId, + TInputState::TouchId touchId, + const TInputState::KeyHistory::Holder &keyHistory, + const TInputState::ButtonHistory::Holder &buttonHistory ): id(++lastId), deviceId(deviceId), @@ -84,14 +84,17 @@ TTrack::push_back(const TTrackPoint &point) { points_.push_back(point); if (size() == 1) return; - const TTrackPoint &prev = *(points_.end() - 2); + const TTrackPoint &prev = *(points_.rbegin() + 1); TTrackPoint &p = points_.back(); + // fix originalIndex if (p.originalIndex < prev.originalIndex) p.originalIndex = prev.originalIndex; - if (p.time < prev.time) - p.time = prev.time; + // fix time + p.time = std::max(p.time, prev.time + TToolTimer::step); + + // calculate length TPointD d = p.position - prev.position; p.length = prev.length + sqrt(d.x*d.x + d.y*d.y); }