diff options
Diffstat (limited to 'src/yuzu/applets')
| -rw-r--r-- | src/yuzu/applets/software_keyboard.cpp | 152 | ||||
| -rw-r--r-- | src/yuzu/applets/software_keyboard.h | 79 | 
2 files changed, 231 insertions, 0 deletions
diff --git a/src/yuzu/applets/software_keyboard.cpp b/src/yuzu/applets/software_keyboard.cpp new file mode 100644 index 000000000..8a26fdff1 --- /dev/null +++ b/src/yuzu/applets/software_keyboard.cpp @@ -0,0 +1,152 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <algorithm> +#include <mutex> +#include <QDialogButtonBox> +#include <QFont> +#include <QLabel> +#include <QLineEdit> +#include <QVBoxLayout> +#include "core/hle/lock.h" +#include "yuzu/applets/software_keyboard.h" +#include "yuzu/main.h" + +QtSoftwareKeyboardValidator::QtSoftwareKeyboardValidator( +    Core::Frontend::SoftwareKeyboardParameters parameters) +    : parameters(std::move(parameters)) {} + +QValidator::State QtSoftwareKeyboardValidator::validate(QString& input, int& pos) const { +    if (input.size() > parameters.max_length) +        return Invalid; +    if (parameters.disable_space && input.contains(' ')) +        return Invalid; +    if (parameters.disable_address && input.contains('@')) +        return Invalid; +    if (parameters.disable_percent && input.contains('%')) +        return Invalid; +    if (parameters.disable_slash && (input.contains('/') || input.contains('\\'))) +        return Invalid; +    if (parameters.disable_number && +        std::any_of(input.begin(), input.end(), [](QChar c) { return c.isDigit(); })) { +        return Invalid; +    } + +    if (parameters.disable_download_code && +        std::any_of(input.begin(), input.end(), [](QChar c) { return c == 'O' || c == 'I'; })) { +        return Invalid; +    } + +    return Acceptable; +} + +QtSoftwareKeyboardDialog::QtSoftwareKeyboardDialog( +    QWidget* parent, Core::Frontend::SoftwareKeyboardParameters parameters_) +    : QDialog(parent), parameters(std::move(parameters_)) { +    layout = new QVBoxLayout; + +    header_label = new QLabel(QString::fromStdU16String(parameters.header_text)); +    header_label->setFont({header_label->font().family(), 11, QFont::Bold}); +    if (header_label->text().isEmpty()) +        header_label->setText(tr("Enter text:")); + +    sub_label = new QLabel(QString::fromStdU16String(parameters.sub_text)); +    sub_label->setFont({sub_label->font().family(), sub_label->font().pointSize(), +                        sub_label->font().weight(), true}); +    sub_label->setHidden(parameters.sub_text.empty()); + +    guide_label = new QLabel(QString::fromStdU16String(parameters.guide_text)); +    guide_label->setHidden(parameters.guide_text.empty()); + +    length_label = new QLabel(QStringLiteral("0/%1").arg(parameters.max_length)); +    length_label->setAlignment(Qt::AlignRight); +    length_label->setFont({length_label->font().family(), 8}); + +    line_edit = new QLineEdit; +    line_edit->setValidator(new QtSoftwareKeyboardValidator(parameters)); +    line_edit->setMaxLength(static_cast<int>(parameters.max_length)); +    line_edit->setText(QString::fromStdU16String(parameters.initial_text)); +    line_edit->setCursorPosition( +        parameters.cursor_at_beginning ? 0 : static_cast<int>(parameters.initial_text.size())); +    line_edit->setEchoMode(parameters.password ? QLineEdit::Password : QLineEdit::Normal); + +    connect(line_edit, &QLineEdit::textChanged, this, [this](const QString& text) { +        length_label->setText(QStringLiteral("%1/%2").arg(text.size()).arg(parameters.max_length)); +    }); + +    buttons = new QDialogButtonBox; +    buttons->addButton(tr("Cancel"), QDialogButtonBox::RejectRole); +    buttons->addButton(parameters.submit_text.empty() +                           ? tr("OK") +                           : QString::fromStdU16String(parameters.submit_text), +                       QDialogButtonBox::AcceptRole); + +    connect(buttons, &QDialogButtonBox::accepted, this, &QtSoftwareKeyboardDialog::accept); +    connect(buttons, &QDialogButtonBox::rejected, this, &QtSoftwareKeyboardDialog::reject); +    layout->addWidget(header_label); +    layout->addWidget(sub_label); +    layout->addWidget(guide_label); +    layout->addWidget(length_label); +    layout->addWidget(line_edit); +    layout->addWidget(buttons); +    setLayout(layout); +    setWindowTitle(tr("Software Keyboard")); +} + +QtSoftwareKeyboardDialog::~QtSoftwareKeyboardDialog() = default; + +void QtSoftwareKeyboardDialog::accept() { +    ok = true; +    text = line_edit->text().toStdU16String(); +    QDialog::accept(); +} + +void QtSoftwareKeyboardDialog::reject() { +    ok = false; +    text.clear(); +    QDialog::reject(); +} + +std::u16string QtSoftwareKeyboardDialog::GetText() const { +    return text; +} + +bool QtSoftwareKeyboardDialog::GetStatus() const { +    return ok; +} + +QtSoftwareKeyboard::QtSoftwareKeyboard(GMainWindow& main_window) { +    connect(this, &QtSoftwareKeyboard::MainWindowGetText, &main_window, +            &GMainWindow::SoftwareKeyboardGetText, Qt::QueuedConnection); +    connect(this, &QtSoftwareKeyboard::MainWindowTextCheckDialog, &main_window, +            &GMainWindow::SoftwareKeyboardInvokeCheckDialog, Qt::BlockingQueuedConnection); +    connect(&main_window, &GMainWindow::SoftwareKeyboardFinishedText, this, +            &QtSoftwareKeyboard::MainWindowFinishedText, Qt::QueuedConnection); +} + +QtSoftwareKeyboard::~QtSoftwareKeyboard() = default; + +void QtSoftwareKeyboard::RequestText(std::function<void(std::optional<std::u16string>)> out, +                                     Core::Frontend::SoftwareKeyboardParameters parameters) const { +    text_output = std::move(out); +    emit MainWindowGetText(parameters); +} + +void QtSoftwareKeyboard::SendTextCheckDialog(std::u16string error_message, +                                             std::function<void()> finished_check) const { +    this->finished_check = std::move(finished_check); +    emit MainWindowTextCheckDialog(error_message); +} + +void QtSoftwareKeyboard::MainWindowFinishedText(std::optional<std::u16string> text) { +    // Acquire the HLE mutex +    std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock); +    text_output(text); +} + +void QtSoftwareKeyboard::MainWindowFinishedCheckDialog() { +    // Acquire the HLE mutex +    std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock); +    finished_check(); +} diff --git a/src/yuzu/applets/software_keyboard.h b/src/yuzu/applets/software_keyboard.h new file mode 100644 index 000000000..c63720ba4 --- /dev/null +++ b/src/yuzu/applets/software_keyboard.h @@ -0,0 +1,79 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <QDialog> +#include <QValidator> +#include "common/assert.h" +#include "core/frontend/applets/software_keyboard.h" + +class GMainWindow; +class QDialogButtonBox; +class QLabel; +class QLineEdit; +class QVBoxLayout; +class QtSoftwareKeyboard; + +class QtSoftwareKeyboardValidator final : public QValidator { +public: +    explicit QtSoftwareKeyboardValidator(Core::Frontend::SoftwareKeyboardParameters parameters); +    State validate(QString& input, int& pos) const override; + +private: +    Core::Frontend::SoftwareKeyboardParameters parameters; +}; + +class QtSoftwareKeyboardDialog final : public QDialog { +    Q_OBJECT + +public: +    QtSoftwareKeyboardDialog(QWidget* parent, +                             Core::Frontend::SoftwareKeyboardParameters parameters); +    ~QtSoftwareKeyboardDialog() override; + +    void accept() override; +    void reject() override; + +    std::u16string GetText() const; +    bool GetStatus() const; + +private: +    bool ok = false; +    std::u16string text; + +    QDialogButtonBox* buttons; +    QLabel* header_label; +    QLabel* sub_label; +    QLabel* guide_label; +    QLabel* length_label; +    QLineEdit* line_edit; +    QVBoxLayout* layout; + +    Core::Frontend::SoftwareKeyboardParameters parameters; +}; + +class QtSoftwareKeyboard final : public QObject, public Core::Frontend::SoftwareKeyboardApplet { +    Q_OBJECT + +public: +    explicit QtSoftwareKeyboard(GMainWindow& parent); +    ~QtSoftwareKeyboard() override; + +    void RequestText(std::function<void(std::optional<std::u16string>)> out, +                     Core::Frontend::SoftwareKeyboardParameters parameters) const override; +    void SendTextCheckDialog(std::u16string error_message, +                             std::function<void()> finished_check) const override; + +signals: +    void MainWindowGetText(Core::Frontend::SoftwareKeyboardParameters parameters) const; +    void MainWindowTextCheckDialog(std::u16string error_message) const; + +private: +    void MainWindowFinishedText(std::optional<std::u16string> text); +    void MainWindowFinishedCheckDialog(); + +    mutable std::function<void(std::optional<std::u16string>)> text_output; +    mutable std::function<void()> finished_check; +};  | 
