diff options
author | NeatNit <neatnit@gmail.com> | 2018-10-01 22:42:49 +0300 |
---|---|---|
committer | fearlessTobi <thm.frey@gmail.com> | 2018-10-09 20:26:57 +0200 |
commit | 4f24343f32ed253efb2cedba03d20c620841dca1 (patch) | |
tree | 1fffd231c45fa4681c0a20c682c3ba5f7946c27c /src/yuzu | |
parent | 561d79e03443aec02f54e1e43437bc1d5b90ca88 (diff) |
implemented touch in Qt and SDL
change TouchToPixelPos to return std::pair<int, int>
static_cast (SDL)
various minor style and code improvements
style - PascalCase for function names
made touch events private
const pointer arg in touch events
make TouchToPixelPos a const member function
did I do this right?
braces on barely-multiline if
remove question comment (confirmed in Discord)
fixed consts
remove unused parameter from TouchEndEvent
DRY - High-DPI scaled touch put in separate function
also fixes a bug where if you start touching (with either mouse or touchscreen) and drag the mouse to the LEFT of the emulator window, the touch point jumps to the RIGHT side of the touchscreen; draggin to above the window would make it jump to the bottom.
implicit conversion from QPoint to QPointF, apparently
I have no idea what const even means but I'll put it here anyway
remove unused or used-once variables
make touch scaling functions const, and put their implementations together
removed unused FingerID parameters
QTouchEvent forward declaration; add comment to TouchBegin that was lost in an edit
better DRY in SDL
To do -> TODO(NeatNit)
remove unused include
Diffstat (limited to 'src/yuzu')
-rw-r--r-- | src/yuzu/bootmanager.cpp | 71 | ||||
-rw-r--r-- | src/yuzu/bootmanager.h | 10 |
2 files changed, 73 insertions, 8 deletions
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 4e4c108ab..e8ab23326 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -110,6 +110,7 @@ GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) std::string window_title = fmt::format("yuzu {} | {}-{}", Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc); setWindowTitle(QString::fromStdString(window_title)); + setAttribute(Qt::WA_AcceptTouchEvents); InputCommon::Init(); InputCommon::StartJoystickEventHandler(); @@ -190,11 +191,17 @@ QByteArray GRenderWindow::saveGeometry() { return geometry; } -qreal GRenderWindow::windowPixelRatio() { +qreal GRenderWindow::windowPixelRatio() const { // windowHandle() might not be accessible until the window is displayed to screen. return windowHandle() ? windowHandle()->screen()->devicePixelRatio() : 1.0f; } +std::pair<unsigned, unsigned> GRenderWindow::ScaleTouch(const QPointF pos) const { + const qreal pixel_ratio = windowPixelRatio(); + return {static_cast<unsigned>(std::max(std::round(pos.x() * pixel_ratio), qreal{0.0})), + static_cast<unsigned>(std::max(std::round(pos.y() * pixel_ratio), qreal{0.0}))}; +} + void GRenderWindow::closeEvent(QCloseEvent* event) { emit Closed(); QWidget::closeEvent(event); @@ -209,31 +216,81 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event) { } void GRenderWindow::mousePressEvent(QMouseEvent* event) { + if (event->source() == Qt::MouseEventSynthesizedBySystem) + return; // touch input is handled in TouchBeginEvent + auto pos = event->pos(); if (event->button() == Qt::LeftButton) { - qreal pixelRatio = windowPixelRatio(); - this->TouchPressed(static_cast<unsigned>(pos.x() * pixelRatio), - static_cast<unsigned>(pos.y() * pixelRatio)); + const auto [x, y] = ScaleTouch(pos); + this->TouchPressed(x, y); } else if (event->button() == Qt::RightButton) { InputCommon::GetMotionEmu()->BeginTilt(pos.x(), pos.y()); } } void GRenderWindow::mouseMoveEvent(QMouseEvent* event) { + if (event->source() == Qt::MouseEventSynthesizedBySystem) + return; // touch input is handled in TouchUpdateEvent + auto pos = event->pos(); - qreal pixelRatio = windowPixelRatio(); - this->TouchMoved(std::max(static_cast<unsigned>(pos.x() * pixelRatio), 0u), - std::max(static_cast<unsigned>(pos.y() * pixelRatio), 0u)); + const auto [x, y] = ScaleTouch(pos); + this->TouchMoved(x, y); InputCommon::GetMotionEmu()->Tilt(pos.x(), pos.y()); } void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { + if (event->source() == Qt::MouseEventSynthesizedBySystem) + return; // touch input is handled in TouchEndEvent + if (event->button() == Qt::LeftButton) this->TouchReleased(); else if (event->button() == Qt::RightButton) InputCommon::GetMotionEmu()->EndTilt(); } +void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) { + // TouchBegin always has exactly one touch point, so take the .first() + const auto [x, y] = ScaleTouch(event->touchPoints().first().pos()); + this->TouchPressed(x, y); +} + +void GRenderWindow::TouchUpdateEvent(const QTouchEvent* event) { + QPointF pos; + int active_points = 0; + + // average all active touch points + for (const auto tp : event->touchPoints()) { + if (tp.state() & (Qt::TouchPointPressed | Qt::TouchPointMoved | Qt::TouchPointStationary)) { + active_points++; + pos += tp.pos(); + } + } + + pos /= active_points; + + const auto [x, y] = ScaleTouch(pos); + this->TouchMoved(x, y); +} + +void GRenderWindow::TouchEndEvent() { + this->TouchReleased(); +} + +bool GRenderWindow::event(QEvent* event) { + if (event->type() == QEvent::TouchBegin) { + TouchBeginEvent(static_cast<QTouchEvent*>(event)); + return true; + } else if (event->type() == QEvent::TouchUpdate) { + TouchUpdateEvent(static_cast<QTouchEvent*>(event)); + return true; + } else if (event->type() == QEvent::TouchEnd || event->type() == QEvent::TouchCancel) { + TouchEndEvent(); + return true; + } + + return QWidget::event(event); +} + void GRenderWindow::focusOutEvent(QFocusEvent* event) { QWidget::focusOutEvent(event); InputCommon::GetKeyboard()->ReleaseAllKeys(); diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index f133bfadf..873985564 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -15,6 +15,7 @@ class QKeyEvent; class QScreen; +class QTouchEvent; class GGLWidgetInternal; class GMainWindow; @@ -119,7 +120,7 @@ public: void restoreGeometry(const QByteArray& geometry); // overridden QByteArray saveGeometry(); // overridden - qreal windowPixelRatio(); + qreal windowPixelRatio() const; void closeEvent(QCloseEvent* event) override; @@ -130,6 +131,8 @@ public: void mouseMoveEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; + bool event(QEvent* event) override; + void focusOutEvent(QFocusEvent* event) override; void OnClientAreaResized(unsigned width, unsigned height); @@ -148,6 +151,11 @@ signals: void Closed(); private: + std::pair<unsigned, unsigned> ScaleTouch(const QPointF pos) const; + void TouchBeginEvent(const QTouchEvent* event); + void TouchUpdateEvent(const QTouchEvent* event); + void TouchEndEvent(); + void OnMinimalClientAreaChangeRequest( const std::pair<unsigned, unsigned>& minimal_size) override; |