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 "parabolic.h"
0007 
0008 // local
0009 #include "view.h"
0010 
0011 // Qt
0012 #include <QMetaObject>
0013 
0014 namespace Latte {
0015 namespace ViewPart {
0016 
0017 Parabolic::Parabolic(Latte::View *parent)
0018     : QObject(parent),
0019       m_view(parent)
0020 {
0021     //! Parabolic Item Nullifier does not need any big interval in order to avoid
0022     //! nullifing currentParabolicItem too fast and as such send a false signal
0023     //! that NO parabolic item is hovered currently
0024     m_parabolicItemNullifier.setInterval(1);
0025     m_parabolicItemNullifier.setSingleShot(true);
0026     connect(&m_parabolicItemNullifier, &QTimer::timeout, this, [&]() {
0027         setCurrentParabolicItem(nullptr);
0028     });
0029 
0030     connect(this, &Parabolic::currentParabolicItemChanged, this, &Parabolic::onCurrentParabolicItemChanged);
0031 
0032     connect(m_view, &View::eventTriggered, this, &Parabolic::onEvent);
0033 }
0034 
0035 Parabolic::~Parabolic()
0036 {
0037 }
0038 
0039 QQuickItem *Parabolic::currentParabolicItem() const
0040 {
0041     return m_currentParabolicItem;
0042 }
0043 
0044 void Parabolic::setCurrentParabolicItem(QQuickItem *item)
0045 {
0046     if (m_currentParabolicItem == item) {
0047         return;
0048     }
0049 
0050     if (m_currentParabolicItem) {
0051         QMetaObject::invokeMethod(m_currentParabolicItem, "parabolicExited", Qt::QueuedConnection);
0052     }
0053 
0054     m_currentParabolicItem = item;
0055     emit currentParabolicItemChanged();
0056 }
0057 
0058 void Parabolic::onEvent(QEvent *e)
0059 {
0060     if (!e) {
0061         return;
0062     }
0063 
0064     switch (e->type()) {
0065 
0066     case QEvent::Leave:
0067         setCurrentParabolicItem(nullptr);
0068         break;
0069     case QEvent::MouseMove:
0070         if (auto me = dynamic_cast<QMouseEvent *>(e)) {
0071             if (m_currentParabolicItem) {
0072                 QPointF internal = m_currentParabolicItem->mapFromScene(me->windowPos());
0073 
0074                 if (m_currentParabolicItem->contains(internal)) {
0075                     m_parabolicItemNullifier.stop();
0076                     //! sending move event to parabolic item
0077                     QMetaObject::invokeMethod(m_currentParabolicItem,
0078                                               "parabolicMove",
0079                                               Qt::QueuedConnection,
0080                                               Q_ARG(qreal, internal.x()),
0081                                               Q_ARG(qreal, internal.y()));
0082                 } else {
0083                     m_lastOrphanParabolicMove = me->windowPos();
0084                     //! clearing parabolic item
0085                     m_parabolicItemNullifier.start();
0086                 }
0087             } else {
0088                 m_lastOrphanParabolicMove = me->windowPos();
0089             }
0090         }
0091     default:
0092         break;
0093     }
0094 
0095 }
0096 
0097 void Parabolic::onCurrentParabolicItemChanged()
0098 {
0099     m_parabolicItemNullifier.stop();
0100 
0101     if (m_currentParabolicItem) {
0102         QPointF internal = m_currentParabolicItem->mapFromScene(m_lastOrphanParabolicMove);
0103 
0104         if (m_currentParabolicItem->contains(internal)) {
0105             //! sending enter event to parabolic item
0106             QMetaObject::invokeMethod(m_currentParabolicItem,
0107                                       "parabolicEntered",
0108                                       Qt::QueuedConnection,
0109                                       Q_ARG(qreal, internal.x()),
0110                                       Q_ARG(qreal, internal.y()));
0111         }
0112     }
0113 }
0114 
0115 }
0116 }
0117