| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- // Copyright 2021 yuzu Emulator Project
- // Licensed under GPLv2 or any later version
- // Refer to the license.txt file included.
- #pragma once
- #include <array>
- #include <atomic>
- #include <memory>
- #include <thread>
- #include <QDialog>
- #include <QValidator>
- #include "core/frontend/applets/software_keyboard.h"
- enum class HIDButton : u8;
- class InputInterpreter;
- namespace Core {
- class System;
- }
- namespace Ui {
- class QtSoftwareKeyboardDialog;
- }
- class GMainWindow;
- class QtSoftwareKeyboardDialog final : public QDialog {
- Q_OBJECT
- public:
- QtSoftwareKeyboardDialog(QWidget* parent, Core::System& system_, bool is_inline_,
- Core::Frontend::KeyboardInitializeParameters initialize_parameters_);
- ~QtSoftwareKeyboardDialog() override;
- void ShowNormalKeyboard(QPoint pos, QSize size);
- void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
- std::u16string text_check_message);
- void ShowInlineKeyboard(Core::Frontend::InlineAppearParameters appear_parameters, QPoint pos,
- QSize size);
- void HideInlineKeyboard();
- void InlineTextChanged(Core::Frontend::InlineTextParameters text_parameters);
- void ExitKeyboard();
- signals:
- void SubmitNormalText(Service::AM::Applets::SwkbdResult result, std::u16string submitted_text,
- bool confirmed = false) const;
- void SubmitInlineText(Service::AM::Applets::SwkbdReplyType reply_type,
- std::u16string submitted_text, s32 cursor_position) const;
- public slots:
- void open() override;
- void reject() override;
- protected:
- /// We override the keyPressEvent for inputting text into the inline software keyboard.
- void keyPressEvent(QKeyEvent* event) override;
- private:
- enum class Direction {
- Left,
- Up,
- Right,
- Down,
- };
- enum class BottomOSKIndex {
- LowerCase,
- UpperCase,
- NumberPad,
- };
- /**
- * Moves and resizes the window to a specified position and size.
- *
- * @param pos Top-left window position
- * @param size Window size
- */
- void MoveAndResizeWindow(QPoint pos, QSize size);
- /**
- * Rescales all keyboard elements to account for High DPI displays.
- *
- * @param width Window width
- * @param height Window height
- * @param dpi_scale Display scaling factor
- */
- void RescaleKeyboardElements(float width, float height, float dpi_scale);
- /// Sets the keyboard type based on initialize_parameters.
- void SetKeyboardType();
- /// Sets the password mode based on initialize_parameters.
- void SetPasswordMode();
- /// Sets the text draw type based on initialize_parameters.
- void SetTextDrawType();
- /// Sets the controller image at the bottom left of the software keyboard.
- void SetControllerImage();
- /// Disables buttons based on initialize_parameters.
- void DisableKeyboardButtons();
- /// Changes whether the backspace or/and ok buttons should be enabled or disabled.
- void SetBackspaceOkEnabled();
- /**
- * Validates the input text sent in based on the parameters in initialize_parameters.
- *
- * @param input_text Input text
- *
- * @returns True if the input text is valid, false otherwise.
- */
- bool ValidateInputText(const QString& input_text);
- /// Switches between LowerCase and UpperCase (Shift and Caps Lock)
- void ChangeBottomOSKIndex();
- /// Processes a keyboard button click from the UI as normal keyboard input.
- void NormalKeyboardButtonClicked(QPushButton* button);
- /// Processes a keyboard button click from the UI as inline keyboard input.
- void InlineKeyboardButtonClicked(QPushButton* button);
- /**
- * Inserts a string of arbitrary length into the current_text at the current cursor position.
- * This is only used for the inline software keyboard.
- */
- void InlineTextInsertString(std::u16string_view string);
- /// Setup the mouse hover workaround for "focusing" buttons. This should only be called once.
- void SetupMouseHover();
- /**
- * Handles button presses and converts them into keyboard input.
- *
- * @tparam HIDButton The list of buttons that can be converted into keyboard input.
- */
- template <HIDButton... T>
- void HandleButtonPressedOnce();
- /**
- * Handles button holds and converts them into keyboard input.
- *
- * @tparam HIDButton The list of buttons that can be converted into keyboard input.
- */
- template <HIDButton... T>
- void HandleButtonHold();
- /**
- * Translates a button press to focus or click a keyboard button.
- *
- * @param button The button press to process.
- */
- void TranslateButtonPress(HIDButton button);
- /**
- * Moves the focus of a button in a certain direction.
- *
- * @param direction The direction to move.
- */
- void MoveButtonDirection(Direction direction);
- /**
- * Moves the text cursor in a certain direction.
- *
- * @param direction The direction to move.
- */
- void MoveTextCursorDirection(Direction direction);
- void StartInputThread();
- void StopInputThread();
- /// The thread where input is being polled and processed.
- void InputThread();
- std::unique_ptr<Ui::QtSoftwareKeyboardDialog> ui;
- Core::System& system;
- // True if it is the inline software keyboard.
- bool is_inline;
- // Common software keyboard initialize parameters.
- Core::Frontend::KeyboardInitializeParameters initialize_parameters;
- // Used only by the inline software keyboard since the QLineEdit or QTextEdit is hidden.
- std::u16string current_text;
- s32 cursor_position{0};
- static constexpr std::size_t NUM_ROWS_NORMAL = 5;
- static constexpr std::size_t NUM_COLUMNS_NORMAL = 12;
- static constexpr std::size_t NUM_ROWS_NUMPAD = 4;
- static constexpr std::size_t NUM_COLUMNS_NUMPAD = 4;
- // Stores the normal keyboard layout.
- std::array<std::array<std::array<QPushButton*, NUM_COLUMNS_NORMAL>, NUM_ROWS_NORMAL>, 2>
- keyboard_buttons;
- // Stores the numberpad keyboard layout.
- std::array<std::array<QPushButton*, NUM_COLUMNS_NUMPAD>, NUM_ROWS_NUMPAD> numberpad_buttons;
- // Contains a set of all buttons used in keyboard_buttons and numberpad_buttons.
- std::array<QPushButton*, 110> all_buttons;
- std::size_t row{0};
- std::size_t column{0};
- BottomOSKIndex bottom_osk_index{BottomOSKIndex::LowerCase};
- std::atomic<bool> caps_lock_enabled{false};
- std::unique_ptr<InputInterpreter> input_interpreter;
- std::thread input_thread;
- std::atomic<bool> input_thread_running{};
- };
- class QtSoftwareKeyboard final : public QObject, public Core::Frontend::SoftwareKeyboardApplet {
- Q_OBJECT
- public:
- explicit QtSoftwareKeyboard(GMainWindow& parent);
- ~QtSoftwareKeyboard() override;
- void InitializeKeyboard(
- bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters,
- std::function<void(Service::AM::Applets::SwkbdResult, std::u16string, bool)>
- submit_normal_callback_,
- std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
- submit_inline_callback_) override;
- void ShowNormalKeyboard() const override;
- void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
- std::u16string text_check_message) const override;
- void ShowInlineKeyboard(
- Core::Frontend::InlineAppearParameters appear_parameters) const override;
- void HideInlineKeyboard() const override;
- void InlineTextChanged(Core::Frontend::InlineTextParameters text_parameters) const override;
- void ExitKeyboard() const override;
- signals:
- void MainWindowInitializeKeyboard(
- bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters) const;
- void MainWindowShowNormalKeyboard() const;
- void MainWindowShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
- std::u16string text_check_message) const;
- void MainWindowShowInlineKeyboard(
- Core::Frontend::InlineAppearParameters appear_parameters) const;
- void MainWindowHideInlineKeyboard() const;
- void MainWindowInlineTextChanged(Core::Frontend::InlineTextParameters text_parameters) const;
- void MainWindowExitKeyboard() const;
- private:
- void SubmitNormalText(Service::AM::Applets::SwkbdResult result, std::u16string submitted_text,
- bool confirmed) const;
- void SubmitInlineText(Service::AM::Applets::SwkbdReplyType reply_type,
- std::u16string submitted_text, s32 cursor_position) const;
- mutable std::function<void(Service::AM::Applets::SwkbdResult, std::u16string, bool)>
- submit_normal_callback;
- mutable std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
- submit_inline_callback;
- };
|