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.
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QKeyEvent>
|
||||
#include <QOffscreenSurface>
|
||||
|
@ -14,6 +15,7 @@
|
|||
#include <QWindow>
|
||||
#include <fmt/format.h>
|
||||
#include "citra_qt/bootmanager.h"
|
||||
#include "citra_qt/main.h"
|
||||
#include "common/microprofile.h"
|
||||
#include "common/scm_rev.h"
|
||||
#include "core/3ds.h"
|
||||
|
@ -31,6 +33,15 @@ EmuThread::EmuThread(Frontend::GraphicsContext& core_context) : core_context(cor
|
|||
|
||||
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() {
|
||||
MicroProfileOnThreadCreate("EmuThread");
|
||||
Frontend::ScopeAcquireContext scope(core_context);
|
||||
|
@ -138,6 +149,15 @@ bool OpenGLWindow::event(QEvent* event) {
|
|||
case QEvent::InputMethodQuery:
|
||||
case QEvent::TouchCancel:
|
||||
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:
|
||||
return QWindow::event(event);
|
||||
}
|
||||
|
@ -298,15 +318,19 @@ void GRenderWindow::TouchEndEvent() {
|
|||
}
|
||||
|
||||
bool GRenderWindow::event(QEvent* event) {
|
||||
if (event->type() == QEvent::TouchBegin) {
|
||||
switch (event->type()) {
|
||||
case QEvent::TouchBegin:
|
||||
TouchBeginEvent(static_cast<QTouchEvent*>(event));
|
||||
return true;
|
||||
} else if (event->type() == QEvent::TouchUpdate) {
|
||||
case QEvent::TouchUpdate:
|
||||
TouchUpdateEvent(static_cast<QTouchEvent*>(event));
|
||||
return true;
|
||||
} else if (event->type() == QEvent::TouchEnd || event->type() == QEvent::TouchCancel) {
|
||||
case QEvent::TouchEnd:
|
||||
case QEvent::TouchCancel:
|
||||
TouchEndEvent();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
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++) {
|
||||
QStandardItem* action = parent->child(key_column_id, 0);
|
||||
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())
|
||||
continue;
|
||||
for (auto& [action_name, hotkey] : sub_actions) {
|
||||
for (auto & [action_name, hotkey] : sub_actions) {
|
||||
if (action_name != action->text())
|
||||
continue;
|
||||
hotkey.keyseq = QKeySequence(keyseq->text());
|
||||
|
|
|
@ -127,11 +127,10 @@ void ConfigureWeb::OnLoginChanged() {
|
|||
void ConfigureWeb::VerifyLogin() {
|
||||
ui->button_verify_login->setDisabled(true);
|
||||
ui->button_verify_login->setText(tr("Verifying..."));
|
||||
verify_watcher.setFuture(QtConcurrent::run(
|
||||
[username = UsernameFromDisplayToken(ui->edit_token->text().toStdString()),
|
||||
token = TokenFromDisplayToken(ui->edit_token->text().toStdString())] {
|
||||
return Core::VerifyLogin(username, token);
|
||||
}));
|
||||
verify_watcher.setFuture(QtConcurrent::run([
|
||||
username = UsernameFromDisplayToken(ui->edit_token->text().toStdString()),
|
||||
token = TokenFromDisplayToken(ui->edit_token->text().toStdString())
|
||||
] { return Core::VerifyLogin(username, token); }));
|
||||
}
|
||||
|
||||
void ConfigureWeb::OnLoginVerified() {
|
||||
|
|
|
@ -1869,14 +1869,33 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
|
|||
QWidget::closeEvent(event);
|
||||
}
|
||||
|
||||
static bool IsSingleFileDropEvent(QDropEvent* event) {
|
||||
const QMimeData* mimeData = event->mimeData();
|
||||
return mimeData->hasUrls() && mimeData->urls().length() == 1;
|
||||
static bool IsSingleFileDropEvent(const QMimeData* mime) {
|
||||
return mime->hasUrls() && mime->urls().length() == 1;
|
||||
}
|
||||
|
||||
void GMainWindow::dropEvent(QDropEvent* event) {
|
||||
if (!IsSingleFileDropEvent(event)) {
|
||||
return;
|
||||
static const std::array<std::string, 8> AcceptedExtensions = {"cci", "3ds", "cxi", "bin",
|
||||
"3dsx", "app", "elf", "axf"};
|
||||
|
||||
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();
|
||||
|
@ -1891,16 +1910,19 @@ void GMainWindow::dropEvent(QDropEvent* event) {
|
|||
BootGame(filename);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GMainWindow::dropEvent(QDropEvent* event) {
|
||||
DropAction(event);
|
||||
}
|
||||
|
||||
void GMainWindow::dragEnterEvent(QDragEnterEvent* event) {
|
||||
if (IsSingleFileDropEvent(event)) {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
AcceptDropEvent(event);
|
||||
}
|
||||
|
||||
void GMainWindow::dragMoveEvent(QDragMoveEvent* event) {
|
||||
event->acceptProposedAction();
|
||||
AcceptDropEvent(event);
|
||||
}
|
||||
|
||||
bool GMainWindow::ConfirmChangeGame() {
|
||||
|
|
|
@ -41,6 +41,7 @@ class QProgressBar;
|
|||
class RegistersWidget;
|
||||
class Updater;
|
||||
class WaitTreeWidget;
|
||||
|
||||
namespace DiscordRPC {
|
||||
class DiscordInterface;
|
||||
}
|
||||
|
@ -69,8 +70,12 @@ public:
|
|||
GameList* game_list;
|
||||
std::unique_ptr<DiscordRPC::DiscordInterface> discord_rpc;
|
||||
|
||||
bool DropAction(QDropEvent* event);
|
||||
void AcceptDropEvent(QDropEvent* event);
|
||||
|
||||
public slots:
|
||||
void OnAppFocusStateChanged(Qt::ApplicationState state);
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
|
@ -78,8 +83,8 @@ signals:
|
|||
* about to start. At this time, the core system emulation has been initialized, and all
|
||||
* emulation handles and memory should be valid.
|
||||
*
|
||||
* @param emu_thread Pointer to the newly created EmuThread (to be used by widgets that need to
|
||||
* access/change emulation state).
|
||||
* @param emu_thread Pointer to the newly created EmuThread (to be used by widgets that need
|
||||
* to access/change emulation state).
|
||||
*/
|
||||
void EmulationStarting(EmuThread* emu_thread);
|
||||
|
||||
|
|
Loading…
Reference in a new issue