File indexing completed on 2024-12-22 04:12:57

0001 /*
0002  *  SPDX-FileCopyrightText: 2013 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __KIS_DELEGATED_TOOL_H
0008 #define __KIS_DELEGATED_TOOL_H
0009 
0010 #include <KoPointerEvent.h>
0011 #include <KoShape.h>
0012 
0013 #include <QLayout>
0014 #include <QPointer>
0015 
0016 #include "canvas/kis_canvas2.h"
0017 #include "input/kis_input_manager.h"
0018 #include "kis_delegated_tool_policies.h"
0019 #include "kis_tool.h"
0020 #include <KisOptionCollectionWidget.h>
0021 
0022 #define PRESS_CONDITION_OM(_event, _mode, _button, _modifier)           \
0023     (this->mode() == (_mode) && (_event)->button() == (_button) &&      \
0024      ((_event)->modifiers() & (_modifier) ||                            \
0025       (_event)->modifiers() == Qt::NoModifier))
0026 
0027 template <class BaseClass, class DelegateTool, class ActivationPolicy = NoopActivationPolicy>
0028     class KisDelegatedTool : public BaseClass
0029 {
0030 public:
0031     KisDelegatedTool(KoCanvasBase *canvas,
0032                      const QCursor &cursor,
0033                      DelegateTool *delegateTool)
0034         : BaseClass(canvas, cursor),
0035           m_localTool(delegateTool)
0036     {
0037     }
0038 
0039     DelegateTool* localTool() const {
0040         return m_localTool.data();
0041     }
0042 
0043     void activate(const QSet<KoShape*> &shapes) override
0044     {
0045         BaseClass::activate(shapes);
0046         m_localTool->activate(shapes);
0047         ActivationPolicy::onActivate(BaseClass::canvas());
0048 
0049         KisInputManager *inputManager = (static_cast<KisCanvas2*>(BaseClass::canvas()))->globalInputManager();
0050         if (inputManager) {
0051             inputManager->attachPriorityEventFilter(this);
0052         }
0053     }
0054 
0055     void deactivate() override
0056     {
0057         m_localTool->deactivate();
0058         BaseClass::deactivate();
0059 
0060         KisInputManager *inputManager = (static_cast<KisCanvas2*>(BaseClass::canvas()))->globalInputManager();
0061         if (inputManager) {
0062             inputManager->detachPriorityEventFilter(this);
0063         }
0064     }
0065 
0066     void mousePressEvent(KoPointerEvent *event) override
0067     {
0068         if(PRESS_CONDITION_OM(event, KisTool::HOVER_MODE,
0069                               Qt::LeftButton, Qt::ShiftModifier |
0070                               Qt::ControlModifier | Qt::AltModifier)) {
0071 
0072             this->setMode(KisTool::PAINT_MODE);
0073 
0074             Q_ASSERT(m_localTool);
0075             m_localTool->mousePressEvent(event);
0076         }
0077         else {
0078             BaseClass::mousePressEvent(event);
0079         }
0080     }
0081 
0082     void mouseDoubleClickEvent(KoPointerEvent *event) override
0083     {
0084         if(PRESS_CONDITION_OM(event, KisTool::HOVER_MODE,
0085                               Qt::LeftButton, Qt::ShiftModifier |
0086                               Qt::ControlModifier | Qt::AltModifier)) {
0087 
0088             Q_ASSERT(m_localTool);
0089             m_localTool->mouseDoubleClickEvent(event);
0090         }
0091         else {
0092             BaseClass::mouseDoubleClickEvent(event);
0093         }
0094     }
0095 
0096     void mouseMoveEvent(KoPointerEvent *event) override
0097     {
0098         Q_ASSERT(m_localTool);
0099         m_localTool->mouseMoveEvent(event);
0100 
0101         BaseClass::mouseMoveEvent(event);
0102     }
0103 
0104     void mouseReleaseEvent(KoPointerEvent *event) override
0105     {
0106         if (this->mode() == KisTool::PAINT_MODE && event->button() == Qt::LeftButton) {
0107             this->setMode(KisTool::HOVER_MODE);
0108 
0109             Q_ASSERT(m_localTool);
0110             m_localTool->mouseReleaseEvent(event);
0111         }
0112         else {
0113             BaseClass::mouseReleaseEvent(event);
0114         }
0115     }
0116 
0117     void paint(QPainter &painter, const KoViewConverter &converter) override
0118     {
0119         Q_ASSERT(m_localTool);
0120         m_localTool->paint(painter, converter);
0121     }
0122 
0123     QList<QPointer<QWidget> > createOptionWidgets() override
0124     {
0125         QList<QPointer<QWidget>> baseWidgetList =
0126             BaseClass::createOptionWidgets();
0127         QList<QPointer<QWidget>> localWidgetList =
0128             m_localTool->createOptionWidgets();
0129 
0130         if (baseWidgetList.size() > 0
0131             && dynamic_cast<KisOptionCollectionWidget *>(
0132                 baseWidgetList.first().data())) {
0133             KisOptionCollectionWidget *baseOptionsWidget =
0134                 dynamic_cast<KisOptionCollectionWidget *>(
0135                     baseWidgetList.first().data());
0136             for (int i = 0; i < localWidgetList.size(); ++i) {
0137                 QWidget *widget = localWidgetList[i];
0138                 KisOptionCollectionWidgetWithHeader *section =
0139                     new KisOptionCollectionWidgetWithHeader(
0140                         widget->windowTitle());
0141                 const QString sectionName = "section" + QString::number(i);
0142                 section->appendWidget(sectionName + "Widget", widget);
0143                 baseOptionsWidget->appendWidget(sectionName, section);
0144             }
0145         } else {
0146             baseWidgetList.append(localWidgetList);
0147         }
0148         return baseWidgetList;
0149     }
0150 
0151 protected:
0152     QScopedPointer<DelegateTool> m_localTool;
0153 };
0154 
0155 #endif /* __KIS_DELEGATED_TOOL_H */