21 #include "strokemanager.h"
27 #include <QPainterPath>
29 #include "pointerevent.h"
32 StrokeManager::StrokeManager()
43 void StrokeManager::reset()
45 mStrokeStarted =
false;
46 pressureQueue.clear();
51 mStabilizerLevel = -1;
54 void StrokeManager::setPressure(
float pressure)
56 mTabletPressure = pressure;
59 void StrokeManager::pointerPressEvent(
PointerEvent* event)
65 mLastPressPixel = mCurrentPressPixel;
66 mCurrentPressPixel =
event->posF();
69 mLastPixel = mCurrentPixel =
event->posF();
71 mStrokeStarted =
true;
75 void StrokeManager::pointerMoveEvent(
PointerEvent* event)
78 if (mStabilizerLevel != -1)
80 smoothMousePos(event->
posF());
85 mLastPixel = mCurrentPixel;
86 mCurrentPixel =
event->posF();
87 mLastInterpolated = mCurrentPixel;
95 void StrokeManager::pointerReleaseEvent(
PointerEvent* event)
100 pointerMoveEvent(event);
103 mStrokeStarted =
false;
106 void StrokeManager::setStabilizerLevel(
int level)
108 mStabilizerLevel = level;
111 void StrokeManager::smoothMousePos(
QPointF pos)
116 if (mStabilizerLevel == StabilizationLevel::NONE)
118 mLastPixel = mCurrentPixel;
120 mLastInterpolated = mCurrentPixel;
122 else if (mStabilizerLevel == StabilizationLevel::SIMPLE)
125 smoothPos =
QPointF((pos.
x() + mCurrentPixel.
x()) / 2.0, (pos.
y() + mCurrentPixel.
y()) / 2.0);
126 mLastPixel = mCurrentPixel;
127 mCurrentPixel = smoothPos;
128 mLastInterpolated = mCurrentPixel;
131 while (strokeQueue.size() >= STROKE_QUEUE_LENGTH)
133 strokeQueue.pop_front();
136 strokeQueue.push_back(smoothPos);
138 else if (mStabilizerLevel == StabilizationLevel::STRONG)
140 smoothPos =
QPointF((pos.
x() + mLastInterpolated.
x()) / 2.0, (pos.
y() + mLastInterpolated.
y()) / 2.0);
142 mLastInterpolated = mCurrentPixel;
143 mCurrentPixel = smoothPos;
144 mLastPixel = mLastInterpolated;
163 if (mStabilizerLevel == StabilizationLevel::SIMPLE)
167 pressureQueue.clear();
169 mSingleshotTime.
start();
170 previousTime = mSingleshotTime.
elapsed();
172 mLastPixel = firstPoint;
174 else if (mStabilizerLevel == StabilizationLevel::STRONG)
176 mSingleshotTime.
start();
177 previousTime = mSingleshotTime.
elapsed();
181 pressureQueue.clear();
183 const int sampleSize = 5;
184 Q_ASSERT(sampleSize > 0);
187 for (
int i = sampleSize; i > 0; i--)
189 strokeQueue.
enqueue(firstPoint);
193 mLastInterpolated = firstPoint;
199 else if (mStabilizerLevel == StabilizationLevel::NONE)
203 pressureQueue.clear();
205 mLastPixel = firstPoint;
210 void StrokeManager::interpolatePoll()
216 strokeQueue.
enqueue(mLastInterpolated);
219 void StrokeManager::interpolatePollAndPaint()
222 if (!strokeQueue.isEmpty())
234 if (mStabilizerLevel == StabilizationLevel::SIMPLE)
236 result = tangentInpolOp(result);
239 else if (mStabilizerLevel == StabilizationLevel::STRONG)
244 result = meanInpolOp(result, x, y, pressure);
247 else if (mStabilizerLevel == StabilizationLevel::NONE)
249 result = noInpolOp(result);
256 setPressure(getPressure());
258 points << mLastPixel << mLastPixel << mCurrentPixel << mCurrentPixel;
262 mLastPixel = mCurrentPixel;
269 int time = mSingleshotTime.
elapsed();
270 static const qreal smoothness = 1.f;
271 QLineF line(mLastPixel, mCurrentPixel);
273 qreal scaleFactor = line.length() * 3.f;
275 if (!mHasTangent && scaleFactor > 0.01f)
283 m_previousTangent = (mCurrentPixel - mLastPixel) * smoothness / (3.0 * scaleFactor);
287 if (_line.length() < 2)
289 m_previousTangent =
QPointF(0, 0);
294 QPointF c1 = mLastPixel + m_previousTangent * scaleFactor;
295 QPointF newTangent = (mCurrentPixel - c1) * smoothness / (3.0 * scaleFactor);
297 if (scaleFactor == 0)
309 QPointF c2 = mCurrentPixel - newTangent * scaleFactor;
312 points << mLastPixel << c1 << c2 << mCurrentPixel;
314 m_previousTangent = newTangent;
324 for (
int i = 0; i < strokeQueue.size(); i++)
326 x += strokeQueue[i].x();
327 y += strokeQueue[i].y();
328 pressure += getPressure();
332 x /= strokeQueue.size();
333 y /= strokeQueue.size();
334 pressure /= strokeQueue.size();
337 QPointF mNewInterpolated = mLastInterpolated;
338 mNewInterpolated =
QPointF(x, y);
340 points << mLastPixel << mLastInterpolated << mNewInterpolated << mCurrentPixel;
344 mLastPixel = mNewInterpolated;
349 void StrokeManager::interpolateEnd()
353 if (mStabilizerLevel == StabilizationLevel::STRONG)
355 if (!strokeQueue.isEmpty())
361 Q_ASSERT(sampleSize > 0);
362 for (
int i = sampleSize; i > 0; i--)
void setInterval(int msec)
QPointF posF() const
Returns the QPointF of the device Returns pos() if used on mouse event.
bool isTabletEvent() const
Returns true if the device was tablet, otherwise false.
qreal pressure() const
Returns a value between 0 and 1 for tablet events, otherwise 1.0.
Qt::MouseButton button() const
Returns Qt::MouseButton()
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
qint64 elapsed() const const