91 lines
1.8 KiB
C++
91 lines
1.8 KiB
C++
#pragma once
|
|
|
|
#include <QQuickItem>
|
|
#include <QQuickWindow>
|
|
#include <QWheelEvent>
|
|
#include <QCoreApplication>
|
|
#include <QPointer>
|
|
#include <QDebug>
|
|
|
|
namespace ZShell::components {
|
|
|
|
class WheelInverter : public QQuickItem {
|
|
Q_OBJECT
|
|
QML_ELEMENT
|
|
|
|
Q_PROPERTY(
|
|
QQuickItem* target READ target WRITE setTarget NOTIFY targetChanged)
|
|
|
|
public:
|
|
using QQuickItem::QQuickItem;
|
|
|
|
QQuickItem* target() const { return m_target; }
|
|
|
|
void setTarget(QQuickItem* target) {
|
|
if (m_target == target) return;
|
|
|
|
if (m_target) m_target->removeEventFilter(this);
|
|
|
|
m_target = target;
|
|
|
|
if (m_target) m_target->installEventFilter(this);
|
|
|
|
emit targetChanged();
|
|
}
|
|
|
|
protected:
|
|
class InvertedWheelEvent : public QWheelEvent {
|
|
public:
|
|
using QWheelEvent::QWheelEvent;
|
|
|
|
bool invertedByWheelInverter = true;
|
|
};
|
|
|
|
bool eventFilter(QObject* watched, QEvent* event) override {
|
|
if (watched != m_target || event->type() != QEvent::Wheel)
|
|
return QQuickItem::eventFilter(watched, event);
|
|
|
|
auto* wheel = static_cast<QWheelEvent*>(event);
|
|
|
|
const bool inverted = dynamic_cast<InvertedWheelEvent*>(wheel) !=
|
|
nullptr;
|
|
|
|
if (inverted) return false;
|
|
|
|
auto* window = m_target ? m_target->window() : nullptr;
|
|
if (!window) {
|
|
qInfo() << "[WheelInverter] no window";
|
|
return false;
|
|
}
|
|
|
|
const QPointF windowPos =
|
|
window->mapFromGlobal(wheel->globalPosition());
|
|
|
|
auto* invertedEvent = new InvertedWheelEvent(
|
|
windowPos,
|
|
wheel->globalPosition(),
|
|
-wheel->pixelDelta(),
|
|
-wheel->angleDelta(),
|
|
wheel->buttons(),
|
|
wheel->modifiers(),
|
|
wheel->phase(),
|
|
wheel->inverted(),
|
|
wheel->source(),
|
|
wheel->pointingDevice());
|
|
|
|
invertedEvent->setTimestamp(wheel->timestamp());
|
|
|
|
QCoreApplication::postEvent(window, invertedEvent);
|
|
|
|
return true;
|
|
}
|
|
|
|
signals:
|
|
void targetChanged();
|
|
|
|
private:
|
|
QPointer<QQuickItem> m_target;
|
|
};
|
|
|
|
} // namespace ZShell::components
|