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.
 | ||||
| 
 | ||||
| #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…
	
	Add table
		Add a link
		
	
		Reference in a new issue