File indexing completed on 2024-12-01 11:10:42
0001 /* 0002 SPDX-FileCopyrightText: 2020 Michail Vourlakos <mvourlakos@gmail.com> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "eventssink.h" 0007 0008 // local 0009 #include "view.h" 0010 #include "positioner.h" 0011 0012 // Qt 0013 #include <QDragEnterEvent> 0014 #include <QDragMoveEvent> 0015 #include <QDropEvent> 0016 #include <QMouseEvent> 0017 #include <QPointF> 0018 #include <QRectF> 0019 0020 0021 namespace Latte { 0022 namespace ViewPart { 0023 0024 EventsSink::EventsSink(Latte::View *parent) 0025 : QObject(parent), 0026 m_view(parent) 0027 { 0028 } 0029 0030 EventsSink::~EventsSink() 0031 { 0032 } 0033 0034 QQuickItem *EventsSink::originParentItem() const 0035 { 0036 return m_originParentItem; 0037 } 0038 0039 QQuickItem *EventsSink::destinationItem() const 0040 { 0041 return m_destinationItem; 0042 } 0043 0044 void EventsSink::setSink(QQuickItem *originParent, QQuickItem *destination) 0045 { 0046 if ((m_originParentItem == originParent) && (m_destinationItem == destination)) { 0047 return; 0048 } 0049 0050 m_originParentItem = originParent; 0051 m_destinationItem = destination; 0052 0053 emit itemsChanged(); 0054 } 0055 0056 bool EventsSink::isActive() 0057 { 0058 return ((m_originParentItem != nullptr) && (m_destinationItem != nullptr)); 0059 } 0060 0061 void EventsSink::release() 0062 { 0063 setSink(nullptr, nullptr); 0064 } 0065 0066 QEvent *EventsSink::onEvent(QEvent *e) 0067 { 0068 if (!e) { 0069 return nullptr; 0070 } 0071 0072 if (!isActive()) { 0073 return e; 0074 } 0075 0076 QEvent *sunkevent = e; 0077 0078 switch (e->type()) { 0079 case QEvent::Leave: 0080 release(); 0081 break; 0082 case QEvent::DragEnter: 0083 if (auto de = static_cast<QDragEnterEvent *>(e)) { 0084 QPointF point = de->posF(); 0085 if (originSinksContain(point)) { 0086 auto de2 = new QDragEnterEvent(positionAdjustedForDestination(point).toPoint(), 0087 de->possibleActions(), 0088 de->mimeData(), 0089 de->mouseButtons(), 0090 de->keyboardModifiers()); 0091 sunkevent = de2; 0092 } else if (!destinationContains(point)) { 0093 release(); 0094 } 0095 } 0096 break; 0097 0098 case QEvent::DragMove: 0099 if (auto de = static_cast<QDragMoveEvent *>(e)) { 0100 QPointF point = de->posF(); 0101 if (originSinksContain(point)) { 0102 auto de2 = new QDragMoveEvent(positionAdjustedForDestination(point).toPoint(), 0103 de->possibleActions(), 0104 de->mimeData(), 0105 de->mouseButtons(), 0106 de->keyboardModifiers()); 0107 0108 sunkevent = de2; 0109 } else if (!destinationContains(point)) { 0110 release(); 0111 } 0112 } 0113 break; 0114 0115 case QEvent::Drop: 0116 if (auto de = static_cast<QDropEvent *>(e)) { 0117 QPointF point = de->posF(); 0118 if (originSinksContain(point)) { 0119 auto de2 = new QDropEvent(positionAdjustedForDestination(point).toPoint(), 0120 de->possibleActions(), 0121 de->mimeData(), 0122 de->mouseButtons(), 0123 de->keyboardModifiers()); 0124 0125 sunkevent = de2; 0126 } else if (!destinationContains(point)) { 0127 release(); 0128 } 0129 } 0130 0131 break; 0132 0133 case QEvent::MouseMove: 0134 if (auto me = dynamic_cast<QMouseEvent *>(e)) { 0135 if (m_view->positioner() && m_view->positioner()->isCursorInsideView() && originSinksContain(me->windowPos())) { 0136 auto positionadjusted = positionAdjustedForDestination(me->windowPos()); 0137 auto me2 = new QMouseEvent(me->type(), 0138 positionadjusted, 0139 positionadjusted, 0140 positionadjusted + m_view->position(), 0141 me->button(), me->buttons(), me->modifiers()); 0142 0143 sunkevent = me2; 0144 } else if (!destinationContains(me->windowPos())) { 0145 release(); 0146 } 0147 } 0148 break; 0149 0150 case QEvent::MouseButtonPress: 0151 if (auto me = dynamic_cast<QMouseEvent *>(e)) { 0152 if (originSinksContain(me->windowPos())) { 0153 auto positionadjusted = positionAdjustedForDestination(me->windowPos()); 0154 auto me2 = new QMouseEvent(me->type(), 0155 positionadjusted, 0156 positionadjusted, 0157 positionadjusted + m_view->position(), 0158 me->button(), me->buttons(), me->modifiers()); 0159 0160 qDebug() << "Sunk Event:: sunk event pressed..."; 0161 sunkevent = me2; 0162 } else if (!destinationContains(me->windowPos())) { 0163 release(); 0164 } 0165 } 0166 break; 0167 0168 case QEvent::MouseButtonRelease: 0169 if (auto me = dynamic_cast<QMouseEvent *>(e)) { 0170 if (originSinksContain(me->windowPos())) { 0171 auto positionadjusted = positionAdjustedForDestination(me->windowPos()); 0172 auto me2 = new QMouseEvent(me->type(), 0173 positionadjusted, 0174 positionadjusted, 0175 positionadjusted + m_view->position(), 0176 me->button(), me->buttons(), me->modifiers()); 0177 0178 sunkevent = me2; 0179 } else if (!destinationContains(me->windowPos())) { 0180 release(); 0181 } 0182 } 0183 break; 0184 0185 case QEvent::Wheel: 0186 if (auto we = dynamic_cast<QWheelEvent *>(e)) { 0187 QPoint pos = we->position().toPoint(); 0188 if (originSinksContain(pos)) { 0189 auto positionadjusted = positionAdjustedForDestination(pos); 0190 auto we2 = new QWheelEvent(positionadjusted, 0191 positionadjusted + m_view->position(), 0192 we->pixelDelta(), we->angleDelta(), we->angleDelta().y(), 0193 we->orientation(), we->buttons(), we->modifiers(), we->phase()); 0194 0195 sunkevent = we2; 0196 } else if (!destinationContains(pos)) { 0197 release(); 0198 } 0199 } 0200 break; 0201 default: 0202 break; 0203 } 0204 0205 return sunkevent; 0206 } 0207 0208 QPointF EventsSink::positionAdjustedForDestination(const QPointF &point) const 0209 { 0210 QRectF destinationRectToScene = m_destinationItem->mapRectToScene(QRectF(0, 0, m_destinationItem->width() - 1, m_destinationItem->height() - 1)); 0211 0212 return QPointF(qBound(destinationRectToScene.left(), point.x(), destinationRectToScene.right()), 0213 qBound(destinationRectToScene.top(), point.y(), destinationRectToScene.bottom())); 0214 } 0215 0216 bool EventsSink::destinationContains(const QPointF &point) const 0217 { 0218 QRectF destinationRectToScene = m_destinationItem->mapRectToScene(QRectF(0, 0, m_destinationItem->width() - 1, m_destinationItem->height() - 1)); 0219 0220 return destinationRectToScene.contains(point); 0221 } 0222 0223 bool EventsSink::originSinksContain(const QPointF &point) const 0224 { 0225 QRegion originsRegion; 0226 0227 for(const auto currentOrigin: m_originParentItem->childItems()) { 0228 QRectF currentOriginGeometry = currentOrigin->mapRectToScene(QRectF(0, 0, currentOrigin->width(), currentOrigin->height())); 0229 originsRegion = originsRegion.united(currentOriginGeometry.toRect()); 0230 } 0231 0232 return originsRegion.contains(point.toPoint()); 0233 } 0234 0235 } 0236 } 0237