mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue