Redesign layout closer original

This commit is contained in:
w1naenator 2025-03-28 17:33:22 +02:00
parent 569ab0c87f
commit 5a874b18ba
7 changed files with 428 additions and 82 deletions

View File

@ -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

View File

@ -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) {

View 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},
};

View 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;

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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) {