File indexing completed on 2024-05-19 04:29:22

0001 /*
0002  *  SPDX-FileCopyrightText: 2023 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #ifndef KISWIDGETWITHIDLETASK_H
0007 #define KISWIDGETWITHIDLETASK_H
0008 
0009 #include <QWidget>
0010 #include "KisIdleTasksManager.h"
0011 
0012 class KisCanvas2;
0013 class KoColorSpace;
0014 
0015 template <typename BaseWidget>
0016 class KisWidgetWithIdleTask : public BaseWidget
0017 {
0018 public:
0019     KisWidgetWithIdleTask(QWidget *parent = 0, Qt::WindowFlags flags = Qt::WindowFlags())
0020         : BaseWidget (parent, flags)
0021     {
0022     }
0023 
0024     ~KisWidgetWithIdleTask() override = default;
0025 
0026     virtual void setCanvas(KisCanvas2 *canvas) {
0027         if (m_canvas) {
0028             m_idleTaskGuard = KisIdleTasksManager::TaskGuard();
0029         }
0030 
0031         m_canvas = canvas;
0032 
0033         if (m_canvas) {
0034             if (this->isVisible()) {
0035                 m_idleTaskGuard = registerIdleTask(m_canvas);
0036             }
0037         }
0038 
0039         clearCachedState();
0040         this->update();
0041     }
0042 
0043     void showEvent(QShowEvent *event) override {
0044         BaseWidget::showEvent(event);
0045 
0046         // see a comment at the declaration of `m_isVisibleState`
0047         if (!m_isVisibleState) {
0048             m_isVisibleState = true;
0049 
0050             KIS_SAFE_ASSERT_RECOVER(!m_idleTaskGuard.isValid()) {
0051                 m_idleTaskGuard = KisIdleTasksManager::TaskGuard();
0052             }
0053 
0054             if (m_canvas) {
0055                 m_idleTaskGuard = registerIdleTask(m_canvas);
0056             }
0057             if (m_idleTaskGuard.isValid()) {
0058                 m_idleTaskGuard.trigger();
0059             }
0060         }
0061     }
0062 
0063     void hideEvent(QHideEvent *event) override {
0064         BaseWidget::hideEvent(event);
0065 
0066         // see a comment at the declaration of `m_isVisibleState`
0067         if (m_isVisibleState) {
0068             m_isVisibleState = false;
0069 
0070             KIS_SAFE_ASSERT_RECOVER_NOOP(!m_canvas || m_idleTaskGuard.isValid());
0071             m_idleTaskGuard = KisIdleTasksManager::TaskGuard();
0072 
0073             clearCachedState();
0074         }
0075     }
0076 
0077     void triggerCacheUpdate() {
0078         if (m_idleTaskGuard.isValid()) {
0079             m_idleTaskGuard.trigger();
0080         }
0081     }
0082 
0083     [[nodiscard]]
0084     virtual KisIdleTasksManager::TaskGuard registerIdleTask(KisCanvas2 *canvas) = 0;
0085     virtual void clearCachedState() = 0;
0086 
0087 protected:
0088     KisCanvas2 *m_canvas {0};
0089     KisIdleTasksManager::TaskGuard m_idleTaskGuard;
0090 
0091     /**
0092      * Hide/show events may be unbalanced so we track their parity with
0093      * an internal state. Also, we cannot rely on this->isVisible(),
0094      * because its state is different on different platforms during the
0095      * event delivery.
0096      */
0097     bool m_isVisibleState {false};
0098 };
0099 
0100 #endif // KISWIDGETWITHIDLETASK_H