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 }