mirror of
https://github.com/citra-emu/citra-nightly.git
synced 2025-10-04 22:07:03 +00:00
implemented touch in Qt and SDL
This commit is contained in:
parent
0e42fa9fa7
commit
f0faaf0db4
|
@ -41,6 +41,39 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmuWindow_SDL2::TouchToPixelPos(float touch_x, float touch_y, int* pixel_x, int* pixel_y) {
|
||||||
|
int w, h;
|
||||||
|
SDL_GetWindowSize(render_window, &w, &h);
|
||||||
|
|
||||||
|
touch_x *= w;
|
||||||
|
touch_y *= h;
|
||||||
|
|
||||||
|
*pixel_x = (int)(touch_x + 0.5);
|
||||||
|
*pixel_y = (int)(touch_y + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuWindow_SDL2::OnFingerDown(SDL_FingerID finger, float x, float y) {
|
||||||
|
// To do: keep track of multitouch using the fingerID and a dictionary of some kind
|
||||||
|
// This isn't critical because the best we can do when we have that is to average them, like the
|
||||||
|
// 3DS does
|
||||||
|
|
||||||
|
int px, py;
|
||||||
|
TouchToPixelPos(x, y, &px, &py);
|
||||||
|
|
||||||
|
TouchPressed((unsigned)std::max(px, 0), (unsigned)std::max(py, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuWindow_SDL2::OnFingerMotion(SDL_FingerID finger, float x, float y) {
|
||||||
|
int px, py;
|
||||||
|
TouchToPixelPos(x, y, &px, &py);
|
||||||
|
|
||||||
|
TouchMoved((unsigned)std::max(px, 0), (unsigned)std::max(py, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuWindow_SDL2::OnFingerUp(SDL_FingerID finger) {
|
||||||
|
TouchReleased();
|
||||||
|
}
|
||||||
|
|
||||||
void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) {
|
void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) {
|
||||||
if (state == SDL_PRESSED) {
|
if (state == SDL_PRESSED) {
|
||||||
InputCommon::GetKeyboard()->PressKey(key);
|
InputCommon::GetKeyboard()->PressKey(key);
|
||||||
|
@ -178,11 +211,25 @@ void EmuWindow_SDL2::PollEvents() {
|
||||||
OnKeyEvent(static_cast<int>(event.key.keysym.scancode), event.key.state);
|
OnKeyEvent(static_cast<int>(event.key.keysym.scancode), event.key.state);
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEMOTION:
|
case SDL_MOUSEMOTION:
|
||||||
OnMouseMotion(event.motion.x, event.motion.y);
|
// ignore if it came from touch
|
||||||
|
if (event.button.which != SDL_TOUCH_MOUSEID)
|
||||||
|
OnMouseMotion(event.motion.x, event.motion.y);
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
case SDL_MOUSEBUTTONUP:
|
case SDL_MOUSEBUTTONUP:
|
||||||
OnMouseButton(event.button.button, event.button.state, event.button.x, event.button.y);
|
// ignore if it came from touch
|
||||||
|
if (event.button.which != SDL_TOUCH_MOUSEID)
|
||||||
|
OnMouseButton(event.button.button, event.button.state, event.button.x,
|
||||||
|
event.button.y);
|
||||||
|
break;
|
||||||
|
case SDL_FINGERDOWN:
|
||||||
|
OnFingerDown(event.tfinger.fingerId, event.tfinger.x, event.tfinger.y);
|
||||||
|
break;
|
||||||
|
case SDL_FINGERMOTION:
|
||||||
|
OnFingerMotion(event.tfinger.fingerId, event.tfinger.x, event.tfinger.y);
|
||||||
|
break;
|
||||||
|
case SDL_FINGERUP:
|
||||||
|
OnFingerUp(event.tfinger.fingerId);
|
||||||
break;
|
break;
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
is_open = false;
|
is_open = false;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <SDL_touch.h> // should it include all of <SDL>?
|
||||||
#include "core/frontend/emu_window.h"
|
#include "core/frontend/emu_window.h"
|
||||||
|
|
||||||
struct SDL_Window;
|
struct SDL_Window;
|
||||||
|
@ -40,6 +41,18 @@ private:
|
||||||
/// Called by PollEvents when a mouse button is pressed or released
|
/// Called by PollEvents when a mouse button is pressed or released
|
||||||
void OnMouseButton(u32 button, u8 state, s32 x, s32 y);
|
void OnMouseButton(u32 button, u8 state, s32 x, s32 y);
|
||||||
|
|
||||||
|
/// Translates pixel position (0..1) to pixel positions
|
||||||
|
void TouchToPixelPos(float touch_x, float touch_y, int* pixel_x, int* pixel_y);
|
||||||
|
|
||||||
|
/// Called by PollEvents when a finger starts touching the touchscreen
|
||||||
|
void OnFingerDown(SDL_FingerID finger, float x, float y);
|
||||||
|
|
||||||
|
/// Called by PollEvents when a finger moves while touching the touchscreen
|
||||||
|
void OnFingerMotion(SDL_FingerID finger, float x, float y);
|
||||||
|
|
||||||
|
/// Called by PollEvents when a finger stops touching the touchscreen
|
||||||
|
void OnFingerUp(SDL_FingerID finger);
|
||||||
|
|
||||||
/// Called by PollEvents when any event that may cause the window to be resized occurs
|
/// Called by PollEvents when any event that may cause the window to be resized occurs
|
||||||
void OnResize();
|
void OnResize();
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,7 @@ GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread)
|
||||||
std::string window_title = fmt::format("Citra {} | {}-{}", Common::g_build_name,
|
std::string window_title = fmt::format("Citra {} | {}-{}", Common::g_build_name,
|
||||||
Common::g_scm_branch, Common::g_scm_desc);
|
Common::g_scm_branch, Common::g_scm_desc);
|
||||||
setWindowTitle(QString::fromStdString(window_title));
|
setWindowTitle(QString::fromStdString(window_title));
|
||||||
|
setAttribute(Qt::WA_AcceptTouchEvents);
|
||||||
|
|
||||||
InputCommon::Init();
|
InputCommon::Init();
|
||||||
}
|
}
|
||||||
|
@ -210,6 +211,9 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::mousePressEvent(QMouseEvent* event) {
|
void GRenderWindow::mousePressEvent(QMouseEvent* event) {
|
||||||
|
if (event->source() == Qt::MouseEventSynthesizedBySystem)
|
||||||
|
return; // touch input is handled in touchBeginEvent
|
||||||
|
|
||||||
auto pos = event->pos();
|
auto pos = event->pos();
|
||||||
if (event->button() == Qt::LeftButton) {
|
if (event->button() == Qt::LeftButton) {
|
||||||
qreal pixelRatio = windowPixelRatio();
|
qreal pixelRatio = windowPixelRatio();
|
||||||
|
@ -221,6 +225,9 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
|
void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
|
||||||
|
if (event->source() == Qt::MouseEventSynthesizedBySystem)
|
||||||
|
return; // touch input is handled in touchUpdateEvent
|
||||||
|
|
||||||
auto pos = event->pos();
|
auto pos = event->pos();
|
||||||
qreal pixelRatio = windowPixelRatio();
|
qreal pixelRatio = windowPixelRatio();
|
||||||
this->TouchMoved(std::max(static_cast<unsigned>(pos.x() * pixelRatio), 0u),
|
this->TouchMoved(std::max(static_cast<unsigned>(pos.x() * pixelRatio), 0u),
|
||||||
|
@ -229,12 +236,71 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
|
void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
|
||||||
|
if (event->source() == Qt::MouseEventSynthesizedBySystem)
|
||||||
|
return; // touch input is handled in touchEndEvent
|
||||||
|
|
||||||
if (event->button() == Qt::LeftButton)
|
if (event->button() == Qt::LeftButton)
|
||||||
this->TouchReleased();
|
this->TouchReleased();
|
||||||
else if (event->button() == Qt::RightButton)
|
else if (event->button() == Qt::RightButton)
|
||||||
InputCommon::GetMotionEmu()->EndTilt();
|
InputCommon::GetMotionEmu()->EndTilt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GRenderWindow::touchBeginEvent(QTouchEvent* event) {
|
||||||
|
auto points = event->touchPoints();
|
||||||
|
auto tp = points.first(); // there should only be 1 point in TouchBegin
|
||||||
|
auto pos = tp.pos();
|
||||||
|
|
||||||
|
// Copied from mousePressEvent:
|
||||||
|
qreal pixelRatio = windowPixelRatio();
|
||||||
|
this->TouchPressed(static_cast<unsigned>(pos.x() * pixelRatio),
|
||||||
|
static_cast<unsigned>(pos.y() * pixelRatio));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GRenderWindow::touchUpdateEvent(QTouchEvent* event) {
|
||||||
|
qreal x = 0.0, y = 0.0;
|
||||||
|
int activePoints = 0;
|
||||||
|
auto points = event->touchPoints();
|
||||||
|
|
||||||
|
for (int i = 0; i < points.count(); i++) {
|
||||||
|
auto tp = points[i];
|
||||||
|
|
||||||
|
if (tp.state() & (Qt::TouchPointPressed | Qt::TouchPointMoved | Qt::TouchPointStationary)) {
|
||||||
|
activePoints++;
|
||||||
|
|
||||||
|
x += tp.pos().x();
|
||||||
|
y += tp.pos().y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x /= activePoints;
|
||||||
|
y /= activePoints;
|
||||||
|
|
||||||
|
// Copied from mouseMoveEvent:
|
||||||
|
qreal pixelRatio = windowPixelRatio();
|
||||||
|
this->TouchMoved(std::max(static_cast<unsigned>(x * pixelRatio), 0u),
|
||||||
|
std::max(static_cast<unsigned>(y * pixelRatio), 0u));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GRenderWindow::touchEndEvent(QTouchEvent* event) {
|
||||||
|
// Copied from mouseReleaseEvent:
|
||||||
|
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(static_cast<QTouchEvent*>(event));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QWidget::event(event);
|
||||||
|
}
|
||||||
|
|
||||||
void GRenderWindow::focusOutEvent(QFocusEvent* event) {
|
void GRenderWindow::focusOutEvent(QFocusEvent* event) {
|
||||||
QWidget::focusOutEvent(event);
|
QWidget::focusOutEvent(event);
|
||||||
InputCommon::GetKeyboard()->ReleaseAllKeys();
|
InputCommon::GetKeyboard()->ReleaseAllKeys();
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <QGLWidget>
|
#include <QGLWidget>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <QTouchEvent>
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/frontend/emu_window.h"
|
#include "core/frontend/emu_window.h"
|
||||||
|
@ -130,6 +131,12 @@ public:
|
||||||
void mouseMoveEvent(QMouseEvent* event) override;
|
void mouseMoveEvent(QMouseEvent* event) override;
|
||||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||||
|
|
||||||
|
void touchBeginEvent(QTouchEvent* event);
|
||||||
|
void touchUpdateEvent(QTouchEvent* event);
|
||||||
|
void touchEndEvent(QTouchEvent* event);
|
||||||
|
|
||||||
|
bool event(QEvent* event) override;
|
||||||
|
|
||||||
void focusOutEvent(QFocusEvent* event) override;
|
void focusOutEvent(QFocusEvent* event) override;
|
||||||
|
|
||||||
void OnClientAreaResized(unsigned width, unsigned height);
|
void OnClientAreaResized(unsigned width, unsigned height);
|
||||||
|
|
Loading…
Reference in a new issue