Fix drag and drop
This commit is contained in:
parent
86f203e6e8
commit
782eae7f65
5 changed files with 72 additions and 22 deletions
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QDragEnterEvent>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QOffscreenSurface>
|
#include <QOffscreenSurface>
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "citra_qt/bootmanager.h"
|
#include "citra_qt/bootmanager.h"
|
||||||
|
#include "citra_qt/main.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "core/3ds.h"
|
#include "core/3ds.h"
|
||||||
|
@ -31,6 +33,15 @@ EmuThread::EmuThread(Frontend::GraphicsContext& core_context) : core_context(cor
|
||||||
|
|
||||||
EmuThread::~EmuThread() = default;
|
EmuThread::~EmuThread() = default;
|
||||||
|
|
||||||
|
static GMainWindow* GetMainWindow() {
|
||||||
|
for (QWidget* w : qApp->topLevelWidgets()) {
|
||||||
|
if (GMainWindow* main = qobject_cast<GMainWindow*>(w)) {
|
||||||
|
return main;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void EmuThread::run() {
|
void EmuThread::run() {
|
||||||
MicroProfileOnThreadCreate("EmuThread");
|
MicroProfileOnThreadCreate("EmuThread");
|
||||||
Frontend::ScopeAcquireContext scope(core_context);
|
Frontend::ScopeAcquireContext scope(core_context);
|
||||||
|
@ -138,6 +149,15 @@ bool OpenGLWindow::event(QEvent* event) {
|
||||||
case QEvent::InputMethodQuery:
|
case QEvent::InputMethodQuery:
|
||||||
case QEvent::TouchCancel:
|
case QEvent::TouchCancel:
|
||||||
return QCoreApplication::sendEvent(event_handler, event);
|
return QCoreApplication::sendEvent(event_handler, event);
|
||||||
|
case QEvent::Drop:
|
||||||
|
GetMainWindow()->DropAction(static_cast<QDropEvent*>(event));
|
||||||
|
return true;
|
||||||
|
case QEvent::DragResponse:
|
||||||
|
case QEvent::DragEnter:
|
||||||
|
case QEvent::DragLeave:
|
||||||
|
case QEvent::DragMove:
|
||||||
|
GetMainWindow()->AcceptDropEvent(static_cast<QDropEvent*>(event));
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
return QWindow::event(event);
|
return QWindow::event(event);
|
||||||
}
|
}
|
||||||
|
@ -298,15 +318,19 @@ void GRenderWindow::TouchEndEvent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GRenderWindow::event(QEvent* event) {
|
bool GRenderWindow::event(QEvent* event) {
|
||||||
if (event->type() == QEvent::TouchBegin) {
|
switch (event->type()) {
|
||||||
|
case QEvent::TouchBegin:
|
||||||
TouchBeginEvent(static_cast<QTouchEvent*>(event));
|
TouchBeginEvent(static_cast<QTouchEvent*>(event));
|
||||||
return true;
|
return true;
|
||||||
} else if (event->type() == QEvent::TouchUpdate) {
|
case QEvent::TouchUpdate:
|
||||||
TouchUpdateEvent(static_cast<QTouchEvent*>(event));
|
TouchUpdateEvent(static_cast<QTouchEvent*>(event));
|
||||||
return true;
|
return true;
|
||||||
} else if (event->type() == QEvent::TouchEnd || event->type() == QEvent::TouchCancel) {
|
case QEvent::TouchEnd:
|
||||||
|
case QEvent::TouchCancel:
|
||||||
TouchEndEvent();
|
TouchEndEvent();
|
||||||
return true;
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QWidget::event(event);
|
return QWidget::event(event);
|
||||||
|
|
|
@ -105,10 +105,10 @@ void ConfigureHotkeys::ApplyConfiguration(HotkeyRegistry& registry) {
|
||||||
for (int key_column_id = 0; key_column_id < parent->rowCount(); key_column_id++) {
|
for (int key_column_id = 0; key_column_id < parent->rowCount(); key_column_id++) {
|
||||||
QStandardItem* action = parent->child(key_column_id, 0);
|
QStandardItem* action = parent->child(key_column_id, 0);
|
||||||
QStandardItem* keyseq = parent->child(key_column_id, 1);
|
QStandardItem* keyseq = parent->child(key_column_id, 1);
|
||||||
for (auto& [group, sub_actions] : registry.hotkey_groups) {
|
for (auto & [group, sub_actions] : registry.hotkey_groups) {
|
||||||
if (group != parent->text())
|
if (group != parent->text())
|
||||||
continue;
|
continue;
|
||||||
for (auto& [action_name, hotkey] : sub_actions) {
|
for (auto & [action_name, hotkey] : sub_actions) {
|
||||||
if (action_name != action->text())
|
if (action_name != action->text())
|
||||||
continue;
|
continue;
|
||||||
hotkey.keyseq = QKeySequence(keyseq->text());
|
hotkey.keyseq = QKeySequence(keyseq->text());
|
||||||
|
|
|
@ -127,11 +127,10 @@ void ConfigureWeb::OnLoginChanged() {
|
||||||
void ConfigureWeb::VerifyLogin() {
|
void ConfigureWeb::VerifyLogin() {
|
||||||
ui->button_verify_login->setDisabled(true);
|
ui->button_verify_login->setDisabled(true);
|
||||||
ui->button_verify_login->setText(tr("Verifying..."));
|
ui->button_verify_login->setText(tr("Verifying..."));
|
||||||
verify_watcher.setFuture(QtConcurrent::run(
|
verify_watcher.setFuture(QtConcurrent::run([
|
||||||
[username = UsernameFromDisplayToken(ui->edit_token->text().toStdString()),
|
username = UsernameFromDisplayToken(ui->edit_token->text().toStdString()),
|
||||||
token = TokenFromDisplayToken(ui->edit_token->text().toStdString())] {
|
token = TokenFromDisplayToken(ui->edit_token->text().toStdString())
|
||||||
return Core::VerifyLogin(username, token);
|
] { return Core::VerifyLogin(username, token); }));
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureWeb::OnLoginVerified() {
|
void ConfigureWeb::OnLoginVerified() {
|
||||||
|
|
|
@ -1869,14 +1869,33 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
|
||||||
QWidget::closeEvent(event);
|
QWidget::closeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsSingleFileDropEvent(QDropEvent* event) {
|
static bool IsSingleFileDropEvent(const QMimeData* mime) {
|
||||||
const QMimeData* mimeData = event->mimeData();
|
return mime->hasUrls() && mime->urls().length() == 1;
|
||||||
return mimeData->hasUrls() && mimeData->urls().length() == 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::dropEvent(QDropEvent* event) {
|
static const std::array<std::string, 8> AcceptedExtensions = {"cci", "3ds", "cxi", "bin",
|
||||||
if (!IsSingleFileDropEvent(event)) {
|
"3dsx", "app", "elf", "axf"};
|
||||||
return;
|
|
||||||
|
static bool IsCorrectFileExtension(const QMimeData* mime) {
|
||||||
|
const QString& filename = mime->urls().at(0).toLocalFile();
|
||||||
|
return std::find(AcceptedExtensions.begin(), AcceptedExtensions.end(),
|
||||||
|
QFileInfo(filename).suffix().toStdString()) != AcceptedExtensions.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsAcceptableDropEvent(QDropEvent* event) {
|
||||||
|
return IsSingleFileDropEvent(event->mimeData()) && IsCorrectFileExtension(event->mimeData());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GMainWindow::AcceptDropEvent(QDropEvent* event) {
|
||||||
|
if (IsAcceptableDropEvent(event)) {
|
||||||
|
event->setDropAction(Qt::DropAction::LinkAction);
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GMainWindow::DropAction(QDropEvent* event) {
|
||||||
|
if (!IsAcceptableDropEvent(event)) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QMimeData* mime_data = event->mimeData();
|
const QMimeData* mime_data = event->mimeData();
|
||||||
|
@ -1891,16 +1910,19 @@ void GMainWindow::dropEvent(QDropEvent* event) {
|
||||||
BootGame(filename);
|
BootGame(filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GMainWindow::dropEvent(QDropEvent* event) {
|
||||||
|
DropAction(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::dragEnterEvent(QDragEnterEvent* event) {
|
void GMainWindow::dragEnterEvent(QDragEnterEvent* event) {
|
||||||
if (IsSingleFileDropEvent(event)) {
|
AcceptDropEvent(event);
|
||||||
event->acceptProposedAction();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::dragMoveEvent(QDragMoveEvent* event) {
|
void GMainWindow::dragMoveEvent(QDragMoveEvent* event) {
|
||||||
event->acceptProposedAction();
|
AcceptDropEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GMainWindow::ConfirmChangeGame() {
|
bool GMainWindow::ConfirmChangeGame() {
|
||||||
|
|
|
@ -41,6 +41,7 @@ class QProgressBar;
|
||||||
class RegistersWidget;
|
class RegistersWidget;
|
||||||
class Updater;
|
class Updater;
|
||||||
class WaitTreeWidget;
|
class WaitTreeWidget;
|
||||||
|
|
||||||
namespace DiscordRPC {
|
namespace DiscordRPC {
|
||||||
class DiscordInterface;
|
class DiscordInterface;
|
||||||
}
|
}
|
||||||
|
@ -69,8 +70,12 @@ public:
|
||||||
GameList* game_list;
|
GameList* game_list;
|
||||||
std::unique_ptr<DiscordRPC::DiscordInterface> discord_rpc;
|
std::unique_ptr<DiscordRPC::DiscordInterface> discord_rpc;
|
||||||
|
|
||||||
|
bool DropAction(QDropEvent* event);
|
||||||
|
void AcceptDropEvent(QDropEvent* event);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void OnAppFocusStateChanged(Qt::ApplicationState state);
|
void OnAppFocusStateChanged(Qt::ApplicationState state);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,8 +83,8 @@ signals:
|
||||||
* about to start. At this time, the core system emulation has been initialized, and all
|
* about to start. At this time, the core system emulation has been initialized, and all
|
||||||
* emulation handles and memory should be valid.
|
* emulation handles and memory should be valid.
|
||||||
*
|
*
|
||||||
* @param emu_thread Pointer to the newly created EmuThread (to be used by widgets that need to
|
* @param emu_thread Pointer to the newly created EmuThread (to be used by widgets that need
|
||||||
* access/change emulation state).
|
* to access/change emulation state).
|
||||||
*/
|
*/
|
||||||
void EmulationStarting(EmuThread* emu_thread);
|
void EmulationStarting(EmuThread* emu_thread);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue