File indexing completed on 2024-12-22 04:13:03

0001 /*
0002  *  SPDX-FileCopyrightText: 2016 Alvin Wong <alvinhochun-at-gmail-com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "KisStabilizerDelayedPaintHelper.h"
0008 
0009 constexpr int fixedPaintTimerInterval = 20;
0010 
0011 KisStabilizerDelayedPaintHelper::TimedPaintInfo::TimedPaintInfo(int elapsedTime, KisPaintInformation paintInfo)
0012     : elapsedTime(elapsedTime)
0013     , paintInfo(paintInfo)
0014 {
0015 }
0016 
0017 KisStabilizerDelayedPaintHelper::KisStabilizerDelayedPaintHelper()
0018 {
0019     connect(&m_paintTimer, SIGNAL(timeout()), SLOT(stabilizerDelayedPaintTimer()));
0020 }
0021 
0022 void KisStabilizerDelayedPaintHelper::start(const KisPaintInformation &firstPaintInfo) {
0023     if (running()) {
0024         cancel();
0025     }
0026     m_paintTimer.setInterval(fixedPaintTimerInterval);
0027     m_paintTimer.start();
0028     m_elapsedTimer.start();
0029     m_lastPendingTime = m_elapsedTimer.elapsed();
0030     m_lastPaintTime = m_lastPendingTime;
0031     m_paintQueue.enqueue(TimedPaintInfo(m_lastPendingTime, firstPaintInfo));
0032 }
0033 
0034 void KisStabilizerDelayedPaintHelper::update(const QVector<KisPaintInformation> &newPaintInfos) {
0035     int now = m_elapsedTimer.elapsed();
0036     int delayedPaintInterval = m_elapsedTimer.elapsed() - m_lastPendingTime;
0037     for (int i = 0; i < newPaintInfos.size(); i++) {
0038         // TODO: Risk of overflowing?
0039         int offsetTime = (delayedPaintInterval * i) / newPaintInfos.size();
0040         m_paintQueue.enqueue(TimedPaintInfo(now + offsetTime, newPaintInfos[i]));
0041     }
0042     m_lastPendingTime = now;
0043 }
0044 
0045 void KisStabilizerDelayedPaintHelper::paintSome() {
0046     // This function is also called from KisToolFreehandHelper::paint
0047     m_lastPaintTime = m_elapsedTimer.elapsed();
0048     if (m_paintQueue.isEmpty()) {
0049         return;
0050     }
0051     int now = m_lastPaintTime;
0052     // Always keep one in the queue since painting requires two points
0053     while (m_paintQueue.size() > 1 && m_paintQueue.head().elapsedTime <= now) {
0054         const TimedPaintInfo dequeued = m_paintQueue.dequeue();
0055         m_paintLine(dequeued.paintInfo, m_paintQueue.head().paintInfo);
0056     }
0057 }
0058 
0059 void KisStabilizerDelayedPaintHelper::end() {
0060     m_paintTimer.stop();
0061     m_elapsedTimer.invalidate();
0062     if (m_paintQueue.isEmpty()) {
0063         return;
0064     }
0065     TimedPaintInfo dequeued = m_paintQueue.dequeue();
0066     while (!m_paintQueue.isEmpty()) {
0067         const TimedPaintInfo dequeued2 = m_paintQueue.dequeue();
0068         m_paintLine(dequeued.paintInfo, dequeued2.paintInfo);
0069         dequeued = dequeued2;
0070     }
0071 }
0072 
0073 void KisStabilizerDelayedPaintHelper::cancel() {
0074     m_paintTimer.stop();
0075     m_paintQueue.clear();
0076 }
0077 
0078 void KisStabilizerDelayedPaintHelper::stabilizerDelayedPaintTimer() {
0079     if (m_elapsedTimer.elapsed() - m_lastPaintTime < fixedPaintTimerInterval) {
0080         return;
0081     }
0082     paintSome();
0083     // Explicitly update the outline because this is outside the pointer event
0084     m_requestUpdateOutline();
0085 }