mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-23 10:35:03 +00:00
Redesign layout closer original
This commit is contained in:
parent
569ab0c87f
commit
5a874b18ba
@ -446,6 +446,8 @@ set(IME_LIB src/core/libraries/ime/error_dialog.cpp
|
||||
src/core/libraries/ime/ime_dialog.h
|
||||
src/core/libraries/ime/ime_ui.cpp
|
||||
src/core/libraries/ime/ime_ui.h
|
||||
src/core/libraries/ime/ime_keyboard_layouts.cpp
|
||||
src/core/libraries/ime/ime_keyboard_layouts.h
|
||||
src/core/libraries/ime/ime_keyboard_ui.cpp
|
||||
src/core/libraries/ime/ime_keyboard_ui.h
|
||||
src/core/libraries/ime/ime.cpp
|
||||
|
@ -351,8 +351,15 @@ void ImeDialogUi::DrawKeyboard() {
|
||||
has_logged = true;
|
||||
}
|
||||
|
||||
bool done_pressed = false;
|
||||
|
||||
DrawVirtualKeyboard(state->current_text.begin(), state->max_text_length * 4,
|
||||
&state->input_changed, kb_mode, shift_enabled);
|
||||
&state->input_changed, kb_mode, shift_enabled, &done_pressed);
|
||||
|
||||
if (done_pressed) {
|
||||
*status = OrbisImeDialogStatus::Finished;
|
||||
result->endstatus = OrbisImeDialogEndStatus::Ok;
|
||||
}
|
||||
}
|
||||
|
||||
int ImeDialogUi::InputTextCallback(ImGuiInputTextCallbackData* data) {
|
||||
|
237
src/core/libraries/ime/ime_keyboard_layouts.cpp
Normal file
237
src/core/libraries/ime/ime_keyboard_layouts.cpp
Normal file
@ -0,0 +1,237 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "ime_keyboard_layouts.h"
|
||||
|
||||
const std::vector<Key> kUppercaseLayout = {
|
||||
// Row 1
|
||||
{0, 0, 1, 1, "1", "", KeyType::Text},
|
||||
{0, 1, 1, 1, "2", "", KeyType::Text},
|
||||
{0, 2, 1, 1, "3", "", KeyType::Text},
|
||||
{0, 3, 1, 1, "4", "", KeyType::Text},
|
||||
{0, 4, 1, 1, "5", "", KeyType::Text},
|
||||
{0, 5, 1, 1, "6", "", KeyType::Text},
|
||||
{0, 6, 1, 1, "7", "", KeyType::Text},
|
||||
{0, 7, 1, 1, "8", "", KeyType::Text},
|
||||
{0, 8, 1, 1, "9", "", KeyType::Text},
|
||||
{0, 9, 1, 1, "0", "", KeyType::Text},
|
||||
|
||||
// Row 2
|
||||
{1, 0, 1, 1, "Q", "", KeyType::Text},
|
||||
{1, 1, 1, 1, "W", "", KeyType::Text},
|
||||
{1, 2, 1, 1, "E", "", KeyType::Text},
|
||||
{1, 3, 1, 1, "R", "", KeyType::Text},
|
||||
{1, 4, 1, 1, "T", "", KeyType::Text},
|
||||
{1, 5, 1, 1, "Y", "", KeyType::Text},
|
||||
{1, 6, 1, 1, "U", "", KeyType::Text},
|
||||
{1, 7, 1, 1, "I", "", KeyType::Text},
|
||||
{1, 8, 1, 1, "O", "", KeyType::Text},
|
||||
{1, 9, 1, 1, "P", "", KeyType::Text},
|
||||
|
||||
// Row 3
|
||||
{2, 0, 1, 1, "A", "", KeyType::Text},
|
||||
{2, 1, 1, 1, "S", "", KeyType::Text},
|
||||
{2, 2, 1, 1, "D", "", KeyType::Text},
|
||||
{2, 3, 1, 1, "F", "", KeyType::Text},
|
||||
{2, 4, 1, 1, "G", "", KeyType::Text},
|
||||
{2, 5, 1, 1, "H", "", KeyType::Text},
|
||||
{2, 6, 1, 1, "J", "", KeyType::Text},
|
||||
{2, 7, 1, 1, "K", "", KeyType::Text},
|
||||
{2, 8, 1, 1, "L", "", KeyType::Text},
|
||||
{2, 9, 1, 1, "\"", "", KeyType::Text},
|
||||
|
||||
// Row 4
|
||||
{3, 0, 1, 1, "Z", "", KeyType::Text},
|
||||
{3, 1, 1, 1, "X", "", KeyType::Text},
|
||||
{3, 2, 1, 1, "C", "", KeyType::Text},
|
||||
{3, 3, 1, 1, "V", "", KeyType::Text},
|
||||
{3, 4, 1, 1, "B", "", KeyType::Text},
|
||||
{3, 5, 1, 1, "N", "", KeyType::Text},
|
||||
{3, 6, 1, 1, "M", "", KeyType::Text},
|
||||
{3, 7, 1, 1, "-", "", KeyType::Text},
|
||||
{3, 8, 1, 1, "_", "", KeyType::Text},
|
||||
{3, 9, 1, 1, "/", "", KeyType::Text},
|
||||
|
||||
// Row 5
|
||||
{4, 0, 1, 1, "SF", "L2", KeyType::Shift}, //{4, 0, 1, 1, "⇧", "L2", KeyType::Shift},
|
||||
{4, 1, 1, 1, "@#:", "L2+TRI", KeyType::SymbolsLayout},
|
||||
{4, 2, 1, 1, "à", "L3", KeyType::UnknownFunction},
|
||||
{4, 3, 4, 1, "Space", "TRI", KeyType::Space}, //{4, 3, 4, 1, "Space", "△", KeyType::Space},
|
||||
//{4, 4, 4, 1, "Space", "△", KeyType::Space},
|
||||
//{4, 5, 4, 1, "Space", "△", KeyType::Space},
|
||||
//{4, 6, 4, 1, "Space", "△", KeyType::Space},
|
||||
{4, 7, 1, 1, "", "", KeyType::Disabled},
|
||||
{4, 8, 2, 1, "DEL", "SQR", KeyType::Backspace}, //{4, 8, 2, 1, "⌫", "▢", KeyType::Backspace},
|
||||
//{4, 9, 2, 1, "⌫", "▢", KeyType::Backspace},
|
||||
|
||||
// Row 6
|
||||
{5, 0, 1, 1, "UP", "", KeyType::CursorUp}, //{5, 0, 1, 1, "▲", "", KeyType::CursorUp},
|
||||
{5, 1, 1, 1, "DN", "", KeyType::CursorDown}, //{5, 1, 1, 1, "▼", "", KeyType::CursorDown},
|
||||
{5, 2, 1, 1, "LT", "L1", KeyType::CursorLeft}, //{5, 2, 1, 1, "◀", "L1", KeyType::CursorLeft},
|
||||
{5, 3, 1, 1, "RT", "R1",
|
||||
KeyType::CursorRight}, //{5, 3, 1, 1, "▶", "R1", KeyType::CursorRight},
|
||||
{5, 4, 1, 1, "KB", "",
|
||||
KeyType::ToggleKeyboard}, //{5, 4, 1, 1, "⌨", "", KeyType::ToggleKeyboard},
|
||||
{5, 5, 1, 1, "...", "", KeyType::MoreOptions}, //{5, 5, 1, 1, "…", "", KeyType::MoreOptions},
|
||||
{5, 6, 1, 1, "CR", "R1",
|
||||
KeyType::ControllerAction}, //{5, 6, 1, 1, "🎮⊕", "R1", KeyType::ControllerAction},
|
||||
{5, 7, 1, 1, "", "", KeyType::Disabled},
|
||||
{5, 8, 2, 1, "Done", "R2", KeyType::Done},
|
||||
//{5, 9, 2, 1, "Done", "R2", KeyType::Done},
|
||||
};
|
||||
|
||||
const std::vector<Key> kLowercaseLayout = {
|
||||
// Row 1
|
||||
{0, 0, 1, 1, "1", "", KeyType::Text},
|
||||
{0, 1, 1, 1, "2", "", KeyType::Text},
|
||||
{0, 2, 1, 1, "3", "", KeyType::Text},
|
||||
{0, 3, 1, 1, "4", "", KeyType::Text},
|
||||
{0, 4, 1, 1, "5", "", KeyType::Text},
|
||||
{0, 5, 1, 1, "6", "", KeyType::Text},
|
||||
{0, 6, 1, 1, "7", "", KeyType::Text},
|
||||
{0, 7, 1, 1, "8", "", KeyType::Text},
|
||||
{0, 8, 1, 1, "9", "", KeyType::Text},
|
||||
{0, 9, 1, 1, "0", "", KeyType::Text},
|
||||
|
||||
// Row 2
|
||||
{1, 0, 1, 1, "q", "", KeyType::Text},
|
||||
{1, 1, 1, 1, "w", "", KeyType::Text},
|
||||
{1, 2, 1, 1, "e", "", KeyType::Text},
|
||||
{1, 3, 1, 1, "r", "", KeyType::Text},
|
||||
{1, 4, 1, 1, "t", "", KeyType::Text},
|
||||
{1, 5, 1, 1, "y", "", KeyType::Text},
|
||||
{1, 6, 1, 1, "u", "", KeyType::Text},
|
||||
{1, 7, 1, 1, "i", "", KeyType::Text},
|
||||
{1, 8, 1, 1, "o", "", KeyType::Text},
|
||||
{1, 9, 1, 1, "p", "", KeyType::Text},
|
||||
|
||||
// Row 3
|
||||
{2, 0, 1, 1, "a", "", KeyType::Text},
|
||||
{2, 1, 1, 1, "s", "", KeyType::Text},
|
||||
{2, 2, 1, 1, "d", "", KeyType::Text},
|
||||
{2, 3, 1, 1, "f", "", KeyType::Text},
|
||||
{2, 4, 1, 1, "g", "", KeyType::Text},
|
||||
{2, 5, 1, 1, "h", "", KeyType::Text},
|
||||
{2, 6, 1, 1, "j", "", KeyType::Text},
|
||||
{2, 7, 1, 1, "k", "", KeyType::Text},
|
||||
{2, 8, 1, 1, "l", "", KeyType::Text},
|
||||
{2, 9, 1, 1, "-", "", KeyType::Text},
|
||||
|
||||
// Row 4
|
||||
{3, 0, 1, 1, "z", "", KeyType::Text},
|
||||
{3, 1, 1, 1, "x", "", KeyType::Text},
|
||||
{3, 2, 1, 1, "c", "", KeyType::Text},
|
||||
{3, 3, 1, 1, "v", "", KeyType::Text},
|
||||
{3, 4, 1, 1, "b", "", KeyType::Text},
|
||||
{3, 5, 1, 1, "n", "", KeyType::Text},
|
||||
{3, 6, 1, 1, "m", "", KeyType::Text},
|
||||
{3, 7, 1, 1, "@", "", KeyType::Text},
|
||||
{3, 8, 1, 1, ".", "", KeyType::Text},
|
||||
{3, 9, 1, 1, "_", "", KeyType::Text},
|
||||
|
||||
// Row 5
|
||||
{4, 0, 1, 1, "SF", "L2", KeyType::Shift}, //{4, 0, 1, 1, "⇧", "L2", KeyType::Shift},
|
||||
{4, 1, 1, 1, "@#:", "L2+TRI",
|
||||
KeyType::SymbolsLayout}, //{4, 1, 1, 1, "@#:", "L2+△", KeyType::Symbols},
|
||||
{4, 2, 1, 1, "à", "L3", KeyType::UnknownFunction},
|
||||
{4, 3, 4, 1, "Space", "TRI", KeyType::Space}, //{4, 3, 4, 1, "Space", "△", KeyType::Space},
|
||||
//{4, 4, 4, 1, "Space", "△", KeyType::Space},
|
||||
//{4, 5, 4, 1, "Space", "△", KeyType::Space},
|
||||
//{4, 6, 4, 1, "Space", "△", KeyType::Space},
|
||||
{4, 7, 1, 1, "", "", KeyType::Disabled},
|
||||
{4, 8, 2, 1, "DEL", "SQR", KeyType::Backspace}, //{4, 8, 2, 1, "⌫", "▢", KeyType::Backspace},
|
||||
//{4, 8, 2, 1, "⌫", "▢", KeyType::Backspace},
|
||||
|
||||
// Row 6
|
||||
{5, 0, 1, 1, "UP", "", KeyType::CursorUp}, // {5, 0, 1, 1, "▲", "", KeyType::CursorUp},
|
||||
{5, 1, 1, 1, "DN", "", KeyType::CursorDown}, //{5, 1, 1, 1, "▼", "", KeyType::CursorDown},
|
||||
{5, 2, 1, 1, "LT", "L1", KeyType::CursorLeft}, //{5, 2, 1, 1, "◀", "L1", KeyType::CursorLeft},
|
||||
{5, 3, 1, 1, "RT", "R1",
|
||||
KeyType::CursorRight}, //{5, 3, 1, 1, "▶", "R1", KeyType::CursorRight},
|
||||
{5, 4, 1, 1, "KB", "",
|
||||
KeyType::ToggleKeyboard}, //{5, 4, 1, 1, "⌨", "", KeyType::ToggleKeyboard},
|
||||
{5, 5, 1, 1, "...", "", KeyType::MoreOptions}, //{5, 5, 1, 1, "…", "", KeyType::MoreOptions},
|
||||
{5, 6, 1, 1, "CR", "R1",
|
||||
KeyType::ControllerAction}, //{5, 6, 1, 1, "🎮⊕", "R1", KeyType::ControllerAction},
|
||||
{5, 7, 1, 1, "", "", KeyType::Disabled},
|
||||
{5, 8, 2, 1, "Done", "R2", KeyType::Done},
|
||||
//{5, 9, 2, 1, "Done", "R2", KeyType::Done},
|
||||
};
|
||||
|
||||
const std::vector<Key> kSymbols1Layout = {
|
||||
// Row 1
|
||||
{0, 0, 1, 1, "!", "", KeyType::Text},
|
||||
{0, 1, 1, 1, "?", "", KeyType::Text},
|
||||
{0, 2, 1, 1, "\"", "", KeyType::Text},
|
||||
{0, 3, 1, 1, "'", "", KeyType::Text},
|
||||
{0, 4, 1, 1, "#", "", KeyType::Text},
|
||||
{0, 5, 1, 1, "%", "", KeyType::Text},
|
||||
{0, 6, 1, 1, "(", "", KeyType::Text},
|
||||
{0, 7, 1, 1, ")", "", KeyType::Text},
|
||||
{0, 8, 1, 1, "()", "", KeyType::Text},
|
||||
{0, 9, 1, 1, "/", "", KeyType::Text},
|
||||
|
||||
// Row 2
|
||||
{1, 0, 1, 1, "-", "", KeyType::Text},
|
||||
{1, 1, 1, 1, "_", "", KeyType::Text},
|
||||
{1, 2, 1, 1, ",", "", KeyType::Text},
|
||||
{1, 3, 1, 1, ".", "", KeyType::Text},
|
||||
{1, 4, 1, 1, ":", "", KeyType::Text},
|
||||
{1, 5, 1, 1, ";", "", KeyType::Text},
|
||||
{1, 6, 1, 1, "*", "", KeyType::Text},
|
||||
{1, 7, 1, 1, "+", "", KeyType::Text},
|
||||
{1, 8, 1, 1, "=", "", KeyType::Text},
|
||||
{1, 9, 1, 1, "&", "", KeyType::Text},
|
||||
|
||||
// Row 3
|
||||
{2, 0, 1, 1, "<", "", KeyType::Text},
|
||||
{2, 1, 1, 1, ">", "", KeyType::Text},
|
||||
{2, 2, 1, 1, "@", "", KeyType::Text},
|
||||
{2, 3, 1, 1, "[", "", KeyType::Text},
|
||||
{2, 4, 1, 1, "]", "", KeyType::Text},
|
||||
{2, 5, 1, 1, "[]", "", KeyType::Text},
|
||||
{2, 6, 1, 1, "{", "", KeyType::Text},
|
||||
{2, 7, 1, 1, "}", "", KeyType::Text},
|
||||
{2, 8, 1, 1, "{}", "", KeyType::Text},
|
||||
{2, 9, 1, 2, "→", "", KeyType::UnknownFunction}, // Next symbols page (SYM2)
|
||||
|
||||
// Row 4
|
||||
{3, 0, 1, 1, "\\", "", KeyType::Text},
|
||||
{3, 1, 1, 1, "|", "", KeyType::Text},
|
||||
{3, 2, 1, 1, "^", "", KeyType::Text},
|
||||
{3, 3, 1, 1, "`", "", KeyType::Text},
|
||||
{3, 4, 1, 1, "$", "", KeyType::Text},
|
||||
{3, 5, 1, 1, "€", "", KeyType::Text},
|
||||
{3, 6, 1, 1, "´", "", KeyType::Text},
|
||||
{3, 7, 1, 1, "ˊ", "", KeyType::Text},
|
||||
{3, 8, 1, 1, "ˊ", "", KeyType::Text},
|
||||
//{3, 9, 1, 2, "→", "", KeyType::UnknownFunction}, // Next symbols page (SYM2)
|
||||
|
||||
// Row 5
|
||||
{4, 0, 1, 1, "", "", KeyType::Disabled},
|
||||
{4, 1, 1, 1, "ABC", "L2+TRI",
|
||||
KeyType::TextLayout}, //{4, 1, 1, 1, "ABC", "L2+△", KeyType::Symbols},
|
||||
{4, 2, 1, 1, "", "", KeyType::Disabled},
|
||||
{4, 3, 4, 1, "Space", "TRI", KeyType::Space}, //{4, 3, 4, 1, "Space", "△", KeyType::Space},
|
||||
//{4, 4, 4, 1, "Space", "△", KeyType::Space},
|
||||
//{4, 5, 4, 1, "Space", "△", KeyType::Space},
|
||||
//{4, 6, 4, 1, "Space", "△", KeyType::Space},
|
||||
{4, 7, 1, 1, "", "", KeyType::Disabled},
|
||||
{4, 8, 2, 1, "DEL", "SQR", KeyType::Backspace}, //{4, 8, 2, 1, "⌫", "▢", KeyType::Backspace},
|
||||
//{4, 9, 2, 1, "⌫", "▢", KeyType::Backspace},
|
||||
|
||||
// Row 6
|
||||
{5, 0, 1, 1, "UP", "", KeyType::CursorUp}, // {5, 0, 1, 1, "▲", "", KeyType::CursorUp},
|
||||
{5, 1, 1, 1, "DN", "", KeyType::CursorDown}, //{5, 1, 1, 1, "▼", "", KeyType::CursorDown},
|
||||
{5, 2, 1, 1, "LT", "L1", KeyType::CursorLeft}, //{5, 2, 1, 1, "◀", "L1", KeyType::CursorLeft},
|
||||
{5, 3, 1, 1, "RT", "R1",
|
||||
KeyType::CursorRight}, //{5, 3, 1, 1, "▶", "R1", KeyType::CursorRight},
|
||||
{5, 4, 1, 1, "KB", "",
|
||||
KeyType::ToggleKeyboard}, //{5, 4, 1, 1, "⌨", "", KeyType::ToggleKeyboard},
|
||||
{5, 5, 1, 1, "...", "", KeyType::MoreOptions}, //{5, 5, 1, 1, "…", "", KeyType::MoreOptions},
|
||||
{5, 6, 1, 1, "CR", "R1",
|
||||
KeyType::ControllerAction}, //{5, 6, 1, 1, "🎮⊕", "R1", KeyType::ControllerAction},
|
||||
{5, 7, 1, 1, "", "", KeyType::Disabled},
|
||||
{5, 8, 2, 1, "Done", "R2", KeyType::Done},
|
||||
//{5, 9, 2, 1, "Done", "R2", KeyType::Done},
|
||||
};
|
41
src/core/libraries/ime/ime_keyboard_layouts.h
Normal file
41
src/core/libraries/ime/ime_keyboard_layouts.h
Normal file
@ -0,0 +1,41 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum class KeyType {
|
||||
Text, // Inserts character(s) into input buffer
|
||||
Backspace, // Deletes last character
|
||||
Space, // Adds space
|
||||
Enter, // Submits input
|
||||
Shift, // Toggle uppercase/lowercase
|
||||
SymbolsLayout, // Switch to symbols layout
|
||||
TextLayout, // Switch to text layout
|
||||
Done, // Finish and close keyboard
|
||||
CursorLeft,
|
||||
CursorRight,
|
||||
CursorUp,
|
||||
CursorDown,
|
||||
ToggleKeyboard, // Toggles keyboard layout
|
||||
MoreOptions, // "..." button
|
||||
ControllerAction, // e.g. R3 🎮⊕
|
||||
Disabled, // Filler or placeholder
|
||||
UnknownFunction, // now same as disabled
|
||||
};
|
||||
|
||||
struct Key {
|
||||
int row;
|
||||
int col;
|
||||
int colspan = 1;
|
||||
int rowspan = 1;
|
||||
std::string label;
|
||||
std::string controller_hint;
|
||||
KeyType type = KeyType::Text; // default to Text input
|
||||
};
|
||||
|
||||
extern const std::vector<Key> kUppercaseLayout;
|
||||
extern const std::vector<Key> kLowercaseLayout;
|
||||
extern const std::vector<Key> kSymbols1Layout;
|
@ -1,96 +1,134 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <imgui.h>
|
||||
#include "ime_keyboard_layouts.h"
|
||||
#include "ime_keyboard_ui.h"
|
||||
|
||||
using namespace ImGui;
|
||||
|
||||
void DrawVirtualKeyboard(char* buffer, std::size_t buffer_capacity, bool* input_changed,
|
||||
KeyboardMode& kb_mode, bool& shift_enabled) {
|
||||
const char* row1_letters = "QWERTYUIOP";
|
||||
const char* row2_letters = "ASDFGHJKL";
|
||||
const char* row3_letters = "ZXCVBNM";
|
||||
KeyboardMode& kb_mode, bool& shift_enabled, bool* done_pressed) {
|
||||
const std::vector<Key>* layout = nullptr;
|
||||
|
||||
const char* row1_symbols = "1234567890";
|
||||
const char* row2_symbols = "!@#$%^&*()";
|
||||
const char* row3_symbols = "-_=+[]{}";
|
||||
if (kb_mode == KeyboardMode::Symbols) {
|
||||
layout = &kSymbols1Layout;
|
||||
} else {
|
||||
layout = shift_enabled ? &kUppercaseLayout : &kLowercaseLayout;
|
||||
}
|
||||
|
||||
auto draw_row = [&](const char* row, float offset_x) {
|
||||
ImGui::SetCursorPosX(offset_x);
|
||||
for (int i = 0; row[i] != '\0'; ++i) {
|
||||
char ch = shift_enabled ? row[i] : static_cast<char>(tolower(row[i]));
|
||||
std::string key(1, ch);
|
||||
if (ImGui::Button(key.c_str(), ImVec2(35, 35))) {
|
||||
size_t len = std::strlen(buffer);
|
||||
if (len + 1 < buffer_capacity) {
|
||||
buffer[len] = ch;
|
||||
buffer[len + 1] = '\0';
|
||||
if (input_changed) {
|
||||
*input_changed = true;
|
||||
RenderKeyboardLayout(*layout, buffer, buffer_capacity, input_changed, kb_mode, shift_enabled,
|
||||
done_pressed);
|
||||
}
|
||||
|
||||
void RenderKeyboardLayout(const std::vector<Key>& layout, char* buffer, std::size_t buffer_capacity,
|
||||
bool* input_changed, KeyboardMode& kb_mode, bool& shift_enabled,
|
||||
bool* done_pressed) {
|
||||
// Define desired total layout size (in pixels)
|
||||
const float layout_width = 485.0f;
|
||||
const float layout_height = 200.0f;
|
||||
const float cell_spacing = 4.0f;
|
||||
const float hint_padding = 2.0f;
|
||||
|
||||
// Find max rows and columns
|
||||
int max_col = 0;
|
||||
int max_row = 0;
|
||||
for (const Key& key : layout) {
|
||||
max_col = std::max(max_col, key.col + static_cast<int>(key.colspan));
|
||||
max_row = std::max(max_row, key.row + static_cast<int>(key.rowspan));
|
||||
}
|
||||
|
||||
// Calculate cell size dynamically
|
||||
const float cell_width = (layout_width - (max_col - 1) * cell_spacing) / max_col;
|
||||
const float cell_height = (layout_height - (max_row - 1) * cell_spacing) / max_row;
|
||||
|
||||
const ImVec2 origin = ImGui::GetCursorScreenPos();
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
for (const Key& key : layout) {
|
||||
float x = origin.x + key.col * (cell_width + cell_spacing);
|
||||
float y = origin.y + key.row * (cell_height + cell_spacing);
|
||||
|
||||
ImVec2 pos(x, y);
|
||||
ImVec2 size(key.colspan * cell_width + (key.colspan - 1) * cell_spacing,
|
||||
key.rowspan * cell_height + (key.rowspan - 1) * cell_spacing);
|
||||
|
||||
std::string button_id =
|
||||
key.label.empty() ? "##empty_" + std::to_string(key.row) + "_" + std::to_string(key.col)
|
||||
: key.label;
|
||||
|
||||
ImGui::SetCursorScreenPos(pos);
|
||||
|
||||
if (ImGui::Button(button_id.c_str(), size)) {
|
||||
switch (key.type) {
|
||||
case KeyType::Text:
|
||||
if (!key.label.empty()) {
|
||||
size_t len = std::strlen(buffer);
|
||||
if (len + key.label.size() < buffer_capacity) {
|
||||
std::strcat(buffer, key.label.c_str());
|
||||
if (input_changed)
|
||||
*input_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
}
|
||||
ImGui::NewLine();
|
||||
};
|
||||
|
||||
// SHIFT status label
|
||||
if (shift_enabled) {
|
||||
ImGui::SetCursorPosX(20.0f);
|
||||
ImGui::TextColored(ImVec4(0.2f, 0.6f, 1.0f, 1.0f), "SHIFT ENABLED");
|
||||
}
|
||||
|
||||
draw_row(kb_mode == KeyboardMode::Letters ? row1_letters : row1_symbols, 20.0f);
|
||||
draw_row(kb_mode == KeyboardMode::Letters ? row2_letters : row2_symbols, 35.0f);
|
||||
draw_row(kb_mode == KeyboardMode::Letters ? row3_letters : row3_symbols, 80.0f);
|
||||
|
||||
ImGui::SetCursorPosX(20.0f);
|
||||
|
||||
bool highlight = shift_enabled;
|
||||
if (highlight) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.6f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
if (ImGui::Button("SHIFT", ImVec2(75, 35))) {
|
||||
shift_enabled = !shift_enabled;
|
||||
}
|
||||
|
||||
if (highlight) {
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("SPACE", ImVec2(100, 35))) {
|
||||
size_t len = std::strlen(buffer);
|
||||
if (len + 1 < buffer_capacity) {
|
||||
buffer[len] = ' ';
|
||||
buffer[len + 1] = '\0';
|
||||
if (input_changed) {
|
||||
*input_changed = true;
|
||||
break;
|
||||
case KeyType::Backspace:
|
||||
if (buffer[0] != '\0') {
|
||||
size_t len = std::strlen(buffer);
|
||||
buffer[len - 1] = '\0';
|
||||
if (input_changed)
|
||||
*input_changed = true;
|
||||
}
|
||||
break;
|
||||
case KeyType::Space:
|
||||
if (std::strlen(buffer) + 1 < buffer_capacity) {
|
||||
std::strcat(buffer, " ");
|
||||
if (input_changed)
|
||||
*input_changed = true;
|
||||
}
|
||||
break;
|
||||
case KeyType::Enter:
|
||||
case KeyType::Done:
|
||||
if (done_pressed)
|
||||
*done_pressed = true;
|
||||
break;
|
||||
case KeyType::Shift:
|
||||
shift_enabled = !shift_enabled;
|
||||
break;
|
||||
case KeyType::SymbolsLayout:
|
||||
kb_mode = KeyboardMode::Symbols;
|
||||
break;
|
||||
case KeyType::TextLayout:
|
||||
kb_mode = KeyboardMode::Letters;
|
||||
break;
|
||||
case KeyType::ToggleKeyboard:
|
||||
kb_mode = (kb_mode == KeyboardMode::Letters) ? KeyboardMode::Symbols
|
||||
: KeyboardMode::Letters;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
// Controller hint
|
||||
if (!key.controller_hint.empty()) {
|
||||
float original_font_size = ImGui::GetFontSize();
|
||||
float small_font_size = original_font_size * 0.5f;
|
||||
|
||||
if (ImGui::Button("DELETE", ImVec2(75, 35))) {
|
||||
size_t len = std::strlen(buffer);
|
||||
if (len > 0) {
|
||||
buffer[len - 1] = '\0';
|
||||
if (input_changed) {
|
||||
*input_changed = true;
|
||||
}
|
||||
ImVec2 text_size =
|
||||
ImGui::CalcTextSize(key.controller_hint.c_str(), nullptr, false, -1.0f) *
|
||||
(small_font_size / original_font_size);
|
||||
|
||||
ImVec2 text_pos = pos + ImVec2(hint_padding, hint_padding);
|
||||
ImVec2 bg_min = text_pos - ImVec2(1.0f, 1.0f);
|
||||
ImVec2 bg_max = text_pos + text_size + ImVec2(2.0f, 1.0f);
|
||||
|
||||
ImU32 bg_color = IM_COL32(0, 0, 0, 160);
|
||||
ImU32 fg_color = IM_COL32(255, 255, 255, 200);
|
||||
|
||||
draw_list->AddRectFilled(bg_min, bg_max, bg_color, 2.0f);
|
||||
draw_list->AddText(nullptr, small_font_size, text_pos, fg_color,
|
||||
key.controller_hint.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(kb_mode == KeyboardMode::Letters ? "123" : "ABC", ImVec2(60, 35))) {
|
||||
kb_mode =
|
||||
(kb_mode == KeyboardMode::Letters) ? KeyboardMode::Symbols : KeyboardMode::Letters;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,23 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/cstring.h"
|
||||
#include "common/types.h"
|
||||
#include "core/libraries/ime/ime_dialog.h"
|
||||
#include "core/libraries/ime/ime_keyboard_layouts.h"
|
||||
|
||||
enum class KeyboardMode { Letters, Symbols };
|
||||
|
||||
// Renders the virtual keyboard and modifies buffer if a key is pressed.
|
||||
// Flags:
|
||||
// - `input_changed`: set to true if the text buffer changes
|
||||
// - `done_pressed`: set to true if the Done/Enter key was pressed
|
||||
void DrawVirtualKeyboard(char* buffer, std::size_t buffer_capacity, bool* input_changed,
|
||||
KeyboardMode& kb_mode, bool& shift_enabled);
|
||||
KeyboardMode& kb_mode, bool& shift_enabled, bool* done_pressed);
|
||||
|
||||
// Renders a specific keyboard layout and processes key events.
|
||||
void RenderKeyboardLayout(const std::vector<Key>& layout, char* buffer, std::size_t buffer_capacity,
|
||||
bool* input_changed, KeyboardMode& kb_mode, bool& shift_enabled,
|
||||
bool* done_pressed);
|
||||
|
@ -195,12 +195,19 @@ void ImeUi::DrawKeyboard() {
|
||||
|
||||
static bool has_logged = false;
|
||||
if (!has_logged) {
|
||||
LOG_INFO(Lib_ImeDialog, "Virtual keyboard used from Ime");
|
||||
LOG_INFO(Lib_Ime, "Virtual keyboard used from ImeUi");
|
||||
has_logged = true;
|
||||
}
|
||||
|
||||
DrawVirtualKeyboard(state->current_text.begin(), ime_param->maxTextLength * 4, nullptr, kb_mode,
|
||||
shift_enabled);
|
||||
bool input_changed = false;
|
||||
bool done_pressed = false;
|
||||
|
||||
DrawVirtualKeyboard(state->current_text.begin(), state->current_text.capacity(), &input_changed,
|
||||
kb_mode, shift_enabled, &done_pressed);
|
||||
|
||||
if (done_pressed) {
|
||||
state->SendEnterEvent(); // Submit action
|
||||
}
|
||||
}
|
||||
|
||||
int ImeUi::InputTextCallback(ImGuiInputTextCallbackData* data) {
|
||||
|
Loading…
Reference in New Issue
Block a user