mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #3850 from zhaowenlan1779/swkbd
applets/swkbd: Software Keyboard Implementation
This commit is contained in:
		
						commit
						bf6da61da5
					
				
					 16 changed files with 774 additions and 34 deletions
				
			
		|  | @ -7,6 +7,8 @@ add_executable(citra-qt | |||
|     Info.plist | ||||
|     aboutdialog.cpp | ||||
|     aboutdialog.h | ||||
|     applets/swkbd.cpp | ||||
|     applets/swkbd.h | ||||
|     bootmanager.cpp | ||||
|     bootmanager.h | ||||
|     camera/camera_util.cpp | ||||
|  |  | |||
							
								
								
									
										129
									
								
								src/citra_qt/applets/swkbd.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								src/citra_qt/applets/swkbd.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,129 @@ | |||
| // Copyright 2018 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <QDialogButtonBox> | ||||
| #include <QLabel> | ||||
| #include <QLineEdit> | ||||
| #include <QMessageBox> | ||||
| #include <QString> | ||||
| #include <QVBoxLayout> | ||||
| #include "citra_qt/applets/swkbd.h" | ||||
| 
 | ||||
| QtKeyboardValidator::QtKeyboardValidator(QtKeyboard* keyboard_) : keyboard(keyboard_) {} | ||||
| 
 | ||||
| QtKeyboardValidator::State QtKeyboardValidator::validate(QString& input, int& pos) const { | ||||
|     if (keyboard->ValidateFilters(input.toStdString()) == Frontend::ValidationError::None) { | ||||
|         if (input.size() > keyboard->config.max_text_length) | ||||
|             return State::Invalid; | ||||
|         return State::Acceptable; | ||||
|     } else { | ||||
|         return State::Invalid; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| QtKeyboardDialog::QtKeyboardDialog(QWidget* parent, QtKeyboard* keyboard_) | ||||
|     : QDialog(parent), keyboard(keyboard_) { | ||||
|     using namespace Frontend; | ||||
|     KeyboardConfig config = keyboard->config; | ||||
|     layout = new QVBoxLayout; | ||||
|     label = new QLabel(QString::fromStdString(config.hint_text)); | ||||
|     line_edit = new QLineEdit; | ||||
|     line_edit->setValidator(new QtKeyboardValidator(keyboard)); | ||||
|     buttons = new QDialogButtonBox; | ||||
|     // Initialize buttons
 | ||||
|     switch (config.button_config) { | ||||
|     case ButtonConfig::Triple: | ||||
|         buttons->addButton(config.has_custom_button_text | ||||
|                                ? QString::fromStdString(config.button_text[2]) | ||||
|                                : tr(BUTTON_OKAY), | ||||
|                            QDialogButtonBox::ButtonRole::AcceptRole); | ||||
|         buttons->addButton(config.has_custom_button_text | ||||
|                                ? QString::fromStdString(config.button_text[1]) | ||||
|                                : tr(BUTTON_FORGOT), | ||||
|                            QDialogButtonBox::ButtonRole::HelpRole); | ||||
|         buttons->addButton(config.has_custom_button_text | ||||
|                                ? QString::fromStdString(config.button_text[0]) | ||||
|                                : tr(BUTTON_CANCEL), | ||||
|                            QDialogButtonBox::ButtonRole::RejectRole); | ||||
|         break; | ||||
|     case ButtonConfig::Dual: | ||||
|         buttons->addButton(config.has_custom_button_text | ||||
|                                ? QString::fromStdString(config.button_text[1]) | ||||
|                                : tr(BUTTON_OKAY), | ||||
|                            QDialogButtonBox::ButtonRole::AcceptRole); | ||||
|         buttons->addButton(config.has_custom_button_text | ||||
|                                ? QString::fromStdString(config.button_text[0]) | ||||
|                                : tr(BUTTON_CANCEL), | ||||
|                            QDialogButtonBox::ButtonRole::RejectRole); | ||||
|         break; | ||||
|     case ButtonConfig::Single: | ||||
|         buttons->addButton(config.has_custom_button_text | ||||
|                                ? QString::fromStdString(config.button_text[0]) | ||||
|                                : tr(BUTTON_OKAY), | ||||
|                            QDialogButtonBox::ButtonRole::AcceptRole); | ||||
|         break; | ||||
|     case ButtonConfig::None: | ||||
|         break; | ||||
|     } | ||||
|     connect(buttons, &QDialogButtonBox::accepted, this, [=] { Submit(); }); | ||||
|     connect(buttons, &QDialogButtonBox::rejected, this, [=] { | ||||
|         button = QtKeyboard::cancel_id; | ||||
|         accept(); | ||||
|     }); | ||||
|     connect(buttons, &QDialogButtonBox::helpRequested, this, [=] { | ||||
|         button = QtKeyboard::forgot_id; | ||||
|         accept(); | ||||
|     }); | ||||
|     layout->addWidget(label); | ||||
|     layout->addWidget(line_edit); | ||||
|     layout->addWidget(buttons); | ||||
|     setLayout(layout); | ||||
| } | ||||
| 
 | ||||
| void QtKeyboardDialog::Submit() { | ||||
|     auto error = keyboard->ValidateInput(line_edit->text().toStdString()); | ||||
|     if (error != Frontend::ValidationError::None) { | ||||
|         HandleValidationError(error); | ||||
|     } else { | ||||
|         button = keyboard->ok_id; | ||||
|         text = line_edit->text(); | ||||
|         accept(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void QtKeyboardDialog::HandleValidationError(Frontend::ValidationError error) { | ||||
|     using namespace Frontend; | ||||
|     const std::unordered_map<ValidationError, QString> VALIDATION_ERROR_MESSAGES = { | ||||
|         {ValidationError::FixedLengthRequired, | ||||
|          tr("Text length is not correct (should be %1 characters)") | ||||
|              .arg(keyboard->config.max_text_length)}, | ||||
|         {ValidationError::MaxLengthExceeded, | ||||
|          tr("Text is too long (should be no more than %1 characters)") | ||||
|              .arg(keyboard->config.max_text_length)}, | ||||
|         {ValidationError::BlankInputNotAllowed, tr("Blank input is not allowed")}, | ||||
|         {ValidationError::EmptyInputNotAllowed, tr("Empty input is not allowed")}, | ||||
|     }; | ||||
|     QMessageBox::critical(this, tr("Validation error"), VALIDATION_ERROR_MESSAGES.at(error)); | ||||
| } | ||||
| 
 | ||||
| QtKeyboard::QtKeyboard(QWidget& parent_) : parent(parent_) {} | ||||
| 
 | ||||
| void QtKeyboard::Setup(const Frontend::KeyboardConfig* config) { | ||||
|     SoftwareKeyboard::Setup(config); | ||||
|     if (this->config.button_config != Frontend::ButtonConfig::None) { | ||||
|         ok_id = static_cast<u8>(this->config.button_config); | ||||
|     } | ||||
|     QMetaObject::invokeMethod(this, "OpenInputDialog", Qt::BlockingQueuedConnection); | ||||
| } | ||||
| 
 | ||||
| void QtKeyboard::OpenInputDialog() { | ||||
|     QtKeyboardDialog dialog(&parent, this); | ||||
|     dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | | ||||
|                           Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); | ||||
|     dialog.setWindowModality(Qt::WindowModal); | ||||
|     dialog.exec(); | ||||
|     LOG_INFO(Frontend, "SWKBD input dialog finished, text={}, button={}", dialog.text.toStdString(), | ||||
|              dialog.button); | ||||
|     Finalize(dialog.text.toStdString(), dialog.button); | ||||
| } | ||||
							
								
								
									
										65
									
								
								src/citra_qt/applets/swkbd.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/citra_qt/applets/swkbd.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | |||
| // Copyright 2018 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <QDialog> | ||||
| #include <QValidator> | ||||
| #include "core/frontend/applets/swkbd.h" | ||||
| 
 | ||||
| class QDialogButtonBox; | ||||
| class QLabel; | ||||
| class QLineEdit; | ||||
| class QVBoxLayout; | ||||
| class QtKeyboard; | ||||
| 
 | ||||
| class QtKeyboardValidator final : public QValidator { | ||||
| public: | ||||
|     explicit QtKeyboardValidator(QtKeyboard* keyboard); | ||||
|     State validate(QString& input, int& pos) const override; | ||||
| 
 | ||||
| private: | ||||
|     QtKeyboard* keyboard; | ||||
| }; | ||||
| 
 | ||||
| class QtKeyboardDialog final : public QDialog { | ||||
|     Q_OBJECT | ||||
| 
 | ||||
| public: | ||||
|     QtKeyboardDialog(QWidget* parent, QtKeyboard* keyboard); | ||||
|     void Submit(); | ||||
| 
 | ||||
| private: | ||||
|     void HandleValidationError(Frontend::ValidationError error); | ||||
|     QDialogButtonBox* buttons; | ||||
|     QLabel* label; | ||||
|     QLineEdit* line_edit; | ||||
|     QVBoxLayout* layout; | ||||
|     QtKeyboard* keyboard; | ||||
|     QString text; | ||||
|     u8 button; | ||||
| 
 | ||||
|     friend class QtKeyboard; | ||||
| }; | ||||
| 
 | ||||
| class QtKeyboard final : public QObject, public Frontend::SoftwareKeyboard { | ||||
|     Q_OBJECT | ||||
| 
 | ||||
| public: | ||||
|     explicit QtKeyboard(QWidget& parent); | ||||
|     void Setup(const Frontend::KeyboardConfig* config) override; | ||||
| 
 | ||||
| private: | ||||
|     Q_INVOKABLE void OpenInputDialog(); | ||||
| 
 | ||||
|     /// Index of the buttons
 | ||||
|     u8 ok_id; | ||||
|     static constexpr u8 forgot_id = 1; | ||||
|     static constexpr u8 cancel_id = 0; | ||||
| 
 | ||||
|     QWidget& parent; | ||||
| 
 | ||||
|     friend class QtKeyboardDialog; | ||||
|     friend class QtKeyboardValidator; | ||||
| }; | ||||
|  | @ -16,6 +16,7 @@ | |||
| #include <QtGui> | ||||
| #include <QtWidgets> | ||||
| #include "citra_qt/aboutdialog.h" | ||||
| #include "citra_qt/applets/swkbd.h" | ||||
| #include "citra_qt/bootmanager.h" | ||||
| #include "citra_qt/camera/qt_multimedia_camera.h" | ||||
| #include "citra_qt/camera/still_image_camera.h" | ||||
|  | @ -50,6 +51,7 @@ | |||
| #include "common/string_util.h" | ||||
| #include "core/core.h" | ||||
| #include "core/file_sys/archive_source_sd_savedata.h" | ||||
| #include "core/frontend/applets/default_applets.h" | ||||
| #include "core/gdbstub/gdbstub.h" | ||||
| #include "core/hle/service/fs/archive.h" | ||||
| #include "core/loader/loader.h" | ||||
|  | @ -1468,6 +1470,10 @@ int main(int argc, char* argv[]) { | |||
|     Camera::RegisterFactory("qt", std::make_unique<Camera::QtMultimediaCameraFactory>()); | ||||
|     Camera::QtMultimediaCameraHandler::Init(); | ||||
| 
 | ||||
|     // Register frontend applets
 | ||||
|     Frontend::RegisterDefaultApplets(); | ||||
|     Frontend::RegisterSoftwareKeyboard(std::make_shared<QtKeyboard>(main_window)); | ||||
| 
 | ||||
|     main_window.show(); | ||||
|     return app.exec(); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue